attempt to fix some crashes
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors></Authors>
|
<Authors></Authors>
|
||||||
<Company></Company>
|
<Company></Company>
|
||||||
<Version>0.8.0</Version>
|
<Version>0.8.1</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>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
private readonly Func<ObjectKind, Func<nint>, bool, GameObjectHandler> _gameObjectHandlerFactory;
|
private readonly Func<ObjectKind, Func<nint>, bool, GameObjectHandler> _gameObjectHandlerFactory;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
private readonly IHostApplicationLifetime _lifetime;
|
private readonly IHostApplicationLifetime _lifetime;
|
||||||
|
private CancellationTokenSource _applicationCancellationTokenSource = new();
|
||||||
private Guid _applicationId;
|
private Guid _applicationId;
|
||||||
private Task? _applicationTask;
|
private Task? _applicationTask;
|
||||||
private CharacterData _cachedData = new();
|
private CharacterData _cachedData = new();
|
||||||
@@ -149,6 +150,8 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Guid applicationId = Guid.NewGuid();
|
Guid applicationId = Guid.NewGuid();
|
||||||
|
_applicationCancellationTokenSource.Cancel();
|
||||||
|
_applicationCancellationTokenSource.Dispose();
|
||||||
_downloadCancellationTokenSource?.Cancel();
|
_downloadCancellationTokenSource?.Cancel();
|
||||||
_downloadCancellationTokenSource?.Dispose();
|
_downloadCancellationTokenSource?.Dispose();
|
||||||
_downloadCancellationTokenSource = null;
|
_downloadCancellationTokenSource = null;
|
||||||
@@ -178,13 +181,15 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ApplyBaseData(Guid applicationId, Dictionary<string, string> moddedPaths, string manipulationData)
|
private async Task ApplyBaseData(Guid applicationId, Dictionary<string, string> moddedPaths, string manipulationData, CancellationToken token)
|
||||||
{
|
{
|
||||||
await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!)).ConfigureAwait(false);
|
await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraRemoveTemporaryCollection(Logger, applicationId, PlayerName!)).ConfigureAwait(false);
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, moddedPaths, manipulationData)).ConfigureAwait(false);
|
await _dalamudUtil.RunOnFrameworkThread(() => _ipcManager.PenumbraSetTemporaryMods(Logger, applicationId, PlayerName!, moddedPaths, manipulationData)).ConfigureAwait(false);
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ApplyCustomizationData(Guid applicationId, KeyValuePair<ObjectKind, HashSet<PlayerChanges>> changes, API.Data.CharacterData charaData)
|
private async Task ApplyCustomizationData(Guid applicationId, KeyValuePair<ObjectKind, HashSet<PlayerChanges>> changes, CharacterData charaData, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (PlayerCharacter == IntPtr.Zero) return;
|
if (PlayerCharacter == IntPtr.Zero) return;
|
||||||
var ptr = PlayerCharacter;
|
var ptr = PlayerCharacter;
|
||||||
@@ -197,9 +202,6 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
_ => throw new NotSupportedException("ObjectKind not supported: " + changes.Key)
|
_ => throw new NotSupportedException("ObjectKind not supported: " + changes.Key)
|
||||||
};
|
};
|
||||||
|
|
||||||
CancellationTokenSource applicationTokenSource = new();
|
|
||||||
applicationTokenSource.CancelAfter(TimeSpan.FromSeconds(30));
|
|
||||||
|
|
||||||
if (handler.Address == IntPtr.Zero)
|
if (handler.Address == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
if (handler != _charaHandler) handler.Dispose();
|
if (handler != _charaHandler) handler.Dispose();
|
||||||
@@ -228,11 +230,11 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
case PlayerChanges.Mods:
|
case PlayerChanges.Mods:
|
||||||
if (charaData.GlamourerData.TryGetValue(changes.Key, out var glamourerData))
|
if (charaData.GlamourerData.TryGetValue(changes.Key, out var glamourerData))
|
||||||
{
|
{
|
||||||
await _ipcManager.GlamourerApplyAll(Logger, handler, glamourerData, applicationId, applicationTokenSource.Token).ConfigureAwait(false);
|
await _ipcManager.GlamourerApplyAll(Logger, handler, glamourerData, applicationId, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _ipcManager.PenumbraRedraw(Logger, handler, applicationId, applicationTokenSource.Token).ConfigureAwait(false);
|
await _ipcManager.PenumbraRedraw(Logger, handler, applicationId, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -389,6 +391,9 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
if (downloadToken.IsCancellationRequested) return;
|
if (downloadToken.IsCancellationRequested) return;
|
||||||
|
|
||||||
|
_applicationCancellationTokenSource?.Dispose();
|
||||||
|
_applicationCancellationTokenSource = new();
|
||||||
|
var token = _applicationCancellationTokenSource.Token;
|
||||||
_applicationTask = Task.Run(async () =>
|
_applicationTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
_applicationId = Guid.NewGuid();
|
_applicationId = Guid.NewGuid();
|
||||||
@@ -396,16 +401,18 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
if (updateModdedPaths && (moddedPaths.Any() || !string.IsNullOrEmpty(charaData.ManipulationData)))
|
if (updateModdedPaths && (moddedPaths.Any() || !string.IsNullOrEmpty(charaData.ManipulationData)))
|
||||||
{
|
{
|
||||||
await ApplyBaseData(_applicationId, moddedPaths, charaData.ManipulationData).ConfigureAwait(false);
|
await ApplyBaseData(_applicationId, moddedPaths, charaData.ManipulationData, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
foreach (var kind in updatedData)
|
foreach (var kind in updatedData)
|
||||||
{
|
{
|
||||||
await ApplyCustomizationData(_applicationId, kind, charaData).ConfigureAwait(false);
|
await ApplyCustomizationData(_applicationId, kind, charaData, token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogDebug("[{applicationId}] Application finished", _applicationId);
|
Logger.LogDebug("[{applicationId}] Application finished", _applicationId);
|
||||||
});
|
}, token);
|
||||||
}, downloadToken);
|
}, downloadToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +433,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
|
|||||||
Logger.LogDebug("Unauthorized character change detected");
|
Logger.LogDebug("Unauthorized character change detected");
|
||||||
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).ConfigureAwait(false);
|
_cachedData, _applicationCancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
}, token);
|
}, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -186,12 +186,6 @@ public class DalamudUtilService : IHostedService
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 WorldToScreen(Dalamud.Game.ClientState.Objects.Types.GameObject? obj)
|
|
||||||
{
|
|
||||||
if (obj == null) return Vector2.Zero;
|
|
||||||
return _gameGui.WorldToScreen(obj.Position, out var screenPos) ? screenPos : Vector2.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task WaitWhileCharacterIsDrawing(ILogger logger, GameObjectHandler handler, Guid redrawId, int timeOut = 5000, CancellationToken? ct = null)
|
public async Task WaitWhileCharacterIsDrawing(ILogger logger, GameObjectHandler handler, Guid redrawId, int timeOut = 5000, CancellationToken? ct = null)
|
||||||
{
|
{
|
||||||
if (!_clientState.IsLoggedIn || handler.Address == IntPtr.Zero) return;
|
if (!_clientState.IsLoggedIn || handler.Address == IntPtr.Zero) return;
|
||||||
@@ -202,7 +196,6 @@ public class DalamudUtilService : IHostedService
|
|||||||
int curWaitTime = 0;
|
int curWaitTime = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
|
|
||||||
while ((!ct?.IsCancellationRequested ?? true)
|
while ((!ct?.IsCancellationRequested ?? true)
|
||||||
&& curWaitTime < timeOut
|
&& curWaitTime < timeOut
|
||||||
&& await handler.IsBeingDrawnRunOnFramework().ConfigureAwait(true)) // 0b100000000000 is "still rendering" or something
|
&& await handler.IsBeingDrawnRunOnFramework().ConfigureAwait(true)) // 0b100000000000 is "still rendering" or something
|
||||||
@@ -242,6 +235,12 @@ public class DalamudUtilService : IHostedService
|
|||||||
Thread.Sleep(tick * 2);
|
Thread.Sleep(tick * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 WorldToScreen(Dalamud.Game.ClientState.Objects.Types.GameObject? obj)
|
||||||
|
{
|
||||||
|
if (obj == null) return Vector2.Zero;
|
||||||
|
return _gameGui.WorldToScreen(obj.Position, out var screenPos) ? screenPos : Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
private void FrameworkOnUpdate(Framework framework)
|
private void FrameworkOnUpdate(Framework framework)
|
||||||
{
|
{
|
||||||
_performanceCollector.LogPerformance(this, "FrameworkOnUpdate", FrameworkOnUpdateInternal);
|
_performanceCollector.LogPerformance(this, "FrameworkOnUpdate", FrameworkOnUpdateInternal);
|
||||||
|
|||||||
@@ -679,7 +679,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause);
|
var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause);
|
||||||
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
var connectedIcon = !_serverManager.CurrentServer.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink;
|
||||||
|
|
||||||
if (_apiController.ServerState != ServerState.Reconnecting)
|
if (_apiController.ServerState is not (ServerState.Reconnecting or ServerState.Disconnecting))
|
||||||
{
|
{
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||||
if (ImGuiComponents.IconButton(connectedIcon))
|
if (ImGuiComponents.IconButton(connectedIcon))
|
||||||
@@ -819,6 +819,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
ServerState.Connecting => "Attempting to connect to the server.",
|
ServerState.Connecting => "Attempting to connect to the server.",
|
||||||
ServerState.Reconnecting => "Connection to server interrupted, attempting to reconnect to the server.",
|
ServerState.Reconnecting => "Connection to server interrupted, attempting to reconnect to the server.",
|
||||||
ServerState.Disconnected => "You are currently disconnected from the Mare Synchronos server.",
|
ServerState.Disconnected => "You are currently disconnected from the Mare Synchronos server.",
|
||||||
|
ServerState.Disconnecting => "Disconnecting from the server",
|
||||||
ServerState.Unauthorized => "Server Response: " + _apiController.AuthFailureMessage,
|
ServerState.Unauthorized => "Server Response: " + _apiController.AuthFailureMessage,
|
||||||
ServerState.Offline => "Your selected Mare Synchronos server is currently offline.",
|
ServerState.Offline => "Your selected Mare Synchronos server is currently offline.",
|
||||||
ServerState.VersionMisMatch =>
|
ServerState.VersionMisMatch =>
|
||||||
@@ -838,6 +839,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
ServerState.Reconnecting => ImGuiColors.DalamudRed,
|
ServerState.Reconnecting => ImGuiColors.DalamudRed,
|
||||||
ServerState.Connected => ImGuiColors.ParsedGreen,
|
ServerState.Connected => ImGuiColors.ParsedGreen,
|
||||||
ServerState.Disconnected => ImGuiColors.DalamudYellow,
|
ServerState.Disconnected => ImGuiColors.DalamudYellow,
|
||||||
|
ServerState.Disconnecting => ImGuiColors.DalamudYellow,
|
||||||
ServerState.Unauthorized => ImGuiColors.DalamudRed,
|
ServerState.Unauthorized => ImGuiColors.DalamudRed,
|
||||||
ServerState.VersionMisMatch => ImGuiColors.DalamudRed,
|
ServerState.VersionMisMatch => ImGuiColors.DalamudRed,
|
||||||
ServerState.Offline => ImGuiColors.DalamudRed,
|
ServerState.Offline => ImGuiColors.DalamudRed,
|
||||||
@@ -854,6 +856,7 @@ public class CompactUi : WindowMediatorSubscriberBase
|
|||||||
ServerState.Reconnecting => "Reconnecting",
|
ServerState.Reconnecting => "Reconnecting",
|
||||||
ServerState.Connecting => "Connecting",
|
ServerState.Connecting => "Connecting",
|
||||||
ServerState.Disconnected => "Disconnected",
|
ServerState.Disconnected => "Disconnected",
|
||||||
|
ServerState.Disconnecting => "Disconnecting",
|
||||||
ServerState.Unauthorized => "Unauthorized",
|
ServerState.Unauthorized => "Unauthorized",
|
||||||
ServerState.VersionMisMatch => "Version mismatch",
|
ServerState.VersionMisMatch => "Version mismatch",
|
||||||
ServerState.Offline => "Unavailable",
|
ServerState.Offline => "Unavailable",
|
||||||
|
|||||||
@@ -147,7 +147,11 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
_configService.Current.ShowTransferWindow = showTransferWindow;
|
_configService.Current.ShowTransferWindow = showTransferWindow;
|
||||||
_configService.Save();
|
_configService.Save();
|
||||||
}
|
}
|
||||||
|
UiSharedService.DrawHelpText($"The download window will show the current progress of outstanding downloads.{Environment.NewLine}{Environment.NewLine}" +
|
||||||
|
$"What do W/Q/P/D stand for?{Environment.NewLine}W = Waiting for Slot (see Maximum Parallel Downloads){Environment.NewLine}" +
|
||||||
|
$"Q = Queued on Server, waiting for queue ready signal{Environment.NewLine}" +
|
||||||
|
$"P = Processing download (aka downloading){Environment.NewLine}" +
|
||||||
|
$"D = Decompressing download");
|
||||||
if (!_configService.Current.ShowTransferWindow) ImGui.BeginDisabled();
|
if (!_configService.Current.ShowTransferWindow) ImGui.BeginDisabled();
|
||||||
ImGui.Indent();
|
ImGui.Indent();
|
||||||
bool editTransferWindowPosition = _uiShared.EditTrackerPosition;
|
bool editTransferWindowPosition = _uiShared.EditTrackerPosition;
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
|
|||||||
|
|
||||||
private async Task StopConnection(ServerState state)
|
private async Task StopConnection(ServerState state)
|
||||||
{
|
{
|
||||||
ServerState = state;
|
ServerState = ServerState.Disconnecting;
|
||||||
|
|
||||||
if (_mareHub is not null)
|
if (_mareHub is not null)
|
||||||
{
|
{
|
||||||
@@ -346,5 +346,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
|
|||||||
_mareHub = null;
|
_mareHub = null;
|
||||||
_connectionDto = null;
|
_connectionDto = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerState = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,11 @@ public enum ServerState
|
|||||||
Offline,
|
Offline,
|
||||||
Connecting,
|
Connecting,
|
||||||
Reconnecting,
|
Reconnecting,
|
||||||
|
Disconnecting,
|
||||||
Disconnected,
|
Disconnected,
|
||||||
Connected,
|
Connected,
|
||||||
Unauthorized,
|
Unauthorized,
|
||||||
VersionMisMatch,
|
VersionMisMatch,
|
||||||
RateLimited,
|
RateLimited,
|
||||||
NoSecretKey,
|
NoSecretKey,
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user