fixes some more crashes
This commit is contained in:
@@ -16,8 +16,9 @@ public class CacheCreationService : MediatorSubscriberBase, IDisposable
|
|||||||
private readonly CancellationTokenSource _cts = new();
|
private readonly CancellationTokenSource _cts = new();
|
||||||
private readonly List<GameObjectHandler> _playerRelatedObjects = new();
|
private readonly List<GameObjectHandler> _playerRelatedObjects = new();
|
||||||
private CancellationTokenSource _palettePlusCts = new();
|
private CancellationTokenSource _palettePlusCts = new();
|
||||||
|
private SemaphoreSlim _cacheCreateLock = new(1);
|
||||||
|
|
||||||
public unsafe CacheCreationService(ILogger<CacheCreationService> logger, MareMediator mediator, GameObjectHandlerFactory gameObjectHandlerFactory,
|
public CacheCreationService(ILogger<CacheCreationService> logger, MareMediator mediator, GameObjectHandlerFactory gameObjectHandlerFactory,
|
||||||
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil) : base(logger, mediator)
|
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil) : base(logger, mediator)
|
||||||
{
|
{
|
||||||
_characterDataFactory = characterDataFactory;
|
_characterDataFactory = characterDataFactory;
|
||||||
@@ -25,7 +26,9 @@ public class CacheCreationService : MediatorSubscriberBase, IDisposable
|
|||||||
Mediator.Subscribe<CreateCacheForObjectMessage>(this, (msg) =>
|
Mediator.Subscribe<CreateCacheForObjectMessage>(this, (msg) =>
|
||||||
{
|
{
|
||||||
var actualMsg = (CreateCacheForObjectMessage)msg;
|
var actualMsg = (CreateCacheForObjectMessage)msg;
|
||||||
|
_cacheCreateLock.Wait();
|
||||||
_cachesToCreate[actualMsg.ObjectToCreateFor.ObjectKind] = actualMsg.ObjectToCreateFor;
|
_cachesToCreate[actualMsg.ObjectToCreateFor.ObjectKind] = actualMsg.ObjectToCreateFor;
|
||||||
|
_cacheCreateLock.Release();
|
||||||
});
|
});
|
||||||
|
|
||||||
_playerRelatedObjects.AddRange(new List<GameObjectHandler>()
|
_playerRelatedObjects.AddRange(new List<GameObjectHandler>()
|
||||||
@@ -46,56 +49,44 @@ public class CacheCreationService : MediatorSubscriberBase, IDisposable
|
|||||||
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (msg) => ProcessCacheCreation());
|
Mediator.Subscribe<DelayedFrameworkUpdateMessage>(this, (msg) => ProcessCacheCreation());
|
||||||
Mediator.Subscribe<CustomizePlusMessage>(this, (msg) => CustomizePlusChanged((CustomizePlusMessage)msg));
|
Mediator.Subscribe<CustomizePlusMessage>(this, async (_) => await AddPlayerCacheToCreate().ConfigureAwait(false));
|
||||||
Mediator.Subscribe<HeelsOffsetMessage>(this, (msg) => HeelsOffsetChanged((HeelsOffsetMessage)msg));
|
Mediator.Subscribe<HeelsOffsetMessage>(this, async (_) => await AddPlayerCacheToCreate().ConfigureAwait(false));
|
||||||
Mediator.Subscribe<PalettePlusMessage>(this, (msg) => PalettePlusChanged((PalettePlusMessage)msg));
|
Mediator.Subscribe<PalettePlusMessage>(this, (_) => PalettePlusChanged());
|
||||||
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, (msg) => _cachesToCreate[ObjectKind.Player] = _playerRelatedObjects.First(p => p.ObjectKind == ObjectKind.Player));
|
Mediator.Subscribe<PenumbraModSettingChangedMessage>(this, async (msg) => await AddPlayerCacheToCreate().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PalettePlusChanged(PalettePlusMessage msg)
|
private async Task AddPlayerCacheToCreate()
|
||||||
{
|
{
|
||||||
if (!string.Equals(msg.Data, _playerData.PalettePlusPalette, StringComparison.Ordinal))
|
await _cacheCreateLock.WaitAsync().ConfigureAwait(false);
|
||||||
{
|
_cachesToCreate[ObjectKind.Player] = _playerRelatedObjects.First(p => p.ObjectKind == ObjectKind.Player);
|
||||||
_playerData.PalettePlusPalette = msg.Data ?? string.Empty;
|
_cacheCreateLock.Release();
|
||||||
|
|
||||||
_palettePlusCts?.Cancel();
|
|
||||||
_palettePlusCts?.Dispose();
|
|
||||||
_palettePlusCts = new();
|
|
||||||
var token = _palettePlusCts.Token;
|
|
||||||
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
|
|
||||||
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
|
||||||
}, token);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HeelsOffsetChanged(HeelsOffsetMessage msg)
|
private void PalettePlusChanged()
|
||||||
{
|
{
|
||||||
if (msg.Offset != _playerData.HeelsOffset)
|
_palettePlusCts?.Cancel();
|
||||||
{
|
_palettePlusCts?.Dispose();
|
||||||
_playerData.HeelsOffset = msg.Offset;
|
_palettePlusCts = new();
|
||||||
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
var token = _palettePlusCts.Token;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CustomizePlusChanged(CustomizePlusMessage msg)
|
Task.Run(async () =>
|
||||||
{
|
|
||||||
if (!string.Equals(msg.Data, _playerData.CustomizePlusScale, StringComparison.Ordinal))
|
|
||||||
{
|
{
|
||||||
_playerData.CustomizePlusScale = msg.Data ?? string.Empty;
|
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
|
||||||
Mediator.Publish(new CharacterDataCreatedMessage(_playerData.ToAPI()));
|
await AddPlayerCacheToCreate().ConfigureAwait(false);
|
||||||
}
|
}, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessCacheCreation()
|
private void ProcessCacheCreation()
|
||||||
{
|
{
|
||||||
if (_cachesToCreate.Any() && (_cacheCreationTask?.IsCompleted ?? true))
|
if (_cachesToCreate.Any() && (_cacheCreationTask?.IsCompleted ?? true))
|
||||||
{
|
{
|
||||||
|
_cacheCreateLock.Wait();
|
||||||
var toCreate = _cachesToCreate.ToList();
|
var toCreate = _cachesToCreate.ToList();
|
||||||
_cachesToCreate.Clear();
|
_cachesToCreate.Clear();
|
||||||
|
_cacheCreateLock.Release();
|
||||||
|
|
||||||
_cacheCreationTask = Task.Run(async () =>
|
_cacheCreationTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -508,15 +508,12 @@ public class IpcManager : MediatorSubscriberBase, IDisposable
|
|||||||
public void PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName)
|
public void PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName)
|
||||||
{
|
{
|
||||||
if (!CheckPenumbraApi()) return;
|
if (!CheckPenumbraApi()) return;
|
||||||
ActionQueue.Enqueue(() =>
|
var collName = "Mare_" + characterName;
|
||||||
{
|
logger.LogTrace("[{applicationId}] Removing temp collection for {collName}", applicationId, collName);
|
||||||
var collName = "Mare_" + characterName;
|
var ret = _penumbraRemoveTemporaryMod.Invoke("MareChara", collName, 0);
|
||||||
logger.LogTrace("[{applicationId}] Removing temp collection for {collName}", applicationId, collName);
|
logger.LogTrace("[{applicationId}] RemoveTemporaryMod: {ret}", applicationId, ret);
|
||||||
var ret = _penumbraRemoveTemporaryMod.Invoke("MareChara", collName, 0);
|
var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collName);
|
||||||
logger.LogTrace("[{applicationId}] RemoveTemporaryMod: {ret}", applicationId, ret);
|
logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2);
|
||||||
var ret2 = _penumbraRemoveTemporaryCollection.Invoke(collName);
|
|
||||||
logger.LogTrace("[{applicationId}] RemoveTemporaryCollection: {ret2}", applicationId, ret2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PenumbraResolvePath(string path)
|
public string PenumbraResolvePath(string path)
|
||||||
@@ -541,26 +538,23 @@ public class IpcManager : MediatorSubscriberBase, IDisposable
|
|||||||
{
|
{
|
||||||
if (!CheckPenumbraApi()) return;
|
if (!CheckPenumbraApi()) return;
|
||||||
|
|
||||||
ActionQueue.Enqueue(() =>
|
var idx = _dalamudUtil.GetIndexFromObjectTableByName(characterName);
|
||||||
|
if (idx == null)
|
||||||
{
|
{
|
||||||
var idx = _dalamudUtil.GetIndexFromObjectTableByName(characterName);
|
return;
|
||||||
if (idx == null)
|
}
|
||||||
{
|
var collName = "Mare_" + characterName;
|
||||||
return;
|
var ret = _penumbraCreateNamedTemporaryCollection.Invoke(collName);
|
||||||
}
|
logger.LogTrace("[{applicationId}] Creating Temp Collection {collName}, Success: {ret}", applicationId, collName, ret);
|
||||||
var collName = "Mare_" + characterName;
|
var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx.Value, c: true);
|
||||||
var ret = _penumbraCreateNamedTemporaryCollection.Invoke(collName);
|
logger.LogTrace("[{applicationId}] Assigning Temp Collection {collName} to index {idx}", applicationId, collName, idx.Value);
|
||||||
logger.LogTrace("[{applicationId}] Creating Temp Collection {collName}, Success: {ret}", applicationId, collName, ret);
|
foreach (var mod in modPaths)
|
||||||
var retAssign = _penumbraAssignTemporaryCollection.Invoke(collName, idx.Value, c: true);
|
{
|
||||||
logger.LogTrace("[{applicationId}] Assigning Temp Collection {collName} to index {idx}", applicationId, collName, idx.Value);
|
logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value);
|
||||||
foreach (var mod in modPaths)
|
}
|
||||||
{
|
|
||||||
logger.LogTrace("[{applicationId}] Change: {from} => {to}", applicationId, mod.Key, mod.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret2 = _penumbraAddTemporaryMod.Invoke("MareChara", collName, modPaths, manipulationData, 0);
|
var ret2 = _penumbraAddTemporaryMod.Invoke("MareChara", collName, modPaths, manipulationData, 0);
|
||||||
logger.LogTrace("[{applicationId}] Setting temp mods for {collName}, Success: {ret2}", applicationId, collName, ret2);
|
logger.LogTrace("[{applicationId}] Setting temp mods for {collName}, Success: {ret2}", applicationId, collName, ret2);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public (string[] forward, string[][] reverse) PenumbraResolvePaths(string[] forward, string[] reverse)
|
public (string[] forward, string[][] reverse) PenumbraResolvePaths(string[] forward, string[] reverse)
|
||||||
@@ -589,20 +583,17 @@ public class IpcManager : MediatorSubscriberBase, IDisposable
|
|||||||
|
|
||||||
private void HeelsOffsetChange(float offset)
|
private void HeelsOffsetChange(float offset)
|
||||||
{
|
{
|
||||||
Mediator.Publish(new HeelsOffsetMessage(offset));
|
Mediator.Publish(new HeelsOffsetMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCustomizePlusScaleChange(string? scale)
|
private void OnCustomizePlusScaleChange(string? scale)
|
||||||
{
|
{
|
||||||
if (scale != null) scale = Convert.ToBase64String(Encoding.UTF8.GetBytes(scale));
|
Mediator.Publish(new CustomizePlusMessage());
|
||||||
Mediator.Publish(new CustomizePlusMessage(scale));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPalettePlusPaletteChange(Character character, string palette)
|
private void OnPalettePlusPaletteChange(Character character, string palette)
|
||||||
{
|
{
|
||||||
if (character.Address == 0 || character.Address != _dalamudUtil.PlayerPointer) return;
|
Mediator.Publish(new PalettePlusMessage());
|
||||||
if (palette != null) palette = Convert.ToBase64String(Encoding.UTF8.GetBytes(palette));
|
|
||||||
Mediator.Publish(new PalettePlusMessage(palette));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PalettePlusSetPalette(IntPtr character, string palette)
|
public async Task PalettePlusSetPalette(IntPtr character, string palette)
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ public record PenumbraModSettingChangedMessage : IMessage;
|
|||||||
public record PenumbraInitializedMessage : IMessage;
|
public record PenumbraInitializedMessage : IMessage;
|
||||||
public record PenumbraDisposedMessage : IMessage;
|
public record PenumbraDisposedMessage : IMessage;
|
||||||
public record PenumbraRedrawMessage(IntPtr Address, int ObjTblIdx, bool WasRequested) : IMessage;
|
public record PenumbraRedrawMessage(IntPtr Address, int ObjTblIdx, bool WasRequested) : IMessage;
|
||||||
public record HeelsOffsetMessage(float Offset) : IMessage;
|
public record HeelsOffsetMessage() : IMessage;
|
||||||
public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, string FilePath) : IMessage;
|
public record PenumbraResourceLoadMessage(IntPtr GameObject, string GamePath, string FilePath) : IMessage;
|
||||||
public record CustomizePlusMessage(string? Data) : IMessage;
|
public record CustomizePlusMessage() : IMessage;
|
||||||
public record PalettePlusMessage(string? Data) : IMessage;
|
public record PalettePlusMessage() : IMessage;
|
||||||
public record PlayerChangedMessage(API.Data.CharacterData Data) : IMessage;
|
public record PlayerChangedMessage(API.Data.CharacterData Data) : IMessage;
|
||||||
public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : IMessage;
|
public record CharacterChangedMessage(GameObjectHandler GameObjectHandler) : IMessage;
|
||||||
public record TransientResourceChangedMessage(IntPtr Address) : IMessage;
|
public record TransientResourceChangedMessage(IntPtr Address) : IMessage;
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ public class GameObjectHandler : MediatorSubscriberBase
|
|||||||
|
|
||||||
private unsafe bool IsBeingDrawn(IntPtr drawObj, IntPtr curPtr)
|
private unsafe bool IsBeingDrawn(IntPtr drawObj, IntPtr curPtr)
|
||||||
{
|
{
|
||||||
return drawObj == IntPtr.Zero || (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0)
|
_logger.LogTrace("IsBeingDrawn for ptr {curPtr} : {drawObj}", curPtr.ToString("X"), drawObj.ToString("X"));
|
||||||
|
return drawObj == IntPtr.Zero
|
||||||
|
|| (((CharacterBase*)drawObj)->HasModelInSlotLoaded != 0)
|
||||||
|| (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0)
|
|| (((CharacterBase*)drawObj)->HasModelFilesInSlotLoaded != 0)
|
||||||
|| (((GameObject*)curPtr)->RenderFlags & 0b100000000000) == 0b100000000000;
|
|| (((GameObject*)curPtr)->RenderFlags & 0b100000000000) == 0b100000000000;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user