This commit is contained in:
rootdarkarchon
2023-05-01 16:43:10 +02:00
parent 2f5a07653e
commit 640adc124e
3 changed files with 90 additions and 87 deletions

View File

@@ -170,30 +170,24 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
public async Task CustomizePlusRevert(IntPtr character) public async Task CustomizePlusRevert(IntPtr character)
{ {
if (!CheckCustomizePlusApi()) return; if (!CheckCustomizePlusApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj is Character c) if (gameObj is Character c)
{ {
Logger.LogTrace("CustomizePlus reverting for {chara}", c.Address.ToString("X")); Logger.LogTrace("CustomizePlus reverting for {chara}", c.Address.ToString("X"));
_customizePlusRevert!.InvokeAction(c); await _dalamudUtil.RunOnFrameworkThread(() => _customizePlusRevert!.InvokeAction(c)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public async Task CustomizePlusSetBodyScale(IntPtr character, string scale) public async Task CustomizePlusSetBodyScale(IntPtr character, string scale)
{ {
if (!CheckCustomizePlusApi() || string.IsNullOrEmpty(scale)) return; if (!CheckCustomizePlusApi() || string.IsNullOrEmpty(scale)) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj is Character c) if (gameObj is Character c)
{ {
string decodedScale = Encoding.UTF8.GetString(Convert.FromBase64String(scale)); string decodedScale = Encoding.UTF8.GetString(Convert.FromBase64String(scale));
Logger.LogTrace("CustomizePlus applying for {chara}", c.Address.ToString("X")); Logger.LogTrace("CustomizePlus applying for {chara}", c.Address.ToString("X"));
_customizePlusSetBodyScaleToCharacter!.InvokeAction(decodedScale, c); await _dalamudUtil.RunOnFrameworkThread(() => _customizePlusSetBodyScaleToCharacter!.InvokeAction(decodedScale, c)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public async Task<string> GetCustomizePlusScale() public async Task<string> GetCustomizePlusScale()
@@ -215,11 +209,15 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return;
try try
{ {
await _glamourerApplicationSemaphore.WaitAsync().ConfigureAwait(true); await _glamourerApplicationSemaphore.WaitAsync(token).ConfigureAwait(false);
var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(false); var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(false);
if (gameObj is Character c) if (gameObj is Character c)
{ {
await PenumbraRedrawAsync(logger, handler, applicationId, () => _glamourerApplyAll!.InvokeAction(customization, c), fireAndForget, token).ConfigureAwait(false); await PenumbraRedrawAsync(logger, handler, applicationId, () =>
{
logger.LogDebug("[{appid}] Calling on IPC: GlamourerApplyAll", applicationId);
_glamourerApplyAll!.InvokeAction(customization, c);
}, fireAndForget).ConfigureAwait(false);
} }
} }
finally finally
@@ -233,12 +231,20 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return; if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization) || _dalamudUtil.IsZoning) return;
try try
{ {
await _glamourerApplicationSemaphore.WaitAsync().ConfigureAwait(false); await _glamourerApplicationSemaphore.WaitAsync(token).ConfigureAwait(false);
var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(false); var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(false);
if (gameObj is Character c) if (gameObj is Character c)
{ {
await PenumbraRedrawAsync(logger, handler, applicationid, () => _glamourerApplyOnlyCustomization!.InvokeAction(customization, c), fireAndForget, token).ConfigureAwait(false); await PenumbraRedrawAsync(logger, handler, applicationid, () =>
await PenumbraRedrawAsync(logger, handler, applicationid, () => _glamourerApplyOnlyEquipment!.InvokeAction(equipment, c), fireAndForget, token).ConfigureAwait(false); {
logger.LogDebug("[{appid}] Calling on IPC: GlamourerApplyOnlyCustomization", applicationid);
_glamourerApplyOnlyCustomization!.InvokeAction(customization, c);
}, fireAndForget).ConfigureAwait(false);
await PenumbraRedrawAsync(logger, handler, applicationid, () =>
{
logger.LogDebug("[{appid}] Calling on IPC: GlamourerApplyOnlyEquipment", applicationid);
_glamourerApplyOnlyEquipment!.InvokeAction(equipment, c);
}, fireAndForget).ConfigureAwait(false);
} }
} }
finally finally
@@ -273,43 +279,34 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
public async Task HeelsRestoreOffsetForPlayer(IntPtr character) public async Task HeelsRestoreOffsetForPlayer(IntPtr character)
{ {
if (!CheckHeelsApi()) return; if (!CheckHeelsApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj != null) if (gameObj != null)
{ {
Logger.LogTrace("Restoring Heels data to {chara}", character.ToString("X")); Logger.LogTrace("Restoring Heels data to {chara}", character.ToString("X"));
_heelsUnregisterPlayer.InvokeAction(gameObj); await _dalamudUtil.RunOnFrameworkThread(() => _heelsUnregisterPlayer.InvokeAction(gameObj)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public async Task HeelsSetOffsetForPlayer(IntPtr character, float offset) public async Task HeelsSetOffsetForPlayer(IntPtr character, float offset)
{ {
if (!CheckHeelsApi()) return; if (!CheckHeelsApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj != null) if (gameObj != null)
{ {
Logger.LogTrace("Applying Heels data to {chara}", character.ToString("X")); Logger.LogTrace("Applying Heels data to {chara}", character.ToString("X"));
_heelsRegisterPlayer.InvokeAction(gameObj, offset); await _dalamudUtil.RunOnFrameworkThread(() => _heelsRegisterPlayer.InvokeAction(gameObj, offset)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public async Task HonorificClearTitle(nint character) public async Task HonorificClearTitle(nint character)
{ {
if (!CheckHonorificApi()) return; if (!CheckHonorificApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj is PlayerCharacter c) if (gameObj is PlayerCharacter c)
{ {
Logger.LogTrace("Honorific removing for {addr}", c.Address.ToString("X")); Logger.LogTrace("Honorific removing for {addr}", c.Address.ToString("X"));
_honorificClearCharacterTitle!.InvokeAction(c); await _dalamudUtil.RunOnFrameworkThread(() => _honorificClearCharacterTitle!.InvokeAction(c)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public string HonorificGetTitle() public string HonorificGetTitle()
@@ -322,11 +319,11 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
public async Task HonorificSetTitle(IntPtr character, string honorificData) public async Task HonorificSetTitle(IntPtr character, string honorificData)
{ {
if (!CheckHonorificApi()) return; if (!CheckHonorificApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () =>
{
Logger.LogTrace("Applying Honorific data to {chara}", character.ToString("X")); Logger.LogTrace("Applying Honorific data to {chara}", character.ToString("X"));
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true); var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
if (gameObj is PlayerCharacter pc) if (gameObj is PlayerCharacter pc)
{
await _dalamudUtil.RunOnFrameworkThread(() =>
{ {
if (string.IsNullOrEmpty(honorificData)) if (string.IsNullOrEmpty(honorificData))
{ {
@@ -336,9 +333,9 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
{ {
_honorificSetCharacterTitle!.InvokeAction(pc, honorificData[1..], honorificData[0] == '1'); _honorificSetCharacterTitle!.InvokeAction(pc, honorificData[1..], honorificData[0] == '1');
} }
}
}).ConfigureAwait(false); }).ConfigureAwait(false);
} }
}
public async Task<string> PalettePlusBuildPalette() public async Task<string> PalettePlusBuildPalette()
{ {
@@ -351,24 +348,21 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
public async Task PalettePlusRemovePalette(IntPtr character) public async Task PalettePlusRemovePalette(IntPtr character)
{ {
if (!CheckPalettePlusApi()) return; if (!CheckPalettePlusApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj is Character c) if (gameObj is Character c)
{ {
Logger.LogTrace("PalettePlus removing for {addr}", c.Address.ToString("X")); Logger.LogTrace("PalettePlus removing for {addr}", c.Address.ToString("X"));
_palettePlusRemoveCharaPalette!.InvokeAction(c); await _dalamudUtil.RunOnFrameworkThread(() => _palettePlusRemoveCharaPalette!.InvokeAction(c)).ConfigureAwait(false);
} }
}).ConfigureAwait(false);
} }
public async Task PalettePlusSetPalette(IntPtr character, string palette) public async Task PalettePlusSetPalette(IntPtr character, string palette)
{ {
if (!CheckPalettePlusApi()) return; if (!CheckPalettePlusApi()) return;
await _dalamudUtil.RunOnFrameworkThread(async () => var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(false);
{
var gameObj = await _dalamudUtil.CreateGameObject(character).ConfigureAwait(true);
if (gameObj is Character c) if (gameObj is Character c)
{
await _dalamudUtil.RunOnFrameworkThread(() =>
{ {
string decodedPalette = Encoding.UTF8.GetString(Convert.FromBase64String(palette)); string decodedPalette = Encoding.UTF8.GetString(Convert.FromBase64String(palette));
@@ -382,9 +376,9 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
Logger.LogTrace("PalettePlus applying for {addr}", c.Address.ToString("X")); Logger.LogTrace("PalettePlus applying for {addr}", c.Address.ToString("X"));
_palettePlusSetCharaPalette!.InvokeAction(c, decodedPalette); _palettePlusSetCharaPalette!.InvokeAction(c, decodedPalette);
} }
}
}).ConfigureAwait(false); }).ConfigureAwait(false);
} }
}
public string PenumbraGetMetaManipulations() public string PenumbraGetMetaManipulations()
{ {
@@ -395,14 +389,23 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
public async Task PenumbraRedraw(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token, bool fireAndForget = false) public async Task PenumbraRedraw(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token, bool fireAndForget = false)
{ {
if (!CheckPenumbraApi() || _dalamudUtil.IsZoning) return; if (!CheckPenumbraApi() || _dalamudUtil.IsZoning) return;
await _dalamudUtil.RunOnFrameworkThread(async () => try
{ {
var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(true); await _glamourerApplicationSemaphore.WaitAsync(token).ConfigureAwait(false);
var gameObj = await _dalamudUtil.CreateGameObject(handler.Address).ConfigureAwait(false);
if (gameObj is Character c) if (gameObj is Character c)
{ {
await PenumbraRedrawAsync(logger, handler, applicationId, () => _penumbraRedrawObject!.Invoke(c, RedrawType.Redraw), fireAndForget, token).ConfigureAwait(false); await PenumbraRedrawAsync(logger, handler, applicationId, () =>
{
logger.LogDebug("[{appid}] Calling on IPC: PenumbraRedraw", applicationId);
_penumbraRedrawObject!.Invoke(c, RedrawType.Redraw);
}, fireAndForget).ConfigureAwait(false);
}
}
finally
{
_glamourerApplicationSemaphore.Release();
} }
}).ConfigureAwait(false);
} }
public async Task PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName) public async Task PenumbraRemoveTemporaryCollection(ILogger logger, Guid applicationId, string characterName)
@@ -648,7 +651,7 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
_penumbraRedraw!.Invoke("self", RedrawType.Redraw); _penumbraRedraw!.Invoke("self", RedrawType.Redraw);
} }
private async Task PenumbraRedrawAsync(ILogger logger, GameObjectHandler obj, Guid applicationId, Action action, bool fireAndForget, CancellationToken token) private async Task PenumbraRedrawAsync(ILogger logger, GameObjectHandler obj, Guid applicationId, Action action, bool fireAndForget)
{ {
Mediator.Publish(new PenumbraStartRedrawMessage(obj.Address)); Mediator.Publish(new PenumbraStartRedrawMessage(obj.Address));
@@ -660,13 +663,10 @@ public sealed class IpcManager : DisposableMediatorSubscriberBase
{ {
await _dalamudUtil.RunOnFrameworkThread(action).ConfigureAwait(false); await _dalamudUtil.RunOnFrameworkThread(action).ConfigureAwait(false);
var disposeToken = _disposalCts.Token; await Task.Delay(TimeSpan.FromSeconds(1), _disposalCts.Token).ConfigureAwait(false);
var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(disposeToken, token).Token;
await Task.Delay(TimeSpan.FromSeconds(1), combinedToken).ConfigureAwait(false); if (!_disposalCts.Token.IsCancellationRequested)
await _dalamudUtil.WaitWhileCharacterIsDrawing(logger, obj, applicationId, 30000, _disposalCts.Token).ConfigureAwait(false);
if (!combinedToken.IsCancellationRequested)
await _dalamudUtil.WaitWhileCharacterIsDrawing(logger, obj, applicationId, 30000, combinedToken).ConfigureAwait(false);
} }
else else
{ {

View File

@@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<Authors></Authors> <Authors></Authors>
<Company></Company> <Company></Company>
<Version>0.8.30</Version> <Version>0.8.31</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>

View File

@@ -32,7 +32,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
private CancellationTokenSource? _applicationCancellationTokenSource = new(); private CancellationTokenSource? _applicationCancellationTokenSource = new();
private Guid _applicationId; private Guid _applicationId;
private Task? _applicationTask; private Task? _applicationTask;
private CharacterData _cachedData = new(); private CharacterData? _cachedData = null;
private GameObjectHandler? _charaHandler; private GameObjectHandler? _charaHandler;
private CancellationTokenSource? _downloadCancellationTokenSource = new(); private CancellationTokenSource? _downloadCancellationTokenSource = new();
private int _framesSinceNotVisible = 0; private int _framesSinceNotVisible = 0;
@@ -91,14 +91,14 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
SetUploading(false); SetUploading(false);
Logger.LogDebug("Received data for {player}", this); Logger.LogDebug("Received data for {player}", this);
Logger.LogDebug("Hash for data is {newHash}, current cache hash is {oldHash}", characterData.DataHash.Value, _cachedData.DataHash.Value); Logger.LogDebug("Hash for data is {newHash}, current cache hash is {oldHash}", characterData.DataHash.Value, _cachedData?.DataHash.Value ?? "NODATA");
Logger.LogDebug("Checking for files to download for player {name}", this); Logger.LogDebug("Checking for files to download for player {name}", this);
if (!_ipcManager.CheckPenumbraApi()) return; if (!_ipcManager.CheckPenumbraApi()) return;
if (!_ipcManager.CheckGlamourerApi()) return; if (!_ipcManager.CheckGlamourerApi()) return;
if (string.Equals(characterData.DataHash.Value, _cachedData.DataHash.Value, StringComparison.Ordinal) && !forced) return; if (string.Equals(characterData.DataHash.Value, _cachedData?.DataHash.Value ?? string.Empty, StringComparison.Ordinal) && !forced) return;
if (_dalamudUtil.IsInCutscene || _dalamudUtil.IsInGpose) if (_dalamudUtil.IsInCutscene || _dalamudUtil.IsInGpose)
{ {
@@ -106,7 +106,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
return; return;
} }
var charaDataToUpdate = CheckUpdatedData(_cachedData.DeepClone(), characterData, forced); var charaDataToUpdate = CheckUpdatedData(_cachedData?.DeepClone() ?? new(), characterData, forced);
if (charaDataToUpdate.TryGetValue(ObjectKind.Player, out var playerChanges)) if (charaDataToUpdate.TryGetValue(ObjectKind.Player, out var playerChanges))
{ {
@@ -163,7 +163,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
Logger.LogTrace("[{applicationId}] Restoring state for {name} ({OnlineUser})", applicationId, name, OnlineUser); Logger.LogTrace("[{applicationId}] Restoring state for {name} ({OnlineUser})", applicationId, name, OnlineUser);
_ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name).GetAwaiter().GetResult(); _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, name).GetAwaiter().GetResult();
foreach (KeyValuePair<ObjectKind, List<FileReplacementData>> item in _cachedData.FileReplacements) foreach (KeyValuePair<ObjectKind, List<FileReplacementData>> item in _cachedData?.FileReplacements ?? new())
{ {
try try
{ {
@@ -184,7 +184,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
finally finally
{ {
PlayerName = null; PlayerName = null;
_cachedData = new(); _cachedData = null;
Logger.LogDebug("Disposing {name} complete", name); Logger.LogDebug("Disposing {name} complete", name);
} }
} }
@@ -539,9 +539,12 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
var applicationId = Guid.NewGuid(); var applicationId = Guid.NewGuid();
await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, applicationId, ct: token).ConfigureAwait(false); await _dalamudUtil.WaitWhileCharacterIsDrawing(Logger, _charaHandler!, applicationId, ct: token).ConfigureAwait(false);
Logger.LogDebug("Unauthorized character change detected"); Logger.LogDebug("Unauthorized character change detected");
if (_cachedData != null)
{
await ApplyCustomizationData(applicationId, new(ObjectKind.Player, await ApplyCustomizationData(applicationId, new(ObjectKind.Player,
new HashSet<PlayerChanges>(new[] { PlayerChanges.Palette, PlayerChanges.Customize, PlayerChanges.Heels, PlayerChanges.Mods })), new HashSet<PlayerChanges>(new[] { PlayerChanges.Palette, PlayerChanges.Customize, PlayerChanges.Heels, PlayerChanges.Mods })),
_cachedData, token).ConfigureAwait(false); _cachedData, token).ConfigureAwait(false);
}
}, token); }, token);
} }
@@ -685,7 +688,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
PluginLog.Error(ex, "Something went wrong during calculation replacements"); PluginLog.Error(ex, "Something went wrong during calculation replacements");
} }
st.Stop(); st.Stop();
Logger.LogDebug("ModdedPaths calculated in {time}ms, missing files: {count}", st.ElapsedMilliseconds, missingFiles.Count); Logger.LogDebug("ModdedPaths calculated in {time}ms, missing files: {count}, total files: {total}", st.ElapsedMilliseconds, missingFiles.Count, moddedDictionary.Keys.Count);
return missingFiles; return missingFiles;
} }
} }