fixes for pet handling, uploads, clear storage button, remove button while reconnecting, put paused to online/paused, put visible to online
This commit is contained in:
@@ -28,23 +28,6 @@ public class CharacterData
|
||||
[JsonProperty]
|
||||
public string PalettePlusPalette { get; set; } = string.Empty;
|
||||
|
||||
public void AddFileReplacement(ObjectKind objectKind, FileReplacement fileReplacement)
|
||||
{
|
||||
if (!fileReplacement.HasFileReplacement) return;
|
||||
|
||||
if (!FileReplacements.ContainsKey(objectKind)) FileReplacements.Add(objectKind, new HashSet<FileReplacement>());
|
||||
|
||||
var existingReplacement = FileReplacements[objectKind].SingleOrDefault(f => string.Equals(f.ResolvedPath, fileReplacement.ResolvedPath, StringComparison.OrdinalIgnoreCase));
|
||||
if (existingReplacement != null)
|
||||
{
|
||||
existingReplacement.GamePaths.AddRange(fileReplacement.GamePaths.Where(e => !existingReplacement.GamePaths.Contains(e, StringComparer.OrdinalIgnoreCase)));
|
||||
}
|
||||
else
|
||||
{
|
||||
FileReplacements[objectKind].Add(fileReplacement);
|
||||
}
|
||||
}
|
||||
|
||||
public API.Data.CharacterData ToAPI()
|
||||
{
|
||||
var fileReplacements = FileReplacements.ToDictionary(k => k.Key, k => k.Value.Where(f => f.HasFileReplacement && !f.IsFileSwap).GroupBy(f => f.Hash, StringComparer.OrdinalIgnoreCase).Select(g =>
|
||||
@@ -76,7 +59,7 @@ public class CharacterData
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new();
|
||||
foreach (var fileReplacement in FileReplacements.SelectMany(k => k.Value).OrderBy(a => a.GamePaths[0], StringComparer.Ordinal))
|
||||
foreach (var fileReplacement in FileReplacements.SelectMany(k => k.Value).OrderBy(a => a.GamePaths.First(), StringComparer.Ordinal))
|
||||
{
|
||||
stringBuilder.AppendLine(fileReplacement.ToString());
|
||||
}
|
||||
|
||||
@@ -8,18 +8,18 @@ public class FileReplacement
|
||||
{
|
||||
public FileReplacement(List<string> gamePaths, string filePath, FileCacheManager fileDbManager)
|
||||
{
|
||||
GamePaths = gamePaths.Select(g => g.Replace('\\', '/')).ToList();
|
||||
GamePaths = gamePaths.Select(g => g.Replace('\\', '/')).ToHashSet(StringComparer.Ordinal);
|
||||
ResolvedPath = filePath.Replace('\\', '/');
|
||||
HashLazy = new(() => !IsFileSwap ? fileDbManager.GetFileCacheByPath(ResolvedPath)?.Hash ?? string.Empty : string.Empty);
|
||||
}
|
||||
|
||||
public bool Computed => IsFileSwap || !HasFileReplacement || !string.IsNullOrEmpty(Hash);
|
||||
|
||||
public List<string> GamePaths { get; init; } = new();
|
||||
public HashSet<string> GamePaths { get; init; } = new();
|
||||
|
||||
public bool HasFileReplacement => GamePaths.Count >= 1 && GamePaths.Any(p => !string.Equals(p, ResolvedPath, StringComparison.Ordinal));
|
||||
|
||||
public bool IsFileSwap => !Regex.IsMatch(ResolvedPath, @"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript) && !string.Equals(GamePaths[0], ResolvedPath, StringComparison.Ordinal);
|
||||
public bool IsFileSwap => !Regex.IsMatch(ResolvedPath, @"^[a-zA-Z]:(/|\\)", RegexOptions.ECMAScript) && !string.Equals(GamePaths.First(), ResolvedPath, StringComparison.Ordinal);
|
||||
|
||||
public string Hash => HashLazy.Value;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using MareSynchronos.Utils;
|
||||
using Penumbra.String;
|
||||
using MareSynchronos.API.Data.Enum;
|
||||
using MareSynchronos.Mediator;
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace MareSynchronos.Models;
|
||||
|
||||
@@ -57,6 +59,8 @@ public class GameObjectHandler : MediatorSubscriberBase
|
||||
|
||||
public byte[] EquipSlotData { get; set; } = new byte[40];
|
||||
public byte[] CustomizeData { get; set; } = new byte[26];
|
||||
private Task? _petClearTask;
|
||||
private CancellationTokenSource? _petCts = new();
|
||||
public byte? HatState { get; set; }
|
||||
public byte? VisorWeaponState { get; set; }
|
||||
private bool _doNotSendUpdate;
|
||||
@@ -64,8 +68,14 @@ public class GameObjectHandler : MediatorSubscriberBase
|
||||
public unsafe bool CheckAndUpdateObject()
|
||||
{
|
||||
var curPtr = CurrentAddress;
|
||||
if (curPtr != IntPtr.Zero)
|
||||
if (curPtr != IntPtr.Zero && (IntPtr)((Character*)curPtr)->GameObject.DrawObject != IntPtr.Zero)
|
||||
{
|
||||
if (ObjectKind == ObjectKind.Pet && _petCts != null)
|
||||
{
|
||||
Logger.Debug("Cancelling PetClearTask for " + ObjectKind);
|
||||
_petCts?.Cancel();
|
||||
_petCts = null;
|
||||
}
|
||||
var chara = (Character*)curPtr;
|
||||
bool addr = Address == IntPtr.Zero || Address != curPtr;
|
||||
bool equip = CompareAndUpdateByteData(chara->EquipSlotData, chara->CustomizeData);
|
||||
@@ -93,11 +103,32 @@ public class GameObjectHandler : MediatorSubscriberBase
|
||||
Address = IntPtr.Zero;
|
||||
DrawObjectAddress = IntPtr.Zero;
|
||||
Logger.Verbose(ObjectKind + " Changed: " + _name + ", now: " + Address + ", " + DrawObjectAddress);
|
||||
if (_sendUpdates && ObjectKind == ObjectKind.Pet)
|
||||
{
|
||||
_petCts?.Cancel();
|
||||
_petCts?.Dispose();
|
||||
_petCts = new();
|
||||
var token = _petCts.Token;
|
||||
_petClearTask = Task.Run(() => PetClearTask(token), token);
|
||||
}
|
||||
else if (_sendUpdates)
|
||||
{
|
||||
Logger.Debug("Sending ClearCachedForObjectMessage for " + ObjectKind);
|
||||
Mediator.Publish(new ClearCacheForObjectMessage(this));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task PetClearTask(CancellationToken token)
|
||||
{
|
||||
Logger.Debug("Running PetClearTask for " + ObjectKind);
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
|
||||
Logger.Debug("Sending ClearCachedForObjectMessage for " + ObjectKind);
|
||||
Mediator.Publish(new ClearCacheForObjectMessage(this));
|
||||
}
|
||||
|
||||
private unsafe bool CompareAndUpdateByteData(byte* equipSlotData, byte* customizeData)
|
||||
{
|
||||
bool hasChanges = false;
|
||||
|
||||
Reference in New Issue
Block a user