attempt to fix some crashes
This commit is contained in:
		| @@ -3,7 +3,7 @@ | ||||
|   <PropertyGroup> | ||||
|     <Authors></Authors> | ||||
|     <Company></Company> | ||||
|     <Version>0.8.0</Version> | ||||
|     <Version>0.8.1</Version> | ||||
|     <Description></Description> | ||||
|     <Copyright></Copyright> | ||||
|     <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 IpcManager _ipcManager; | ||||
|     private readonly IHostApplicationLifetime _lifetime; | ||||
|     private CancellationTokenSource _applicationCancellationTokenSource = new(); | ||||
|     private Guid _applicationId; | ||||
|     private Task? _applicationTask; | ||||
|     private CharacterData _cachedData = new(); | ||||
| @@ -149,6 +150,8 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|         try | ||||
|         { | ||||
|             Guid applicationId = Guid.NewGuid(); | ||||
|             _applicationCancellationTokenSource.Cancel(); | ||||
|             _applicationCancellationTokenSource.Dispose(); | ||||
|             _downloadCancellationTokenSource?.Cancel(); | ||||
|             _downloadCancellationTokenSource?.Dispose(); | ||||
|             _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); | ||||
|         token.ThrowIfCancellationRequested(); | ||||
|         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; | ||||
|         var ptr = PlayerCharacter; | ||||
| @@ -197,9 +202,6 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|             _ => throw new NotSupportedException("ObjectKind not supported: " + changes.Key) | ||||
|         }; | ||||
|  | ||||
|         CancellationTokenSource applicationTokenSource = new(); | ||||
|         applicationTokenSource.CancelAfter(TimeSpan.FromSeconds(30)); | ||||
|  | ||||
|         if (handler.Address == IntPtr.Zero) | ||||
|         { | ||||
|             if (handler != _charaHandler) handler.Dispose(); | ||||
| @@ -228,11 +230,11 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|                 case PlayerChanges.Mods: | ||||
|                     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 | ||||
|                     { | ||||
|                         await _ipcManager.PenumbraRedraw(Logger, handler, applicationId, applicationTokenSource.Token).ConfigureAwait(false); | ||||
|                         await _ipcManager.PenumbraRedraw(Logger, handler, applicationId, token).ConfigureAwait(false); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
| @@ -389,6 +391,9 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|  | ||||
|             if (downloadToken.IsCancellationRequested) return; | ||||
|  | ||||
|             _applicationCancellationTokenSource?.Dispose(); | ||||
|             _applicationCancellationTokenSource = new(); | ||||
|             var token = _applicationCancellationTokenSource.Token; | ||||
|             _applicationTask = Task.Run(async () => | ||||
|             { | ||||
|                 _applicationId = Guid.NewGuid(); | ||||
| @@ -396,16 +401,18 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|  | ||||
|                 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) | ||||
|                 { | ||||
|                     await ApplyCustomizationData(_applicationId, kind, charaData).ConfigureAwait(false); | ||||
|                     await ApplyCustomizationData(_applicationId, kind, charaData, token).ConfigureAwait(false); | ||||
|                 } | ||||
|  | ||||
|                 Logger.LogDebug("[{applicationId}] Application finished", _applicationId); | ||||
|             }); | ||||
|             }, token); | ||||
|         }, downloadToken); | ||||
|     } | ||||
|  | ||||
| @@ -426,7 +433,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | ||||
|             Logger.LogDebug("Unauthorized character change detected"); | ||||
|             await ApplyCustomizationData(applicationId, new(ObjectKind.Player, | ||||
|                 new HashSet<PlayerChanges>(new[] { PlayerChanges.Palette, PlayerChanges.Customize, PlayerChanges.Heels, PlayerChanges.Mods })), | ||||
|                 _cachedData).ConfigureAwait(false); | ||||
|                 _cachedData, _applicationCancellationTokenSource.Token).ConfigureAwait(false); | ||||
|         }, token); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -186,12 +186,6 @@ public class DalamudUtilService : IHostedService | ||||
|         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) | ||||
|     { | ||||
|         if (!_clientState.IsLoggedIn || handler.Address == IntPtr.Zero) return; | ||||
| @@ -202,7 +196,6 @@ public class DalamudUtilService : IHostedService | ||||
|         int curWaitTime = 0; | ||||
|         try | ||||
|         { | ||||
|             // ReSharper disable once LoopVariableIsNeverChangedInsideLoop | ||||
|             while ((!ct?.IsCancellationRequested ?? true) | ||||
|                    && curWaitTime < timeOut | ||||
|                    && await handler.IsBeingDrawnRunOnFramework().ConfigureAwait(true)) // 0b100000000000 is "still rendering" or something | ||||
| @@ -242,6 +235,12 @@ public class DalamudUtilService : IHostedService | ||||
|         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) | ||||
|     { | ||||
|         _performanceCollector.LogPerformance(this, "FrameworkOnUpdate", FrameworkOnUpdateInternal); | ||||
|   | ||||
| @@ -679,7 +679,7 @@ public class CompactUi : WindowMediatorSubscriberBase | ||||
|         var color = UiSharedService.GetBoolColor(!_serverManager.CurrentServer!.FullPause); | ||||
|         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); | ||||
|             if (ImGuiComponents.IconButton(connectedIcon)) | ||||
| @@ -819,6 +819,7 @@ public class CompactUi : WindowMediatorSubscriberBase | ||||
|             ServerState.Connecting => "Attempting to connect 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.Disconnecting => "Disconnecting from the server", | ||||
|             ServerState.Unauthorized => "Server Response: " + _apiController.AuthFailureMessage, | ||||
|             ServerState.Offline => "Your selected Mare Synchronos server is currently offline.", | ||||
|             ServerState.VersionMisMatch => | ||||
| @@ -838,6 +839,7 @@ public class CompactUi : WindowMediatorSubscriberBase | ||||
|             ServerState.Reconnecting => ImGuiColors.DalamudRed, | ||||
|             ServerState.Connected => ImGuiColors.ParsedGreen, | ||||
|             ServerState.Disconnected => ImGuiColors.DalamudYellow, | ||||
|             ServerState.Disconnecting => ImGuiColors.DalamudYellow, | ||||
|             ServerState.Unauthorized => ImGuiColors.DalamudRed, | ||||
|             ServerState.VersionMisMatch => ImGuiColors.DalamudRed, | ||||
|             ServerState.Offline => ImGuiColors.DalamudRed, | ||||
| @@ -854,6 +856,7 @@ public class CompactUi : WindowMediatorSubscriberBase | ||||
|             ServerState.Reconnecting => "Reconnecting", | ||||
|             ServerState.Connecting => "Connecting", | ||||
|             ServerState.Disconnected => "Disconnected", | ||||
|             ServerState.Disconnecting => "Disconnecting", | ||||
|             ServerState.Unauthorized => "Unauthorized", | ||||
|             ServerState.VersionMisMatch => "Version mismatch", | ||||
|             ServerState.Offline => "Unavailable", | ||||
|   | ||||
| @@ -147,7 +147,11 @@ public class SettingsUi : WindowMediatorSubscriberBase | ||||
|             _configService.Current.ShowTransferWindow = showTransferWindow; | ||||
|             _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(); | ||||
|         ImGui.Indent(); | ||||
|         bool editTransferWindowPosition = _uiShared.EditTrackerPosition; | ||||
|   | ||||
| @@ -334,7 +334,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM | ||||
|  | ||||
|     private async Task StopConnection(ServerState state) | ||||
|     { | ||||
|         ServerState = state; | ||||
|         ServerState = ServerState.Disconnecting; | ||||
|  | ||||
|         if (_mareHub is not null) | ||||
|         { | ||||
| @@ -346,5 +346,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM | ||||
|             _mareHub = null; | ||||
|             _connectionDto = null; | ||||
|         } | ||||
|  | ||||
|         ServerState = state; | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,7 @@ public enum ServerState | ||||
|     Offline, | ||||
|     Connecting, | ||||
|     Reconnecting, | ||||
|     Disconnecting, | ||||
|     Disconnected, | ||||
|     Connected, | ||||
|     Unauthorized, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 rootdarkarchon
					rootdarkarchon