update logo, fix incorrectly generating data in duties and other situations (we just don't know)
This commit is contained in:
		| @@ -8,11 +8,13 @@ namespace MareSynchronos.Factories | |||||||
|     { |     { | ||||||
|         private readonly IpcManager ipcManager; |         private readonly IpcManager ipcManager; | ||||||
|         private readonly ClientState clientState; |         private readonly ClientState clientState; | ||||||
|  |         private string playerName; | ||||||
|  |  | ||||||
|         public FileReplacementFactory(IpcManager ipcManager, ClientState clientState) |         public FileReplacementFactory(IpcManager ipcManager, ClientState clientState) | ||||||
|         { |         { | ||||||
|             this.ipcManager = ipcManager; |             this.ipcManager = ipcManager; | ||||||
|             this.clientState = clientState; |             this.clientState = clientState; | ||||||
|  |             playerName = null!; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public FileReplacement Create(string gamePath, bool resolve = true) |         public FileReplacement Create(string gamePath, bool resolve = true) | ||||||
| @@ -20,7 +22,10 @@ namespace MareSynchronos.Factories | |||||||
|             var fileReplacement = new FileReplacement(gamePath, ipcManager.PenumbraModDirectory()!); |             var fileReplacement = new FileReplacement(gamePath, ipcManager.PenumbraModDirectory()!); | ||||||
|             if (!resolve) return fileReplacement; |             if (!resolve) return fileReplacement; | ||||||
|  |  | ||||||
|             string playerName = clientState.LocalPlayer!.Name.ToString(); |             if(clientState.LocalPlayer != null) | ||||||
|  |             { | ||||||
|  |                 playerName = clientState.LocalPlayer.Name.ToString(); | ||||||
|  |             } | ||||||
|             fileReplacement.SetResolvedPath(ipcManager.PenumbraResolvePath(gamePath, playerName)!); |             fileReplacement.SetResolvedPath(ipcManager.PenumbraResolvePath(gamePath, playerName)!); | ||||||
|             if (!fileReplacement.HasFileReplacement) |             if (!fileReplacement.HasFileReplacement) | ||||||
|             { |             { | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ namespace MareSynchronos.Hooks | |||||||
|         private readonly GameGui gameGui; |         private readonly GameGui gameGui; | ||||||
|         private readonly ObjectTable objectTable; |         private readonly ObjectTable objectTable; | ||||||
|         private readonly DalamudPluginInterface pluginInterface; |         private readonly DalamudPluginInterface pluginInterface; | ||||||
|         private ConcurrentBag<FileReplacement> cachedResources = new(); |         private ConcurrentDictionary<string, FileReplacement> cachedResources = new(); | ||||||
|         private GameObject* lastGameObject = null; |         private GameObject* lastGameObject = null; | ||||||
|         private ConcurrentBag<FileReplacement> loadedMaterials = new(); |         private ConcurrentBag<FileReplacement> loadedMaterials = new(); | ||||||
|  |  | ||||||
| @@ -81,57 +81,63 @@ namespace MareSynchronos.Hooks | |||||||
|         { |         { | ||||||
|             foreach (var resource in cachedResources) |             foreach (var resource in cachedResources) | ||||||
|             { |             { | ||||||
|                 resource.IsInUse = false; |                 resource.Value.IsInUse = false; | ||||||
|                 resource.ImcData = string.Empty; |                 resource.Value.ImcData = string.Empty; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             PluginLog.Debug("Invaldated resource cache"); |             PluginLog.Verbose("Invaldated resource cache"); | ||||||
|  |  | ||||||
|             var cache = new CharacterCache(); |             var cache = new CharacterCache(); | ||||||
|  |  | ||||||
|             var model = (CharacterBase*)((Character*)clientState.LocalPlayer!.Address)->GameObject.GetDrawObject(); |             try | ||||||
|             for (var idx = 0; idx < model->SlotCount; ++idx) |  | ||||||
|             { |             { | ||||||
|                 var mdl = (RenderModel*)model->ModelArray[idx]; |                 var model = (CharacterBase*)((Character*)clientState.LocalPlayer!.Address)->GameObject.GetDrawObject(); | ||||||
|                 if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara) |                 for (var idx = 0; idx < model->SlotCount; ++idx) | ||||||
|                 { |                 { | ||||||
|                     continue; |                     var mdl = (RenderModel*)model->ModelArray[idx]; | ||||||
|                 } |                     if (mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara) | ||||||
|  |  | ||||||
|                 var mdlResource = factory.Create(new Utf8String(mdl->ResourceHandle->FileName()).ToString()); |  | ||||||
|                 var cachedMdlResource = cachedResources.First(r => r.IsReplacedByThis(mdlResource)); |  | ||||||
|  |  | ||||||
|                 var imc = (ResourceHandle*)model->IMCArray[idx]; |  | ||||||
|                 if (imc != null) |  | ||||||
|                 { |  | ||||||
|                     byte[] imcData = new byte[imc->Data->DataLength]; |  | ||||||
|                     Marshal.Copy((IntPtr)imc->Data->DataPtr, imcData, 0, (int)imc->Data->DataLength); |  | ||||||
|                     string imcDataStr = BitConverter.ToString(imcData).Replace("-", ""); |  | ||||||
|                     cachedMdlResource.ImcData = imcDataStr; |  | ||||||
|                 } |  | ||||||
|                 cache.AddAssociatedResource(cachedMdlResource, null!, null!); |  | ||||||
|  |  | ||||||
|                 for (int mtrlIdx = 0; mtrlIdx < mdl->MaterialCount; mtrlIdx++) |  | ||||||
|                 { |  | ||||||
|                     var mtrl = (Material*)mdl->Materials[mtrlIdx]; |  | ||||||
|                     if (mtrl == null) continue; |  | ||||||
|  |  | ||||||
|                     var mtrlFileResource = factory.Create(new Utf8String(mtrl->ResourceHandle->FileName()).ToString().Split("|")[2]); |  | ||||||
|                     var cachedMtrlResource = cachedResources.First(r => r.IsReplacedByThis(mtrlFileResource)); |  | ||||||
|                     cache.AddAssociatedResource(cachedMtrlResource, cachedMdlResource, null!); |  | ||||||
|  |  | ||||||
|                     var mtrlResource = (MtrlResource*)mtrl->ResourceHandle; |  | ||||||
|                     for (int resIdx = 0; resIdx < mtrlResource->NumTex; resIdx++) |  | ||||||
|                     { |                     { | ||||||
|                         var texPath = new Utf8String(mtrlResource->TexString(resIdx)); |                         continue; | ||||||
|  |                     } | ||||||
|  |  | ||||||
|                         if (string.IsNullOrEmpty(texPath.ToString())) continue; |                     var mdlResource = factory.Create(new Utf8String(mdl->ResourceHandle->FileName()).ToString()); | ||||||
|  |                     var cachedMdlResource = cachedResources.First(r => r.Value.IsReplacedByThis(mdlResource)).Value; | ||||||
|  |  | ||||||
|                         var texResource = factory.Create(texPath.ToString()); |                     var imc = (ResourceHandle*)model->IMCArray[idx]; | ||||||
|                         var cachedTexResource = cachedResources.First(r => r.IsReplacedByThis(texResource)); |                     if (imc != null) | ||||||
|                         cache.AddAssociatedResource(cachedTexResource, cachedMdlResource, cachedMtrlResource); |                     { | ||||||
|  |                         byte[] imcData = new byte[imc->Data->DataLength]; | ||||||
|  |                         Marshal.Copy((IntPtr)imc->Data->DataPtr, imcData, 0, (int)imc->Data->DataLength); | ||||||
|  |                         string imcDataStr = BitConverter.ToString(imcData).Replace("-", ""); | ||||||
|  |                         cachedMdlResource.ImcData = imcDataStr; | ||||||
|  |                     } | ||||||
|  |                     cache.AddAssociatedResource(cachedMdlResource, null!, null!); | ||||||
|  |  | ||||||
|  |                     for (int mtrlIdx = 0; mtrlIdx < mdl->MaterialCount; mtrlIdx++) | ||||||
|  |                     { | ||||||
|  |                         var mtrl = (Material*)mdl->Materials[mtrlIdx]; | ||||||
|  |                         if (mtrl == null) continue; | ||||||
|  |  | ||||||
|  |                         var mtrlFileResource = factory.Create(new Utf8String(mtrl->ResourceHandle->FileName()).ToString().Split("|")[2]); | ||||||
|  |                         var cachedMtrlResource = cachedResources.First(r => r.Value.IsReplacedByThis(mtrlFileResource)).Value; | ||||||
|  |                         cache.AddAssociatedResource(cachedMtrlResource, cachedMdlResource, null!); | ||||||
|  |  | ||||||
|  |                         var mtrlResource = (MtrlResource*)mtrl->ResourceHandle; | ||||||
|  |                         for (int resIdx = 0; resIdx < mtrlResource->NumTex; resIdx++) | ||||||
|  |                         { | ||||||
|  |                             var texPath = new Utf8String(mtrlResource->TexString(resIdx)); | ||||||
|  |  | ||||||
|  |                             if (string.IsNullOrEmpty(texPath.ToString())) continue; | ||||||
|  |  | ||||||
|  |                             var texResource = factory.Create(texPath.ToString()); | ||||||
|  |                             var cachedTexResource = cachedResources.First(r => r.Value.IsReplacedByThis(texResource)).Value; | ||||||
|  |                             cache.AddAssociatedResource(cachedTexResource, cachedMdlResource, cachedMtrlResource); | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |             } catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 PluginLog.Error(ex, ex.Message); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             return cache; |             return cache; | ||||||
| @@ -141,15 +147,15 @@ namespace MareSynchronos.Hooks | |||||||
|         { |         { | ||||||
|             var cache = BuildCharacterCache(); |             var cache = BuildCharacterCache(); | ||||||
|  |  | ||||||
|             PluginLog.Debug("--- CURRENTLY LOADED FILES ---"); |             PluginLog.Verbose("--- CURRENTLY LOADED FILES ---"); | ||||||
|  |  | ||||||
|             PluginLog.Debug(cache.ToString()); |             PluginLog.Verbose(cache.ToString()); | ||||||
|  |  | ||||||
|             PluginLog.Debug("--- LOOSE FILES ---"); |             PluginLog.Verbose("--- LOOSE FILES ---"); | ||||||
|  |  | ||||||
|             foreach (var resource in cachedResources.Where(r => !r.IsInUse).OrderBy(a => a.GamePath)) |             foreach (var resource in cachedResources.Where(r => !r.Value.IsInUse).OrderBy(a => a.Value.GamePath)) | ||||||
|             { |             { | ||||||
|                 PluginLog.Debug(resource.ToString()); |                 PluginLog.Verbose(resource.ToString()); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             return cache.FileReplacements; |             return cache.FileReplacements; | ||||||
| @@ -160,7 +166,7 @@ namespace MareSynchronos.Hooks | |||||||
|             cachedResources.Clear(); |             cachedResources.Clear(); | ||||||
|             SetupHumanHooks(); |             SetupHumanHooks(); | ||||||
|             EnableHumanHooks(); |             EnableHumanHooks(); | ||||||
|             PluginLog.Debug("Hooks enabled"); |             PluginLog.Verbose("Hooks enabled"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void StopHooks() |         public void StopHooks() | ||||||
| @@ -171,9 +177,9 @@ namespace MareSynchronos.Hooks | |||||||
|  |  | ||||||
|         private void AddRequestedResource(FileReplacement replacement) |         private void AddRequestedResource(FileReplacement replacement) | ||||||
|         { |         { | ||||||
|             if (!cachedResources.Any(a => a.IsReplacedByThis(replacement))) |             if (!cachedResources.Any(a => a.Value.IsReplacedByThis(replacement)) || cachedResources.Any(c => c.Key == replacement.GamePath)) | ||||||
|             { |             { | ||||||
|                 cachedResources.Add(replacement); |                 cachedResources[replacement.GamePath] = replacement; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -195,8 +201,8 @@ namespace MareSynchronos.Hooks | |||||||
|                 var gameObj = GetGameObjectFromDrawObject(drawBase, idx); |                 var gameObj = GetGameObjectFromDrawObject(drawBase, idx); | ||||||
|                 if (clientState.LocalPlayer != null && gameObj == (GameObject*)clientState.LocalPlayer!.Address) |                 if (clientState.LocalPlayer != null && gameObj == (GameObject*)clientState.LocalPlayer!.Address) | ||||||
|                 { |                 { | ||||||
|                     PluginLog.Debug("Clearing resources"); |                     PluginLog.Verbose("Clearing resources"); | ||||||
|                     cachedResources.Clear(); |                     //cachedResources.Clear(); | ||||||
|                     DrawObjectToObject.Clear(); |                     DrawObjectToObject.Clear(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -326,13 +332,17 @@ namespace MareSynchronos.Hooks | |||||||
|             { |             { | ||||||
|                 var mtrl = (MtrlResource*)mtrlResourceHandle; |                 var mtrl = (MtrlResource*)mtrlResourceHandle; | ||||||
|                 var mtrlPath = Utf8String.FromSpanUnsafe(mtrl->Handle.FileNameSpan(), true, null, true); |                 var mtrlPath = Utf8String.FromSpanUnsafe(mtrl->Handle.FileNameSpan(), true, null, true); | ||||||
|  |                 PluginLog.Verbose("Attempting to resolve: " + mtrlPath.ToString()); | ||||||
|                 var mtrlResource = factory.Create(mtrlPath.ToString()); |                 var mtrlResource = factory.Create(mtrlPath.ToString()); | ||||||
|                 var existingMat = loadedMaterials.FirstOrDefault(m => m.IsReplacedByThis(mtrlResource)); |                 var existingMat = loadedMaterials.FirstOrDefault(m => m.IsReplacedByThis(mtrlResource)); | ||||||
|                 if (existingMat != null) |                 if (existingMat != null) | ||||||
|                 { |                 { | ||||||
|  |                     PluginLog.Verbose("Resolving material: " + existingMat.GamePath); | ||||||
|                     for (int i = 0; i < mtrl->NumTex; i++) |                     for (int i = 0; i < mtrl->NumTex; i++) | ||||||
|                     { |                     { | ||||||
|                         var texPath = new Utf8String(mtrl->TexString(i)); |                         var texPath = new Utf8String(mtrl->TexString(i)); | ||||||
|  |                         PluginLog.Verbose("Resolving tex: " + texPath.ToString()); | ||||||
|  |  | ||||||
|                         AddRequestedResource(factory.Create(texPath.ToString())); |                         AddRequestedResource(factory.Create(texPath.ToString())); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
| @@ -347,8 +357,8 @@ namespace MareSynchronos.Hooks | |||||||
|  |  | ||||||
|         private byte LoadMtrlTexDetour(IntPtr mtrlResourceHandle) |         private byte LoadMtrlTexDetour(IntPtr mtrlResourceHandle) | ||||||
|         { |         { | ||||||
|             if (clientState.LocalPlayer != null) |             //if (clientState.LocalPlayer != null) | ||||||
|                 LoadMtrlHelper(mtrlResourceHandle); |             LoadMtrlHelper(mtrlResourceHandle); | ||||||
|             var ret = LoadMtrlTexHook!.Original(mtrlResourceHandle); |             var ret = LoadMtrlTexHook!.Original(mtrlResourceHandle); | ||||||
|             return ret; |             return ret; | ||||||
|         } |         } | ||||||
| @@ -394,6 +404,7 @@ namespace MareSynchronos.Hooks | |||||||
|                     return path; |                     return path; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  |                 PluginLog.Verbose("Resolving resource: " + gamepath.ToString()); | ||||||
|                 PlayerLoadEvent?.Invoke((IntPtr)gameObject, new EventArgs()); |                 PlayerLoadEvent?.Invoke((IntPtr)gameObject, new EventArgs()); | ||||||
|  |  | ||||||
|                 var resource = factory.Create(gamepath.ToString()); |                 var resource = factory.Create(gamepath.ToString()); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| { | { | ||||||
|   "Author": "your name here", |   "Author": "darkarchon", | ||||||
|   "Name": "Mare Synchronos", |   "Name": "Mare Synchronos", | ||||||
|   "Punchline": "", |   "Punchline": "", | ||||||
|   "Description": "", |   "Description": "", | ||||||
| @@ -9,5 +9,7 @@ | |||||||
|     "sample", |     "sample", | ||||||
|     "plugin", |     "plugin", | ||||||
|     "goats" |     "goats" | ||||||
|   ] |   ], | ||||||
|  |   "IconUrl": "https://raw.githubusercontent.com/Penumbra-Sync/client/main/MareSynchronos/images/logo.png", | ||||||
|  |   "RepoUrl": "https://github.com/Penumbra-Sync/client" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ namespace MareSynchronos.Models | |||||||
|             FileReplacements.Where(x => x.HasFileReplacement) |             FileReplacements.Where(x => x.HasFileReplacement) | ||||||
|             .Concat(FileReplacements.SelectMany(f => f.Associated).Where(f => f.HasFileReplacement)) |             .Concat(FileReplacements.SelectMany(f => f.Associated).Where(f => f.HasFileReplacement)) | ||||||
|             .Concat(FileReplacements.SelectMany(f => f.Associated).SelectMany(f => f.Associated).Where(f => f.HasFileReplacement)) |             .Concat(FileReplacements.SelectMany(f => f.Associated).SelectMany(f => f.Associated).Where(f => f.HasFileReplacement)) | ||||||
|             .Distinct() |             .Distinct().OrderBy(f => f.GamePath) | ||||||
|             .ToList(); |             .ToList(); | ||||||
|  |  | ||||||
|         public List<FileReplacement> FileReplacements { get; set; } = new List<FileReplacement>(); |         public List<FileReplacement> FileReplacements { get; set; } = new List<FileReplacement>(); | ||||||
| @@ -26,6 +26,9 @@ namespace MareSynchronos.Models | |||||||
|  |  | ||||||
|         public bool IsReady => FileReplacements.All(f => f.Computed); |         public bool IsReady => FileReplacements.All(f => f.Computed); | ||||||
|  |  | ||||||
|  |         [JsonProperty] | ||||||
|  |         public string CacheHash { get; set; } = string.Empty; | ||||||
|  |  | ||||||
|         [JsonProperty] |         [JsonProperty] | ||||||
|         public uint JobId { get; set; } = 0; |         public uint JobId { get; set; } = 0; | ||||||
|         public void AddAssociatedResource(FileReplacement resource, FileReplacement mdlParent, FileReplacement mtrlParent) |         public void AddAssociatedResource(FileReplacement resource, FileReplacement mdlParent, FileReplacement mtrlParent) | ||||||
|   | |||||||
| @@ -142,5 +142,16 @@ namespace MareSynchronos.Models | |||||||
|  |  | ||||||
|             return base.Equals(obj); |             return base.Equals(obj); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override int GetHashCode() | ||||||
|  |         { | ||||||
|  |             int result = 13; | ||||||
|  |             result *= 397; | ||||||
|  |             result += Hash.GetHashCode(); | ||||||
|  |             result += GamePath.GetHashCode(); | ||||||
|  |             result += ImcData.GetHashCode(); | ||||||
|  |  | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ using Newtonsoft.Json.Serialization; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using MareSynchronos.Managers; | using MareSynchronos.Managers; | ||||||
| using FFXIVClientStructs.FFXIV.Client.Game.Object; | using FFXIVClientStructs.FFXIV.Client.Game.Object; | ||||||
|  | using MareSynchronos.Utils; | ||||||
|  |  | ||||||
| namespace MareSynchronos | namespace MareSynchronos | ||||||
| { | { | ||||||
| @@ -132,10 +133,12 @@ namespace MareSynchronos | |||||||
|             var obj = (GameObject*)(IntPtr)sender; |             var obj = (GameObject*)(IntPtr)sender; | ||||||
|             drawHookTask = Task.Run(() => |             drawHookTask = Task.Run(() => | ||||||
|             { |             { | ||||||
|  |                 PluginLog.Debug("Waiting for charater to be drawn"); | ||||||
|                 while ((obj->RenderFlags & 0b100000000000) == 0b100000000000) // 0b100000000000 is "still rendering" or something |                 while ((obj->RenderFlags & 0b100000000000) == 0b100000000000) // 0b100000000000 is "still rendering" or something | ||||||
|                 { |                 { | ||||||
|                     Thread.Sleep(10); |                     Thread.Sleep(10); | ||||||
|                 } |                 } | ||||||
|  |                 PluginLog.Debug("Character finished drawing"); | ||||||
|  |  | ||||||
|                 // we should recalculate cache here |                 // we should recalculate cache here | ||||||
|                 // probably needs a different method |                 // probably needs a different method | ||||||
| @@ -174,6 +177,10 @@ namespace MareSynchronos | |||||||
|                         await Task.Delay(50); |                         await Task.Delay(50); | ||||||
|                     } |                     } | ||||||
|                     var json = JsonConvert.SerializeObject(cache, Formatting.Indented); |                     var json = JsonConvert.SerializeObject(cache, Formatting.Indented); | ||||||
|  |  | ||||||
|  |                     cache.CacheHash = Crypto.GetHash(json); | ||||||
|  |                      | ||||||
|  |                     json = JsonConvert.SerializeObject(cache, Formatting.Indented); | ||||||
|                     PluginLog.Debug(json); |                     PluginLog.Debug(json); | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 102 KiB | 
		Reference in New Issue
	
	Block a user
	 Stanley Dimant
					Stanley Dimant