diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index da0d7c2c6..9404b5b10 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -108,11 +108,6 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
///
public bool DoPluginTest { get; set; } = false;
- ///
- /// Gets or sets a key to opt into Dalamud staging builds.
- ///
- public string? DalamudBetaKey { get; set; } = null;
-
///
/// Gets or sets a list of custom repos.
///
@@ -278,11 +273,6 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
///
public bool IsResumeGameAfterPluginLoad { get; set; } = false;
- ///
- /// Gets or sets the kind of beta to download when matches the server value.
- ///
- public string? DalamudBetaKind { get; set; }
-
///
/// Gets or sets a value indicating whether any plugin should be loaded when the game is started.
/// It is reset immediately when read.
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index d017bf85a..ed0aa6c4d 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -41,7 +41,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
try
{
Log.Verbose("Starting data load...");
-
+
using (Timings.Start("Lumina Init"))
{
var luminaOptions = new LuminaOptions
@@ -53,12 +53,25 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
DefaultExcelLanguage = this.Language.ToLumina(),
};
- this.GameData = new(
- Path.Combine(Path.GetDirectoryName(Environment.ProcessPath)!, "sqpack"),
- luminaOptions)
+ try
{
- StreamPool = new(),
- };
+ this.GameData = new(
+ Path.Combine(Path.GetDirectoryName(Environment.ProcessPath)!, "sqpack"),
+ luminaOptions)
+ {
+ StreamPool = new(),
+ };
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Lumina GameData init failed");
+ Util.Fatal(
+ "Dalamud could not read required game data files. This likely means your game installation is corrupted or incomplete.\n\n" +
+ "Please repair your installation by right-clicking the login button in XIVLauncher and choosing \"Repair game files\".",
+ "Dalamud");
+
+ return;
+ }
Log.Information("Lumina is ready: {0}", this.GameData.DataPath);
@@ -71,7 +84,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
dalamud.StartInfo.TroubleshootingPackData);
this.HasModifiedGameDataFiles =
tsInfo?.IndexIntegrity is LauncherTroubleshootingInfo.IndexIntegrityResult.Failed or LauncherTroubleshootingInfo.IndexIntegrityResult.Exception;
-
+
if (this.HasModifiedGameDataFiles)
Log.Verbose("Game data integrity check failed!\n{TsData}", dalamud.StartInfo.TroubleshootingPackData);
}
@@ -130,7 +143,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
#region Lumina Wrappers
///
- public ExcelSheet GetExcelSheet(ClientLanguage? language = null, string? name = null) where T : struct, IExcelRow
+ public ExcelSheet GetExcelSheet(ClientLanguage? language = null, string? name = null) where T : struct, IExcelRow
=> this.Excel.GetSheet(language?.ToLumina(), name);
///
@@ -138,7 +151,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
=> this.Excel.GetSubrowSheet(language?.ToLumina(), name);
///
- public FileResource? GetFile(string path)
+ public FileResource? GetFile(string path)
=> this.GetFile(path);
///
@@ -161,7 +174,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
: Task.FromException(new FileNotFoundException("The file could not be found."));
///
- public bool FileExists(string path)
+ public bool FileExists(string path)
=> this.GameData.FileExists(path);
#endregion
diff --git a/Dalamud/Game/Internal/DalamudAtkTweaks.cs b/Dalamud/Game/Internal/DalamudAtkTweaks.cs
index 486af463c..466401ef3 100644
--- a/Dalamud/Game/Internal/DalamudAtkTweaks.cs
+++ b/Dalamud/Game/Internal/DalamudAtkTweaks.cs
@@ -113,7 +113,7 @@ internal sealed unsafe class DalamudAtkTweaks : IInternalDisposableService
private void AtkUnitBaseReceiveGlobalEventDetour(AtkUnitBase* thisPtr, AtkEventType eventType, int eventParam, AtkEvent* atkEvent, AtkEventData* atkEventData)
{
// 3 == Close
- if (eventType == AtkEventType.InputReceived && WindowSystem.HasAnyWindowSystemFocus && atkEventData != null && *(int*)atkEventData == 3 && this.configuration.IsFocusManagementEnabled)
+ if (eventType == AtkEventType.InputReceived && WindowSystem.ShouldInhibitAtkCloseEvents && atkEventData != null && *(int*)atkEventData == 3 && this.configuration.IsFocusManagementEnabled)
{
Log.Verbose($"Cancelling global event SendHotkey command due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
return;
@@ -124,7 +124,7 @@ internal sealed unsafe class DalamudAtkTweaks : IInternalDisposableService
private void AgentHudOpenSystemMenuDetour(AgentHUD* thisPtr, AtkValue* atkValueArgs, uint menuSize)
{
- if (WindowSystem.HasAnyWindowSystemFocus && this.configuration.IsFocusManagementEnabled)
+ if (WindowSystem.ShouldInhibitAtkCloseEvents && this.configuration.IsFocusManagementEnabled)
{
Log.Verbose($"Cancelling OpenSystemMenu due to WindowSystem {WindowSystem.FocusedWindowSystemNamespace}");
return;
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index 202334580..64e1acaa4 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -182,7 +182,7 @@ internal class DalamudInterface : IInternalDisposableService
() => Service.GetNullable()?.ToggleDevMenu(),
VirtualKey.SHIFT);
- if (!configuration.DalamudBetaKind.IsNullOrEmpty())
+ if (Util.GetActiveTrack() != "release")
{
titleScreenMenu.AddEntryCore(
Loc.Localize("TSMDalamudDevMenu", "Developer Menu"),
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index d68bc8bef..76a1b5172 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -1175,6 +1175,7 @@ internal partial class InterfaceManager : IInternalDisposableService
WindowSystem.HasAnyWindowSystemFocus = false;
WindowSystem.FocusedWindowSystemNamespace = string.Empty;
+ WindowSystem.ShouldInhibitAtkCloseEvents = false;
if (this.IsDispatchingEvents)
{
diff --git a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs
index 4e95b718e..9cc14ea14 100644
--- a/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/BranchSwitcherWindow.cs
@@ -6,7 +6,6 @@ using System.Net.Http.Json;
using System.Threading.Tasks;
using Dalamud.Bindings.ImGui;
-using Dalamud.Configuration.Internal;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing;
@@ -15,6 +14,8 @@ using Dalamud.Utility;
using Newtonsoft.Json;
+using Serilog;
+
namespace Dalamud.Interface.Internal.Windows;
///
@@ -47,7 +48,7 @@ public class BranchSwitcherWindow : Window
Debug.Assert(this.branches != null, "this.branches != null");
var trackName = Util.GetActiveTrack();
- this.selectedBranchIndex = this.branches.IndexOf(x => x.Value.Track != trackName);
+ this.selectedBranchIndex = this.branches.IndexOf(x => x.Value.Track == trackName);
if (this.selectedBranchIndex == -1)
{
this.selectedBranchIndex = 0;
@@ -86,12 +87,9 @@ public class BranchSwitcherWindow : Window
if (ImGui.Button("Pick & Restart"u8))
{
- var config = Service.Get();
- config.DalamudBetaKind = pickedBranch.Key;
- config.DalamudBetaKey = pickedBranch.Value.Key;
-
- // If we exit immediately, we need to write out the new config now
- config.ForceSave();
+ var newTrackName = pickedBranch.Key;
+ var newTrackKey = pickedBranch.Value.Key;
+ Log.Verbose("Switching to branch {Branch} with key {Key}", newTrackName, newTrackKey);
var appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var xlPath = Path.Combine(appData, "XIVLauncher", "current", "XIVLauncher.exe");
@@ -104,8 +102,8 @@ public class BranchSwitcherWindow : Window
UseShellExecute = false,
};
- ps.ArgumentList.Add($"--dalamud-beta-kind={config.DalamudBetaKind}");
- ps.ArgumentList.Add($"--dalamud-beta-key={(config.DalamudBetaKey.IsNullOrEmpty() ? "invalid" : config.DalamudBetaKey)}");
+ ps.ArgumentList.Add($"--dalamud-beta-kind={newTrackName}");
+ ps.ArgumentList.Add($"--dalamud-beta-key={(newTrackKey.IsNullOrEmpty() ? "invalid" : newTrackKey)}");
Process.Start(ps);
Environment.Exit(0);
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index b203b3894..ac092bd25 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -302,8 +302,7 @@ internal class PluginInstallerWindow : Window, IDisposable
this.profileManagerWidget.Reset();
- var config = Service.Get();
- if (this.staleDalamudNewVersion == null && !config.DalamudBetaKind.IsNullOrEmpty())
+ if (this.staleDalamudNewVersion == null && !Util.GetActiveTrack().IsNullOrEmpty())
{
Service.Get().GetVersionForCurrentTrack().ContinueWith(t =>
{
@@ -311,10 +310,10 @@ internal class PluginInstallerWindow : Window, IDisposable
return;
var versionInfo = t.Result;
- if (versionInfo.AssemblyVersion != Util.GetScmVersion() &&
- versionInfo.Track != "release" &&
- string.Equals(versionInfo.Key, config.DalamudBetaKey, StringComparison.OrdinalIgnoreCase))
+ if (versionInfo.AssemblyVersion != Util.GetScmVersion())
+ {
this.staleDalamudNewVersion = versionInfo.AssemblyVersion;
+ }
});
}
}
diff --git a/Dalamud/Interface/Windowing/Window.cs b/Dalamud/Interface/Windowing/Window.cs
index 44ff62199..f12e87099 100644
--- a/Dalamud/Interface/Windowing/Window.cs
+++ b/Dalamud/Interface/Windowing/Window.cs
@@ -226,6 +226,16 @@ public abstract class Window
///
public bool AllowClickthrough { get; set; } = true;
+ ///
+ /// Gets a value indicating whether this window is pinned.
+ ///
+ public bool IsPinned => this.internalIsPinned;
+
+ ///
+ /// Gets a value indicating whether this window is click-through.
+ ///
+ public bool IsClickthrough => this.internalIsClickthrough;
+
///
/// Gets or sets a list of available title bar buttons.
///
diff --git a/Dalamud/Interface/Windowing/WindowSystem.cs b/Dalamud/Interface/Windowing/WindowSystem.cs
index 87bd199a1..d6e9649bb 100644
--- a/Dalamud/Interface/Windowing/WindowSystem.cs
+++ b/Dalamud/Interface/Windowing/WindowSystem.cs
@@ -60,6 +60,12 @@ public class WindowSystem
///
public string? Namespace { get; set; }
+ ///
+ /// Gets or sets a value indicating whether ATK close events should be inhibited while any window has focus.
+ /// Does not respect windows that are pinned or clickthrough.
+ ///
+ internal static bool ShouldInhibitAtkCloseEvents { get; set; }
+
///
/// Add a window to this .
/// The window system doesn't own your window, it just renders it
@@ -130,7 +136,7 @@ public class WindowSystem
window.DrawInternal(flags, persistence);
}
- var focusedWindow = this.windows.FirstOrDefault(window => window.IsFocused && window.RespectCloseHotkey);
+ var focusedWindow = this.windows.FirstOrDefault(window => window.IsFocused);
this.HasAnyFocus = focusedWindow != default;
if (this.HasAnyFocus)
@@ -155,6 +161,11 @@ public class WindowSystem
}
}
+ ShouldInhibitAtkCloseEvents |= this.windows.Any(w => w.IsFocused &&
+ w.RespectCloseHotkey &&
+ !w.IsPinned &&
+ !w.IsClickthrough);
+
if (hasNamespace)
ImGui.PopID();
}
diff --git a/Dalamud/Support/DalamudReleases.cs b/Dalamud/Support/DalamudReleases.cs
index 15e851da2..603c77487 100644
--- a/Dalamud/Support/DalamudReleases.cs
+++ b/Dalamud/Support/DalamudReleases.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Networking.Http;
+using Dalamud.Utility;
using Newtonsoft.Json;
@@ -15,7 +16,7 @@ namespace Dalamud.Support;
internal class DalamudReleases : IServiceType
{
private const string VersionInfoUrl = "https://kamori.goats.dev/Dalamud/Release/VersionInfo?track={0}";
-
+
private readonly HappyHttpClient httpClient;
private readonly DalamudConfiguration config;
@@ -30,20 +31,24 @@ internal class DalamudReleases : IServiceType
this.httpClient = httpClient;
this.config = config;
}
-
+
///
/// Get the latest version info for the current track.
///
/// The version info for the current track.
- public async Task GetVersionForCurrentTrack()
+ public async Task GetVersionForCurrentTrack()
{
- var url = string.Format(VersionInfoUrl, [this.config.DalamudBetaKind]);
+ var currentTrack = Util.GetActiveTrack();
+ if (currentTrack.IsNullOrEmpty())
+ return null;
+
+ var url = string.Format(VersionInfoUrl, [currentTrack]);
var response = await this.httpClient.SharedHttpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject(content);
}
-
+
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "laziness")]
public class DalamudVersionInfo
{
diff --git a/Dalamud/Support/Troubleshooting.cs b/Dalamud/Support/Troubleshooting.cs
index 4af8d5ffc..88048c462 100644
--- a/Dalamud/Support/Troubleshooting.cs
+++ b/Dalamud/Support/Troubleshooting.cs
@@ -73,7 +73,7 @@ public static class Troubleshooting
DalamudGitHash = Util.GetGitHash() ?? "Unknown",
GameVersion = startInfo.GameVersion?.ToString() ?? "Unknown",
Language = startInfo.Language.ToString(),
- BetaKey = configuration.DalamudBetaKey,
+ BetaKey = Util.GetActiveTrack(),
DoPluginTest = configuration.DoPluginTest,
LoadAllApiLevels = pluginManager?.LoadAllApiLevels == true,
InterfaceLoaded = interfaceManager?.IsReady ?? false,
diff --git a/Directory.Build.props b/Directory.Build.props
index 5f6da3d94..eabb727e8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -6,6 +6,10 @@
x64
x64
13.0
+
+
+
+ false
diff --git a/lib/FFXIVClientStructs b/lib/FFXIVClientStructs
index 0769d1f18..e5f586630 160000
--- a/lib/FFXIVClientStructs
+++ b/lib/FFXIVClientStructs
@@ -1 +1 @@
-Subproject commit 0769d1f180f859688f47a7a99610e9ce10da946c
+Subproject commit e5f586630ef06fa48d5dc0d8c0fa679323093c77