adjust to send only one packet for all changes at once
This commit is contained in:
		| @@ -7,6 +7,7 @@ using Dalamud.Utility; | ||||
| using FFXIVClientStructs.FFXIV.Client.Game.Character; | ||||
| using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; | ||||
| using FFXIVClientStructs.FFXIV.Client.System.Resource; | ||||
| using MareSynchronos.API; | ||||
| using MareSynchronos.Interop; | ||||
| using MareSynchronos.Managers; | ||||
| using MareSynchronos.Models; | ||||
| @@ -30,7 +31,7 @@ public class CharacterDataFactory | ||||
|         _ipcManager = ipcManager; | ||||
|     } | ||||
|  | ||||
|     public CharacterData? BuildCharacterData(IntPtr playerPointer) | ||||
|     public CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer) | ||||
|     { | ||||
|         if (!_ipcManager.Initialized) | ||||
|         { | ||||
| @@ -39,19 +40,22 @@ public class CharacterDataFactory | ||||
|  | ||||
|         if (playerPointer == IntPtr.Zero) | ||||
|         { | ||||
|             return null; | ||||
|             Logger.Verbose("Pointer was zero for " + objectKind); | ||||
|             previousData.FileReplacements.Remove(objectKind); | ||||
|             previousData.GlamourerString.Remove(objectKind); | ||||
|             return previousData; | ||||
|         } | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             return CreateCharacterData(playerPointer); | ||||
|             return CreateCharacterData(previousData, objectKind, playerPointer); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             Logger.Warn("Failed to create character data"); | ||||
|             Logger.Warn("Failed to create " + objectKind + " data"); | ||||
|             Logger.Warn(e.Message); | ||||
|             Logger.Warn(e.StackTrace ?? string.Empty); | ||||
|             return null; | ||||
|             return previousData; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -60,16 +64,15 @@ public class CharacterDataFactory | ||||
|         return (string.Join("", Enumerable.Repeat("\t", inheritanceLevel)), string.Join("", Enumerable.Repeat("\t", inheritanceLevel + 2))); | ||||
|     } | ||||
|  | ||||
|     private void DebugPrint(FileReplacement fileReplacement, string objectKind, string resourceType, int inheritanceLevel) | ||||
|     private void DebugPrint(FileReplacement fileReplacement, ObjectKind objectKind, string resourceType, int inheritanceLevel) | ||||
|     { | ||||
|         var indentation = GetIndentationForInheritanceLevel(inheritanceLevel); | ||||
|         objectKind += string.IsNullOrEmpty(objectKind) ? "" : " "; | ||||
|  | ||||
|         Logger.Verbose(indentation.Item1 + objectKind + resourceType + " [" + string.Join(", ", fileReplacement.GamePaths) + "]"); | ||||
|         Logger.Verbose(indentation.Item2 + "=> " + fileReplacement.ResolvedPath); | ||||
|     } | ||||
|  | ||||
|     private unsafe void AddReplacementsFromRenderModel(RenderModel* mdl, CharacterData cache, int inheritanceLevel = 0, string objectKind = "") | ||||
|     private unsafe void AddReplacementsFromRenderModel(RenderModel* mdl, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0) | ||||
|     { | ||||
|         if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara) | ||||
|         { | ||||
| @@ -91,18 +94,18 @@ public class CharacterDataFactory | ||||
|         FileReplacement mdlFileReplacement = CreateFileReplacement(mdlPath); | ||||
|         DebugPrint(mdlFileReplacement, objectKind, "Model", inheritanceLevel); | ||||
|  | ||||
|         cache.AddFileReplacement(mdlFileReplacement); | ||||
|         cache.AddFileReplacement(objectKind, mdlFileReplacement); | ||||
|  | ||||
|         for (var mtrlIdx = 0; mtrlIdx < mdl->MaterialCount; mtrlIdx++) | ||||
|         { | ||||
|             var mtrl = (Material*)mdl->Materials[mtrlIdx]; | ||||
|             if (mtrl == null) continue; | ||||
|  | ||||
|             AddReplacementsFromMaterial(mtrl, cache, inheritanceLevel + 1, objectKind); | ||||
|             AddReplacementsFromMaterial(mtrl, objectKind, cache, inheritanceLevel + 1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private unsafe void AddReplacementsFromMaterial(Material* mtrl, CharacterData cache, int inheritanceLevel = 0, string objectKind = "") | ||||
|     private unsafe void AddReplacementsFromMaterial(Material* mtrl, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0) | ||||
|     { | ||||
|         string fileName; | ||||
|         try | ||||
| @@ -122,7 +125,7 @@ public class CharacterDataFactory | ||||
|         var mtrlFileReplacement = CreateFileReplacement(mtrlPath); | ||||
|         DebugPrint(mtrlFileReplacement, objectKind, "Material", inheritanceLevel); | ||||
|  | ||||
|         cache.AddFileReplacement(mtrlFileReplacement); | ||||
|         cache.AddFileReplacement(objectKind, mtrlFileReplacement); | ||||
|  | ||||
|         var mtrlResourceHandle = (MtrlResource*)mtrl->ResourceHandle; | ||||
|         for (var resIdx = 0; resIdx < mtrlResourceHandle->NumTex; resIdx++) | ||||
| @@ -131,11 +134,11 @@ public class CharacterDataFactory | ||||
|  | ||||
|             if (string.IsNullOrEmpty(texPath)) continue; | ||||
|  | ||||
|             AddReplacementsFromTexture(texPath, cache, inheritanceLevel + 1, objectKind); | ||||
|             AddReplacementsFromTexture(texPath, objectKind, cache, inheritanceLevel + 1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void AddReplacementsFromTexture(string texPath, CharacterData cache, int inheritanceLevel = 0, string objectKind = "", bool doNotReverseResolve = true) | ||||
|     private void AddReplacementsFromTexture(string texPath, ObjectKind objectKind, CharacterData cache, int inheritanceLevel = 0, bool doNotReverseResolve = true) | ||||
|     { | ||||
|         if (texPath.IsNullOrEmpty()) return; | ||||
|  | ||||
| @@ -144,7 +147,7 @@ public class CharacterDataFactory | ||||
|         var texFileReplacement = CreateFileReplacement(texPath, doNotReverseResolve); | ||||
|         DebugPrint(texFileReplacement, objectKind, "Texture", inheritanceLevel); | ||||
|  | ||||
|         cache.AddFileReplacement(texFileReplacement); | ||||
|         cache.AddFileReplacement(objectKind, texFileReplacement); | ||||
|  | ||||
|         if (texPath.Contains("/--")) return; | ||||
|  | ||||
| @@ -153,10 +156,10 @@ public class CharacterDataFactory | ||||
|  | ||||
|         DebugPrint(texDx11Replacement, objectKind, "Texture (DX11)", inheritanceLevel); | ||||
|  | ||||
|         cache.AddFileReplacement(texDx11Replacement); | ||||
|         cache.AddFileReplacement(objectKind, texDx11Replacement); | ||||
|     } | ||||
|  | ||||
|     private unsafe CharacterData CreateCharacterData(IntPtr charaPointer) | ||||
|     private unsafe CharacterData CreateCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr charaPointer) | ||||
|     { | ||||
|         Stopwatch st = Stopwatch.StartNew(); | ||||
|         var chara = _dalamudUtil.CreateGameObject(charaPointer)!; | ||||
| @@ -166,20 +169,18 @@ public class CharacterDataFactory | ||||
|             Thread.Sleep(50); | ||||
|         } | ||||
|         _dalamudUtil.WaitWhileCharacterIsDrawing(charaPointer); | ||||
|         var cache = new CharacterData() | ||||
|         { | ||||
|             ManipulationString = _ipcManager.PenumbraGetMetaManipulations(), | ||||
|         }; | ||||
|  | ||||
|         try | ||||
|         if (previousData.FileReplacements.ContainsKey(objectKind)) | ||||
|         { | ||||
|             cache.GlamourerString = _ipcManager.GlamourerGetCharacterCustomization(chara); | ||||
|         } | ||||
|         catch | ||||
|         { | ||||
|             // might not have glamourer data | ||||
|             previousData.FileReplacements[objectKind].Clear(); | ||||
|         } | ||||
|  | ||||
|         previousData.ManipulationString = _ipcManager.PenumbraGetMetaManipulations(); | ||||
|  | ||||
|         if (objectKind is not ObjectKind.Mount) | ||||
|         { | ||||
|             previousData.GlamourerString[objectKind] = _ipcManager.GlamourerGetCharacterCustomization(chara); | ||||
|         } | ||||
|  | ||||
|         var human = (Human*)((Character*)charaPointer)->GameObject.GetDrawObject(); | ||||
|         for (var mdlIdx = 0; mdlIdx < human->CharacterBase.SlotCount; ++mdlIdx) | ||||
| @@ -190,54 +191,50 @@ public class CharacterDataFactory | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             AddReplacementsFromRenderModel(mdl, cache, 0, "Character"); | ||||
|             AddReplacementsFromRenderModel(mdl, objectKind, previousData, 0); | ||||
|         } | ||||
|  | ||||
|         var weaponObject = (Weapon*)((Object*)human)->ChildObject; | ||||
|  | ||||
|         if ((IntPtr)weaponObject != IntPtr.Zero) | ||||
|         if (objectKind == ObjectKind.Player) | ||||
|         { | ||||
|             var mainHandWeapon = weaponObject->WeaponRenderModel->RenderModel; | ||||
|             var weaponObject = (Weapon*)((Object*)human)->ChildObject; | ||||
|  | ||||
|             AddReplacementsFromRenderModel(mainHandWeapon, cache, 0, "Weapon"); | ||||
|  | ||||
|             if (weaponObject->NextSibling != (IntPtr)weaponObject) | ||||
|             if ((IntPtr)weaponObject != IntPtr.Zero) | ||||
|             { | ||||
|                 var offHandWeapon = ((Weapon*)weaponObject->NextSibling)->WeaponRenderModel->RenderModel; | ||||
|                 var mainHandWeapon = weaponObject->WeaponRenderModel->RenderModel; | ||||
|  | ||||
|                 AddReplacementsFromRenderModel(offHandWeapon, cache, 1, "OffHand Weapon"); | ||||
|             } | ||||
|         } | ||||
|                 AddReplacementsFromRenderModel(mainHandWeapon, objectKind, previousData, 0); | ||||
|  | ||||
|         if (!string.IsNullOrEmpty(cache.GlamourerString)) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 AddReplacementSkeleton(((HumanExt*)human)->Human.RaceSexId, cache); | ||||
|                 AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->Decal->FileName()).ToString(), cache, 0, "Decal", false); | ||||
|                 AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->LegacyBodyDecal->FileName()).ToString(), cache, 0, "Legacy Decal", false); | ||||
|                 if (weaponObject->NextSibling != (IntPtr)weaponObject) | ||||
|                 { | ||||
|                     var offHandWeapon = ((Weapon*)weaponObject->NextSibling)->WeaponRenderModel->RenderModel; | ||||
|  | ||||
|                     AddReplacementsFromRenderModel(offHandWeapon, objectKind, previousData, 1); | ||||
|                 } | ||||
|             } | ||||
|             catch { } | ||||
|  | ||||
|             AddReplacementSkeleton(((HumanExt*)human)->Human.RaceSexId, objectKind, previousData); | ||||
|             AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->Decal->FileName()).ToString(), objectKind, previousData, 0, false); | ||||
|             AddReplacementsFromTexture(new Utf8String(((HumanExt*)human)->LegacyBodyDecal->FileName()).ToString(), objectKind, previousData, 0, false); | ||||
|         } | ||||
|  | ||||
|         st.Stop(); | ||||
|         Logger.Verbose("Building Character Data took " + st.Elapsed); | ||||
|         Logger.Verbose("Building " + objectKind + " Data took " + st.Elapsed); | ||||
|  | ||||
|         return cache; | ||||
|         return previousData; | ||||
|     } | ||||
|  | ||||
|     private void AddReplacementSkeleton(ushort raceSexId, CharacterData cache) | ||||
|     private void AddReplacementSkeleton(ushort raceSexId, ObjectKind objectKind, CharacterData cache) | ||||
|     { | ||||
|         string raceSexIdString = raceSexId.ToString("0000"); | ||||
|  | ||||
|         string skeletonPath = $"chara/human/c{raceSexIdString}/skeleton/base/b0001/skl_c{raceSexIdString}b0001.sklb"; | ||||
|  | ||||
|         Logger.Verbose("Adding File Replacement for Skeleton " + skeletonPath); | ||||
|         //Logger.Verbose("Adding File Replacement for Skeleton " + skeletonPath); | ||||
|  | ||||
|         var replacement = CreateFileReplacement(skeletonPath, true); | ||||
|         cache.AddFileReplacement(replacement); | ||||
|         cache.AddFileReplacement(objectKind, replacement); | ||||
|  | ||||
|         DebugPrint(replacement, "Skeleton", "SKLB", 0); | ||||
|         DebugPrint(replacement, objectKind, "SKLB", 0); | ||||
|     } | ||||
|  | ||||
|     private FileReplacement CreateFileReplacement(string path, bool doNotReverseResolve = false) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stanley Dimant
					Stanley Dimant