save but not send hat/visor/weapon state, fix sync of mounts, speed up cache generation a bit
This commit is contained in:
@@ -125,6 +125,14 @@ public class CharacterDataFactory
|
||||
//Logger.Verbose("Adding File Replacement for Material " + fileName);
|
||||
var mtrlPath = fileName.Split("|")[2];
|
||||
|
||||
if (cache.FileReplacements.ContainsKey(objectKind))
|
||||
{
|
||||
if (cache.FileReplacements[objectKind].Any(c => c.ResolvedPath.Contains(mtrlPath)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var mtrlFileReplacement = CreateFileReplacement(mtrlPath);
|
||||
DebugPrint(mtrlFileReplacement, objectKind, "Material", inheritanceLevel);
|
||||
|
||||
@@ -155,6 +163,14 @@ public class CharacterDataFactory
|
||||
|
||||
//Logger.Verbose("Adding File Replacement for Texture " + texPath);
|
||||
|
||||
if (cache.FileReplacements.ContainsKey(objectKind))
|
||||
{
|
||||
if (cache.FileReplacements[objectKind].Any(c => c.GamePaths.Contains(texPath)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var texFileReplacement = CreateFileReplacement(texPath, doNotReverseResolve);
|
||||
DebugPrint(texFileReplacement, objectKind, "Texture", inheritanceLevel);
|
||||
|
||||
|
||||
@@ -73,21 +73,45 @@ public class CachedPlayer
|
||||
List<ObjectKind> charaDataToUpdate = new List<ObjectKind>();
|
||||
foreach (var objectKind in Enum.GetValues<ObjectKind>())
|
||||
{
|
||||
bool doesntContainKey = !_cachedData.FileReplacements.ContainsKey(objectKind)
|
||||
|| (_cachedData.FileReplacements.ContainsKey(objectKind) && !characterData.FileReplacements.ContainsKey(objectKind));
|
||||
if (doesntContainKey)
|
||||
_cachedData.FileReplacements.TryGetValue(objectKind, out var existingFileReplacements);
|
||||
characterData.FileReplacements.TryGetValue(objectKind, out var newFileReplacements);
|
||||
_cachedData.GlamourerData.TryGetValue(objectKind, out var existingGlamourerData);
|
||||
characterData.GlamourerData.TryGetValue(objectKind, out var newGlamourerData);
|
||||
|
||||
bool hasNewButNotOldFileReplacements = newFileReplacements != null && existingFileReplacements == null;
|
||||
bool hasOldButNotNewFileReplacements = existingFileReplacements != null && newFileReplacements == null;
|
||||
bool hasNewButNotOldGlamourerData = newGlamourerData != null && existingGlamourerData == null;
|
||||
bool hasOldButNotNewGlamourerData = existingGlamourerData != null && newGlamourerData == null;
|
||||
bool hasNewAndOldFileReplacements = newFileReplacements != null && existingFileReplacements != null;
|
||||
bool hasNewAndOldGlamourerData = newGlamourerData != null && existingGlamourerData != null;
|
||||
|
||||
if (hasNewButNotOldFileReplacements || hasOldButNotNewFileReplacements || hasNewButNotOldGlamourerData || hasOldButNotNewGlamourerData)
|
||||
{
|
||||
Logger.Debug("Updating " + objectKind);
|
||||
charaDataToUpdate.Add(objectKind);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool listsAreEqual = Enumerable.SequenceEqual(_cachedData.FileReplacements[objectKind], characterData.FileReplacements[objectKind]);
|
||||
bool glamourerDataDifferent = _cachedData.GlamourerData[objectKind] != characterData.GlamourerData[objectKind];
|
||||
if (!listsAreEqual || glamourerDataDifferent)
|
||||
if (hasNewAndOldFileReplacements)
|
||||
{
|
||||
Logger.Debug("Updating " + objectKind);
|
||||
bool listsAreEqual = Enumerable.SequenceEqual(_cachedData.FileReplacements[objectKind], characterData.FileReplacements[objectKind]);
|
||||
if (!listsAreEqual)
|
||||
{
|
||||
Logger.Debug("Updating " + objectKind);
|
||||
charaDataToUpdate.Add(objectKind);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
charaDataToUpdate.Add(objectKind);
|
||||
if (hasNewAndOldGlamourerData)
|
||||
{
|
||||
bool glamourerDataDifferent = _cachedData.GlamourerData[objectKind] != characterData.GlamourerData[objectKind];
|
||||
if (glamourerDataDifferent)
|
||||
{
|
||||
Logger.Debug("Updating " + objectKind);
|
||||
charaDataToUpdate.Add(objectKind);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,10 +162,7 @@ public class CachedPlayer
|
||||
|
||||
foreach (var kind in objectKind)
|
||||
{
|
||||
if (_cachedData.GlamourerData.ContainsKey(kind))
|
||||
{
|
||||
ApplyCustomizationData(kind);
|
||||
}
|
||||
ApplyCustomizationData(kind);
|
||||
}
|
||||
}, downloadToken).ContinueWith(task =>
|
||||
{
|
||||
@@ -195,14 +216,15 @@ public class CachedPlayer
|
||||
private unsafe void ApplyCustomizationData(ObjectKind objectKind)
|
||||
{
|
||||
if (PlayerCharacter is null) return;
|
||||
_cachedData.GlamourerData.TryGetValue(objectKind, out var glamourerData);
|
||||
|
||||
if (objectKind == ObjectKind.Player)
|
||||
{
|
||||
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter!.Address);
|
||||
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter.Address);
|
||||
RequestedPenumbraRedraw = true;
|
||||
Logger.Debug(
|
||||
$"Request Redraw for {PlayerName}");
|
||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], PlayerCharacter!);
|
||||
_ipcManager.GlamourerApplyAll(glamourerData, PlayerCharacter.Address);
|
||||
}
|
||||
else if (objectKind == ObjectKind.Minion)
|
||||
{
|
||||
@@ -210,7 +232,7 @@ public class CachedPlayer
|
||||
if (minion != null)
|
||||
{
|
||||
Logger.Debug($"Request Redraw for Minion");
|
||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], obj: (IntPtr)minion);
|
||||
_ipcManager.GlamourerApplyAll(glamourerData, obj: (IntPtr)minion);
|
||||
}
|
||||
}
|
||||
else if (objectKind == ObjectKind.Pet)
|
||||
@@ -219,7 +241,7 @@ public class CachedPlayer
|
||||
if (pet != IntPtr.Zero)
|
||||
{
|
||||
Logger.Debug("Request Redraw for Pet");
|
||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], pet);
|
||||
_ipcManager.GlamourerApplyAll(glamourerData, pet);
|
||||
}
|
||||
}
|
||||
else if (objectKind == ObjectKind.Companion)
|
||||
@@ -228,7 +250,7 @@ public class CachedPlayer
|
||||
if (companion != IntPtr.Zero)
|
||||
{
|
||||
Logger.Debug("Request Redraw for Companion");
|
||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], companion);
|
||||
_ipcManager.GlamourerApplyAll(glamourerData, companion);
|
||||
}
|
||||
}
|
||||
else if (objectKind == ObjectKind.Mount)
|
||||
|
||||
@@ -116,9 +116,9 @@ namespace MareSynchronos.Managers
|
||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||
}
|
||||
|
||||
public void GlamourerApplyAll(string customization, IntPtr obj)
|
||||
public void GlamourerApplyAll(string? customization, IntPtr obj)
|
||||
{
|
||||
if (!CheckGlamourerApi()) return;
|
||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||
var gameObj = _dalamudUtil.CreateGameObject(obj);
|
||||
if (gameObj != null)
|
||||
{
|
||||
@@ -126,12 +126,6 @@ namespace MareSynchronos.Managers
|
||||
}
|
||||
}
|
||||
|
||||
public void GlamourerApplyAll(string customization, GameObject character)
|
||||
{
|
||||
if (!CheckGlamourerApi()) return;
|
||||
_glamourerApplyAll!.InvokeAction(customization, character);
|
||||
}
|
||||
|
||||
public void GlamourerApplyOnlyEquipment(string customization, GameObject character)
|
||||
{
|
||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
if (_dalamudUtil.IsInGpose) return;
|
||||
|
||||
var unprocessedObjects = playerRelatedObjects.Where(c => c.HasUnprocessedUpdate);
|
||||
var unprocessedObjects = playerRelatedObjects.Where(c => c.HasUnprocessedUpdate).ToList();
|
||||
foreach (var unprocessedObject in unprocessedObjects)
|
||||
{
|
||||
unprocessedObject.IsProcessing = true;
|
||||
@@ -195,11 +195,13 @@ namespace MareSynchronos.Managers
|
||||
LastCreatedCharacterData = cacheDto;
|
||||
}
|
||||
|
||||
if (_apiController.IsConnected && !token.IsCancellationRequested)
|
||||
if (_apiController.IsConnected && !token.IsCancellationRequested && !unprocessedObjects.All(c => c.DoNotSendUpdate))
|
||||
{
|
||||
Logger.Verbose("Invoking PlayerHasChanged");
|
||||
PlayerHasChanged?.Invoke(cacheDto);
|
||||
}
|
||||
|
||||
unprocessedObjects.ForEach(p => p.DoNotSendUpdate = false);
|
||||
}, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<Authors></Authors>
|
||||
<Company></Company>
|
||||
<Version>0.2.3.0</Version>
|
||||
<Version>0.2.4.0</Version>
|
||||
<Description></Description>
|
||||
<Copyright></Copyright>
|
||||
<PackageProjectUrl>https://github.com/Penumbra-Sync/client</PackageProjectUrl>
|
||||
|
||||
@@ -32,8 +32,11 @@ namespace MareSynchronos.Models
|
||||
|
||||
public byte[] EquipSlotData { get; set; } = new byte[40];
|
||||
public byte[] CustomizeData { get; set; } = new byte[26];
|
||||
public byte? HatState { get; set; }
|
||||
public byte? VisorWeaponState { get; set; }
|
||||
|
||||
public bool HasUnprocessedUpdate { get; set; } = false;
|
||||
public bool DoNotSendUpdate { get; set; } = false;
|
||||
public bool IsProcessing { get; set; } = false;
|
||||
|
||||
public unsafe void CheckAndUpdateObject()
|
||||
@@ -94,6 +97,25 @@ namespace MareSynchronos.Models
|
||||
}
|
||||
}
|
||||
|
||||
if (ObjectKind is not ObjectKind.Mount)
|
||||
{
|
||||
var newHatState = Marshal.ReadByte((IntPtr)customizeData + 30, 0);
|
||||
var newWeaponOrVisorState = Marshal.ReadByte((IntPtr)customizeData + 31, 0);
|
||||
if (newHatState != HatState)
|
||||
{
|
||||
if (HatState != null) DoNotSendUpdate = true;
|
||||
HatState = newHatState;
|
||||
hasChanges = true;
|
||||
}
|
||||
|
||||
if (newWeaponOrVisorState != VisorWeaponState)
|
||||
{
|
||||
if (VisorWeaponState != null) DoNotSendUpdate = true;
|
||||
VisorWeaponState = newWeaponOrVisorState;
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ namespace MareSynchronos.Utils
|
||||
}
|
||||
|
||||
if (ct?.IsCancellationRequested ?? false) return;
|
||||
// wait half a second just in case
|
||||
Thread.Sleep(500);
|
||||
// wait quarter a second just in case
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
public void WaitWhileSelfIsDrawing(CancellationToken? token) => WaitWhileCharacterIsDrawing(_clientState.LocalPlayer?.Address ?? new IntPtr(), token);
|
||||
|
||||
Reference in New Issue
Block a user