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);
|
//Logger.Verbose("Adding File Replacement for Material " + fileName);
|
||||||
var mtrlPath = fileName.Split("|")[2];
|
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);
|
var mtrlFileReplacement = CreateFileReplacement(mtrlPath);
|
||||||
DebugPrint(mtrlFileReplacement, objectKind, "Material", inheritanceLevel);
|
DebugPrint(mtrlFileReplacement, objectKind, "Material", inheritanceLevel);
|
||||||
|
|
||||||
@@ -155,6 +163,14 @@ public class CharacterDataFactory
|
|||||||
|
|
||||||
//Logger.Verbose("Adding File Replacement for Texture " + texPath);
|
//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);
|
var texFileReplacement = CreateFileReplacement(texPath, doNotReverseResolve);
|
||||||
DebugPrint(texFileReplacement, objectKind, "Texture", inheritanceLevel);
|
DebugPrint(texFileReplacement, objectKind, "Texture", inheritanceLevel);
|
||||||
|
|
||||||
|
|||||||
@@ -73,21 +73,45 @@ public class CachedPlayer
|
|||||||
List<ObjectKind> charaDataToUpdate = new List<ObjectKind>();
|
List<ObjectKind> charaDataToUpdate = new List<ObjectKind>();
|
||||||
foreach (var objectKind in Enum.GetValues<ObjectKind>())
|
foreach (var objectKind in Enum.GetValues<ObjectKind>())
|
||||||
{
|
{
|
||||||
bool doesntContainKey = !_cachedData.FileReplacements.ContainsKey(objectKind)
|
_cachedData.FileReplacements.TryGetValue(objectKind, out var existingFileReplacements);
|
||||||
|| (_cachedData.FileReplacements.ContainsKey(objectKind) && !characterData.FileReplacements.ContainsKey(objectKind));
|
characterData.FileReplacements.TryGetValue(objectKind, out var newFileReplacements);
|
||||||
if (doesntContainKey)
|
_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);
|
charaDataToUpdate.Add(objectKind);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool listsAreEqual = Enumerable.SequenceEqual(_cachedData.FileReplacements[objectKind], characterData.FileReplacements[objectKind]);
|
if (hasNewAndOldFileReplacements)
|
||||||
bool glamourerDataDifferent = _cachedData.GlamourerData[objectKind] != characterData.GlamourerData[objectKind];
|
|
||||||
if (!listsAreEqual || glamourerDataDifferent)
|
|
||||||
{
|
{
|
||||||
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)
|
foreach (var kind in objectKind)
|
||||||
{
|
{
|
||||||
if (_cachedData.GlamourerData.ContainsKey(kind))
|
ApplyCustomizationData(kind);
|
||||||
{
|
|
||||||
ApplyCustomizationData(kind);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, downloadToken).ContinueWith(task =>
|
}, downloadToken).ContinueWith(task =>
|
||||||
{
|
{
|
||||||
@@ -195,14 +216,15 @@ public class CachedPlayer
|
|||||||
private unsafe void ApplyCustomizationData(ObjectKind objectKind)
|
private unsafe void ApplyCustomizationData(ObjectKind objectKind)
|
||||||
{
|
{
|
||||||
if (PlayerCharacter is null) return;
|
if (PlayerCharacter is null) return;
|
||||||
|
_cachedData.GlamourerData.TryGetValue(objectKind, out var glamourerData);
|
||||||
|
|
||||||
if (objectKind == ObjectKind.Player)
|
if (objectKind == ObjectKind.Player)
|
||||||
{
|
{
|
||||||
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter!.Address);
|
_dalamudUtil.WaitWhileCharacterIsDrawing(PlayerCharacter.Address);
|
||||||
RequestedPenumbraRedraw = true;
|
RequestedPenumbraRedraw = true;
|
||||||
Logger.Debug(
|
Logger.Debug(
|
||||||
$"Request Redraw for {PlayerName}");
|
$"Request Redraw for {PlayerName}");
|
||||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], PlayerCharacter!);
|
_ipcManager.GlamourerApplyAll(glamourerData, PlayerCharacter.Address);
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Minion)
|
else if (objectKind == ObjectKind.Minion)
|
||||||
{
|
{
|
||||||
@@ -210,7 +232,7 @@ public class CachedPlayer
|
|||||||
if (minion != null)
|
if (minion != null)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Request Redraw for Minion");
|
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)
|
else if (objectKind == ObjectKind.Pet)
|
||||||
@@ -219,7 +241,7 @@ public class CachedPlayer
|
|||||||
if (pet != IntPtr.Zero)
|
if (pet != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Debug("Request Redraw for Pet");
|
Logger.Debug("Request Redraw for Pet");
|
||||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], pet);
|
_ipcManager.GlamourerApplyAll(glamourerData, pet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Companion)
|
else if (objectKind == ObjectKind.Companion)
|
||||||
@@ -228,7 +250,7 @@ public class CachedPlayer
|
|||||||
if (companion != IntPtr.Zero)
|
if (companion != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Debug("Request Redraw for Companion");
|
Logger.Debug("Request Redraw for Companion");
|
||||||
_ipcManager.GlamourerApplyAll(_cachedData.GlamourerData[objectKind], companion);
|
_ipcManager.GlamourerApplyAll(glamourerData, companion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (objectKind == ObjectKind.Mount)
|
else if (objectKind == ObjectKind.Mount)
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ namespace MareSynchronos.Managers
|
|||||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
_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);
|
var gameObj = _dalamudUtil.CreateGameObject(obj);
|
||||||
if (gameObj != null)
|
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)
|
public void GlamourerApplyOnlyEquipment(string customization, GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace MareSynchronos.Managers
|
|||||||
{
|
{
|
||||||
if (_dalamudUtil.IsInGpose) return;
|
if (_dalamudUtil.IsInGpose) return;
|
||||||
|
|
||||||
var unprocessedObjects = playerRelatedObjects.Where(c => c.HasUnprocessedUpdate);
|
var unprocessedObjects = playerRelatedObjects.Where(c => c.HasUnprocessedUpdate).ToList();
|
||||||
foreach (var unprocessedObject in unprocessedObjects)
|
foreach (var unprocessedObject in unprocessedObjects)
|
||||||
{
|
{
|
||||||
unprocessedObject.IsProcessing = true;
|
unprocessedObject.IsProcessing = true;
|
||||||
@@ -195,11 +195,13 @@ namespace MareSynchronos.Managers
|
|||||||
LastCreatedCharacterData = cacheDto;
|
LastCreatedCharacterData = cacheDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_apiController.IsConnected && !token.IsCancellationRequested)
|
if (_apiController.IsConnected && !token.IsCancellationRequested && !unprocessedObjects.All(c => c.DoNotSendUpdate))
|
||||||
{
|
{
|
||||||
Logger.Verbose("Invoking PlayerHasChanged");
|
Logger.Verbose("Invoking PlayerHasChanged");
|
||||||
PlayerHasChanged?.Invoke(cacheDto);
|
PlayerHasChanged?.Invoke(cacheDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unprocessedObjects.ForEach(p => p.DoNotSendUpdate = false);
|
||||||
}, token);
|
}, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors></Authors>
|
<Authors></Authors>
|
||||||
<Company></Company>
|
<Company></Company>
|
||||||
<Version>0.2.3.0</Version>
|
<Version>0.2.4.0</Version>
|
||||||
<Description></Description>
|
<Description></Description>
|
||||||
<Copyright></Copyright>
|
<Copyright></Copyright>
|
||||||
<PackageProjectUrl>https://github.com/Penumbra-Sync/client</PackageProjectUrl>
|
<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[] EquipSlotData { get; set; } = new byte[40];
|
||||||
public byte[] CustomizeData { get; set; } = new byte[26];
|
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 HasUnprocessedUpdate { get; set; } = false;
|
||||||
|
public bool DoNotSendUpdate { get; set; } = false;
|
||||||
public bool IsProcessing { get; set; } = false;
|
public bool IsProcessing { get; set; } = false;
|
||||||
|
|
||||||
public unsafe void CheckAndUpdateObject()
|
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;
|
return hasChanges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ namespace MareSynchronos.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ct?.IsCancellationRequested ?? false) return;
|
if (ct?.IsCancellationRequested ?? false) return;
|
||||||
// wait half a second just in case
|
// wait quarter a second just in case
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WaitWhileSelfIsDrawing(CancellationToken? token) => WaitWhileCharacterIsDrawing(_clientState.LocalPlayer?.Address ?? new IntPtr(), token);
|
public void WaitWhileSelfIsDrawing(CancellationToken? token) => WaitWhileCharacterIsDrawing(_clientState.LocalPlayer?.Address ?? new IntPtr(), token);
|
||||||
|
|||||||
Reference in New Issue
Block a user