diff --git a/MareSynchronos/MareConfiguration/Models/ServerStorage.cs b/MareSynchronos/MareConfiguration/Models/ServerStorage.cs index 24a8b03..5b4d36e 100644 --- a/MareSynchronos/MareConfiguration/Models/ServerStorage.cs +++ b/MareSynchronos/MareConfiguration/Models/ServerStorage.cs @@ -13,4 +13,5 @@ public class ServerStorage public bool UseOAuth2 { get; set; } = false; public string? OAuthToken { get; set; } = null; public HttpTransportType HttpTransportType { get; set; } = HttpTransportType.WebSockets; + public bool ForceWebSockets { get; set; } = false; } \ No newline at end of file diff --git a/MareSynchronos/UI/SettingsUi.cs b/MareSynchronos/UI/SettingsUi.cs index 9071493..672fcad 100644 --- a/MareSynchronos/UI/SettingsUi.cs +++ b/MareSynchronos/UI/SettingsUi.cs @@ -1704,6 +1704,21 @@ public class SettingsUi : WindowMediatorSubscriberBase + "If you run into connection issues with e.g. VPNs, try ServerSentEvents first before trying out LongPolling." + UiSharedService.TooltipSeparator + "Note: if the server does not support a specific Transport Type it will fall through to the next automatically: WebSockets > ServerSentEvents > LongPolling"); + if (_dalamudUtilService.IsWine) + { + bool forceWebSockets = selectedServer.ForceWebSockets; + if (ImGui.Checkbox("[wine only] Force WebSockets", ref forceWebSockets)) + { + selectedServer.ForceWebSockets = forceWebSockets; + _serverConfigurationManager.Save(); + } + _uiShared.DrawHelpText("On wine, Mare will automatically fall back to ServerSentEvents/LongPolling, even if WebSockets is selected. " + + "WebSockets are known to crash XIV entirely on wine 8.5 shipped with Dalamud. " + + "Only enable this if you are not running wine 8.5." + Environment.NewLine + + "Note: If the issue gets resolved at some point this option will be removed."); + } + + ImGuiHelpers.ScaledDummy(5); if (ImGui.Checkbox("Use Discord OAuth2 Authentication", ref useOauth)) { diff --git a/MareSynchronos/WebAPI/SignalR/HubFactory.cs b/MareSynchronos/WebAPI/SignalR/HubFactory.cs index fce83c7..f686c17 100644 --- a/MareSynchronos/WebAPI/SignalR/HubFactory.cs +++ b/MareSynchronos/WebAPI/SignalR/HubFactory.cs @@ -1,4 +1,5 @@ using MareSynchronos.API.SignalR; +using MareSynchronos.Services; using MareSynchronos.Services.Mediator; using MareSynchronos.Services.ServerConfiguration; using MareSynchronos.WebAPI.SignalR.Utils; @@ -18,14 +19,17 @@ public class HubFactory : MediatorSubscriberBase private readonly TokenProvider _tokenProvider; private HubConnection? _instance; private bool _isDisposed = false; + private readonly bool _isWine = false; public HubFactory(ILogger logger, MareMediator mediator, ServerConfigurationManager serverConfigurationManager, - TokenProvider tokenProvider, ILoggerProvider pluginLog) : base(logger, mediator) + TokenProvider tokenProvider, ILoggerProvider pluginLog, + DalamudUtilService dalamudUtilService) : base(logger, mediator) { _serverConfigurationManager = serverConfigurationManager; _tokenProvider = tokenProvider; _loggingProvider = pluginLog; + _isWine = dalamudUtilService.IsWine; } public async Task DisposeHubAsync() @@ -66,8 +70,14 @@ public class HubFactory : MediatorSubscriberBase _ => HttpTransportType.WebSockets | HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling }; - var baseTransport = _serverConfigurationManager.GetTransport(); - Logger.LogDebug("Building new HubConnection using transport {transport}", baseTransport); + if (_isWine && !_serverConfigurationManager.CurrentServer.ForceWebSockets + && transportType.HasFlag(HttpTransportType.WebSockets)) + { + Logger.LogDebug("Wine detected, falling back to ServerSentEvents / LongPolling"); + transportType = HttpTransportType.ServerSentEvents | HttpTransportType.LongPolling; + } + + Logger.LogDebug("Building new HubConnection using transport {transport}", transportType); _instance = new HubConnectionBuilder() .WithUrl(_serverConfigurationManager.CurrentApiUrl + IMareHub.Path, options =>