diff --git a/.editorconfig b/.editorconfig
index 141e8c9c9..7b1cbadda 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,6 +6,7 @@ charset = utf-8
end_of_line = lf
insert_final_newline = true
+trim_trailing_whitespace = true
# 4 space indentation
indent_style = space
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 2c564cc81..be44afacc 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1,5 +1,6 @@
name: Build Dalamud
on: [push, pull_request, workflow_dispatch]
+
concurrency:
group: build_dalamud_${{ github.ref_name }}
cancel-in-progress: true
@@ -22,7 +23,7 @@ jobs:
uses: microsoft/setup-msbuild@v1.0.2
- uses: actions/setup-dotnet@v3
with:
- dotnet-version: '8.0.100'
+ dotnet-version: '9.0.200'
- name: Define VERSION
run: |
$env:COMMIT = $env:GITHUB_SHA.Substring(0, 7)
@@ -32,10 +33,8 @@ jobs:
($env:REPO_NAME) >> VERSION
($env:BRANCH) >> VERSION
($env:COMMIT) >> VERSION
- - name: Build Dalamud
- run: .\build.ps1 compile
- - name: Test Dalamud
- run: .\build.ps1 test
+ - name: Build and Test Dalamud
+ run: .\build.ps1 ci
- name: Sign Dalamud
if: ${{ github.repository_owner == 'goatcorp' && github.event_name == 'push' }}
env:
@@ -55,8 +54,9 @@ jobs:
bin/Release/Dalamud.*.dll
bin/Release/Dalamud.*.exe
bin/Release/FFXIVClientStructs.dll
+ bin/Release/cim*.dll
- name: Upload artifact
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: dalamud-artifact
path: bin\Release
@@ -75,7 +75,7 @@ jobs:
run: |
dotnet tool install -g Microsoft.DotNet.ApiCompat.Tool
- name: "Download Proposed Artifacts"
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4.1.7
with:
name: dalamud-artifact
path: .\right
@@ -86,9 +86,9 @@ jobs:
- name: "Verify Compatibility"
run: |
$FILES_TO_VALIDATE = "Dalamud.dll","FFXIVClientStructs.dll","Lumina.dll","Lumina.Excel.dll"
-
+
$retcode = 0
-
+
foreach ($file in $FILES_TO_VALIDATE) {
$testout = ""
Write-Output "::group::=== API COMPATIBILITY CHECK: ${file} ==="
@@ -99,7 +99,7 @@ jobs:
$retcode = 1
}
}
-
+
exit $retcode
deploy_stg:
@@ -112,7 +112,7 @@ jobs:
with:
repository: goatcorp/dalamud-distrib
token: ${{ secrets.UPDATE_PAT }}
- - uses: actions/download-artifact@v2
+ - uses: actions/download-artifact@v4.1.7
with:
name: dalamud-artifact
path: .\scratch
@@ -128,18 +128,18 @@ jobs:
GH_BRANCH: ${{ steps.extract_branch.outputs.branch }}
run: |
Compress-Archive .\scratch\* .\canary.zip # Recreate the release zip
-
+
$branchName = $env:GH_BRANCH
-
+
if ($branchName -eq "master") {
$branchName = "stg"
}
-
+
$newVersion = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\TEMP_gitver.txt")
$revision = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\revision.txt")
$commitHash = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\commit_hash.txt")
Remove-Item -Force -Recurse .\scratch
-
+
if (Test-Path -Path $branchName) {
$versionData = Get-Content ".\${branchName}\version" | ConvertFrom-Json
$oldVersion = $versionData.AssemblyVersion
@@ -158,7 +158,7 @@ jobs:
Write-Host "Deployment folder doesn't exist. Not doing anything."
Remove-Item .\canary.zip
}
-
+
- name: Commit changes
shell: bash
env:
@@ -166,8 +166,8 @@ jobs:
run: |
git config --global user.name "Actions User"
git config --global user.email "actions@github.com"
-
+
git add .
git commit -m "[CI] Update staging for ${DVER} on ${GH_BRANCH}" || true
-
+
git push origin main || true
diff --git a/.github/workflows/rollup.yml b/.github/workflows/rollup.yml
index 70a8fc7b7..8bc9a3c51 100644
--- a/.github/workflows/rollup.yml
+++ b/.github/workflows/rollup.yml
@@ -1,8 +1,8 @@
name: Rollup changes to next version
on:
- push:
- branches:
- - master
+# push:
+# branches:
+# - master
workflow_dispatch:
jobs:
@@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
branches:
- - WORKFLOW_DISABLED_REMOVE_BEFORE_RUNNING
+ - net9
defaults:
run:
diff --git a/.gitmodules b/.gitmodules
index d379480d9..4aa969fda 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,3 +10,12 @@
[submodule "lib/ImGui.NET"]
path = lib/ImGui.NET
url = https://github.com/goatcorp/ImGui.NET.git
+[submodule "lib/cimgui"]
+ path = lib/cimgui
+ url = https://github.com/goatcorp/gc-cimgui
+[submodule "lib/cimplot"]
+ path = lib/cimplot
+ url = https://github.com/goatcorp/gc-cimplot
+[submodule "lib/cimguizmo"]
+ path = lib/cimguizmo
+ url = https://github.com/goatcorp/gc-cimguizmo
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index 497f2b89a..8331affcc 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -76,14 +76,20 @@
"items": {
"type": "string",
"enum": [
+ "CI",
"Clean",
"Compile",
+ "CompileCImGui",
+ "CompileCImGuizmo",
+ "CompileCImPlot",
"CompileDalamud",
"CompileDalamudBoot",
"CompileDalamudCrashHandler",
+ "CompileImGuiNatives",
"CompileInjector",
"CompileInjectorBoot",
"Restore",
+ "SetCILogging",
"Test"
]
}
@@ -98,14 +104,20 @@
"items": {
"type": "string",
"enum": [
+ "CI",
"Clean",
"Compile",
+ "CompileCImGui",
+ "CompileCImGuizmo",
+ "CompileCImPlot",
"CompileDalamud",
"CompileDalamudBoot",
"CompileDalamudCrashHandler",
+ "CompileImGuiNatives",
"CompileInjector",
"CompileInjectorBoot",
"Restore",
+ "SetCILogging",
"Test"
]
}
diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj
index 80435cd67..c18045027 100644
--- a/Dalamud.Boot/Dalamud.Boot.vcxproj
+++ b/Dalamud.Boot/Dalamud.Boot.vcxproj
@@ -28,7 +28,7 @@
v143
false
Unicode
- ..\bin\$(Configuration)\
+ bin\$(Configuration)\
obj\$(Configuration)\
@@ -200,8 +200,10 @@
-
-
-
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/Dalamud.Boot/DalamudStartInfo.cpp b/Dalamud.Boot/DalamudStartInfo.cpp
index f342973b0..5be8f97d0 100644
--- a/Dalamud.Boot/DalamudStartInfo.cpp
+++ b/Dalamud.Boot/DalamudStartInfo.cpp
@@ -109,6 +109,7 @@ void from_json(const nlohmann::json& json, DalamudStartInfo& config) {
config.PluginDirectory = json.value("PluginDirectory", config.PluginDirectory);
config.AssetDirectory = json.value("AssetDirectory", config.AssetDirectory);
config.Language = json.value("Language", config.Language);
+ config.Platform = json.value("Platform", config.Platform);
config.GameVersion = json.value("GameVersion", config.GameVersion);
config.TroubleshootingPackData = json.value("TroubleshootingPackData", std::string{});
config.DelayInitializeMs = json.value("DelayInitializeMs", config.DelayInitializeMs);
diff --git a/Dalamud.Boot/DalamudStartInfo.h b/Dalamud.Boot/DalamudStartInfo.h
index d6524968e..0eeaddeed 100644
--- a/Dalamud.Boot/DalamudStartInfo.h
+++ b/Dalamud.Boot/DalamudStartInfo.h
@@ -17,7 +17,7 @@ struct DalamudStartInfo {
DirectHook = 1,
};
friend void from_json(const nlohmann::json&, DotNetOpenProcessHookMode&);
-
+
enum class ClientLanguage : int {
Japanese,
English,
@@ -47,6 +47,7 @@ struct DalamudStartInfo {
std::string PluginDirectory;
std::string AssetDirectory;
ClientLanguage Language = ClientLanguage::English;
+ std::string Platform;
std::string GameVersion;
std::string TroubleshootingPackData;
int DelayInitializeMs = 0;
diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp
index d191c9e97..5e73962ec 100644
--- a/Dalamud.Boot/dllmain.cpp
+++ b/Dalamud.Boot/dllmain.cpp
@@ -15,7 +15,7 @@ HINSTANCE g_hGameInstance = GetModuleHandleW(nullptr);
HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
g_startInfo.from_envvars();
-
+
std::string jsonParseError;
try {
from_json(nlohmann::json::parse(std::string_view(static_cast(lpParam))), g_startInfo);
@@ -25,7 +25,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
if (g_startInfo.BootShowConsole)
ConsoleSetup(L"Dalamud Boot");
-
+
logging::update_dll_load_status(true);
const auto logFilePath = unicode::convert(g_startInfo.BootLogPath);
@@ -33,16 +33,16 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
auto attemptFallbackLog = false;
if (logFilePath.empty()) {
attemptFallbackLog = true;
-
+
logging::I("No log file path given; not logging to file.");
} else {
try {
logging::start_file_logging(logFilePath, !g_startInfo.BootShowConsole);
logging::I("Logging to file: {}", logFilePath);
-
+
} catch (const std::exception& e) {
attemptFallbackLog = true;
-
+
logging::E("Couldn't open log file: {}", logFilePath);
logging::E("Error: {} / {}", errno, e.what());
}
@@ -63,15 +63,15 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
SYSTEMTIME st;
GetLocalTime(&st);
logFilePath += std::format(L"Dalamud.Boot.{:04}{:02}{:02}.{:02}{:02}{:02}.{:03}.{}.log", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, GetCurrentProcessId());
-
+
try {
logging::start_file_logging(logFilePath, !g_startInfo.BootShowConsole);
logging::I("Logging to fallback log file: {}", logFilePath);
-
+
} catch (const std::exception& e) {
if (!g_startInfo.BootShowConsole && !g_startInfo.BootDisableFallbackConsole)
ConsoleSetup(L"Dalamud Boot - Fallback Console");
-
+
logging::E("Couldn't open fallback log file: {}", logFilePath);
logging::E("Error: {} / {}", errno, e.what());
}
@@ -87,7 +87,7 @@ HRESULT WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) {
} else {
logging::E("Failed to initialize MinHook (status={}({}))", MH_StatusToString(mhStatus), static_cast(mhStatus));
}
-
+
logging::I("Dalamud.Boot Injectable, (c) 2021 XIVLauncher Contributors");
logging::I("Built at: " __DATE__ "@" __TIME__);
@@ -241,11 +241,11 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
case DLL_PROCESS_DETACH:
// do not show debug message boxes on abort() here
_set_abort_behavior(0, _WRITE_ABORT_MSG);
-
+
// process is terminating; don't bother cleaning up
if (lpReserved)
return TRUE;
-
+
logging::update_dll_load_status(false);
xivfixes::apply_all(false);
diff --git a/Dalamud.Boot/utils.cpp b/Dalamud.Boot/utils.cpp
index 65018add4..dbfcf39ee 100644
--- a/Dalamud.Boot/utils.cpp
+++ b/Dalamud.Boot/utils.cpp
@@ -1,4 +1,5 @@
#include "pch.h"
+#include "DalamudStartInfo.h"
#include "utils.h"
@@ -103,7 +104,7 @@ bool utils::loaded_module::find_imported_function_pointer(const char* pcszDllNam
ppFunctionAddress = nullptr;
// This span might be too long in terms of meaningful data; it only serves to prevent accessing memory outsides boundaries.
- for (const auto& importDescriptor : span_as(directory.VirtualAddress, directory.Size / sizeof IMAGE_IMPORT_DESCRIPTOR)) {
+ for (const auto& importDescriptor : span_as(directory.VirtualAddress, directory.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
// Having all zero values signals the end of the table. We didn't find anything.
if (!importDescriptor.OriginalFirstThunk && !importDescriptor.TimeDateStamp && !importDescriptor.ForwarderChain && !importDescriptor.FirstThunk)
@@ -584,6 +585,10 @@ std::vector utils::get_env_list(const wchar_t* pcszName) {
return res;
}
+bool utils::is_running_on_wine() {
+ return g_startInfo.Platform != "WINDOWS";
+}
+
std::filesystem::path utils::get_module_path(HMODULE hModule) {
std::wstring buf(MAX_PATH, L'\0');
while (true) {
diff --git a/Dalamud.Boot/utils.h b/Dalamud.Boot/utils.h
index f10e277c0..2cdaf60a7 100644
--- a/Dalamud.Boot/utils.h
+++ b/Dalamud.Boot/utils.h
@@ -121,7 +121,7 @@ namespace utils {
memory_tenderizer(const void* pAddress, size_t length, DWORD dwNewProtect);
template&& std::is_standard_layout_v>>
- memory_tenderizer(const T& object, DWORD dwNewProtect) : memory_tenderizer(&object, sizeof T, dwNewProtect) {}
+ memory_tenderizer(const T& object, DWORD dwNewProtect) : memory_tenderizer(&object, sizeof(T), dwNewProtect) {}
template
memory_tenderizer(std::span s, DWORD dwNewProtect) : memory_tenderizer(&s[0], s.size(), dwNewProtect) {}
@@ -267,6 +267,8 @@ namespace utils {
return get_env_list(unicode::convert(pcszName).c_str());
}
+ bool is_running_on_wine();
+
std::filesystem::path get_module_path(HMODULE hModule);
/// @brief Find the game main window.
diff --git a/Dalamud.Common/Dalamud.Common.csproj b/Dalamud.Common/Dalamud.Common.csproj
index 594e09021..54a182210 100644
--- a/Dalamud.Common/Dalamud.Common.csproj
+++ b/Dalamud.Common/Dalamud.Common.csproj
@@ -1,7 +1,6 @@
- net8.0
enable
enable
diff --git a/Dalamud.Common/DalamudStartInfo.cs b/Dalamud.Common/DalamudStartInfo.cs
index b27d4b00d..a0d7f8b0b 100644
--- a/Dalamud.Common/DalamudStartInfo.cs
+++ b/Dalamud.Common/DalamudStartInfo.cs
@@ -1,3 +1,4 @@
+using System.Runtime.InteropServices;
using Dalamud.Common.Game;
using Newtonsoft.Json;
@@ -15,7 +16,7 @@ public record DalamudStartInfo
///
public DalamudStartInfo()
{
- // ignored
+ this.Platform = OSPlatform.Create("UNKNOWN");
}
///
@@ -58,6 +59,12 @@ public record DalamudStartInfo
///
public ClientLanguage Language { get; set; } = ClientLanguage.English;
+ ///
+ /// Gets or sets the underlying platform�Dalamud runs on.
+ ///
+ [JsonConverter(typeof(OSPlatformConverter))]
+ public OSPlatform Platform { get; set; }
+
///
/// Gets or sets the current game version code.
///
@@ -125,7 +132,7 @@ public record DalamudStartInfo
public bool BootVehFull { get; set; }
///
- /// Gets or sets a value indicating whether or not ETW should be enabled.
+ /// Gets or sets a value indicating whether ETW should be enabled.
///
public bool BootEnableEtw { get; set; }
diff --git a/Dalamud.Common/OSPlatformConverter.cs b/Dalamud.Common/OSPlatformConverter.cs
new file mode 100644
index 000000000..62d2996d4
--- /dev/null
+++ b/Dalamud.Common/OSPlatformConverter.cs
@@ -0,0 +1,78 @@
+using System.Runtime.InteropServices;
+using Newtonsoft.Json;
+
+namespace Dalamud.Common;
+
+///
+/// Converts a to and from a string (e.g. "FreeBSD").
+///
+public sealed class OSPlatformConverter : JsonConverter
+{
+ ///
+ /// Writes the JSON representation of the object.
+ ///
+ /// The to write to.
+ /// The value.
+ /// The calling serializer.
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
+ {
+ if (value == null)
+ {
+ writer.WriteNull();
+ }
+ else if (value is OSPlatform)
+ {
+ writer.WriteValue(value.ToString());
+ }
+ else
+ {
+ throw new JsonSerializationException("Expected OSPlatform object value");
+ }
+ }
+
+ ///
+ /// Reads the JSON representation of the object.
+ ///
+ /// The to read from.
+ /// Type of the object.
+ /// The existing property value of the JSON that is being converted.
+ /// The calling serializer.
+ /// The object value.
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
+ {
+ if (reader.TokenType == JsonToken.Null)
+ {
+ return null;
+ }
+ else
+ {
+ if (reader.TokenType == JsonToken.String)
+ {
+ try
+ {
+ return OSPlatform.Create((string)reader.Value!);
+ }
+ catch (Exception ex)
+ {
+ throw new JsonSerializationException($"Error parsing OSPlatform string: {reader.Value}", ex);
+ }
+ }
+ else
+ {
+ throw new JsonSerializationException($"Unexpected token or value when parsing OSPlatform. Token: {reader.TokenType}, Value: {reader.Value}");
+ }
+ }
+ }
+
+ ///
+ /// Determines whether this instance can convert the specified object type.
+ ///
+ /// Type of the object.
+ ///
+ /// true if this instance can convert the specified object type; otherwise, false.
+ ///
+ public override bool CanConvert(Type objectType)
+ {
+ return objectType == typeof(OSPlatform);
+ }
+}
diff --git a/Dalamud.Common/Util/EnvironmentUtils.cs b/Dalamud.Common/Util/EnvironmentUtils.cs
new file mode 100644
index 000000000..d6cf65e3d
--- /dev/null
+++ b/Dalamud.Common/Util/EnvironmentUtils.cs
@@ -0,0 +1,18 @@
+using System.Diagnostics.CodeAnalysis;
+
+namespace Dalamud.Common.Util;
+
+public static class EnvironmentUtils
+{
+ ///
+ /// Attempts to get an environment variable using the Try pattern.
+ ///
+ /// The env var to get.
+ /// An output containing the env var, if present.
+ /// A boolean indicating whether the var was present.
+ public static bool TryGetEnvironmentVariable(string variableName, [NotNullWhen(true)] out string? value)
+ {
+ value = Environment.GetEnvironmentVariable(variableName);
+ return value != null;
+ }
+}
diff --git a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
index b9bc63cd1..f51622c7e 100644
--- a/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
+++ b/Dalamud.CorePlugin/Dalamud.CorePlugin.csproj
@@ -1,9 +1,7 @@
Dalamud.CorePlugin
- net8.0-windows
x64
- 10.0
true
false
false
@@ -27,9 +25,9 @@
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj
index 1ff29ea66..c8b648f6d 100644
--- a/Dalamud.Injector/Dalamud.Injector.csproj
+++ b/Dalamud.Injector/Dalamud.Injector.csproj
@@ -1,11 +1,7 @@
- net8.0
win-x64
- x64
- x64;AnyCPU
- 10.0
@@ -45,10 +41,6 @@
DEBUG;TRACE
-
- $(MSBuildProjectDirectory)\
- $(AppOutputBase)=C:\goatsoft\companysecrets\injector\
-
IDE0003;IDE0044;IDE1006;CS1591;CS1701;CS1702
diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs
index 54025d5e2..97cb1fd9e 100644
--- a/Dalamud.Injector/EntryPoint.cs
+++ b/Dalamud.Injector/EntryPoint.cs
@@ -11,6 +11,8 @@ using System.Text.RegularExpressions;
using Dalamud.Common;
using Dalamud.Common.Game;
+using Dalamud.Common.Util;
+
using Newtonsoft.Json;
using Reloaded.Memory.Buffers;
using Serilog;
@@ -95,6 +97,7 @@ namespace Dalamud.Injector
args.Remove("--msgbox2");
args.Remove("--msgbox3");
args.Remove("--etw");
+ args.Remove("--no-legacy-corrupted-state-exceptions");
args.Remove("--veh");
args.Remove("--veh-full");
args.Remove("--no-plugin");
@@ -263,6 +266,35 @@ namespace Dalamud.Injector
}
}
+ private static OSPlatform DetectPlatformHeuristic()
+ {
+ var ntdll = NativeFunctions.GetModuleHandleW("ntdll.dll");
+ var wineServerCallPtr = NativeFunctions.GetProcAddress(ntdll, "wine_server_call");
+ var wineGetHostVersionPtr = NativeFunctions.GetProcAddress(ntdll, "wine_get_host_version");
+ var winePlatform = GetWinePlatform(wineGetHostVersionPtr);
+ var isWine = wineServerCallPtr != nint.Zero;
+
+ static unsafe string? GetWinePlatform(nint wineGetHostVersionPtr)
+ {
+ if (wineGetHostVersionPtr == nint.Zero) return null;
+
+ var methodDelegate = (delegate* unmanaged[Cdecl])wineGetHostVersionPtr;
+ methodDelegate(out var platformPtr, out var _);
+
+ if (platformPtr == null) return null;
+
+ return Marshal.PtrToStringAnsi((nint)platformPtr);
+ }
+
+ if (!isWine)
+ return OSPlatform.Windows;
+
+ if (winePlatform == "Darwin")
+ return OSPlatform.OSX;
+
+ return OSPlatform.Linux;
+ }
+
private static DalamudStartInfo ExtractAndInitializeStartInfoFromArguments(DalamudStartInfo? startInfo, List args)
{
int len;
@@ -278,9 +310,14 @@ namespace Dalamud.Injector
var logName = startInfo.LogName;
var logPath = startInfo.LogPath;
var languageStr = startInfo.Language.ToString().ToLowerInvariant();
+ var platformStr = startInfo.Platform.ToString().ToLowerInvariant();
var unhandledExceptionStr = startInfo.UnhandledException.ToString().ToLowerInvariant();
var troubleshootingData = "{\"empty\": true, \"description\": \"No troubleshooting data supplied.\"}";
+ // env vars are brought in prior to launch args, since args can override them.
+ if (EnvironmentUtils.TryGetEnvironmentVariable("XL_PLATFORM", out var xlPlatformEnv))
+ platformStr = xlPlatformEnv.ToLowerInvariant();
+
for (var i = 2; i < args.Count; i++)
{
if (args[i].StartsWith(key = "--dalamud-working-directory="))
@@ -307,6 +344,10 @@ namespace Dalamud.Injector
{
languageStr = args[i][key.Length..].ToLowerInvariant();
}
+ else if (args[i].StartsWith(key = "--dalamud-platform="))
+ {
+ platformStr = args[i][key.Length..].ToLowerInvariant();
+ }
else if (args[i].StartsWith(key = "--dalamud-tspack-b64="))
{
troubleshootingData = Encoding.UTF8.GetString(Convert.FromBase64String(args[i][key.Length..]));
@@ -378,11 +419,37 @@ namespace Dalamud.Injector
throw new CommandLineException($"\"{languageStr}\" is not a valid supported language.");
}
+ OSPlatform platform;
+
+ // covers both win32 and Windows
+ if (platformStr[0..(len = Math.Min(platformStr.Length, (key = "win").Length))] == key[0..len])
+ {
+ platform = OSPlatform.Windows;
+ }
+ else if (platformStr[0..(len = Math.Min(platformStr.Length, (key = "linux").Length))] == key[0..len])
+ {
+ platform = OSPlatform.Linux;
+ }
+ else if (platformStr[0..(len = Math.Min(platformStr.Length, (key = "macos").Length))] == key[0..len])
+ {
+ platform = OSPlatform.OSX;
+ }
+ else if (platformStr[0..(len = Math.Min(platformStr.Length, (key = "osx").Length))] == key[0..len])
+ {
+ platform = OSPlatform.OSX;
+ }
+ else
+ {
+ platform = DetectPlatformHeuristic();
+ Log.Warning("Heuristically determined host system platform as {platform}", platform);
+ }
+
startInfo.WorkingDirectory = workingDirectory;
startInfo.ConfigurationPath = configurationPath;
startInfo.PluginDirectory = pluginDirectory;
startInfo.AssetDirectory = assetDirectory;
startInfo.Language = clientLanguage;
+ startInfo.Platform = platform;
startInfo.DelayInitializeMs = delayInitializeMs;
startInfo.GameVersion = null;
startInfo.TroubleshootingPackData = troubleshootingData;
@@ -465,13 +532,14 @@ namespace Dalamud.Injector
}
Console.WriteLine("Specifying dalamud start info: [--dalamud-working-directory=path] [--dalamud-configuration-path=path]");
- Console.WriteLine(" [--dalamud-plugin-directory=path]");
+ Console.WriteLine(" [--dalamud-plugin-directory=path] [--dalamud-platform=win32|linux|macOS]");
Console.WriteLine(" [--dalamud-asset-directory=path] [--dalamud-delay-initialize=0(ms)]");
Console.WriteLine(" [--dalamud-client-language=0-3|j(apanese)|e(nglish)|d|g(erman)|f(rench)]");
Console.WriteLine("Verbose logging:\t[-v]");
Console.WriteLine("Show Console:\t[--console] [--crash-handler-console]");
Console.WriteLine("Enable ETW:\t[--etw]");
+ Console.WriteLine("Disable legacy corrupted state exceptions:\t[--no-legacy-corrupted-state-exceptions]");
Console.WriteLine("Enable VEH:\t[--veh], [--veh-full], [--unhandled-exception=default|stalldebug|none]");
Console.WriteLine("Show messagebox:\t[--msgbox1], [--msgbox2], [--msgbox3]");
Console.WriteLine("No plugins:\t[--no-plugin] [--no-3rd-plugin]");
@@ -731,15 +799,42 @@ namespace Dalamud.Injector
{
try
{
- var appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- var xivlauncherDir = Path.Combine(appDataDir, "XIVLauncher");
- var launcherConfigPath = Path.Combine(xivlauncherDir, "launcherConfigV3.json");
- gamePath = Path.Combine(JsonSerializer.CreateDefault().Deserialize>(new JsonTextReader(new StringReader(File.ReadAllText(launcherConfigPath))))["GamePath"], "game", "ffxiv_dx11.exe");
- Log.Information("Using game installation path configuration from from XIVLauncher: {0}", gamePath);
+ if (dalamudStartInfo.Platform == OSPlatform.Windows)
+ {
+ var appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ var xivlauncherDir = Path.Combine(appDataDir, "XIVLauncher");
+ var launcherConfigPath = Path.Combine(xivlauncherDir, "launcherConfigV3.json");
+ gamePath = Path.Combine(
+ JsonSerializer.CreateDefault()
+ .Deserialize>(
+ new JsonTextReader(new StringReader(File.ReadAllText(launcherConfigPath))))["GamePath"],
+ "game",
+ "ffxiv_dx11.exe");
+ Log.Information("Using game installation path configuration from from XIVLauncher: {0}", gamePath);
+ }
+ else if (dalamudStartInfo.Platform == OSPlatform.Linux)
+ {
+ var homeDir = $"Z:\\home\\{Environment.UserName}";
+ var xivlauncherDir = Path.Combine(homeDir, ".xlcore");
+ var launcherConfigPath = Path.Combine(xivlauncherDir, "launcher.ini");
+ var config = File.ReadAllLines(launcherConfigPath)
+ .Where(line => line.Contains('='))
+ .ToDictionary(line => line.Split('=')[0], line => line.Split('=')[1]);
+ gamePath = Path.Combine("Z:" + config["GamePath"].Replace('/', '\\'), "game", "ffxiv_dx11.exe");
+ Log.Information("Using game installation path configuration from from XIVLauncher Core: {0}", gamePath);
+ }
+ else
+ {
+ var homeDir = $"Z:\\Users\\{Environment.UserName}";
+ var xomlauncherDir = Path.Combine(homeDir, "Library", "Application Support", "XIV on Mac");
+ // we could try to parse the binary plist file here if we really wanted to...
+ gamePath = Path.Combine(xomlauncherDir, "ffxiv", "game", "ffxiv_dx11.exe");
+ Log.Information("Using default game installation path from XOM: {0}", gamePath);
+ }
}
catch (Exception)
{
- Log.Error("Failed to read launcherConfigV3.json to get the set-up game path, please specify one using -g");
+ Log.Error("Failed to read launcher config to get the set-up game path, please specify one using -g");
return -1;
}
@@ -794,20 +889,6 @@ namespace Dalamud.Injector
if (encryptArguments)
{
var rawTickCount = (uint)Environment.TickCount;
-
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- [System.Runtime.InteropServices.DllImport("c")]
-#pragma warning disable SA1300
- static extern ulong clock_gettime_nsec_np(int clockId);
-#pragma warning restore SA1300
-
- const int CLOCK_MONOTONIC_RAW = 4;
- var rawTickCountFixed = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / 1000000;
- Log.Information("ArgumentBuilder::DeriveKey() fixing up rawTickCount from {0} to {1} on macOS", rawTickCount, rawTickCountFixed);
- rawTickCount = (uint)rawTickCountFixed;
- }
-
var ticks = rawTickCount & 0xFFFF_FFFFu;
var key = ticks & 0xFFFF_0000u;
gameArguments.Insert(0, $"T={ticks}");
diff --git a/Dalamud.Injector/NativeFunctions.cs b/Dalamud.Injector/NativeFunctions.cs
index 2a4654aaf..06add3acc 100644
--- a/Dalamud.Injector/NativeFunctions.cs
+++ b/Dalamud.Injector/NativeFunctions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace Dalamud.Injector
@@ -910,5 +911,46 @@ namespace Dalamud.Injector
uint dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
DuplicateOptions dwOptions);
+
+ ///
+ /// See https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlew.
+ /// Retrieves a module handle for the specified module. The module must have been loaded by the calling process. To
+ /// avoid the race conditions described in the Remarks section, use the GetModuleHandleEx function.
+ ///
+ ///
+ /// The name of the loaded module (either a .dll or .exe file). If the file name extension is omitted, the default
+ /// library extension .dll is appended. The file name string can include a trailing point character (.) to indicate
+ /// that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure
+ /// to use backslashes (\), not forward slashes (/). The name is compared (case independently) to the names of modules
+ /// currently mapped into the address space of the calling process. If this parameter is NULL, GetModuleHandle returns
+ /// a handle to the file used to create the calling process (.exe file). The GetModuleHandle function does not retrieve
+ /// handles for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag.For more information, see LoadLibraryEx.
+ ///
+ ///
+ /// If the function succeeds, the return value is a handle to the specified module. If the function fails, the return
+ /// value is NULL.To get extended error information, call GetLastError.
+ ///
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
+ public static extern IntPtr GetModuleHandleW(string lpModuleName);
+
+ ///
+ /// Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).
+ ///
+ ///
+ /// A handle to the DLL module that contains the function or variable. The LoadLibrary, LoadLibraryEx, LoadPackagedLibrary,
+ /// or GetModuleHandle function returns this handle. The GetProcAddress function does not retrieve addresses from modules
+ /// that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag.For more information, see LoadLibraryEx.
+ ///
+ ///
+ /// The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be
+ /// in the low-order word; the high-order word must be zero.
+ ///
+ ///
+ /// If the function succeeds, the return value is the address of the exported function or variable. If the function
+ /// fails, the return value is NULL.To get extended error information, call GetLastError.
+ ///
+ [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
+ [SuppressMessage("Globalization", "CA2101:Specify marshaling for P/Invoke string arguments", Justification = "Ansi only")]
+ public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
}
}
diff --git a/Dalamud.Test/Dalamud.Test.csproj b/Dalamud.Test/Dalamud.Test.csproj
index 28e326238..c6c8f8e8a 100644
--- a/Dalamud.Test/Dalamud.Test.csproj
+++ b/Dalamud.Test/Dalamud.Test.csproj
@@ -1,13 +1,5 @@
-
- net8.0-windows
- win-x64
- x64
- x64;AnyCPU
- 11.0
-
-
Dalamud.Test
Dalamud.Test
diff --git a/Dalamud.sln.DotSettings b/Dalamud.sln.DotSettings
index b0f66b736..6d0e1fdcd 100644
--- a/Dalamud.sln.DotSettings
+++ b/Dalamud.sln.DotSettings
@@ -54,6 +54,7 @@
True
True
True
+ True
True
True
True
@@ -66,6 +67,7 @@
True
True
True
+ True
True
True
True
diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index 5b49f5c72..515556b7e 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -4,6 +4,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Threading.Tasks;
using Dalamud.Game.Text;
using Dalamud.Interface;
@@ -11,6 +12,7 @@ using Dalamud.Interface.FontIdentifier;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.ReShadeHandling;
using Dalamud.Interface.Style;
+using Dalamud.Interface.Windowing.Persistence;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Internal.AutoUpdate;
using Dalamud.Plugin.Internal.Profiles;
@@ -45,6 +47,8 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
[JsonIgnore]
private bool isSaveQueued;
+ private Task? writeTask;
+
///
/// Delegate for the event that occurs when the dalamud configuration is saved.
///
@@ -57,7 +61,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
public event DalamudConfigurationSavedDelegate? DalamudConfigurationSaved;
///
- /// Gets or sets a list of muted works.
+ /// Gets or sets a list of muted words.
///
public List? BadWords { get; set; }
@@ -243,13 +247,13 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
///
/// Gets or sets a value indicating whether or not ImGui asserts should be enabled at startup.
///
- public bool AssertsEnabledAtStartup { get; set; }
+ public bool? ImGuiAssertsEnabledAtStartup { get; set; }
///
/// Gets or sets a value indicating whether or not docking should be globally enabled in ImGui.
///
public bool IsDocking { get; set; }
-
+
///
/// Gets or sets a value indicating whether or not plugin user interfaces should trigger sound effects.
/// This setting is effected by the in-game "System Sounds" option and volume.
@@ -261,8 +265,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
/// Gets or sets a value indicating whether or not an additional button allowing pinning and clickthrough options should be shown
/// on plugin title bars when using the Window System.
///
- [JsonProperty("EnablePluginUiAdditionalOptionsExperimental")]
- public bool EnablePluginUiAdditionalOptions { get; set; } = false;
+ public bool EnablePluginUiAdditionalOptions { get; set; } = true;
///
/// Gets or sets a value indicating whether viewports should always be disabled.
@@ -348,6 +351,11 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
///
public bool ProfilesHasSeenTutorial { get; set; } = false;
+ ///
+ /// Gets or sets the default UI preset.
+ ///
+ public PresetModel DefaultUiPreset { get; set; } = new();
+
///
/// Gets or sets the order of DTR elements, by title.
///
@@ -484,10 +492,15 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
public AutoUpdateBehavior? AutoUpdateBehavior { get; set; } = null;
///
- /// Gets or sets a value indicating whether or not users should be notified regularly about pending updates.
+ /// Gets or sets a value indicating whether users should be notified regularly about pending updates.
///
public bool CheckPeriodicallyForUpdates { get; set; } = true;
+ ///
+ /// Gets or sets a value indicating whether users should be notified about updates in chat.
+ ///
+ public bool SendUpdateNotificationToChat { get; set; } = false;
+
///
/// Load a configuration from the provided path.
///
@@ -504,7 +517,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
{
deserialized =
JsonConvert.DeserializeObject(text, SerializerSettings);
-
+
// If this reads as null, the file was empty, that's no good
if (deserialized == null)
throw new Exception("Read config was null.");
@@ -530,7 +543,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
{
Log.Error(e, "Failed to set defaults for DalamudConfiguration");
}
-
+
return deserialized;
}
@@ -549,12 +562,15 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
{
this.Save();
}
-
+
///
void IInternalDisposableService.DisposeService()
{
// Make sure that we save, if a save is queued while we are shutting down
this.Update();
+
+ // Wait for the write task to finish
+ this.writeTask?.Wait();
}
///
@@ -595,22 +611,36 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
this.ReduceMotions = winAnimEnabled == 0;
}
}
-
+
// Migrate old auto-update setting to new auto-update behavior
this.AutoUpdateBehavior ??= this.AutoUpdatePlugins
? Plugin.Internal.AutoUpdate.AutoUpdateBehavior.UpdateAll
: Plugin.Internal.AutoUpdate.AutoUpdateBehavior.OnlyNotify;
#pragma warning restore CS0618
}
-
+
private void Save()
{
ThreadSafety.AssertMainThread();
if (this.configPath is null)
throw new InvalidOperationException("configPath is not set.");
- Service.Get().WriteAllText(
- this.configPath, JsonConvert.SerializeObject(this, SerializerSettings));
+ // Wait for previous write to finish
+ this.writeTask?.Wait();
+
+ this.writeTask = Task.Run(() =>
+ {
+ Service.Get().WriteAllText(
+ this.configPath,
+ JsonConvert.SerializeObject(this, SerializerSettings));
+ }).ContinueWith(t =>
+ {
+ if (t.IsFaulted)
+ {
+ Log.Error(t.Exception, "Failed to save DalamudConfiguration to {Path}", this.configPath);
+ }
+ });
+
this.DalamudConfigurationSaved?.Invoke(this);
}
}
diff --git a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
index 2df9ec5fe..11a8d3567 100644
--- a/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
+++ b/Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
@@ -5,11 +5,6 @@ namespace Dalamud.Configuration.Internal;
///
internal class EnvironmentConfiguration
{
- ///
- /// Gets a value indicating whether the XL_WINEONLINUX setting has been enabled.
- ///
- public static bool XlWineOnLinux { get; } = GetEnvironmentVariable("XL_WINEONLINUX");
-
///
/// Gets a value indicating whether the DALAMUD_NOT_HAVE_PLUGINS setting has been enabled.
///
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index d080a1622..7cc5bae96 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -1,16 +1,12 @@
- net8.0-windows
- x64
- x64;AnyCPU
- 12.0
True
- 10.0.0.7
XIV Launcher addon framework
+ 12.0.0.7
$(DalamudVersion)
$(DalamudVersion)
$(DalamudVersion)
@@ -47,10 +43,6 @@
DEBUG;TRACE
-
- $(MSBuildProjectDirectory)\
- $(AppOutputBase)=C:\goatsoft\companysecrets\dalamud\
-
IDE0002;IDE0003;IDE1006;IDE0044;CA1822;CS1591;CS1701;CS1702
@@ -71,8 +63,8 @@
-
-
+
+
all
@@ -83,12 +75,13 @@
-
-
-
-
+
+
+
+
+
all
@@ -113,6 +106,7 @@
+
@@ -126,6 +120,13 @@
+
+
+
+
+
+
+
@@ -165,7 +166,7 @@
-
+
@@ -173,7 +174,7 @@
???
-
+
diff --git a/Dalamud/DalamudAsset.cs b/Dalamud/DalamudAsset.cs
index 0d91a4b75..27771116e 100644
--- a/Dalamud/DalamudAsset.cs
+++ b/Dalamud/DalamudAsset.cs
@@ -9,6 +9,7 @@ namespace Dalamud;
/// Any asset can cease to exist at any point, even if the enum value exists.
/// Either ship your own assets, or be prepared for errors.
///
+// Implementation notes: avoid specifying numbers too high here. Lookup table is currently implemented as an array.
public enum DalamudAsset
{
///
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index 58eb930a0..d017bf85a 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -1,5 +1,6 @@
using System.IO;
using System.Threading;
+using System.Threading.Tasks;
using Dalamud.Game;
using Dalamud.IoC;
@@ -10,6 +11,7 @@ using Dalamud.Utility.Timing;
using Lumina;
using Lumina.Data;
using Lumina.Excel;
+
using Newtonsoft.Json;
using Serilog;
@@ -27,12 +29,15 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
{
private readonly Thread luminaResourceThread;
private readonly CancellationTokenSource luminaCancellationTokenSource;
+ private readonly RsvResolver rsvResolver;
[ServiceManager.ServiceConstructor]
private DataManager(Dalamud dalamud)
{
this.Language = (ClientLanguage)dalamud.StartInfo.Language;
+ this.rsvResolver = new();
+
try
{
Log.Verbose("Starting data load...");
@@ -43,11 +48,8 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
{
LoadMultithreaded = true,
CacheFileResources = true,
-#if NEVER // Lumina bug
PanicOnSheetChecksumMismatch = true,
-#else
- PanicOnSheetChecksumMismatch = false,
-#endif
+ RsvResolver = this.rsvResolver.TryResolve,
DefaultExcelLanguage = this.Language.ToLumina(),
};
@@ -128,12 +130,12 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
#region Lumina Wrappers
///
- public ExcelSheet? GetExcelSheet() where T : ExcelRow
- => this.Excel.GetSheet();
+ public ExcelSheet GetExcelSheet(ClientLanguage? language = null, string? name = null) where T : struct, IExcelRow
+ => this.Excel.GetSheet(language?.ToLumina(), name);
///
- public ExcelSheet? GetExcelSheet(ClientLanguage language) where T : ExcelRow
- => this.Excel.GetSheet(language.ToLumina());
+ public SubrowExcelSheet GetSubrowExcelSheet(ClientLanguage? language = null, string? name = null) where T : struct, IExcelSubrow
+ => this.Excel.GetSubrowSheet(language?.ToLumina(), name);
///
public FileResource? GetFile(string path)
@@ -148,6 +150,16 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
return this.GameData.Repositories.TryGetValue(filePath.Repository, out var repository) ? repository.GetFile(filePath.Category, filePath) : default;
}
+ ///
+ public Task GetFileAsync(string path, CancellationToken cancellationToken) where T : FileResource =>
+ GameData.ParseFilePath(path) is { } filePath &&
+ this.GameData.Repositories.TryGetValue(filePath.Repository, out var repository)
+ ? Task.Run(
+ () => repository.GetFile(filePath.Category, filePath) ?? throw new FileNotFoundException(
+ "Failed to load file, most likely because the file could not be found."),
+ cancellationToken)
+ : Task.FromException(new FileNotFoundException("The file could not be found."));
+
///
public bool FileExists(string path)
=> this.GameData.FileExists(path);
@@ -159,6 +171,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
{
this.luminaCancellationTokenSource.Cancel();
this.GameData.Dispose();
+ this.rsvResolver.Dispose();
}
private class LauncherTroubleshootingInfo
diff --git a/Dalamud/Data/LuminaUtils.cs b/Dalamud/Data/LuminaUtils.cs
new file mode 100644
index 000000000..6da67f426
--- /dev/null
+++ b/Dalamud/Data/LuminaUtils.cs
@@ -0,0 +1,22 @@
+using Lumina.Excel;
+
+namespace Dalamud.Data;
+
+///
+/// A helper class to easily resolve Lumina data within Dalamud.
+///
+internal static class LuminaUtils
+{
+ private static ExcelModule Module => Service.Get().Excel;
+
+ ///
+ /// Initializes a new instance of the class using the default .
+ ///
+ /// The type of Lumina sheet to resolve.
+ /// The id of the row to resolve.
+ /// A new object.
+ public static RowRef CreateRef(uint rowId) where T : struct, IExcelRow
+ {
+ return new(Module, rowId);
+ }
+}
diff --git a/Dalamud/Data/RsvResolver.cs b/Dalamud/Data/RsvResolver.cs
new file mode 100644
index 000000000..3f507ff1d
--- /dev/null
+++ b/Dalamud/Data/RsvResolver.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+
+using Dalamud.Hooking;
+using Dalamud.Logging.Internal;
+using Dalamud.Memory;
+using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
+using Lumina.Text.ReadOnly;
+
+namespace Dalamud.Data;
+
+///
+/// Provides functionality for resolving RSV strings.
+///
+internal sealed unsafe class RsvResolver : IDisposable
+{
+ private static readonly ModuleLog Log = new("RsvProvider");
+
+ private readonly Hook addRsvStringHook;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public RsvResolver()
+ {
+ this.addRsvStringHook = Hook.FromAddress((nint)LayoutWorld.MemberFunctionPointers.AddRsvString, this.AddRsvStringDetour);
+
+ this.addRsvStringHook.Enable();
+ }
+
+ private Dictionary Lookup { get; } = [];
+
+ /// Attemps to resolve an RSV string.
+ ///
+ public bool TryResolve(ReadOnlySeString rsvString, out ReadOnlySeString resolvedString) =>
+ this.Lookup.TryGetValue(rsvString, out resolvedString);
+
+ ///
+ public void Dispose()
+ {
+ this.addRsvStringHook.Dispose();
+ }
+
+ private bool AddRsvStringDetour(LayoutWorld* @this, byte* rsvString, byte* resolvedString, nuint resolvedStringSize)
+ {
+ var rsv = new ReadOnlySeString(MemoryHelper.ReadRawNullTerminated((nint)rsvString));
+ var resolved = new ReadOnlySeString(new ReadOnlySpan(resolvedString, (int)resolvedStringSize).ToArray());
+ Log.Debug($"Resolving RSV \"{rsv}\" to \"{resolved}\".");
+ this.Lookup[rsv] = resolved;
+ return this.addRsvStringHook.Original(@this, rsvString, resolvedString, resolvedStringSize);
+ }
+}
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 512acd4cc..f6ba990e6 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -179,16 +179,17 @@ public sealed class EntryPoint
Reloaded.Hooks.Tools.Utilities.FasmBasePath = new DirectoryInfo(info.WorkingDirectory);
- // This is due to GitHub not supporting TLS 1.0, so we enable all TLS versions globally
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls;
+ // Apply common fixes for culture issues
+ CultureFixes.Apply();
- if (!Util.IsWine())
+ // Currently VEH is not fully functional on WINE
+ if (info.Platform != OSPlatform.Windows)
InitSymbolHandler(info);
var dalamud = new Dalamud(info, fs, configuration, mainThreadContinueEvent);
- Log.Information("This is Dalamud - Core: {GitHash}, CS: {CsGitHash} [{CsVersion}]",
- Util.GetScmVersion(),
- Util.GetGitHashClientStructs(),
+ Log.Information("This is Dalamud - Core: {GitHash}, CS: {CsGitHash} [{CsVersion}]",
+ Util.GetScmVersion(),
+ Util.GetGitHashClientStructs(),
FFXIVClientStructs.ThisAssembly.Git.Commits);
dalamud.WaitForUnload();
diff --git a/Dalamud/Game/ActionKind.cs b/Dalamud/Game/ActionKind.cs
new file mode 100644
index 000000000..9a574f9a8
--- /dev/null
+++ b/Dalamud/Game/ActionKind.cs
@@ -0,0 +1,89 @@
+namespace Dalamud.Game;
+
+///
+/// Enum describing possible action kinds.
+///
+public enum ActionKind
+{
+ ///
+ /// A Trait.
+ ///
+ Trait = 0,
+
+ ///
+ /// An Action.
+ ///
+ Action = 1,
+
+ ///
+ /// A usable Item.
+ ///
+ Item = 2, // does not work?
+
+ ///
+ /// A usable EventItem.
+ ///
+ EventItem = 3, // does not work?
+
+ ///
+ /// An EventAction.
+ ///
+ EventAction = 4,
+
+ ///
+ /// A GeneralAction.
+ ///
+ GeneralAction = 5,
+
+ ///
+ /// A BuddyAction.
+ ///
+ BuddyAction = 6,
+
+ ///
+ /// A MainCommand.
+ ///
+ MainCommand = 7,
+
+ ///
+ /// A Companion.
+ ///
+ Companion = 8, // unresolved?!
+
+ ///
+ /// A CraftAction.
+ ///
+ CraftAction = 9,
+
+ ///
+ /// An Action (again).
+ ///
+ Action2 = 10, // what's the difference?
+
+ ///
+ /// A PetAction.
+ ///
+ PetAction = 11,
+
+ ///
+ /// A CompanyAction.
+ ///
+ CompanyAction = 12,
+
+ ///
+ /// A Mount.
+ ///
+ Mount = 13,
+
+ // 14-18 unused
+
+ ///
+ /// A BgcArmyAction.
+ ///
+ BgcArmyAction = 19,
+
+ ///
+ /// An Ornament.
+ ///
+ Ornament = 20,
+}
diff --git a/Dalamud/Game/Addon/Events/AddonEventListener.cs b/Dalamud/Game/Addon/Events/AddonEventListener.cs
index cc6416fe8..515785d72 100644
--- a/Dalamud/Game/Addon/Events/AddonEventListener.cs
+++ b/Dalamud/Game/Addon/Events/AddonEventListener.cs
@@ -11,9 +11,9 @@ namespace Dalamud.Game.Addon.Events;
internal unsafe class AddonEventListener : IDisposable
{
private ReceiveEventDelegate? receiveEventDelegate;
-
+
private AtkEventListener* eventListener;
-
+
///
/// Initializes a new instance of the class.
///
@@ -24,7 +24,7 @@ internal unsafe class AddonEventListener : IDisposable
this.eventListener = (AtkEventListener*)Marshal.AllocHGlobal(sizeof(AtkEventListener));
this.eventListener->VirtualTable = (AtkEventListener.AtkEventListenerVirtualTable*)Marshal.AllocHGlobal(sizeof(void*) * 3);
- this.eventListener->VirtualTable->Dtor = (delegate* unmanaged)(delegate* unmanaged)&NullSub;
+ this.eventListener->VirtualTable->Dtor = (delegate* unmanaged)(delegate* unmanaged)&NullSub;
this.eventListener->VirtualTable->ReceiveGlobalEvent = (delegate* unmanaged)(delegate* unmanaged)&NullSub;
this.eventListener->VirtualTable->ReceiveEvent = (delegate* unmanaged)Marshal.GetFunctionPointerForDelegate(this.receiveEventDelegate);
}
@@ -38,17 +38,17 @@ internal unsafe class AddonEventListener : IDisposable
/// Pointer to the AtkEvent.
/// Pointer to the AtkEventData.
public delegate void ReceiveEventDelegate(AtkEventListener* self, AtkEventType eventType, uint eventParam, AtkEvent* eventPtr, AtkEventData* eventDataPtr);
-
+
///
/// Gets the address of this listener.
///
public nint Address => (nint)this.eventListener;
-
+
///
public void Dispose()
{
if (this.eventListener is null) return;
-
+
Marshal.FreeHGlobal((nint)this.eventListener->VirtualTable);
Marshal.FreeHGlobal((nint)this.eventListener);
@@ -88,7 +88,7 @@ internal unsafe class AddonEventListener : IDisposable
node->RemoveEvent(eventType, param, this.eventListener, false);
});
}
-
+
[UnmanagedCallersOnly]
private static void NullSub()
{
diff --git a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs b/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
index 927ed87ab..415e1b169 100644
--- a/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
+++ b/Dalamud/Game/Addon/Events/AddonEventManagerAddressResolver.cs
@@ -16,6 +16,6 @@ internal class AddonEventManagerAddressResolver : BaseAddressResolver
/// The signature scanner to facilitate setup.
protected override void Setup64Bit(ISigScanner scanner)
{
- this.UpdateCursor = scanner.ScanText("48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 E8 ?? ?? ?? ?? 49 8B CE");
+ this.UpdateCursor = scanner.ScanText("48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 4C 8B F1 E8 ?? ?? ?? ?? 49 8B CE"); // unnamed in CS
}
}
diff --git a/Dalamud/Game/Addon/Events/PluginEventController.cs b/Dalamud/Game/Addon/Events/PluginEventController.cs
index d33e2e253..403a812db 100644
--- a/Dalamud/Game/Addon/Events/PluginEventController.cs
+++ b/Dalamud/Game/Addon/Events/PluginEventController.cs
@@ -165,7 +165,7 @@ internal unsafe class PluginEventController : IDisposable
{
var paramKeyMatches = currentEvent->Param == eventEntry.ParamKey;
var eventListenerAddressMatches = (nint)currentEvent->Listener == this.EventListener.Address;
- var eventTypeMatches = currentEvent->Type == eventType;
+ var eventTypeMatches = currentEvent->State.EventType == eventType;
if (paramKeyMatches && eventListenerAddressMatches && eventTypeMatches)
{
diff --git a/Dalamud/Game/Addon/Lifecycle/AddonEvent.cs b/Dalamud/Game/Addon/Lifecycle/AddonEvent.cs
index 91b9dd51f..5fd0ac964 100644
--- a/Dalamud/Game/Addon/Lifecycle/AddonEvent.cs
+++ b/Dalamud/Game/Addon/Lifecycle/AddonEvent.cs
@@ -52,7 +52,7 @@ public enum AddonEvent
PostDraw,
///
- /// An event that is fired immediately before an addon is finalized via and
+ /// An event that is fired immediately before an addon is finalized via and
/// destroyed. After this event, the addon will destruct its UI node data as well as free any allocated memory.
/// This event can be used for cleanup and tracking tasks.
///
diff --git a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleAddressResolver.cs b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleAddressResolver.cs
index baf8bb86c..854d666fd 100644
--- a/Dalamud/Game/Addon/Lifecycle/AddonLifecycleAddressResolver.cs
+++ b/Dalamud/Game/Addon/Lifecycle/AddonLifecycleAddressResolver.cs
@@ -13,19 +13,19 @@ internal unsafe class AddonLifecycleAddressResolver : BaseAddressResolver
/// This is called for a majority of all addon OnSetup's.
///
public nint AddonSetup { get; private set; }
-
+
///
/// Gets the address of the other addon setup hook invoked by the AtkUnitManager.
/// There are two callsites for this vFunc, we need to hook both of them to catch both normal UI and special UI cases like dialogue.
/// This seems to be called rarely for specific addons.
///
public nint AddonSetup2 { get; private set; }
-
+
///
/// Gets the address of the addon finalize hook invoked by the AtkUnitManager.
///
public nint AddonFinalize { get; private set; }
-
+
///
/// Gets the address of the addon draw hook invoked by virtual function call.
///
@@ -35,7 +35,7 @@ internal unsafe class AddonLifecycleAddressResolver : BaseAddressResolver
/// Gets the address of the addon update hook invoked by virtual function call.
///
public nint AddonUpdate { get; private set; }
-
+
///
/// Gets the address of the addon onRequestedUpdate hook invoked by virtual function call.
///
@@ -51,6 +51,6 @@ internal unsafe class AddonLifecycleAddressResolver : BaseAddressResolver
this.AddonFinalize = sig.ScanText("E8 ?? ?? ?? ?? 48 83 EF 01 75 D5");
this.AddonDraw = sig.ScanText("FF 90 ?? ?? ?? ?? 83 EB 01 79 C4 48 81 EF ?? ?? ?? ?? 48 83 ED 01");
this.AddonUpdate = sig.ScanText("FF 90 ?? ?? ?? ?? 40 88 AF ?? ?? ?? ?? 45 33 D2");
- this.AddonOnRequestedUpdate = sig.ScanText("FF 90 98 01 00 00 48 8B 5C 24 30 48 83 C4 20");
+ this.AddonOnRequestedUpdate = sig.ScanText("FF 90 A0 01 00 00 48 8B 5C 24 30");
}
}
diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs
index a41c6ff7a..c40744ca4 100644
--- a/Dalamud/Game/ChatHandlers.cs
+++ b/Dalamud/Game/ChatHandlers.cs
@@ -1,22 +1,14 @@
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
using CheapLoc;
+
using Dalamud.Configuration.Internal;
-using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.Gui;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
-using Dalamud.Game.Text.SeStringHandling.Payloads;
-using Dalamud.Interface;
-using Dalamud.Interface.ImGuiNotification;
-using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal;
-using Dalamud.Interface.Internal.Windows;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal;
using Dalamud.Utility;
@@ -27,49 +19,10 @@ namespace Dalamud.Game;
/// Chat events and public helper functions.
///
[ServiceManager.EarlyLoadedService]
-internal class ChatHandlers : IServiceType
+internal partial class ChatHandlers : IServiceType
{
- private static readonly ModuleLog Log = new("CHATHANDLER");
+ private static readonly ModuleLog Log = new("ChatHandlers");
- private readonly Dictionary retainerSaleRegexes = new()
- {
- {
- ClientLanguage.Japanese,
- new Regex[]
- {
- new Regex(@"^(?:.+)マーケットに(?[\d,.]+)ギルで出品した(?- .*)×(?[\d,.]+)が売れ、(?[\d,.]+)ギルを入手しました。$", RegexOptions.Compiled),
- new Regex(@"^(?:.+)マーケットに(?[\d,.]+)ギルで出品した(?
- .*)が売れ、(?[\d,.]+)ギルを入手しました。$", RegexOptions.Compiled),
- }
- },
- {
- ClientLanguage.English,
- new Regex[]
- {
- new Regex(@"^(?
- .+) you put up for sale in the (?:.+) markets (?:have|has) sold for (?[\d,.]+) gil \(after fees\)\.$", RegexOptions.Compiled),
- }
- },
- {
- ClientLanguage.German,
- new Regex[]
- {
- new Regex(@"^Dein Gehilfe hat (?
- .+) auf dem Markt von (?:.+) für (?[\d,.]+) Gil verkauft\.$", RegexOptions.Compiled),
- new Regex(@"^Dein Gehilfe hat (?
- .+) auf dem Markt von (?:.+) verkauft und (?[\d,.]+) Gil erhalten\.$", RegexOptions.Compiled),
- }
- },
- {
- ClientLanguage.French,
- new Regex[]
- {
- new Regex(@"^Un servant a vendu (?
- .+) pour (?[\d,.]+) gil à (?:.+)\.$", RegexOptions.Compiled),
- }
- },
- };
-
- private readonly Regex urlRegex = new(@"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?", RegexOptions.Compiled);
-
- [ServiceManager.ServiceDependency]
- private readonly Dalamud dalamud = Service.Get();
-
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
@@ -92,6 +45,9 @@ internal class ChatHandlers : IServiceType
///
public bool IsAutoUpdateComplete { get; private set; }
+ [GeneratedRegex(@"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?", RegexOptions.Compiled)]
+ private static partial Regex CompiledUrlRegex();
+
private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
var textVal = message.TextValue;
@@ -100,7 +56,7 @@ internal class ChatHandlers : IServiceType
this.configuration.BadWords.Any(x => !string.IsNullOrEmpty(x) && textVal.Contains(x)))
{
// This seems to be in the user block list - let's not show it
- Log.Debug("Blocklist triggered");
+ Log.Debug("Filtered a message that contained a muted word");
isHandled = true;
return;
}
@@ -127,41 +83,10 @@ internal class ChatHandlers : IServiceType
return;
#endif
- if (type == XivChatType.RetainerSale)
- {
- foreach (var regex in this.retainerSaleRegexes[(ClientLanguage)this.dalamud.StartInfo.Language])
- {
- var matchInfo = regex.Match(message.TextValue);
-
- // we no longer really need to do/validate the item matching since we read the id from the byte array
- // but we'd be checking the main match anyway
- var itemInfo = matchInfo.Groups["item"];
- if (!itemInfo.Success)
- continue;
-
- var itemLink = message.Payloads.FirstOrDefault(x => x.Type == PayloadType.Item) as ItemPayload;
- if (itemLink == default)
- {
- Log.Error("itemLink was null. Msg: {0}", BitConverter.ToString(message.Encode()));
- break;
- }
-
- Log.Debug($"Probable retainer sale: {message}, decoded item {itemLink.Item.RowId}, HQ {itemLink.IsHQ}");
-
- var valueInfo = matchInfo.Groups["value"];
- // not sure if using a culture here would work correctly, so just strip symbols instead
- if (!valueInfo.Success || !int.TryParse(valueInfo.Value.Replace(",", string.Empty).Replace(".", string.Empty), out var itemValue))
- continue;
-
- // Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale(itemLink.Item.RowId, itemValue, itemLink.IsHQ));
- break;
- }
- }
-
var messageCopy = message;
var senderCopy = sender;
- var linkMatch = this.urlRegex.Match(message.TextValue);
+ var linkMatch = CompiledUrlRegex().Match(message.TextValue);
if (linkMatch.Value.Length > 0)
this.LastLink = linkMatch.Value;
}
diff --git a/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs b/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs
index 058d6c0c2..244989476 100644
--- a/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs
+++ b/Dalamud/Game/ClientState/Aetherytes/AetheryteEntry.cs
@@ -1,6 +1,9 @@
-using Dalamud.Game.ClientState.Resolvers;
+using Dalamud.Data;
+
using FFXIVClientStructs.FFXIV.Client.Game.UI;
+using Lumina.Excel;
+
namespace Dalamud.Game.ClientState.Aetherytes;
///
@@ -56,7 +59,7 @@ public interface IAetheryteEntry
///
/// Gets the Aetheryte data related to this aetheryte.
///
- ExcelResolver AetheryteData { get; }
+ RowRef AetheryteData { get; }
}
///
@@ -103,5 +106,5 @@ internal sealed class AetheryteEntry : IAetheryteEntry
public bool IsApartment => this.data.IsApartment;
///
- public ExcelResolver AetheryteData => new(this.AetheryteId);
+ public RowRef AetheryteData => LuminaUtils.CreateRef(this.AetheryteId);
}
diff --git a/Dalamud/Game/ClientState/Buddy/BuddyList.cs b/Dalamud/Game/ClientState/Buddy/BuddyList.cs
index db9b8e562..84cfd24a3 100644
--- a/Dalamud/Game/ClientState/Buddy/BuddyList.cs
+++ b/Dalamud/Game/ClientState/Buddy/BuddyList.cs
@@ -1,14 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
-using Dalamud.Utility;
-using Serilog;
+using FFXIVClientStructs.FFXIV.Client.Game.UI;
namespace Dalamud.Game.ClientState.Buddy;
@@ -28,14 +26,9 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
[ServiceManager.ServiceDependency]
private readonly ClientState clientState = Service.Get();
- private readonly ClientStateAddressResolver address;
-
[ServiceManager.ServiceConstructor]
private BuddyList()
{
- this.address = this.clientState.AddressResolver;
-
- Log.Verbose($"Buddy list address {Util.DescribeAddress(this.address.BuddyList)}");
}
///
@@ -76,14 +69,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
}
}
- ///
- /// Gets the address of the buddy list.
- ///
- internal IntPtr BuddyListAddress => this.address.BuddyList;
-
- private static int BuddyMemberSize { get; } = Marshal.SizeOf();
-
- private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy*)this.BuddyListAddress;
+ private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => &UIState.Instance()->Buddy;
///
public IBuddyMember? this[int index]
diff --git a/Dalamud/Game/ClientState/Buddy/BuddyMember.cs b/Dalamud/Game/ClientState/Buddy/BuddyMember.cs
index a650a7b44..025de611d 100644
--- a/Dalamud/Game/ClientState/Buddy/BuddyMember.cs
+++ b/Dalamud/Game/ClientState/Buddy/BuddyMember.cs
@@ -1,6 +1,8 @@
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.ClientState.Resolvers;
+
+using Lumina.Excel;
namespace Dalamud.Game.ClientState.Buddy;
@@ -45,17 +47,17 @@ public interface IBuddyMember
///
/// Gets the Mount data related to this buddy. It should only be used with companion buddies.
///
- ExcelResolver MountData { get; }
+ RowRef MountData { get; }
///
/// Gets the Pet data related to this buddy. It should only be used with pet buddies.
///
- ExcelResolver PetData { get; }
+ RowRef PetData { get; }
///
/// Gets the Trust data related to this buddy. It should only be used with battle buddies.
///
- ExcelResolver TrustData { get; }
+ RowRef TrustData { get; }
}
///
@@ -94,13 +96,13 @@ internal unsafe class BuddyMember : IBuddyMember
public uint DataID => this.Struct->DataId;
///
- public ExcelResolver MountData => new(this.DataID);
+ public RowRef MountData => LuminaUtils.CreateRef(this.DataID);
///
- public ExcelResolver PetData => new(this.DataID);
+ public RowRef PetData => LuminaUtils.CreateRef(this.DataID);
///
- public ExcelResolver TrustData => new(this.DataID);
+ public RowRef TrustData => LuminaUtils.CreateRef(this.DataID);
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
}
diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs
index b31bcf780..da9873d8d 100644
--- a/Dalamud/Game/ClientState/ClientState.cs
+++ b/Dalamud/Game/ClientState/ClientState.cs
@@ -1,5 +1,4 @@
using System.Linq;
-using System.Runtime.InteropServices;
using Dalamud.Data;
using Dalamud.Game.ClientState.Conditions;
@@ -13,10 +12,15 @@ using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+
+using FFXIVClientStructs.FFXIV.Application.Network;
using FFXIVClientStructs.FFXIV.Client.Game;
+using FFXIVClientStructs.FFXIV.Client.Game.Event;
+using FFXIVClientStructs.FFXIV.Client.Game.UI;
+using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel.Sheets;
using Action = System.Action;
@@ -29,22 +33,23 @@ namespace Dalamud.Game.ClientState;
internal sealed class ClientState : IInternalDisposableService, IClientState
{
private static readonly ModuleLog Log = new("ClientState");
-
+
private readonly GameLifecycle lifecycle;
private readonly ClientStateAddressResolver address;
- private readonly Hook setupTerritoryTypeHook;
+ private readonly Hook setupTerritoryTypeHook;
+ private readonly Hook uiModuleHandlePacketHook;
+ private readonly Hook onLogoutHook;
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service.Get();
-
+
[ServiceManager.ServiceDependency]
private readonly NetworkHandlers networkHandlers = Service.Get();
-
+
private bool lastConditionNone = true;
- private bool lastFramePvP;
[ServiceManager.ServiceConstructor]
- private ClientState(TargetSigScanner sigScanner, Dalamud dalamud, GameLifecycle lifecycle)
+ private unsafe ClientState(TargetSigScanner sigScanner, Dalamud dalamud, GameLifecycle lifecycle)
{
this.lifecycle = lifecycle;
this.address = new ClientStateAddressResolver();
@@ -54,28 +59,37 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
this.ClientLanguage = (ClientLanguage)dalamud.StartInfo.Language;
- Log.Verbose($"SetupTerritoryType address {Util.DescribeAddress(this.address.SetupTerritoryType)}");
+ var setTerritoryTypeAddr = EventFramework.Addresses.SetTerritoryTypeId.Value;
+ Log.Verbose($"SetupTerritoryType address {Util.DescribeAddress(setTerritoryTypeAddr)}");
- this.setupTerritoryTypeHook = Hook.FromAddress(this.address.SetupTerritoryType, this.SetupTerritoryTypeDetour);
+ this.setupTerritoryTypeHook = Hook.FromAddress(setTerritoryTypeAddr, this.SetupTerritoryTypeDetour);
+ this.uiModuleHandlePacketHook = Hook.FromAddress((nint)UIModule.StaticVirtualTablePointer->HandlePacket, this.UIModuleHandlePacketDetour);
+ this.onLogoutHook = Hook.FromAddress((nint)LogoutCallbackInterface.StaticVirtualTablePointer->OnLogout, this.OnLogoutDetour);
this.framework.Update += this.FrameworkOnOnUpdateEvent;
-
this.networkHandlers.CfPop += this.NetworkHandlersOnCfPop;
this.setupTerritoryTypeHook.Enable();
+ this.uiModuleHandlePacketHook.Enable();
+ this.onLogoutHook.Enable();
}
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr SetupTerritoryTypeDelegate(IntPtr manager, ushort terriType);
+ private unsafe delegate void ProcessPacketPlayerSetupDelegate(nint a1, nint packet);
///
public event Action? TerritoryChanged;
+ ///
+ public event IClientState.ClassJobChangeDelegate? ClassJobChanged;
+
+ ///
+ public event IClientState.LevelChangeDelegate? LevelChanged;
+
///
public event Action? Login;
///
- public event Action? Logout;
+ public event IClientState.LogoutDelegate? Logout;
///
public event Action? EnterPvP;
@@ -98,7 +112,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
get
{
var agentMap = AgentMap.Instance();
- return agentMap != null ? AgentMap.Instance()->CurrentMapId : 0;
+ return agentMap != null ? agentMap->CurrentMapId : 0;
}
}
@@ -106,16 +120,23 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
public IPlayerCharacter? LocalPlayer => Service.GetNullable()?[0] as IPlayerCharacter;
///
- public ulong LocalContentId => (ulong)Marshal.ReadInt64(this.address.LocalContentId);
+ public unsafe ulong LocalContentId => PlayerState.Instance()->ContentId;
///
- public bool IsLoggedIn { get; private set; }
+ public unsafe bool IsLoggedIn
+ {
+ get
+ {
+ var agentLobby = AgentLobby.Instance();
+ return agentLobby != null && agentLobby->IsLoggedIn;
+ }
+ }
///
public bool IsPvP { get; private set; }
///
- public bool IsPvPExcludingDen { get; private set; }
+ public bool IsPvPExcludingDen => this.IsPvP && this.TerritoryType != 250;
///
public bool IsGPosing => GameMain.IsInGPose();
@@ -124,25 +145,25 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
/// Gets client state address resolver.
///
internal ClientStateAddressResolver AddressResolver => this.address;
-
+
///
public bool IsClientIdle(out ConditionFlag blockingFlag)
{
blockingFlag = 0;
if (this.LocalPlayer is null) return true;
-
+
var condition = Service.GetNullable();
-
+
var blockingConditions = condition.AsReadOnlySet().Except([
- ConditionFlag.NormalConditions,
- ConditionFlag.Jumping,
- ConditionFlag.Mounted,
+ ConditionFlag.NormalConditions,
+ ConditionFlag.Jumping,
+ ConditionFlag.Mounted,
ConditionFlag.UsingParasol]);
blockingFlag = blockingConditions.FirstOrDefault();
return blockingFlag == 0;
}
-
+
///
public bool IsClientIdle() => this.IsClientIdle(out _);
@@ -152,23 +173,89 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
void IInternalDisposableService.DisposeService()
{
this.setupTerritoryTypeHook.Dispose();
- this.framework.Update -= this.FrameworkOnOnUpdateEvent;
+ this.uiModuleHandlePacketHook.Dispose();
+ this.onLogoutHook.Dispose();
+
+ this.framework.Update -= this.FrameworkOnOnUpdateEvent;
this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop;
}
- private IntPtr SetupTerritoryTypeDetour(IntPtr manager, ushort terriType)
+ private unsafe void SetupTerritoryTypeDetour(EventFramework* eventFramework, ushort territoryType)
{
- this.TerritoryType = terriType;
- this.TerritoryChanged?.InvokeSafely(terriType);
+ Log.Debug("TerritoryType changed: {0}", territoryType);
- Log.Debug("TerritoryType changed: {0}", terriType);
+ this.TerritoryType = territoryType;
+ this.TerritoryChanged?.InvokeSafely(territoryType);
- return this.setupTerritoryTypeHook.Original(manager, terriType);
+ var rowRef = LuminaUtils.CreateRef(territoryType);
+ if (rowRef.IsValid)
+ {
+ var isPvP = rowRef.Value.IsPvpZone;
+ if (isPvP != this.IsPvP)
+ {
+ this.IsPvP = isPvP;
+
+ if (this.IsPvP)
+ {
+ Log.Debug("EnterPvP");
+ this.EnterPvP?.InvokeSafely();
+ }
+ else
+ {
+ Log.Debug("LeavePvP");
+ this.LeavePvP?.InvokeSafely();
+ }
+ }
+ }
+
+ this.setupTerritoryTypeHook.Original(eventFramework, territoryType);
}
- private void NetworkHandlersOnCfPop(ContentFinderCondition e)
+ private unsafe void UIModuleHandlePacketDetour(UIModule* thisPtr, UIModulePacketType type, uint uintParam, void* packet)
{
- this.CfPop?.InvokeSafely(e);
+ this.uiModuleHandlePacketHook.Original(thisPtr, type, uintParam, packet);
+
+ switch (type)
+ {
+ case UIModulePacketType.ClassJobChange when this.ClassJobChanged is { } callback:
+ {
+ var classJobId = uintParam;
+
+ foreach (var action in callback.GetInvocationList().Cast())
+ {
+ try
+ {
+ action(classJobId);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
+
+ break;
+ }
+
+ case UIModulePacketType.LevelChange when this.LevelChanged is { } callback:
+ {
+ var classJobId = *(uint*)packet;
+ var level = *(ushort*)((nint)packet + 4);
+
+ foreach (var action in callback.GetInvocationList().Cast())
+ {
+ try
+ {
+ action(classJobId, level);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
+
+ break;
+ }
+ }
}
private void FrameworkOnOnUpdateEvent(IFramework framework1)
@@ -184,40 +271,58 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
{
Log.Debug("Is login");
this.lastConditionNone = false;
- this.IsLoggedIn = true;
this.Login?.InvokeSafely();
gameGui.ResetUiHideState();
this.lifecycle.ResetLogout();
}
+ }
- if (!condition.Any() && this.lastConditionNone == false)
+ private unsafe void OnLogoutDetour(LogoutCallbackInterface* thisPtr, LogoutCallbackInterface.LogoutParams* logoutParams)
+ {
+ var gameGui = Service.GetNullable();
+
+ if (logoutParams != null)
{
- Log.Debug("Is logout");
- this.lastConditionNone = true;
- this.IsLoggedIn = false;
- this.Logout?.InvokeSafely();
- gameGui.ResetUiHideState();
-
- this.lifecycle.SetLogout();
- }
-
- this.IsPvP = GameMain.IsInPvPArea();
- this.IsPvPExcludingDen = this.IsPvP && this.TerritoryType != 250;
-
- if (this.IsPvP != this.lastFramePvP)
- {
- this.lastFramePvP = this.IsPvP;
-
- if (this.IsPvP)
+ try
{
- this.EnterPvP?.InvokeSafely();
+ var type = logoutParams->Type;
+ var code = logoutParams->Code;
+
+ Log.Debug("Logout: Type {type}, Code {code}", type, code);
+
+ if (this.Logout is { } callback)
+ {
+ foreach (var action in callback.GetInvocationList().Cast())
+ {
+ try
+ {
+ action(type, code);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Exception during raise of {handler}", action.Method);
+ }
+ }
+ }
+
+ gameGui?.ResetUiHideState();
+ this.lastConditionNone = true; // unblock login flag
+
+ this.lifecycle.SetLogout();
}
- else
+ catch (Exception ex)
{
- this.LeavePvP?.InvokeSafely();
+ Log.Error(ex, "Exception during OnLogoutDetour");
}
}
+
+ this.onLogoutHook.Original(thisPtr, logoutParams);
+ }
+
+ private void NetworkHandlersOnCfPop(ContentFinderCondition e)
+ {
+ this.CfPop?.InvokeSafely(e);
}
}
@@ -240,28 +345,36 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
internal ClientStatePluginScoped()
{
this.clientStateService.TerritoryChanged += this.TerritoryChangedForward;
+ this.clientStateService.ClassJobChanged += this.ClassJobChangedForward;
+ this.clientStateService.LevelChanged += this.LevelChangedForward;
this.clientStateService.Login += this.LoginForward;
this.clientStateService.Logout += this.LogoutForward;
this.clientStateService.EnterPvP += this.EnterPvPForward;
this.clientStateService.LeavePvP += this.ExitPvPForward;
this.clientStateService.CfPop += this.ContentFinderPopForward;
}
-
+
///
public event Action? TerritoryChanged;
-
+
+ ///
+ public event IClientState.ClassJobChangeDelegate? ClassJobChanged;
+
+ ///
+ public event IClientState.LevelChangeDelegate? LevelChanged;
+
///
public event Action? Login;
-
+
///
- public event Action? Logout;
-
+ public event IClientState.LogoutDelegate? Logout;
+
///
public event Action? EnterPvP;
-
+
///
public event Action? LeavePvP;
-
+
///
public event Action? CfPop;
@@ -270,7 +383,7 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
///
public ushort TerritoryType => this.clientStateService.TerritoryType;
-
+
///
public uint MapId => this.clientStateService.MapId;
@@ -302,6 +415,8 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
void IInternalDisposableService.DisposeService()
{
this.clientStateService.TerritoryChanged -= this.TerritoryChangedForward;
+ this.clientStateService.ClassJobChanged -= this.ClassJobChangedForward;
+ this.clientStateService.LevelChanged -= this.LevelChangedForward;
this.clientStateService.Login -= this.LoginForward;
this.clientStateService.Logout -= this.LogoutForward;
this.clientStateService.EnterPvP -= this.EnterPvPForward;
@@ -317,13 +432,17 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
}
private void TerritoryChangedForward(ushort territoryId) => this.TerritoryChanged?.Invoke(territoryId);
-
+
+ private void ClassJobChangedForward(uint classJobId) => this.ClassJobChanged?.Invoke(classJobId);
+
+ private void LevelChangedForward(uint classJobId, uint level) => this.LevelChanged?.Invoke(classJobId, level);
+
private void LoginForward() => this.Login?.Invoke();
-
- private void LogoutForward() => this.Logout?.Invoke();
-
+
+ private void LogoutForward(int type, int code) => this.Logout?.Invoke(type, code);
+
private void EnterPvPForward() => this.EnterPvP?.Invoke();
-
+
private void ExitPvPForward() => this.LeavePvP?.Invoke();
private void ContentFinderPopForward(ContentFinderCondition cfc) => this.CfPop?.Invoke(cfc);
diff --git a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs
index 5a5351a38..97bc5dae1 100644
--- a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs
+++ b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs
@@ -7,39 +7,6 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver
{
// Static offsets
- ///
- /// Gets the address of the actor table.
- ///
- public IntPtr ObjectTable { get; private set; }
-
- ///
- /// Gets the address of the buddy list.
- ///
- public IntPtr BuddyList { get; private set; }
-
- ///
- /// Gets the address of a pointer to the fate table.
- ///
- ///
- /// This is a static address to a pointer, not the address of the table itself.
- ///
- public IntPtr FateTablePtr { get; private set; }
-
- ///
- /// Gets the address of the Group Manager.
- ///
- public IntPtr GroupManager { get; private set; }
-
- ///
- /// Gets the address of the local content id.
- ///
- public IntPtr LocalContentId { get; private set; }
-
- ///
- /// Gets the address of job gauge data.
- ///
- public IntPtr JobGaugeData { get; private set; }
-
///
/// Gets the address of the keyboard state.
///
@@ -50,23 +17,12 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver
///
public IntPtr KeyboardStateIndexArray { get; private set; }
- ///
- /// Gets the address of the condition flag array.
- ///
- public IntPtr ConditionFlags { get; private set; }
-
// Functions
///
- /// Gets the address of the method which sets the territory type.
+ /// Gets the address of the method which sets up the player.
///
- public IntPtr SetupTerritoryType { get; private set; }
-
- ///
- /// Gets the address of the method which polls the gamepads for data.
- /// Called every frame, even when `Enable Gamepad` is off in the settings.
- ///
- public IntPtr GamepadPoll { get; private set; }
+ public IntPtr ProcessPacketPlayerSetup { get; private set; }
///
/// Scan for and setup any configured address pointers.
@@ -74,27 +30,12 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver
/// The signature scanner to facilitate setup.
protected override void Setup64Bit(ISigScanner sig)
{
- this.ObjectTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 44 0F B6 83 ?? ?? ?? ?? C6 83 ?? ?? ?? ?? ??");
-
- this.BuddyList = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 45 84 E4 75 1A F6 45 12 04");
-
- this.FateTablePtr = sig.GetStaticAddressFromSig("48 8B 15 ?? ?? ?? ?? 48 8B F1 44 0F B7 41");
-
- this.GroupManager = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 B8 ?? ?? ?? ?? ?? 77 71");
-
- this.LocalContentId = sig.GetStaticAddressFromSig("48 0F 44 0D ?? ?? ?? ?? 48 8D 57 08");
- this.JobGaugeData = sig.GetStaticAddressFromSig("48 8B 3D ?? ?? ?? ?? 33 ED") + 0x8;
-
- this.SetupTerritoryType = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 83 EC 20 0F B7 DA");
+ this.ProcessPacketPlayerSetup = sig.ScanText("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 48 8B DA E8 ?? ?? ?? ?? 48 8B D3"); // not in cs struct
// These resolve to fixed offsets only, without the base address added in, so GetStaticAddressFromSig() can't be used.
// lea rcx, ds:1DB9F74h[rax*4] KeyboardState
// movzx edx, byte ptr [rbx+rsi+1D5E0E0h] KeyboardStateIndexArray
this.KeyboardState = sig.ScanText("48 8D 0C 85 ?? ?? ?? ?? 8B 04 31 85 C2 0F 85") + 0x4;
this.KeyboardStateIndexArray = sig.ScanText("0F B6 94 33 ?? ?? ?? ?? 84 D2") + 0x4;
-
- this.ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 8B D3 E8 ?? ?? ?? ?? 32 C0 48 83 C4 20");
-
- this.GamepadPoll = sig.ScanText("40 55 53 57 41 54 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 44 0F 29 B4 24");
}
}
diff --git a/Dalamud/Game/ClientState/Conditions/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs
index 6fee02fd6..8f39df46f 100644
--- a/Dalamud/Game/ClientState/Conditions/Condition.cs
+++ b/Dalamud/Game/ClientState/Conditions/Condition.cs
@@ -28,10 +28,9 @@ internal sealed class Condition : IInternalDisposableService, ICondition
private bool isDisposed;
[ServiceManager.ServiceConstructor]
- private Condition(ClientState clientState)
+ private unsafe Condition()
{
- var resolver = clientState.AddressResolver;
- this.Address = resolver.ConditionFlags;
+ this.Address = (nint)FFXIVClientStructs.FFXIV.Client.Game.Conditions.Instance();
// Initialization
for (var i = 0; i < MaxConditionEntries; i++)
diff --git a/Dalamud/Game/ClientState/Fates/Fate.cs b/Dalamud/Game/ClientState/Fates/Fate.cs
index 2d32cc04c..f48e66ad6 100644
--- a/Dalamud/Game/ClientState/Fates/Fate.cs
+++ b/Dalamud/Game/ClientState/Fates/Fate.cs
@@ -1,10 +1,11 @@
using System.Numerics;
using Dalamud.Data;
-using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Memory;
+using Lumina.Excel;
+
namespace Dalamud.Game.ClientState.Fates;
///
@@ -20,7 +21,7 @@ public interface IFate : IEquatable
///
/// Gets game data linked to this Fate.
///
- Lumina.Excel.GeneratedSheets.Fate GameData { get; }
+ RowRef GameData { get; }
///
/// Gets the time this started.
@@ -70,8 +71,14 @@ public interface IFate : IEquatable
///
/// Gets a value indicating whether or not this has a EXP bonus.
///
+ [Obsolete($"Use {nameof(HasBonus)} instead")]
bool HasExpBonus { get; }
+ ///
+ /// Gets a value indicating whether or not this has a bonus.
+ ///
+ bool HasBonus { get; }
+
///
/// Gets the icon id of this .
///
@@ -105,7 +112,7 @@ public interface IFate : IEquatable
///
/// Gets the territory this is located in.
///
- ExcelResolver TerritoryType { get; }
+ RowRef TerritoryType { get; }
///
/// Gets the address of this Fate in memory.
@@ -185,7 +192,7 @@ internal unsafe partial class Fate : IFate
public ushort FateId => this.Struct->FateId;
///
- public Lumina.Excel.GeneratedSheets.Fate GameData => Service.Get().GetExcelSheet().GetRow(this.FateId);
+ public RowRef GameData => LuminaUtils.CreateRef(this.FateId);
///
public int StartTimeEpoch => this.Struct->StartTimeEpoch;
@@ -215,8 +222,12 @@ internal unsafe partial class Fate : IFate
public byte Progress => this.Struct->Progress;
///
+ [Obsolete($"Use {nameof(HasBonus)} instead")]
public bool HasExpBonus => this.Struct->IsExpBonus;
+ ///
+ public bool HasBonus => this.Struct->IsBonus;
+
///
public uint IconId => this.Struct->IconId;
@@ -238,5 +249,5 @@ internal unsafe partial class Fate : IFate
///
/// Gets the territory this is located in.
///
- public ExcelResolver TerritoryType => new(this.Struct->TerritoryId);
+ public RowRef TerritoryType => LuminaUtils.CreateRef(this.Struct->MapMarkers[0].TerritoryId);
}
diff --git a/Dalamud/Game/ClientState/Fates/FateState.cs b/Dalamud/Game/ClientState/Fates/FateState.cs
index 8f2ef85cc..ad605a99c 100644
--- a/Dalamud/Game/ClientState/Fates/FateState.cs
+++ b/Dalamud/Game/ClientState/Fates/FateState.cs
@@ -8,25 +8,25 @@ public enum FateState : byte
///
/// The Fate is active.
///
- Running = 0x02,
+ Running = 0x04,
///
/// The Fate has ended.
///
- Ended = 0x04,
+ Ended = 0x07,
///
/// The player failed the Fate.
///
- Failed = 0x05,
+ Failed = 0x08,
///
/// The Fate is preparing to run.
///
- Preparation = 0x07,
+ Preparation = 0x03,
///
/// The Fate is preparing to end.
///
- WaitingForEnd = 0x08,
+ WaitingForEnd = 0x05,
}
diff --git a/Dalamud/Game/ClientState/Fates/FateTable.cs b/Dalamud/Game/ClientState/Fates/FateTable.cs
index abd5bac41..1bf557ad5 100644
--- a/Dalamud/Game/ClientState/Fates/FateTable.cs
+++ b/Dalamud/Game/ClientState/Fates/FateTable.cs
@@ -4,9 +4,8 @@ using System.Collections.Generic;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
-using Dalamud.Utility;
-using Serilog;
+using CSFateManager = FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager;
namespace Dalamud.Game.ClientState.Fates;
@@ -20,55 +19,34 @@ namespace Dalamud.Game.ClientState.Fates;
#pragma warning restore SA1015
internal sealed partial class FateTable : IServiceType, IFateTable
{
- private readonly ClientStateAddressResolver address;
-
[ServiceManager.ServiceConstructor]
- private FateTable(ClientState clientState)
+ private FateTable()
{
- this.address = clientState.AddressResolver;
-
- Log.Verbose($"Fate table address {Util.DescribeAddress(this.address.FateTablePtr)}");
}
///
- public IntPtr Address => this.address.FateTablePtr;
+ public unsafe IntPtr Address => (nint)CSFateManager.Instance();
///
public unsafe int Length
{
get
{
- var fateTable = this.FateTableAddress;
- if (fateTable == IntPtr.Zero)
+ var fateManager = CSFateManager.Instance();
+ if (fateManager == null)
return 0;
// Sonar used this to check if the table was safe to read
- if (Struct->FateDirector == null)
+ if (fateManager->FateDirector == null)
return 0;
- if (Struct->Fates.First == null || Struct->Fates.Last == null)
+ if (fateManager->Fates.First == null || fateManager->Fates.Last == null)
return 0;
- return Struct->Fates.Count;
+ return fateManager->Fates.Count;
}
}
- ///
- /// Gets the address of the Fate table.
- ///
- internal unsafe IntPtr FateTableAddress
- {
- get
- {
- if (this.address.FateTablePtr == IntPtr.Zero)
- return IntPtr.Zero;
-
- return *(IntPtr*)this.address.FateTablePtr;
- }
- }
-
- private unsafe FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager*)this.FateTableAddress;
-
///
public IFate? this[int index]
{
@@ -99,11 +77,11 @@ internal sealed partial class FateTable : IServiceType, IFateTable
if (index >= this.Length)
return IntPtr.Zero;
- var fateTable = this.FateTableAddress;
- if (fateTable == IntPtr.Zero)
+ var fateManager = CSFateManager.Instance();
+ if (fateManager == null)
return IntPtr.Zero;
- return (IntPtr)this.Struct->Fates[index].Value;
+ return (IntPtr)fateManager->Fates[index].Value;
}
///
diff --git a/Dalamud/Game/ClientState/GamePad/GamepadInput.cs b/Dalamud/Game/ClientState/GamePad/GamepadInput.cs
deleted file mode 100644
index 32439cd08..000000000
--- a/Dalamud/Game/ClientState/GamePad/GamepadInput.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.ClientState.GamePad;
-
-///
-/// Struct which gets populated by polling the gamepads.
-///
-/// Has an array of gamepads, among many other things (here not mapped).
-/// All we really care about is the final data which the game uses to determine input.
-///
-/// The size is definitely bigger than only the following fields but I do not know how big.
-///
-[StructLayout(LayoutKind.Explicit)]
-public struct GamepadInput
-{
- ///
- /// Left analogue stick's horizontal value, -99 for left, 99 for right.
- ///
- [FieldOffset(0x88)]
- public int LeftStickX;
-
- ///
- /// Left analogue stick's vertical value, -99 for down, 99 for up.
- ///
- [FieldOffset(0x8C)]
- public int LeftStickY;
-
- ///
- /// Right analogue stick's horizontal value, -99 for left, 99 for right.
- ///
- [FieldOffset(0x90)]
- public int RightStickX;
-
- ///
- /// Right analogue stick's vertical value, -99 for down, 99 for up.
- ///
- [FieldOffset(0x94)]
- public int RightStickY;
-
- ///
- /// Raw input, set the whole time while a button is held. See for the mapping.
- ///
- ///
- /// This is a bitfield.
- ///
- [FieldOffset(0x98)]
- public ushort ButtonsRaw;
-
- ///
- /// Button pressed, set once when the button is pressed. See for the mapping.
- ///
- ///
- /// This is a bitfield.
- ///
- [FieldOffset(0x9C)]
- public ushort ButtonsPressed;
-
- ///
- /// Button released input, set once right after the button is not hold anymore. See for the mapping.
- ///
- ///
- /// This is a bitfield.
- ///
- [FieldOffset(0xA0)]
- public ushort ButtonsReleased;
-
- ///
- /// Repeatedly emits the held button input in fixed intervals. See for the mapping.
- ///
- ///
- /// This is a bitfield.
- ///
- [FieldOffset(0xA4)]
- public ushort ButtonsRepeat;
-}
diff --git a/Dalamud/Game/ClientState/GamePad/GamepadState.cs b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
index 05d691823..5237c6f0c 100644
--- a/Dalamud/Game/ClientState/GamePad/GamepadState.cs
+++ b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
@@ -4,7 +4,8 @@ using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
-using Dalamud.Utility;
+
+using FFXIVClientStructs.FFXIV.Client.System.Input;
using ImGuiNET;
using Serilog;
@@ -23,7 +24,7 @@ namespace Dalamud.Game.ClientState.GamePad;
#pragma warning restore SA1015
internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
{
- private readonly Hook? gamepadPoll;
+ private readonly Hook? gamepadPoll;
private bool isDisposed;
@@ -35,25 +36,21 @@ internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
[ServiceManager.ServiceConstructor]
private GamepadState(ClientState clientState)
{
- var resolver = clientState.AddressResolver;
- Log.Verbose($"GamepadPoll address {Util.DescribeAddress(resolver.GamepadPoll)}");
- this.gamepadPoll = Hook.FromAddress(resolver.GamepadPoll, this.GamepadPollDetour);
+ this.gamepadPoll = Hook.FromAddress((nint)PadDevice.StaticVirtualTablePointer->Poll, this.GamepadPollDetour);
this.gamepadPoll?.Enable();
}
- private delegate int ControllerPoll(IntPtr controllerInput);
-
///
/// Gets the pointer to the current instance of the GamepadInput struct.
///
public IntPtr GamepadInputAddress { get; private set; }
///
- public Vector2 LeftStick =>
+ public Vector2 LeftStick =>
new(this.leftStickX, this.leftStickY);
-
+
///
- public Vector2 RightStick =>
+ public Vector2 RightStick =>
new(this.rightStickX, this.rightStickY);
///
@@ -61,28 +58,28 @@ internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
///
/// Exposed internally for Debug Data window.
///
- internal ushort ButtonsPressed { get; private set; }
+ internal GamepadButtons ButtonsPressed { get; private set; }
///
/// Gets raw button bitmask, set the whole time while a button is held. See for the mapping.
///
/// Exposed internally for Debug Data window.
///
- internal ushort ButtonsRaw { get; private set; }
+ internal GamepadButtons ButtonsRaw { get; private set; }
///
/// Gets button released bitmask, set once right after the button is not hold anymore. See for the mapping.
///
/// Exposed internally for Debug Data window.
///
- internal ushort ButtonsReleased { get; private set; }
+ internal GamepadButtons ButtonsReleased { get; private set; }
///
/// Gets button repeat bitmask, emits the held button input in fixed intervals. See for the mapping.
///
/// Exposed internally for Debug Data window.
///
- internal ushort ButtonsRepeat { get; private set; }
+ internal GamepadButtons ButtonsRepeat { get; private set; }
///
/// Gets or sets a value indicating whether detour should block gamepad input for game.
@@ -95,16 +92,16 @@ internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
internal bool NavEnableGamepad { get; set; }
///
- public float Pressed(GamepadButtons button) => (this.ButtonsPressed & (ushort)button) > 0 ? 1 : 0;
+ public float Pressed(GamepadButtons button) => (this.ButtonsPressed & button) > 0 ? 1 : 0;
///
- public float Repeat(GamepadButtons button) => (this.ButtonsRepeat & (ushort)button) > 0 ? 1 : 0;
+ public float Repeat(GamepadButtons button) => (this.ButtonsRepeat & button) > 0 ? 1 : 0;
///
- public float Released(GamepadButtons button) => (this.ButtonsReleased & (ushort)button) > 0 ? 1 : 0;
+ public float Released(GamepadButtons button) => (this.ButtonsReleased & button) > 0 ? 1 : 0;
///
- public float Raw(GamepadButtons button) => (this.ButtonsRaw & (ushort)button) > 0 ? 1 : 0;
+ public float Raw(GamepadButtons button) => (this.ButtonsRaw & button) > 0 ? 1 : 0;
///
/// Disposes this instance, alongside its hooks.
@@ -115,28 +112,28 @@ internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
GC.SuppressFinalize(this);
}
- private int GamepadPollDetour(IntPtr gamepadInput)
+ private nint GamepadPollDetour(PadDevice* gamepadInput)
{
var original = this.gamepadPoll!.Original(gamepadInput);
try
{
- this.GamepadInputAddress = gamepadInput;
- var input = (GamepadInput*)gamepadInput;
- this.leftStickX = input->LeftStickX;
- this.leftStickY = input->LeftStickY;
- this.rightStickX = input->RightStickX;
- this.rightStickY = input->RightStickY;
- this.ButtonsRaw = input->ButtonsRaw;
- this.ButtonsPressed = input->ButtonsPressed;
- this.ButtonsReleased = input->ButtonsReleased;
- this.ButtonsRepeat = input->ButtonsRepeat;
+ this.GamepadInputAddress = (nint)gamepadInput;
+
+ this.leftStickX = gamepadInput->GamepadInputData.LeftStickX;
+ this.leftStickY = gamepadInput->GamepadInputData.LeftStickY;
+ this.rightStickX = gamepadInput->GamepadInputData.RightStickX;
+ this.rightStickY = gamepadInput->GamepadInputData.RightStickY;
+ this.ButtonsRaw = (GamepadButtons)gamepadInput->GamepadInputData.Buttons;
+ this.ButtonsPressed = (GamepadButtons)gamepadInput->GamepadInputData.ButtonsPressed;
+ this.ButtonsReleased = (GamepadButtons)gamepadInput->GamepadInputData.ButtonsReleased;
+ this.ButtonsRepeat = (GamepadButtons)gamepadInput->GamepadInputData.ButtonsRepeat;
if (this.NavEnableGamepad)
{
- input->LeftStickX = 0;
- input->LeftStickY = 0;
- input->RightStickX = 0;
- input->RightStickY = 0;
+ gamepadInput->GamepadInputData.LeftStickX = 0;
+ gamepadInput->GamepadInputData.LeftStickY = 0;
+ gamepadInput->GamepadInputData.RightStickX = 0;
+ gamepadInput->GamepadInputData.RightStickY = 0;
// NOTE (Chiv) Zeroing `ButtonsRaw` destroys `ButtonPressed`, `ButtonReleased`
// and `ButtonRepeat` as the game uses the RAW input to determine those (apparently).
@@ -153,16 +150,16 @@ internal unsafe class GamepadState : IInternalDisposableService, IGamepadState
// `ButtonPressed` while ImGuiConfigFlags.NavEnableGamepad is set.
// This is debatable.
// ImGui itself does not care either way as it uses the Raw values and does its own state handling.
- const ushort deletionMask = (ushort)(~GamepadButtons.L2
- & ~GamepadButtons.R2
- & ~GamepadButtons.DpadDown
- & ~GamepadButtons.DpadLeft
- & ~GamepadButtons.DpadUp
- & ~GamepadButtons.DpadRight);
- input->ButtonsRaw &= deletionMask;
- input->ButtonsPressed = 0;
- input->ButtonsReleased = 0;
- input->ButtonsRepeat = 0;
+ const GamepadButtonsFlags deletionMask = ~GamepadButtonsFlags.L2
+ & ~GamepadButtonsFlags.R2
+ & ~GamepadButtonsFlags.DPadDown
+ & ~GamepadButtonsFlags.DPadLeft
+ & ~GamepadButtonsFlags.DPadUp
+ & ~GamepadButtonsFlags.DPadRight;
+ gamepadInput->GamepadInputData.Buttons &= deletionMask;
+ gamepadInput->GamepadInputData.ButtonsPressed = 0;
+ gamepadInput->GamepadInputData.ButtonsReleased = 0;
+ gamepadInput->GamepadInputData.ButtonsRepeat = 0;
return 0;
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/BeastChakra.cs b/Dalamud/Game/ClientState/JobGauge/Enums/BeastChakra.cs
index bbe4ad70d..9191ca020 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/BeastChakra.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/BeastChakra.cs
@@ -8,20 +8,20 @@ public enum BeastChakra : byte
///
/// No chakra.
///
- NONE = 0,
+ None = 0,
///
/// The Opo-Opo chakra.
///
- OPOOPO = 1,
+ OpoOpo = 1,
///
/// The Raptor chakra.
///
- RAPTOR = 2,
+ Raptor = 2,
///
/// The Coeurl chakra.
///
- COEURL = 3,
+ Coeurl = 3,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs b/Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs
index 24ffc2b19..89fceed96 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs
@@ -8,45 +8,45 @@ public enum CardType : byte
///
/// No card.
///
- NONE = 0,
+ None = 0,
///
/// The Balance card.
///
- BALANCE = 1,
+ Balance = 1,
///
/// The Bole card.
///
- BOLE = 2,
+ Bole = 2,
///
/// The Arrow card.
///
- ARROW = 3,
+ Arrow = 3,
///
/// The Spear card.
///
- SPEAR = 4,
+ Spear = 4,
///
/// The Ewer card.
///
- EWER = 5,
+ Ewer = 5,
///
/// The Spire card.
///
- SPIRE = 6,
+ Spire = 6,
///
/// The Lord of Crowns card.
///
- LORD = 7,
+ Lord = 7,
///
/// The Lady of Crowns card.
///
- LADY = 8,
+ Lady = 8,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/DeliriumStep.cs b/Dalamud/Game/ClientState/JobGauge/Enums/DeliriumStep.cs
new file mode 100644
index 000000000..d2a41b93c
--- /dev/null
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/DeliriumStep.cs
@@ -0,0 +1,22 @@
+namespace Dalamud.Game.ClientState.JobGauge.Enums;
+
+///
+/// Enum representing the current step of Delirium.
+///
+public enum DeliriumStep
+{
+ ///
+ /// Scarlet Delirium can be used.
+ ///
+ ScarletDelirium = 0,
+
+ ///
+ /// Comeuppance can be used.
+ ///
+ Comeuppance = 1,
+
+ ///
+ /// Torcleaver can be used.
+ ///
+ Torcleaver = 2,
+}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs b/Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs
index b674d11b8..446489bd1 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs
@@ -8,10 +8,10 @@ public enum DismissedFairy : byte
///
/// Dismissed fairy is Eos.
///
- EOS = 6,
+ Eos = 6,
///
/// Dismissed fairy is Selene.
///
- SELENE = 7,
+ Selene = 7,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/DrawType.cs b/Dalamud/Game/ClientState/JobGauge/Enums/DrawType.cs
index f8833d6d0..619059daa 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/DrawType.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/DrawType.cs
@@ -8,10 +8,10 @@ public enum DrawType : byte
///
/// Astral Draw active.
///
- ASTRAL = 0,
+ Astral = 0,
///
/// Umbral Draw active.
///
- UMBRAL = 1,
+ Umbral = 1,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Kaeshi.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Kaeshi.cs
index e35dcc7f9..86e58771b 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/Kaeshi.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/Kaeshi.cs
@@ -8,25 +8,25 @@ public enum Kaeshi : byte
///
/// No Kaeshi is active.
///
- NONE = 0,
+ None = 0,
///
/// Kaeshi: Higanbana type.
///
- HIGANBANA = 1,
+ Higanbana = 1,
///
/// Kaeshi: Goken type.
///
- GOKEN = 2,
+ Goken = 2,
///
/// Kaeshi: Setsugekka type.
///
- SETSUGEKKA = 3,
+ Setsugekka = 3,
///
/// Kaeshi: Namikiri type.
///
- NAMIKIRI = 4,
+ Namikiri = 4,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs
index 31ee6dac1..8955c0735 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs
@@ -8,15 +8,15 @@ public enum Mudras : byte
///
/// Ten mudra.
///
- TEN = 1,
+ Ten = 1,
///
/// Chi mudra.
///
- CHI = 2,
+ Chi = 2,
///
/// Jin mudra.
///
- JIN = 3,
+ Jin = 3,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs
index 8be5c739e..f61e54104 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/Nadi.cs
@@ -9,15 +9,15 @@ public enum Nadi : byte
///
/// No nadi.
///
- NONE = 0,
+ None = 0,
///
/// The Lunar nadi.
///
- LUNAR = 1,
+ Lunar = 1,
///
/// The Solar nadi.
///
- SOLAR = 2,
+ Solar = 2,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs b/Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs
index 248caa396..c10c369d3 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs
@@ -8,40 +8,40 @@ public enum PetGlam : byte
///
/// No pet glam.
///
- NONE = 0,
+ None = 0,
///
/// Emerald carbuncle pet glam.
///
- EMERALD = 1,
+ Emerald = 1,
///
/// Topaz carbuncle pet glam.
///
- TOPAZ = 2,
+ Topaz = 2,
///
/// Ruby carbuncle pet glam.
///
- RUBY = 3,
+ Ruby = 3,
///
/// Normal carbuncle pet glam.
///
- CARBUNCLE = 4,
+ Carbuncle = 4,
///
/// Ifrit Egi pet glam.
///
- IFRIT = 5,
+ Ifrit = 5,
///
/// Titan Egi pet glam.
///
- TITAN = 6,
+ Titan = 6,
///
/// Garuda Egi pet glam.
///
- GARUDA = 7,
+ Garuda = 7,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs
index a1a6035c6..0eb86b1b1 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs
@@ -9,20 +9,20 @@ public enum Sen : byte
///
/// No Sen.
///
- NONE = 0,
+ None = 0,
///
/// Setsu Sen type.
///
- SETSU = 1 << 0,
+ Setsu = 1 << 0,
///
/// Getsu Sen type.
///
- GETSU = 1 << 1,
+ Getsu = 1 << 1,
///
/// Ka Sen type.
///
- KA = 1 << 2,
+ Ka = 1 << 2,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/SerpentCombo.cs b/Dalamud/Game/ClientState/JobGauge/Enums/SerpentCombo.cs
index 0fc50d87a..f4850cf8c 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/SerpentCombo.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/SerpentCombo.cs
@@ -8,35 +8,35 @@ public enum SerpentCombo : byte
///
/// No Serpent combo is active.
///
- NONE = 0,
+ None = 0,
///
/// Death Rattle action.
///
- DEATHRATTLE = 1,
+ DeathRattle = 1,
///
/// Last Lash action.
///
- LASTLASH = 2,
+ LastLash = 2,
///
/// First Legacy action.
///
- FIRSTLEGACY = 3,
+ FirstLegacy = 3,
///
/// Second Legacy action.
///
- SECONDLEGACY = 4,
+ SecondLegacy = 4,
///
/// Third Legacy action.
///
- THIRDLEGACY = 5,
+ ThirdLegacy = 5,
///
/// Fourth Legacy action.
///
- FOURTHLEGACY = 6,
+ FourthLegacy = 6,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/Song.cs b/Dalamud/Game/ClientState/JobGauge/Enums/Song.cs
index c23fbbbff..7ca6b6c07 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/Song.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/Song.cs
@@ -8,20 +8,20 @@ public enum Song : byte
///
/// No song is active type.
///
- NONE = 0,
+ None = 0,
///
/// Mage's Ballad type.
///
- MAGE = 1,
+ Mage = 1,
///
/// Army's Paeon type.
///
- ARMY = 2,
+ Army = 2,
///
/// The Wanderer's Minuet type.
///
- WANDERER = 3,
+ Wanderer = 3,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/SummonAttunement.cs b/Dalamud/Game/ClientState/JobGauge/Enums/SummonAttunement.cs
new file mode 100644
index 000000000..a07c0d04f
--- /dev/null
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/SummonAttunement.cs
@@ -0,0 +1,30 @@
+namespace Dalamud.Game.ClientState.JobGauge.Enums;
+
+///
+/// Enum representing the current attunement of a summoner.
+///
+public enum SummonAttunement
+{
+ ///
+ /// No attunement.
+ ///
+ None = 0,
+
+ ///
+ /// Attuned to the summon Ifrit.
+ /// Same as .
+ ///
+ Ifrit = 1,
+
+ ///
+ /// Attuned to the summon Titan.
+ /// Same as .
+ ///
+ Titan = 2,
+
+ ///
+ /// Attuned to the summon Garuda.
+ /// Same as .
+ ///
+ Garuda = 3,
+}
diff --git a/Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs b/Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs
index 30cc0fff0..37569f4bf 100644
--- a/Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs
@@ -8,10 +8,10 @@ public enum SummonPet : byte
///
/// No pet.
///
- NONE = 0,
+ None = 0,
///
/// The summoned pet Carbuncle.
///
- CARBUNCLE = 23,
+ Carbuncle = 23,
}
diff --git a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs
index e0ae986c5..67429956b 100644
--- a/Dalamud/Game/ClientState/JobGauge/JobGauges.cs
+++ b/Dalamud/Game/ClientState/JobGauge/JobGauges.cs
@@ -5,9 +5,8 @@ using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
-using Dalamud.Utility;
-using Serilog;
+using CSJobGaugeManager = FFXIVClientStructs.FFXIV.Client.Game.JobGaugeManager;
namespace Dalamud.Game.ClientState.JobGauge;
@@ -21,18 +20,15 @@ namespace Dalamud.Game.ClientState.JobGauge;
#pragma warning restore SA1015
internal class JobGauges : IServiceType, IJobGauges
{
- private Dictionary cache = new();
+ private Dictionary cache = [];
[ServiceManager.ServiceConstructor]
- private JobGauges(ClientState clientState)
+ private JobGauges()
{
- this.Address = clientState.AddressResolver.JobGaugeData;
-
- Log.Verbose($"JobGaugeData address {Util.DescribeAddress(this.Address)}");
}
///
- public IntPtr Address { get; }
+ public unsafe IntPtr Address => (nint)(&CSJobGaugeManager.Instance()->EmptyGauge);
///
public T Get() where T : JobGaugeBase
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs
index ebf70abe7..c4058132a 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs
@@ -19,11 +19,6 @@ public unsafe class BLMGauge : JobGaugeBase
public short EnochianTimer => this.Struct->EnochianTimer;
- ///
- /// Gets the time remaining for Astral Fire or Umbral Ice in milliseconds.
- ///
- public short ElementTimeRemaining => this.Struct->ElementTimeRemaining;
-
///
/// Gets the number of Polyglot stacks remaining.
///
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs
index bfcf3cc38..8880c3555 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs
@@ -40,15 +40,15 @@ public unsafe class BRDGauge : JobGaugeBaseSongFlags.HasFlag(SongFlags.WanderersMinuet))
- return Song.WANDERER;
+ return Song.Wanderer;
if (this.Struct->SongFlags.HasFlag(SongFlags.ArmysPaeon))
- return Song.ARMY;
+ return Song.Army;
if (this.Struct->SongFlags.HasFlag(SongFlags.MagesBallad))
- return Song.MAGE;
+ return Song.Mage;
- return Song.NONE;
+ return Song.None;
}
}
@@ -60,15 +60,15 @@ public unsafe class BRDGauge : JobGaugeBaseSongFlags.HasFlag(SongFlags.WanderersMinuetLastPlayed))
- return Song.WANDERER;
+ return Song.Wanderer;
if (this.Struct->SongFlags.HasFlag(SongFlags.ArmysPaeonLastPlayed))
- return Song.ARMY;
+ return Song.Army;
if (this.Struct->SongFlags.HasFlag(SongFlags.MagesBalladLastPlayed))
- return Song.MAGE;
+ return Song.Mage;
- return Song.NONE;
+ return Song.None;
}
}
@@ -76,7 +76,7 @@ public unsafe class BRDGauge : JobGaugeBase
///
- /// This will always return an array of size 3, inactive Coda are represented by .
+ /// This will always return an array of size 3, inactive Coda are represented by .
///
public Song[] Coda
{
@@ -84,9 +84,9 @@ public unsafe class BRDGauge : JobGaugeBaseSongFlags.HasFlag(SongFlags.MagesBalladCoda) ? Song.MAGE : Song.NONE,
- this.Struct->SongFlags.HasFlag(SongFlags.ArmysPaeonCoda) ? Song.ARMY : Song.NONE,
- this.Struct->SongFlags.HasFlag(SongFlags.WanderersMinuetCoda) ? Song.WANDERER : Song.NONE,
+ this.Struct->SongFlags.HasFlag(SongFlags.MagesBalladCoda) ? Song.Mage : Song.None,
+ this.Struct->SongFlags.HasFlag(SongFlags.ArmysPaeonCoda) ? Song.Army : Song.None,
+ this.Struct->SongFlags.HasFlag(SongFlags.WanderersMinuetCoda) ? Song.Wanderer : Song.None,
};
}
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs
index 834087040..c56d03db0 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs
@@ -1,9 +1,12 @@
+using Dalamud.Game.ClientState.JobGauge.Enums;
+using FFXIVClientStructs.FFXIV.Client.Game.Gauge;
+
namespace Dalamud.Game.ClientState.JobGauge.Types;
///
/// In-memory DRK job gauge.
///
-public unsafe class DRKGauge : JobGaugeBase
+public unsafe class DRKGauge : JobGaugeBase
{
///
/// Initializes a new instance of the class.
@@ -34,4 +37,16 @@ public unsafe class DRKGauge : JobGaugeBase
/// true or false.
public bool HasDarkArts => this.Struct->DarkArtsState > 0;
+
+ ///
+ /// Gets the step of the Delirium Combo (Scarlet Delirium, Comeuppance,
+ /// Torcleaver) that the player is on.
+ /// Does not in any way consider whether the player is still under Delirium, or
+ /// if the player still has stacks of Delirium to use.
+ ///
+ ///
+ /// Value will persist until combo is finished OR
+ /// if the combo is not completed then the value will stay until about halfway into Delirium's cooldown.
+ ///
+ public DeliriumStep DeliriumComboStep => (DeliriumStep)this.Struct->DeliriumStep;
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs
index 803740f33..31a5ceb9b 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs
@@ -27,7 +27,7 @@ public unsafe class MNKGauge : JobGaugeBase
///
- /// This will always return an array of size 3, inactive Beast Chakra are represented by .
+ /// This will always return an array of size 3, inactive Beast Chakra are represented by .
///
public BeastChakra[] BeastChakra => this.Struct->BeastChakra.Select(c => (BeastChakra)c).ToArray();
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs
index f3417f002..52dc0e51a 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs
@@ -40,17 +40,17 @@ public unsafe class SAMGauge : JobGaugeBase
/// true or false.
- public bool HasSetsu => (this.Sen & Sen.SETSU) != 0;
+ public bool HasSetsu => (this.Sen & Sen.Setsu) != 0;
///
/// Gets a value indicating whether the Getsu Sen is active.
///
/// true or false.
- public bool HasGetsu => (this.Sen & Sen.GETSU) != 0;
+ public bool HasGetsu => (this.Sen & Sen.Getsu) != 0;
///
/// Gets a value indicating whether the Ka Sen is active.
///
/// true or false.
- public bool HasKa => (this.Sen & Sen.KA) != 0;
+ public bool HasKa => (this.Sen & Sen.Ka) != 0;
}
diff --git a/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs b/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs
index aa7e27fd2..899ea78eb 100644
--- a/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs
+++ b/Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs
@@ -25,25 +25,46 @@ public unsafe class SMNGauge : JobGaugeBase
///
/// Gets the time remaining for the current attunement.
///
- public ushort AttunmentTimerRemaining => this.Struct->AttunementTimer;
+ [Obsolete("Typo fixed. Use AttunementTimerRemaining instead.", true)]
+ public ushort AttunmentTimerRemaining => this.AttunementTimerRemaining;
+
+ ///
+ /// Gets the time remaining for the current attunement.
+ ///
+ public ushort AttunementTimerRemaining => this.Struct->AttunementTimer;
///
/// Gets the summon that will return after the current summon expires.
- /// This maps to the sheet.
+ /// This maps to the sheet.
///
public SummonPet ReturnSummon => (SummonPet)this.Struct->ReturnSummon;
///
/// Gets the summon glam for the .
- /// This maps to the sheet.
+ /// This maps to the sheet.
///
public PetGlam ReturnSummonGlam => (PetGlam)this.Struct->ReturnSummonGlam;
///
- /// Gets the amount of aspected Attunment remaining.
+ /// Gets the amount of aspected Attunement remaining.
///
+ ///
+ /// As of 7.01, this should be treated as a bit field.
+ /// Use and instead.
+ ///
public byte Attunement => this.Struct->Attunement;
+ ///
+ /// Gets the count of attunement cost resource available.
+ ///
+ public byte AttunementCount => this.Struct->AttunementCount;
+
+ ///
+ /// Gets the type of attunement available.
+ /// Use the summon attuned accessors instead.
+ ///
+ public SummonAttunement AttunementType => (SummonAttunement)this.Struct->AttunementType;
+
///
/// Gets the current aether flags.
/// Use the summon accessors instead.
@@ -84,19 +105,19 @@ public unsafe class SMNGauge : JobGaugeBase
/// Gets a value indicating whether if Ifrit is currently attuned.
///
/// true or false.
- public bool IsIfritAttuned => this.AetherFlags.HasFlag(AetherFlags.IfritAttuned) && !this.AetherFlags.HasFlag(AetherFlags.GarudaAttuned);
+ public bool IsIfritAttuned => this.AttunementType == SummonAttunement.Ifrit;
///
/// Gets a value indicating whether if Titan is currently attuned.
///
/// true or false.
- public bool IsTitanAttuned => this.AetherFlags.HasFlag(AetherFlags.TitanAttuned) && !this.AetherFlags.HasFlag(AetherFlags.GarudaAttuned);
+ public bool IsTitanAttuned => this.AttunementType == SummonAttunement.Titan;
///
/// Gets a value indicating whether if Garuda is currently attuned.
///
/// true or false.
- public bool IsGarudaAttuned => this.AetherFlags.HasFlag(AetherFlags.GarudaAttuned);
+ public bool IsGarudaAttuned => this.AttunementType == SummonAttunement.Garuda;
///
/// Gets a value indicating whether there are any Aetherflow stacks available.
diff --git a/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs b/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
index 9c10a84ab..ff356989a 100644
--- a/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
+++ b/Dalamud/Game/ClientState/Objects/Enums/BattleNpcSubKind.cs
@@ -27,7 +27,12 @@ public enum BattleNpcSubKind : byte
Chocobo = 3,
///
- /// BattleNpc representing a standard enemy.
+ /// BattleNpc representing a standard enemy. This includes allies (overworld guards and allies in single-player duties).
///
Enemy = 5,
+
+ ///
+ /// BattleNpc representing an NPC party member (from Duty Support, Trust, or Grand Company Command Mission).
+ ///
+ NpcPartyMember = 9,
}
diff --git a/Dalamud/Game/ClientState/Objects/ObjectTable.cs b/Dalamud/Game/ClientState/Objects/ObjectTable.cs
index 50f4e81ce..f97385fce 100644
--- a/Dalamud/Game/ClientState/Objects/ObjectTable.cs
+++ b/Dalamud/Game/ClientState/Objects/ObjectTable.cs
@@ -7,15 +7,15 @@ using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
-using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+using FFXIVClientStructs.Interop;
+
using Microsoft.Extensions.ObjectPool;
-using Serilog;
-
using CSGameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
+using CSGameObjectManager = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObjectManager;
namespace Dalamud.Game.ClientState.Objects;
@@ -29,62 +29,58 @@ namespace Dalamud.Game.ClientState.Objects;
#pragma warning restore SA1015
internal sealed partial class ObjectTable : IServiceType, IObjectTable
{
- private const int ObjectTableLength = 599;
+ private static int objectTableLength;
private readonly ClientState clientState;
- private readonly CachedEntry[] cachedObjectTable = new CachedEntry[ObjectTableLength];
-
- private readonly ObjectPool multiThreadedEnumerators =
- new DefaultObjectPoolProvider().Create();
+ private readonly CachedEntry[] cachedObjectTable;
private readonly Enumerator?[] frameworkThreadEnumerators = new Enumerator?[4];
- private long nextMultithreadedUsageWarnTime;
-
[ServiceManager.ServiceConstructor]
private unsafe ObjectTable(ClientState clientState)
{
this.clientState = clientState;
- var nativeObjectTableAddress = (CSGameObject**)this.clientState.AddressResolver.ObjectTable;
+ var nativeObjectTable = CSGameObjectManager.Instance()->Objects.IndexSorted;
+ objectTableLength = nativeObjectTable.Length;
+
+ this.cachedObjectTable = new CachedEntry[objectTableLength];
for (var i = 0; i < this.cachedObjectTable.Length; i++)
- this.cachedObjectTable[i] = new(nativeObjectTableAddress, i);
+ this.cachedObjectTable[i] = new(nativeObjectTable.GetPointer(i));
for (var i = 0; i < this.frameworkThreadEnumerators.Length; i++)
this.frameworkThreadEnumerators[i] = new(this, i);
-
- Log.Verbose($"Object table address {Util.DescribeAddress(this.clientState.AddressResolver.ObjectTable)}");
}
///
- public nint Address
+ public unsafe nint Address
{
get
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
- return this.clientState.AddressResolver.ObjectTable;
+ return (nint)(&CSGameObjectManager.Instance()->Objects);
}
}
///
- public int Length => ObjectTableLength;
+ public int Length => objectTableLength;
///
public IGameObject? this[int index]
{
get
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
- return index is >= ObjectTableLength or < 0 ? null : this.cachedObjectTable[index].Update();
+ return (index >= objectTableLength || index < 0) ? null : this.cachedObjectTable[index].Update();
}
}
///
public IGameObject? SearchById(ulong gameObjectId)
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
if (gameObjectId is 0)
return null;
@@ -101,7 +97,7 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
///
public IGameObject? SearchByEntityId(uint entityId)
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
if (entityId is 0 or 0xE0000000)
return null;
@@ -118,15 +114,15 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
///
public unsafe nint GetObjectAddress(int index)
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
- return index is < 0 or >= ObjectTableLength ? nint.Zero : (nint)this.cachedObjectTable[index].Address;
+ return (index >= objectTableLength || index < 0) ? nint.Zero : (nint)this.cachedObjectTable[index].Address;
}
///
public unsafe IGameObject? CreateObjectReference(nint address)
{
- _ = this.WarnMultithreadedUsage();
+ ThreadSafety.AssertMainThread();
if (this.clientState.LocalContentId == 0)
return null;
@@ -150,55 +146,22 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
};
}
- [Api10ToDo("Use ThreadSafety.AssertMainThread() instead of this.")]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private bool WarnMultithreadedUsage()
- {
- if (ThreadSafety.IsMainThread)
- return false;
-
- var n = Environment.TickCount64;
- if (this.nextMultithreadedUsageWarnTime < n)
- {
- this.nextMultithreadedUsageWarnTime = n + 30000;
-
- Log.Warning(
- "{plugin} is accessing {objectTable} outside the main thread. This is deprecated.",
- Service.Get().FindCallingPlugin()?.Name ?? "",
- nameof(ObjectTable));
- }
-
- return true;
- }
-
/// Stores an object table entry, with preallocated concrete types.
- internal readonly unsafe struct CachedEntry
+ /// Initializes a new instance of the struct.
+ /// A pointer to the object table entry this entry should be pointing to.
+ internal readonly unsafe struct CachedEntry(Pointer* gameObjectPtr)
{
- private readonly CSGameObject** gameObjectPtrPtr;
- private readonly PlayerCharacter playerCharacter;
- private readonly BattleNpc battleNpc;
- private readonly Npc npc;
- private readonly EventObj eventObj;
- private readonly GameObject gameObject;
-
- /// Initializes a new instance of the struct.
- /// The object table that this entry should be pointing to.
- /// The slot index inside the table.
- public CachedEntry(CSGameObject** ownerTable, int slot)
- {
- this.gameObjectPtrPtr = ownerTable + slot;
- this.playerCharacter = new(nint.Zero);
- this.battleNpc = new(nint.Zero);
- this.npc = new(nint.Zero);
- this.eventObj = new(nint.Zero);
- this.gameObject = new(nint.Zero);
- }
+ private readonly PlayerCharacter playerCharacter = new(nint.Zero);
+ private readonly BattleNpc battleNpc = new(nint.Zero);
+ private readonly Npc npc = new(nint.Zero);
+ private readonly EventObj eventObj = new(nint.Zero);
+ private readonly GameObject gameObject = new(nint.Zero);
/// Gets the address of the underlying native object. May be null.
public CSGameObject* Address
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => *this.gameObjectPtrPtr;
+ get => gameObjectPtr->Value;
}
/// Updates and gets the wrapped game object pointed by this struct.
@@ -235,14 +198,7 @@ internal sealed partial class ObjectTable
///
public IEnumerator GetEnumerator()
{
- // If something's trying to enumerate outside the framework thread, we use the ObjectPool.
- if (this.WarnMultithreadedUsage())
- {
- // let's not
- var e = this.multiThreadedEnumerators.Get();
- e.InitializeForPooledObjects(this);
- return e;
- }
+ ThreadSafety.AssertMainThread();
// If we're on the framework thread, see if there's an already allocated enumerator available for use.
foreach (ref var x in this.frameworkThreadEnumerators.AsSpan())
@@ -263,32 +219,23 @@ internal sealed partial class ObjectTable
///
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
- private sealed class Enumerator : IEnumerator, IResettable
+ private sealed class Enumerator(ObjectTable owner, int slotId) : IEnumerator, IResettable
{
- private readonly int slotId;
- private ObjectTable? owner;
+ private ObjectTable? owner = owner;
private int index = -1;
- public Enumerator() => this.slotId = -1;
-
- public Enumerator(ObjectTable owner, int slotId)
- {
- this.owner = owner;
- this.slotId = slotId;
- }
-
public IGameObject Current { get; private set; } = null!;
object IEnumerator.Current => this.Current;
public bool MoveNext()
{
- if (this.index == ObjectTableLength)
+ if (this.index == objectTableLength)
return false;
var cache = this.owner!.cachedObjectTable.AsSpan();
- for (this.index++; this.index < ObjectTableLength; this.index++)
+ for (this.index++; this.index < objectTableLength; this.index++)
{
if (cache[this.index].Update() is { } ao)
{
@@ -300,8 +247,6 @@ internal sealed partial class ObjectTable
return false;
}
- public void InitializeForPooledObjects(ObjectTable ot) => this.owner = ot;
-
public void Reset() => this.index = -1;
public void Dispose()
@@ -309,10 +254,8 @@ internal sealed partial class ObjectTable
if (this.owner is not { } o)
return;
- if (this.slotId == -1)
- o.multiThreadedEnumerators.Return(this);
- else
- o.frameworkThreadEnumerators[this.slotId] = this;
+ if (slotId != -1)
+ o.frameworkThreadEnumerators[slotId] = this;
}
public bool TryReset()
diff --git a/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs b/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs
index 87fbf39c3..2fd723071 100644
--- a/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs
+++ b/Dalamud/Game/ClientState/Objects/SubKinds/PlayerCharacter.cs
@@ -1,12 +1,8 @@
-using System.Numerics;
-
-using Dalamud.Game.ClientState.Objects.Enums;
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.ClientState.Resolvers;
-using Dalamud.Game.ClientState.Statuses;
-using Dalamud.Game.Text.SeStringHandling;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.ClientState.Objects.SubKinds;
@@ -16,14 +12,14 @@ namespace Dalamud.Game.ClientState.Objects.SubKinds;
public interface IPlayerCharacter : IBattleChara
{
///
- /// Gets the current world of the character.
+ /// Gets the current world of the character.
///
- ExcelResolver CurrentWorld { get; }
+ RowRef CurrentWorld { get; }
///
- /// Gets the home world of the character.
+ /// Gets the home world of the character.
///
- ExcelResolver HomeWorld { get; }
+ RowRef HomeWorld { get; }
}
///
@@ -42,10 +38,10 @@ internal unsafe class PlayerCharacter : BattleChara, IPlayerCharacter
}
///
- public ExcelResolver CurrentWorld => new(this.Struct->CurrentWorld);
+ public RowRef CurrentWorld => LuminaUtils.CreateRef(this.Struct->CurrentWorld);
///
- public ExcelResolver HomeWorld => new(this.Struct->HomeWorld);
+ public RowRef HomeWorld => LuminaUtils.CreateRef(this.Struct->HomeWorld);
///
/// Gets the target actor ID of the PlayerCharacter.
diff --git a/Dalamud/Game/ClientState/Objects/TargetManager.cs b/Dalamud/Game/ClientState/Objects/TargetManager.cs
index 5d7ae8945..f81154693 100644
--- a/Dalamud/Game/ClientState/Objects/TargetManager.cs
+++ b/Dalamud/Game/ClientState/Objects/TargetManager.cs
@@ -20,7 +20,7 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
{
[ServiceManager.ServiceDependency]
private readonly ObjectTable objectTable = Service.Get();
-
+
[ServiceManager.ServiceConstructor]
private TargetManager()
{
@@ -29,8 +29,8 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
///
public IGameObject? Target
{
- get => this.objectTable.CreateObjectReference((IntPtr)Struct->Target);
- set => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
+ get => this.objectTable.CreateObjectReference((IntPtr)Struct->GetHardTarget());
+ set => Struct->SetHardTarget((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address);
}
///
@@ -57,8 +57,8 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
///
public IGameObject? SoftTarget
{
- get => this.objectTable.CreateObjectReference((IntPtr)Struct->SoftTarget);
- set => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
+ get => this.objectTable.CreateObjectReference((IntPtr)Struct->GetSoftTarget());
+ set => Struct->SetSoftTarget((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address);
}
///
@@ -67,7 +67,7 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
get => this.objectTable.CreateObjectReference((IntPtr)Struct->GPoseTarget);
set => Struct->GPoseTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
}
-
+
///
public IGameObject? MouseOverNameplateTarget
{
diff --git a/Dalamud/Game/ClientState/Objects/Types/Character.cs b/Dalamud/Game/ClientState/Objects/Types/Character.cs
index 72f6a9950..a91ecc230 100644
--- a/Dalamud/Game/ClientState/Objects/Types/Character.cs
+++ b/Dalamud/Game/ClientState/Objects/Types/Character.cs
@@ -1,10 +1,12 @@
using System.Runtime.CompilerServices;
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects.Enums;
-using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Memory;
-using Lumina.Excel.GeneratedSheets;
+
+using Lumina.Excel;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.ClientState.Objects.Types;
@@ -61,7 +63,7 @@ public interface ICharacter : IGameObject
///
/// Gets the ClassJob of this Chara.
///
- public ExcelResolver ClassJob { get; }
+ public RowRef ClassJob { get; }
///
/// Gets the level of this Chara.
@@ -87,7 +89,7 @@ public interface ICharacter : IGameObject
///
/// Gets the current online status of the character.
///
- public ExcelResolver OnlineStatus { get; }
+ public RowRef OnlineStatus { get; }
///
/// Gets the status flags.
@@ -97,14 +99,14 @@ public interface ICharacter : IGameObject
///
/// Gets the current mount for this character. Will be null if the character doesn't have a mount.
///
- public ExcelResolver? CurrentMount { get; }
+ public RowRef? CurrentMount { get; }
///
/// Gets the current minion summoned for this character. Will be null if the character doesn't have a minion.
/// This method *will* return information about a spawned (but invisible) minion, e.g. if the character is riding a
/// mount.
///
- public ExcelResolver? CurrentMinion { get; }
+ public RowRef? CurrentMinion { get; }
}
///
@@ -150,7 +152,7 @@ internal unsafe class Character : GameObject, ICharacter
public byte ShieldPercentage => this.Struct->CharacterData.ShieldValue;
///
- public ExcelResolver ClassJob => new(this.Struct->CharacterData.ClassJob);
+ public RowRef ClassJob => LuminaUtils.CreateRef(this.Struct->CharacterData.ClassJob);
///
public byte Level => this.Struct->CharacterData.Level;
@@ -159,7 +161,7 @@ internal unsafe class Character : GameObject, ICharacter
public byte[] Customize => this.Struct->DrawData.CustomizeData.Data.ToArray();
///
- public SeString CompanyTag => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->FreeCompanyTag[0]), 6);
+ public SeString CompanyTag => SeString.Parse(this.Struct->FreeCompanyTag);
///
/// Gets the target object ID of the character.
@@ -170,7 +172,7 @@ internal unsafe class Character : GameObject, ICharacter
public uint NameId => this.Struct->NameId;
///
- public ExcelResolver OnlineStatus => new(this.Struct->CharacterData.OnlineStatus);
+ public RowRef OnlineStatus => LuminaUtils.CreateRef(this.Struct->CharacterData.OnlineStatus);
///
/// Gets the status flags.
@@ -186,28 +188,28 @@ internal unsafe class Character : GameObject, ICharacter
(this.Struct->IsCasting ? StatusFlags.IsCasting : StatusFlags.None);
///
- public ExcelResolver? CurrentMount
+ public RowRef? CurrentMount
{
get
{
if (this.Struct->IsNotMounted()) return null; // just for safety.
var mountId = this.Struct->Mount.MountId;
- return mountId == 0 ? null : new ExcelResolver(mountId);
+ return mountId == 0 ? null : LuminaUtils.CreateRef(mountId);
}
}
///
- public ExcelResolver? CurrentMinion
+ public RowRef? CurrentMinion
{
get
{
if (this.Struct->CompanionObject != null)
- return new ExcelResolver(this.Struct->CompanionObject->BaseId);
+ return LuminaUtils.CreateRef(this.Struct->CompanionObject->BaseId);
// this is only present if a minion is summoned but hidden (e.g. the player's on a mount).
var hiddenCompanionId = this.Struct->CompanionData.CompanionId;
- return hiddenCompanionId == 0 ? null : new ExcelResolver(hiddenCompanionId);
+ return hiddenCompanionId == 0 ? null : LuminaUtils.CreateRef(hiddenCompanionId);
}
}
diff --git a/Dalamud/Game/ClientState/Objects/Types/GameObject.cs b/Dalamud/Game/ClientState/Objects/Types/GameObject.cs
index f9fd87bf4..4209100f0 100644
--- a/Dalamud/Game/ClientState/Objects/Types/GameObject.cs
+++ b/Dalamud/Game/ClientState/Objects/Types/GameObject.cs
@@ -197,7 +197,7 @@ internal partial class GameObject
internal unsafe partial class GameObject : IGameObject
{
///
- public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->Name[0]), 64);
+ public SeString Name => SeString.Parse(this.Struct->Name);
///
public ulong GameObjectId => this.Struct->GetGameObjectId();
diff --git a/Dalamud/Game/ClientState/Party/PartyList.cs b/Dalamud/Game/ClientState/Party/PartyList.cs
index 4fbd8fdfb..a016a8211 100644
--- a/Dalamud/Game/ClientState/Party/PartyList.cs
+++ b/Dalamud/Game/ClientState/Party/PartyList.cs
@@ -6,9 +6,8 @@ using System.Runtime.InteropServices;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
-using Dalamud.Utility;
-using Serilog;
+using CSGroupManager = FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager;
namespace Dalamud.Game.ClientState.Party;
@@ -28,14 +27,9 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
[ServiceManager.ServiceDependency]
private readonly ClientState clientState = Service.Get();
- private readonly ClientStateAddressResolver address;
-
[ServiceManager.ServiceConstructor]
private PartyList()
{
- this.address = this.clientState.AddressResolver;
-
- Log.Verbose($"Group manager address {Util.DescribeAddress(this.address.GroupManager)}");
}
///
@@ -48,7 +42,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
public bool IsAlliance => this.GroupManagerStruct->MainGroup.AllianceFlags > 0;
///
- public IntPtr GroupManagerAddress => this.address.GroupManager;
+ public unsafe IntPtr GroupManagerAddress => (nint)CSGroupManager.Instance();
///
public IntPtr GroupListAddress => (IntPtr)Unsafe.AsPointer(ref GroupManagerStruct->MainGroup.PartyMembers[0]);
diff --git a/Dalamud/Game/ClientState/Party/PartyMember.cs b/Dalamud/Game/ClientState/Party/PartyMember.cs
index 34cd31dec..cf620a7ef 100644
--- a/Dalamud/Game/ClientState/Party/PartyMember.cs
+++ b/Dalamud/Game/ClientState/Party/PartyMember.cs
@@ -1,13 +1,15 @@
using System.Numerics;
using System.Runtime.CompilerServices;
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.ClientState.Statuses;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Memory;
+using Lumina.Excel;
+
namespace Dalamud.Game.ClientState.Party;
///
@@ -71,12 +73,12 @@ public interface IPartyMember
///
/// Gets the territory this party member is located in.
///
- ExcelResolver Territory { get; }
+ RowRef Territory { get; }
///
/// Gets the World this party member resides in.
///
- ExcelResolver World { get; }
+ RowRef World { get; }
///
/// Gets the displayname of this party member.
@@ -91,7 +93,7 @@ public interface IPartyMember
///
/// Gets the classjob of this party member.
///
- ExcelResolver ClassJob { get; }
+ RowRef ClassJob { get; }
///
/// Gets the level of this party member.
@@ -169,17 +171,17 @@ internal unsafe class PartyMember : IPartyMember
///
/// Gets the territory this party member is located in.
///
- public ExcelResolver Territory => new(this.Struct->TerritoryType);
+ public RowRef Territory => LuminaUtils.CreateRef(this.Struct->TerritoryType);
///
/// Gets the World this party member resides in.
///
- public ExcelResolver World => new(this.Struct->HomeWorld);
+ public RowRef World => LuminaUtils.CreateRef(this.Struct->HomeWorld);
///
/// Gets the displayname of this party member.
///
- public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref Struct->Name[0]), 0x40);
+ public SeString Name => SeString.Parse(this.Struct->Name);
///
/// Gets the sex of this party member.
@@ -189,7 +191,7 @@ internal unsafe class PartyMember : IPartyMember
///
/// Gets the classjob of this party member.
///
- public ExcelResolver ClassJob => new(this.Struct->ClassJob);
+ public RowRef ClassJob => LuminaUtils.CreateRef(this.Struct->ClassJob);
///
/// Gets the level of this party member.
diff --git a/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs b/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs
deleted file mode 100644
index 04003d9aa..000000000
--- a/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using Dalamud.Data;
-
-using Lumina.Excel;
-
-namespace Dalamud.Game.ClientState.Resolvers;
-
-///
-/// This object resolves a rowID within an Excel sheet.
-///
-/// The type of Lumina sheet to resolve.
-public class ExcelResolver where T : ExcelRow
-{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The ID of the classJob.
- internal ExcelResolver(uint id)
- {
- this.Id = id;
- }
-
- ///
- /// Gets the ID to be resolved.
- ///
- public uint Id { get; }
-
- ///
- /// Gets GameData linked to this excel row.
- ///
- public T? GameData => Service.Get().GetExcelSheet()?.GetRow(this.Id);
-
- ///
- /// Gets GameData linked to this excel row with the specified language.
- ///
- /// The language.
- /// The ExcelRow in the specified language.
- public T? GetWithLanguage(ClientLanguage language) => Service.Get().GetExcelSheet(language)?.GetRow(this.Id);
-}
diff --git a/Dalamud/Game/ClientState/Statuses/Status.cs b/Dalamud/Game/ClientState/Statuses/Status.cs
index ad1a24b6a..c3493ce55 100644
--- a/Dalamud/Game/ClientState/Statuses/Status.cs
+++ b/Dalamud/Game/ClientState/Statuses/Status.cs
@@ -1,6 +1,8 @@
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.ClientState.Resolvers;
+
+using Lumina.Excel;
namespace Dalamud.Game.ClientState.Statuses;
@@ -31,7 +33,7 @@ public unsafe class Status
///
/// Gets the GameData associated with this status.
///
- public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver(this.Struct->StatusId).GameData;
+ public RowRef GameData => LuminaUtils.CreateRef(this.Struct->StatusId);
///
/// Gets the parameter value of the status.
@@ -40,8 +42,10 @@ public unsafe class Status
///
/// Gets the stack count of this status.
+ /// Only valid if this is a non-food status.
///
- public byte StackCount => this.Struct->StackCount;
+ [Obsolete($"Replaced with {nameof(Param)}", true)]
+ public byte StackCount => (byte)this.Struct->Param;
///
/// Gets the time remaining of this status.
diff --git a/Dalamud/Game/Command/CommandInfo.cs b/Dalamud/Game/Command/CommandInfo.cs
index 8aed817d0..16462a831 100644
--- a/Dalamud/Game/Command/CommandInfo.cs
+++ b/Dalamud/Game/Command/CommandInfo.cs
@@ -11,7 +11,7 @@ public interface IReadOnlyCommandInfo
/// The command itself.
/// The arguments supplied to the command, ready for parsing.
public delegate void HandlerDelegate(string command, string arguments);
-
+
///
/// Gets a which will be called when the command is dispatched.
///
@@ -26,6 +26,11 @@ public interface IReadOnlyCommandInfo
/// Gets a value indicating whether if this command should be shown in the help output.
///
bool ShowInHelp { get; }
+
+ ///
+ /// Gets the display order of this command. Defaults to alphabetical ordering.
+ ///
+ int DisplayOrder { get; }
}
///
@@ -51,4 +56,7 @@ public sealed class CommandInfo : IReadOnlyCommandInfo
///
public bool ShowInHelp { get; set; } = true;
+
+ ///
+ public int DisplayOrder { get; set; } = -1;
}
diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs
index aa6798171..fdaa5833b 100644
--- a/Dalamud/Game/Command/CommandManager.cs
+++ b/Dalamud/Game/Command/CommandManager.cs
@@ -2,17 +2,19 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
-using System.Text.RegularExpressions;
using Dalamud.Console;
-using Dalamud.Game.Gui;
-using Dalamud.Game.Text;
-using Dalamud.Game.Text.SeStringHandling;
+using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services;
+using Dalamud.Utility;
+
+using FFXIVClientStructs.FFXIV.Client.System.String;
+using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Component.Shell;
namespace Dalamud.Game.Command;
@@ -20,38 +22,26 @@ namespace Dalamud.Game.Command;
/// This class manages registered in-game slash commands.
///
[ServiceManager.EarlyLoadedService]
-internal sealed class CommandManager : IInternalDisposableService, ICommandManager
+internal sealed unsafe class CommandManager : IInternalDisposableService, ICommandManager
{
private static readonly ModuleLog Log = new("Command");
private readonly ConcurrentDictionary commandMap = new();
private readonly ConcurrentDictionary<(string, IReadOnlyCommandInfo), string> commandAssemblyNameMap = new();
- private readonly Regex commandRegexEn = new(@"^The command (?.+) does not exist\.$", RegexOptions.Compiled);
- private readonly Regex commandRegexJp = new(@"^そのコマンドはありません。: (?.+)$", RegexOptions.Compiled);
- private readonly Regex commandRegexDe = new(@"^„(?.+)“ existiert nicht als Textkommando\.$", RegexOptions.Compiled);
- private readonly Regex commandRegexFr = new(@"^La commande texte “(?.+)” n'existe pas\.$", RegexOptions.Compiled);
- private readonly Regex commandRegexCn = new(@"^^(“|「)(?.+)(”|」)(出现问题:该命令不存在|出現問題:該命令不存在)。$", RegexOptions.Compiled);
- private readonly Regex currentLangCommandRegex;
- [ServiceManager.ServiceDependency]
- private readonly ChatGui chatGui = Service.Get();
-
+ private readonly Hook? tryInvokeDebugCommandHook;
+
[ServiceManager.ServiceDependency]
private readonly ConsoleManager console = Service.Get();
[ServiceManager.ServiceConstructor]
private CommandManager(Dalamud dalamud)
{
- this.currentLangCommandRegex = (ClientLanguage)dalamud.StartInfo.Language switch
- {
- ClientLanguage.Japanese => this.commandRegexJp,
- ClientLanguage.English => this.commandRegexEn,
- ClientLanguage.German => this.commandRegexDe,
- ClientLanguage.French => this.commandRegexFr,
- _ => this.commandRegexEn,
- };
+ this.tryInvokeDebugCommandHook = Hook.FromAddress(
+ (nint)ShellCommands.MemberFunctionPointers.TryInvokeDebugCommand,
+ this.OnTryInvokeDebugCommand);
+ this.tryInvokeDebugCommandHook.Enable();
- this.chatGui.CheckMessageHandled += this.OnCheckMessageHandled;
this.console.Invoke += this.ConsoleOnInvoke;
}
@@ -113,7 +103,7 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
Log.Error(ex, "Error while dispatching command {CommandName} (Argument: {Argument})", command, argument);
}
}
-
+
///
/// Add a command handler, which you can use to add your own custom commands to the in-game chat.
///
@@ -131,7 +121,7 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
Log.Error("Command {CommandName} is already registered", command);
return false;
}
-
+
if (!this.commandAssemblyNameMap.TryAdd((command, info), loaderAssemblyName))
{
this.commandMap.Remove(command, out _);
@@ -160,6 +150,11 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
///
public bool RemoveHandler(string command)
{
+ if (this.commandAssemblyNameMap.FindFirst(c => c.Key.Item1 == command, out var assemblyKeyValuePair))
+ {
+ this.commandAssemblyNameMap.TryRemove(assemblyKeyValuePair.Key, out _);
+ }
+
return this.commandMap.Remove(command, out _);
}
@@ -184,7 +179,8 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
///
/// The name of the assembly.
/// A list of commands and their associated activation string.
- public List> GetHandlersByAssemblyName(string assemblyName)
+ public List> GetHandlersByAssemblyName(
+ string assemblyName)
{
return this.commandAssemblyNameMap.Where(c => c.Value == assemblyName).ToList();
}
@@ -193,37 +189,20 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
void IInternalDisposableService.DisposeService()
{
this.console.Invoke -= this.ConsoleOnInvoke;
- this.chatGui.CheckMessageHandled -= this.OnCheckMessageHandled;
+ this.tryInvokeDebugCommandHook?.Dispose();
}
-
+
private bool ConsoleOnInvoke(string arg)
{
return arg.StartsWith('/') && this.ProcessCommand(arg);
}
- private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
+ private int OnTryInvokeDebugCommand(ShellCommands* self, Utf8String* command, UIModule* uiModule)
{
- if (type == XivChatType.ErrorMessage && timestamp == 0)
- {
- var cmdMatch = this.currentLangCommandRegex.Match(message.TextValue).Groups["command"];
- if (cmdMatch.Success)
- {
- // Yes, it's a chat command.
- var command = cmdMatch.Value;
- if (this.ProcessCommand(command)) isHandled = true;
- }
- else
- {
- // Always match for china, since they patch in language files without changing the ClientLanguage.
- cmdMatch = this.commandRegexCn.Match(message.TextValue).Groups["command"];
- if (cmdMatch.Success)
- {
- // Yes, it's a Chinese fallback chat command.
- var command = cmdMatch.Value;
- if (this.ProcessCommand(command)) isHandled = true;
- }
- }
- }
+ var result = this.tryInvokeDebugCommandHook!.OriginalDisposeSafe(self, command, uiModule);
+ if (result != -1) return result;
+
+ return this.ProcessCommand(command->ToString()) ? 0 : result;
}
}
@@ -238,7 +217,7 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
internal class CommandManagerPluginScoped : IInternalDisposableService, ICommandManager
{
private static readonly ModuleLog Log = new("Command");
-
+
[ServiceManager.ServiceDependency]
private readonly CommandManager commandManagerService = Service.Get();
@@ -253,10 +232,10 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
{
this.pluginInfo = localPlugin;
}
-
+
///
public ReadOnlyDictionary Commands => this.commandManagerService.Commands;
-
+
///
void IInternalDisposableService.DisposeService()
{
@@ -264,7 +243,7 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
{
this.commandManagerService.RemoveHandler(command);
}
-
+
this.pluginRegisteredCommands.Clear();
}
@@ -275,7 +254,7 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
///
public void DispatchCommand(string command, string argument, IReadOnlyCommandInfo info)
=> this.commandManagerService.DispatchCommand(command, argument, info);
-
+
///
public bool AddHandler(string command, CommandInfo info)
{
@@ -294,7 +273,7 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
return false;
}
-
+
///
public bool RemoveHandler(string command)
{
diff --git a/Dalamud/Game/Config/GameConfig.cs b/Dalamud/Game/Config/GameConfig.cs
index bfb58fd3c..9579d84bc 100644
--- a/Dalamud/Game/Config/GameConfig.cs
+++ b/Dalamud/Game/Config/GameConfig.cs
@@ -121,7 +121,10 @@ internal sealed class GameConfig : IInternalDisposableService, IGameConfig
///
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties) => this.System.TryGetProperties(option.GetName(), out properties);
-
+
+ ///
+ public bool TryGet(SystemConfigOption option, out PadButtonValue value) => this.System.TryGetStringAsEnum(option.GetName(), out value);
+
///
public bool TryGet(UiConfigOption option, out bool value) => this.UiConfig.TryGet(option.GetName(), out value);
@@ -346,7 +349,11 @@ internal class GameConfigPluginScoped : IInternalDisposableService, IGameConfig
///
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties)
=> this.gameConfigService.TryGet(option, out properties);
-
+
+ ///
+ public bool TryGet(SystemConfigOption option, out PadButtonValue value)
+ => this.gameConfigService.TryGet(option, out value);
+
///
public bool TryGet(UiConfigOption option, out bool value)
=> this.gameConfigService.TryGet(option, out value);
diff --git a/Dalamud/Game/Config/GameConfigAddressResolver.cs b/Dalamud/Game/Config/GameConfigAddressResolver.cs
index c171932a9..2491c4033 100644
--- a/Dalamud/Game/Config/GameConfigAddressResolver.cs
+++ b/Dalamud/Game/Config/GameConfigAddressResolver.cs
@@ -13,6 +13,6 @@ internal sealed class GameConfigAddressResolver : BaseAddressResolver
///
protected override void Setup64Bit(ISigScanner scanner)
{
- this.ConfigChangeAddress = scanner.ScanText("E8 ?? ?? ?? ?? 48 8B 3F 49 3B 3E");
+ this.ConfigChangeAddress = scanner.ScanText("E8 ?? ?? ?? ?? 48 8B 3F 49 3B 3E"); // unnamed in CS
}
}
diff --git a/Dalamud/Game/Config/GameConfigSection.cs b/Dalamud/Game/Config/GameConfigSection.cs
index 31e4a0b3f..8ebab8a60 100644
--- a/Dalamud/Game/Config/GameConfigSection.cs
+++ b/Dalamud/Game/Config/GameConfigSection.cs
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics;
+using System.Text;
using Dalamud.Memory;
using Dalamud.Utility;
@@ -51,7 +52,7 @@ public class GameConfigSection
///
/// Event which is fired when a game config option is changed within the section.
///
- internal event EventHandler? Changed;
+ internal event EventHandler? Changed;
///
/// Gets the number of config entries contained within the section.
@@ -357,6 +358,40 @@ public class GameConfigSection
return value;
}
+ /// Attempts to get a string config value as an enum value.
+ /// Name of the config option.
+ /// The returned value of the config option.
+ /// Type of the enum. Name of each enum fields are compared against.
+ /// A value representing the success.
+ public unsafe bool TryGetStringAsEnum(string name, out T value) where T : struct, Enum
+ {
+ value = default;
+ if (!this.TryGetIndex(name, out var index))
+ {
+ return false;
+ }
+
+ if (!this.TryGetEntry(index, out var entry))
+ {
+ return false;
+ }
+
+ if (entry->Type != 4)
+ {
+ return false;
+ }
+
+ if (entry->Value.String == null)
+ {
+ return false;
+ }
+
+ var n8 = entry->Value.String->AsSpan();
+ Span n16 = stackalloc char[Encoding.UTF8.GetCharCount(n8)];
+ Encoding.UTF8.GetChars(n8, n16);
+ return Enum.TryParse(n16, out value);
+ }
+
///
/// Set a string config option.
/// Note: Not all config options will be be immediately reflected in the game.
@@ -491,8 +526,8 @@ public class GameConfigSection
{
if (!this.enumMap.TryGetValue(entry->Index, out var enumObject))
{
- if (entry->Name == null) return null;
- var name = MemoryHelper.ReadStringNullTerminated(new IntPtr(entry->Name));
+ if (entry->Name.Value == null) return null;
+ var name = entry->Name.ToString();
if (Enum.TryParse(typeof(TEnum), name, out enumObject))
{
this.enumMap.TryAdd(entry->Index, enumObject);
@@ -509,7 +544,7 @@ public class GameConfigSection
this.Changed?.InvokeSafely(this, eventArgs);
return eventArgs;
}
-
+
private unsafe bool TryGetIndex(string name, out uint index)
{
if (this.indexMap.TryGetValue(name, out index))
@@ -521,12 +556,12 @@ public class GameConfigSection
var e = configBase->ConfigEntry;
for (var i = 0U; i < configBase->ConfigCount; i++, e++)
{
- if (e->Name == null)
+ if (e->Name.Value == null)
{
continue;
}
- var eName = MemoryHelper.ReadStringNullTerminated(new IntPtr(e->Name));
+ var eName = e->Name.ToString();
if (eName.Equals(name))
{
this.indexMap.TryAdd(name, i);
diff --git a/Dalamud/Game/Config/PadButtonValue.cs b/Dalamud/Game/Config/PadButtonValue.cs
new file mode 100644
index 000000000..bd6da48bb
--- /dev/null
+++ b/Dalamud/Game/Config/PadButtonValue.cs
@@ -0,0 +1,85 @@
+namespace Dalamud.Game.Config;
+
+// ReSharper disable InconsistentNaming
+// ReSharper disable IdentifierTypo
+// ReSharper disable CommentTypo
+
+/// Valid values for PadButton options under .
+/// Names are the valid part. Enum values are exclusively for use with current Dalamud version.
+public enum PadButtonValue
+{
+ /// Auto-run.
+ Autorun_Support,
+
+ /// Change Hotbar Set.
+ Hotbar_Set_Change,
+
+ /// Highlight Left Hotbar.
+ XHB_Left_Start,
+
+ /// Highlight Right Hotbar.
+ XHB_Right_Start,
+
+ /// Not directly referenced by Gamepad button customization window.
+ Cursor_Operation,
+
+ /// Draw Weapon/Lock On.
+ Lockon_and_Sword,
+
+ /// Sit/Lock On.
+ Lockon_and_Sit,
+
+ /// Change Camera.
+ Camera_Modechange,
+
+ /// Reset Camera Position.
+ Camera_Reset,
+
+ /// Draw/Sheathe Weapon.
+ Drawn_Sword,
+
+ /// Lock On.
+ Camera_Lockononly,
+
+ /// Face Target.
+ FaceTarget,
+
+ /// Assist Target.
+ AssistTarget,
+
+ /// Face Camera.
+ LookCamera,
+
+ /// Execute Macro #98 (Exclusive).
+ Macro98,
+
+ /// Execute Macro #99 (Exclusive).
+ Macro99,
+
+ /// Not Assigned.
+ Notset,
+
+ /// Jump/Cancel Casting.
+ Jump,
+
+ /// Select Target/Confirm.
+ Accept,
+
+ /// Cancel.
+ Cancel,
+
+ /// Open Map/Subcommands.
+ Map_Sub,
+
+ /// Open Main Menu.
+ MainCommand,
+
+ /// Select HUD.
+ HUD_Select,
+
+ /// Move Character.
+ Move_Operation,
+
+ /// Move Camera.
+ Camera_Operation,
+}
diff --git a/Dalamud/Game/Config/SystemConfigOption.cs b/Dalamud/Game/Config/SystemConfigOption.cs
index 5305e06d9..154992637 100644
--- a/Dalamud/Game/Config/SystemConfigOption.cs
+++ b/Dalamud/Game/Config/SystemConfigOption.cs
@@ -597,6 +597,20 @@ public enum SystemConfigOption
[GameConfigOption("EnablePsFunction", ConfigType.UInt)]
EnablePsFunction,
+ ///
+ /// System option with the internal name ActiveInstanceGuid.
+ /// This option is a String.
+ ///
+ [GameConfigOption("ActiveInstanceGuid", ConfigType.String)]
+ ActiveInstanceGuid,
+
+ ///
+ /// System option with the internal name ActiveProductGuid.
+ /// This option is a String.
+ ///
+ [GameConfigOption("ActiveProductGuid", ConfigType.String)]
+ ActiveProductGuid,
+
///
/// System option with the internal name WaterWet.
/// This option is a UInt.
@@ -996,6 +1010,27 @@ public enum SystemConfigOption
[GameConfigOption("AutoChangeCameraMode", ConfigType.UInt)]
AutoChangeCameraMode,
+ ///
+ /// System option with the internal name MsqProgress.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("MsqProgress", ConfigType.UInt)]
+ MsqProgress,
+
+ ///
+ /// System option with the internal name PromptConfigUpdate.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("PromptConfigUpdate", ConfigType.UInt)]
+ PromptConfigUpdate,
+
+ ///
+ /// System option with the internal name TitleScreenType.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("TitleScreenType", ConfigType.UInt)]
+ TitleScreenType,
+
///
/// System option with the internal name AccessibilitySoundVisualEnable.
/// This option is a UInt.
@@ -1059,6 +1094,13 @@ public enum SystemConfigOption
[GameConfigOption("IdlingCameraAFK", ConfigType.UInt)]
IdlingCameraAFK,
+ ///
+ /// System option with the internal name FirstConfigBackup.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("FirstConfigBackup", ConfigType.UInt)]
+ FirstConfigBackup,
+
///
/// System option with the internal name MouseSpeed.
/// This option is a Float.
diff --git a/Dalamud/Game/Config/UiConfigOption.cs b/Dalamud/Game/Config/UiConfigOption.cs
index bf329bd6c..1a59b8945 100644
--- a/Dalamud/Game/Config/UiConfigOption.cs
+++ b/Dalamud/Game/Config/UiConfigOption.cs
@@ -10,3572 +10,3607 @@
public enum UiConfigOption
{
///
- /// System option with the internal name BattleEffectSelf.
+ /// UiConfig option with the internal name BattleEffectSelf.
/// This option is a UInt.
///
[GameConfigOption("BattleEffectSelf", ConfigType.UInt)]
BattleEffectSelf,
///
- /// System option with the internal name BattleEffectParty.
+ /// UiConfig option with the internal name BattleEffectParty.
/// This option is a UInt.
///
[GameConfigOption("BattleEffectParty", ConfigType.UInt)]
BattleEffectParty,
///
- /// System option with the internal name BattleEffectOther.
+ /// UiConfig option with the internal name BattleEffectOther.
/// This option is a UInt.
///
[GameConfigOption("BattleEffectOther", ConfigType.UInt)]
BattleEffectOther,
///
- /// System option with the internal name BattleEffectPvPEnemyPc.
+ /// UiConfig option with the internal name BattleEffectPvPEnemyPc.
/// This option is a UInt.
///
[GameConfigOption("BattleEffectPvPEnemyPc", ConfigType.UInt)]
BattleEffectPvPEnemyPc,
///
- /// System option with the internal name WeaponAutoPutAway.
+ /// UiConfig option with the internal name PadMode.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("PadMode", ConfigType.UInt)]
+ PadMode,
+
+ ///
+ /// UiConfig option with the internal name WeaponAutoPutAway.
/// This option is a UInt.
///
[GameConfigOption("WeaponAutoPutAway", ConfigType.UInt)]
WeaponAutoPutAway,
///
- /// System option with the internal name WeaponAutoPutAwayTime.
+ /// UiConfig option with the internal name WeaponAutoPutAwayTime.
/// This option is a UInt.
///
[GameConfigOption("WeaponAutoPutAwayTime", ConfigType.UInt)]
WeaponAutoPutAwayTime,
///
- /// System option with the internal name LipMotionType.
+ /// UiConfig option with the internal name LipMotionType.
/// This option is a UInt.
///
[GameConfigOption("LipMotionType", ConfigType.UInt)]
LipMotionType,
///
- /// System option with the internal name FirstPersonDefaultYAngle.
+ /// UiConfig option with the internal name FirstPersonDefaultYAngle.
/// This option is a Float.
///
[GameConfigOption("FirstPersonDefaultYAngle", ConfigType.Float)]
FirstPersonDefaultYAngle,
///
- /// System option with the internal name FirstPersonDefaultZoom.
+ /// UiConfig option with the internal name FirstPersonDefaultZoom.
/// This option is a Float.
///
[GameConfigOption("FirstPersonDefaultZoom", ConfigType.Float)]
FirstPersonDefaultZoom,
///
- /// System option with the internal name FirstPersonDefaultDistance.
+ /// UiConfig option with the internal name FirstPersonDefaultDistance.
/// This option is a Float.
///
[GameConfigOption("FirstPersonDefaultDistance", ConfigType.Float)]
FirstPersonDefaultDistance,
///
- /// System option with the internal name ThirdPersonDefaultYAngle.
+ /// UiConfig option with the internal name ThirdPersonDefaultYAngle.
/// This option is a Float.
///
[GameConfigOption("ThirdPersonDefaultYAngle", ConfigType.Float)]
ThirdPersonDefaultYAngle,
///
- /// System option with the internal name ThirdPersonDefaultZoom.
+ /// UiConfig option with the internal name ThirdPersonDefaultZoom.
/// This option is a Float.
///
[GameConfigOption("ThirdPersonDefaultZoom", ConfigType.Float)]
ThirdPersonDefaultZoom,
///
- /// System option with the internal name ThirdPersonDefaultDistance.
+ /// UiConfig option with the internal name ThirdPersonDefaultDistance.
/// This option is a Float.
///
[GameConfigOption("ThirdPersonDefaultDistance", ConfigType.Float)]
ThirdPersonDefaultDistance,
///
- /// System option with the internal name LockonDefaultYAngle.
+ /// UiConfig option with the internal name LockonDefaultYAngle.
/// This option is a Float.
///
[GameConfigOption("LockonDefaultYAngle", ConfigType.Float)]
LockonDefaultYAngle,
///
- /// System option with the internal name LockonDefaultZoom.
+ /// UiConfig option with the internal name LockonDefaultZoom.
/// This option is a Float.
///
[GameConfigOption("LockonDefaultZoom", ConfigType.Float)]
LockonDefaultZoom,
///
- /// System option with the internal name LockonDefaultZoom_179.
- /// This option is a Float.
- ///
- [GameConfigOption("LockonDefaultZoom_179", ConfigType.Float)]
- LockonDefaultZoom_179,
-
- ///
- /// System option with the internal name CameraProductionOfAction.
+ /// UiConfig option with the internal name CameraProductionOfAction.
/// This option is a UInt.
///
[GameConfigOption("CameraProductionOfAction", ConfigType.UInt)]
CameraProductionOfAction,
///
- /// System option with the internal name FPSCameraInterpolationType.
+ /// UiConfig option with the internal name FPSCameraInterpolationType.
/// This option is a UInt.
///
[GameConfigOption("FPSCameraInterpolationType", ConfigType.UInt)]
FPSCameraInterpolationType,
///
- /// System option with the internal name FPSCameraVerticalInterpolation.
+ /// UiConfig option with the internal name FPSCameraVerticalInterpolation.
/// This option is a UInt.
///
[GameConfigOption("FPSCameraVerticalInterpolation", ConfigType.UInt)]
FPSCameraVerticalInterpolation,
///
- /// System option with the internal name LegacyCameraCorrectionFix.
+ /// UiConfig option with the internal name LegacyCameraCorrectionFix.
/// This option is a UInt.
///
[GameConfigOption("LegacyCameraCorrectionFix", ConfigType.UInt)]
LegacyCameraCorrectionFix,
///
- /// System option with the internal name LegacyCameraType.
+ /// UiConfig option with the internal name LegacyCameraType.
/// This option is a UInt.
///
[GameConfigOption("LegacyCameraType", ConfigType.UInt)]
LegacyCameraType,
///
- /// System option with the internal name EventCameraAutoControl.
+ /// UiConfig option with the internal name EventCameraAutoControl.
/// This option is a UInt.
///
[GameConfigOption("EventCameraAutoControl", ConfigType.UInt)]
EventCameraAutoControl,
///
- /// System option with the internal name CameraLookBlinkType.
+ /// UiConfig option with the internal name CameraLookBlinkType.
/// This option is a UInt.
///
[GameConfigOption("CameraLookBlinkType", ConfigType.UInt)]
CameraLookBlinkType,
///
- /// System option with the internal name IdleEmoteTime.
+ /// UiConfig option with the internal name IdleEmoteTime.
/// This option is a UInt.
///
[GameConfigOption("IdleEmoteTime", ConfigType.UInt)]
IdleEmoteTime,
///
- /// System option with the internal name IdleEmoteRandomType.
+ /// UiConfig option with the internal name IdleEmoteRandomType.
/// This option is a UInt.
///
[GameConfigOption("IdleEmoteRandomType", ConfigType.UInt)]
IdleEmoteRandomType,
///
- /// System option with the internal name CutsceneSkipIsShip.
+ /// UiConfig option with the internal name CutsceneSkipIsShip.
/// This option is a UInt.
///
[GameConfigOption("CutsceneSkipIsShip", ConfigType.UInt)]
CutsceneSkipIsShip,
///
- /// System option with the internal name CutsceneSkipIsContents.
+ /// UiConfig option with the internal name CutsceneSkipIsContents.
/// This option is a UInt.
///
[GameConfigOption("CutsceneSkipIsContents", ConfigType.UInt)]
CutsceneSkipIsContents,
///
- /// System option with the internal name CutsceneSkipIsHousing.
+ /// UiConfig option with the internal name CutsceneSkipIsHousing.
/// This option is a UInt.
///
[GameConfigOption("CutsceneSkipIsHousing", ConfigType.UInt)]
CutsceneSkipIsHousing,
///
- /// System option with the internal name PetTargetOffInCombat.
+ /// UiConfig option with the internal name PetTargetOffInCombat.
/// This option is a UInt.
///
[GameConfigOption("PetTargetOffInCombat", ConfigType.UInt)]
PetTargetOffInCombat,
///
- /// System option with the internal name GroundTargetFPSPosX.
+ /// UiConfig option with the internal name GroundTargetFPSPosX.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetFPSPosX", ConfigType.UInt)]
GroundTargetFPSPosX,
///
- /// System option with the internal name GroundTargetFPSPosY.
+ /// UiConfig option with the internal name GroundTargetFPSPosY.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetFPSPosY", ConfigType.UInt)]
GroundTargetFPSPosY,
///
- /// System option with the internal name GroundTargetTPSPosX.
+ /// UiConfig option with the internal name GroundTargetTPSPosX.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetTPSPosX", ConfigType.UInt)]
GroundTargetTPSPosX,
///
- /// System option with the internal name GroundTargetTPSPosY.
+ /// UiConfig option with the internal name GroundTargetTPSPosY.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetTPSPosY", ConfigType.UInt)]
GroundTargetTPSPosY,
///
- /// System option with the internal name TargetDisableAnchor.
+ /// UiConfig option with the internal name TargetDisableAnchor.
/// This option is a UInt.
///
[GameConfigOption("TargetDisableAnchor", ConfigType.UInt)]
TargetDisableAnchor,
///
- /// System option with the internal name TargetCircleClickFilterEnableNearestCursor.
+ /// UiConfig option with the internal name TargetCircleClickFilterEnableNearestCursor.
/// This option is a UInt.
///
[GameConfigOption("TargetCircleClickFilterEnableNearestCursor", ConfigType.UInt)]
TargetCircleClickFilterEnableNearestCursor,
///
- /// System option with the internal name TargetEnableMouseOverSelect.
+ /// UiConfig option with the internal name TargetEnableMouseOverSelect.
/// This option is a UInt.
///
[GameConfigOption("TargetEnableMouseOverSelect", ConfigType.UInt)]
TargetEnableMouseOverSelect,
///
- /// System option with the internal name GroundTargetCursorCorrectType.
+ /// UiConfig option with the internal name GroundTargetCursorCorrectType.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetCursorCorrectType", ConfigType.UInt)]
GroundTargetCursorCorrectType,
///
- /// System option with the internal name GroundTargetActionExcuteType.
+ /// UiConfig option with the internal name GroundTargetActionExcuteType.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetActionExcuteType", ConfigType.UInt)]
GroundTargetActionExcuteType,
///
- /// System option with the internal name AutoNearestTarget.
+ /// UiConfig option with the internal name AutoNearestTarget.
/// This option is a UInt.
///
[GameConfigOption("AutoNearestTarget", ConfigType.UInt)]
AutoNearestTarget,
///
- /// System option with the internal name AutoNearestTargetType.
+ /// UiConfig option with the internal name AutoNearestTargetType.
/// This option is a UInt.
///
[GameConfigOption("AutoNearestTargetType", ConfigType.UInt)]
AutoNearestTargetType,
///
- /// System option with the internal name RightClickExclusionPC.
+ /// UiConfig option with the internal name RightClickExclusionPC.
/// This option is a UInt.
///
[GameConfigOption("RightClickExclusionPC", ConfigType.UInt)]
RightClickExclusionPC,
///
- /// System option with the internal name RightClickExclusionBNPC.
+ /// UiConfig option with the internal name RightClickExclusionBNPC.
/// This option is a UInt.
///
[GameConfigOption("RightClickExclusionBNPC", ConfigType.UInt)]
RightClickExclusionBNPC,
///
- /// System option with the internal name RightClickExclusionMinion.
+ /// UiConfig option with the internal name RightClickExclusionMinion.
/// This option is a UInt.
///
[GameConfigOption("RightClickExclusionMinion", ConfigType.UInt)]
RightClickExclusionMinion,
///
- /// System option with the internal name TurnSpeed.
+ /// UiConfig option with the internal name EnableMoveTiltCharacter.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("EnableMoveTiltCharacter", ConfigType.UInt)]
+ EnableMoveTiltCharacter,
+
+ ///
+ /// UiConfig option with the internal name EnableMoveTiltMountGround.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("EnableMoveTiltMountGround", ConfigType.UInt)]
+ EnableMoveTiltMountGround,
+
+ ///
+ /// UiConfig option with the internal name EnableMoveTiltMountFly.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("EnableMoveTiltMountFly", ConfigType.UInt)]
+ EnableMoveTiltMountFly,
+
+ ///
+ /// UiConfig option with the internal name TurnSpeed.
/// This option is a UInt.
///
[GameConfigOption("TurnSpeed", ConfigType.UInt)]
TurnSpeed,
///
- /// System option with the internal name FootEffect.
+ /// UiConfig option with the internal name FootEffect.
/// This option is a UInt.
///
[GameConfigOption("FootEffect", ConfigType.UInt)]
FootEffect,
///
- /// System option with the internal name LegacySeal.
+ /// UiConfig option with the internal name LegacySeal.
/// This option is a UInt.
///
[GameConfigOption("LegacySeal", ConfigType.UInt)]
LegacySeal,
///
- /// System option with the internal name GBarrelDisp.
+ /// UiConfig option with the internal name GBarrelDisp.
/// This option is a UInt.
///
[GameConfigOption("GBarrelDisp", ConfigType.UInt)]
GBarrelDisp,
///
- /// System option with the internal name EgiMirageTypeGaruda.
+ /// UiConfig option with the internal name EgiMirageTypeGaruda.
/// This option is a UInt.
///
[GameConfigOption("EgiMirageTypeGaruda", ConfigType.UInt)]
EgiMirageTypeGaruda,
///
- /// System option with the internal name EgiMirageTypeTitan.
+ /// UiConfig option with the internal name EgiMirageTypeTitan.
/// This option is a UInt.
///
[GameConfigOption("EgiMirageTypeTitan", ConfigType.UInt)]
EgiMirageTypeTitan,
///
- /// System option with the internal name EgiMirageTypeIfrit.
+ /// UiConfig option with the internal name EgiMirageTypeIfrit.
/// This option is a UInt.
///
[GameConfigOption("EgiMirageTypeIfrit", ConfigType.UInt)]
EgiMirageTypeIfrit,
///
- /// System option with the internal name BahamutSize.
+ /// UiConfig option with the internal name BahamutSize.
/// This option is a UInt.
///
[GameConfigOption("BahamutSize", ConfigType.UInt)]
BahamutSize,
///
- /// System option with the internal name PetMirageTypeCarbuncleSupport.
+ /// UiConfig option with the internal name PetMirageTypeCarbuncleSupport.
/// This option is a UInt.
///
[GameConfigOption("PetMirageTypeCarbuncleSupport", ConfigType.UInt)]
PetMirageTypeCarbuncleSupport,
///
- /// System option with the internal name PhoenixSize.
+ /// UiConfig option with the internal name PhoenixSize.
/// This option is a UInt.
///
[GameConfigOption("PhoenixSize", ConfigType.UInt)]
PhoenixSize,
///
- /// System option with the internal name GarudaSize.
+ /// UiConfig option with the internal name GarudaSize.
/// This option is a UInt.
///
[GameConfigOption("GarudaSize", ConfigType.UInt)]
GarudaSize,
///
- /// System option with the internal name TitanSize.
+ /// UiConfig option with the internal name TitanSize.
/// This option is a UInt.
///
[GameConfigOption("TitanSize", ConfigType.UInt)]
TitanSize,
///
- /// System option with the internal name IfritSize.
+ /// UiConfig option with the internal name IfritSize.
/// This option is a UInt.
///
[GameConfigOption("IfritSize", ConfigType.UInt)]
IfritSize,
///
- /// System option with the internal name SolBahamutSize.
+ /// UiConfig option with the internal name SolBahamutSize.
/// This option is a UInt.
///
[GameConfigOption("SolBahamutSize", ConfigType.UInt)]
SolBahamutSize,
///
- /// System option with the internal name PetMirageTypeFairy.
+ /// UiConfig option with the internal name PetMirageTypeFairy.
/// This option is a UInt.
///
[GameConfigOption("PetMirageTypeFairy", ConfigType.UInt)]
PetMirageTypeFairy,
///
- /// System option with the internal name TimeMode.
+ /// UiConfig option with the internal name TimeMode.
/// This option is a UInt.
///
[GameConfigOption("TimeMode", ConfigType.UInt)]
TimeMode,
///
- /// System option with the internal name Time12.
+ /// UiConfig option with the internal name Time12.
/// This option is a UInt.
///
[GameConfigOption("Time12", ConfigType.UInt)]
Time12,
///
- /// System option with the internal name TimeEorzea.
+ /// UiConfig option with the internal name TimeEorzea.
/// This option is a UInt.
///
[GameConfigOption("TimeEorzea", ConfigType.UInt)]
TimeEorzea,
///
- /// System option with the internal name TimeLocal.
+ /// UiConfig option with the internal name TimeLocal.
/// This option is a UInt.
///
[GameConfigOption("TimeLocal", ConfigType.UInt)]
TimeLocal,
///
- /// System option with the internal name TimeServer.
+ /// UiConfig option with the internal name TimeServer.
/// This option is a UInt.
///
[GameConfigOption("TimeServer", ConfigType.UInt)]
TimeServer,
///
- /// System option with the internal name ActiveLS_H.
+ /// UiConfig option with the internal name ActiveLS_H.
/// This option is a UInt.
///
[GameConfigOption("ActiveLS_H", ConfigType.UInt)]
ActiveLS_H,
///
- /// System option with the internal name ActiveLS_L.
+ /// UiConfig option with the internal name ActiveLS_L.
/// This option is a UInt.
///
[GameConfigOption("ActiveLS_L", ConfigType.UInt)]
ActiveLS_L,
///
- /// System option with the internal name HotbarLock.
+ /// UiConfig option with the internal name HotbarLock.
/// This option is a UInt.
///
[GameConfigOption("HotbarLock", ConfigType.UInt)]
HotbarLock,
///
- /// System option with the internal name HotbarDispRecastTime.
+ /// UiConfig option with the internal name HotbarDispRecastTime.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispRecastTime", ConfigType.UInt)]
HotbarDispRecastTime,
///
- /// System option with the internal name HotbarCrossContentsActionEnableInput.
+ /// UiConfig option with the internal name HotbarCrossContentsActionEnableInput.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossContentsActionEnableInput", ConfigType.UInt)]
HotbarCrossContentsActionEnableInput,
///
- /// System option with the internal name HotbarDispRecastTimeDispType.
+ /// UiConfig option with the internal name HotbarDispRecastTimeDispType.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispRecastTimeDispType", ConfigType.UInt)]
HotbarDispRecastTimeDispType,
///
- /// System option with the internal name ExHotbarChangeHotbar1.
+ /// UiConfig option with the internal name ExHotbarChangeHotbar1.
/// This option is a UInt.
///
[GameConfigOption("ExHotbarChangeHotbar1", ConfigType.UInt)]
ExHotbarChangeHotbar1,
///
- /// System option with the internal name HotbarCommon01.
+ /// UiConfig option with the internal name HotbarCommon01.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon01", ConfigType.UInt)]
HotbarCommon01,
///
- /// System option with the internal name HotbarCommon02.
+ /// UiConfig option with the internal name HotbarCommon02.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon02", ConfigType.UInt)]
HotbarCommon02,
///
- /// System option with the internal name HotbarCommon03.
+ /// UiConfig option with the internal name HotbarCommon03.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon03", ConfigType.UInt)]
HotbarCommon03,
///
- /// System option with the internal name HotbarCommon04.
+ /// UiConfig option with the internal name HotbarCommon04.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon04", ConfigType.UInt)]
HotbarCommon04,
///
- /// System option with the internal name HotbarCommon05.
+ /// UiConfig option with the internal name HotbarCommon05.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon05", ConfigType.UInt)]
HotbarCommon05,
///
- /// System option with the internal name HotbarCommon06.
+ /// UiConfig option with the internal name HotbarCommon06.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon06", ConfigType.UInt)]
HotbarCommon06,
///
- /// System option with the internal name HotbarCommon07.
+ /// UiConfig option with the internal name HotbarCommon07.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon07", ConfigType.UInt)]
HotbarCommon07,
///
- /// System option with the internal name HotbarCommon08.
+ /// UiConfig option with the internal name HotbarCommon08.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon08", ConfigType.UInt)]
HotbarCommon08,
///
- /// System option with the internal name HotbarCommon09.
+ /// UiConfig option with the internal name HotbarCommon09.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon09", ConfigType.UInt)]
HotbarCommon09,
///
- /// System option with the internal name HotbarCommon10.
+ /// UiConfig option with the internal name HotbarCommon10.
/// This option is a UInt.
///
[GameConfigOption("HotbarCommon10", ConfigType.UInt)]
HotbarCommon10,
///
- /// System option with the internal name HotbarCrossCommon01.
+ /// UiConfig option with the internal name HotbarCrossCommon01.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon01", ConfigType.UInt)]
HotbarCrossCommon01,
///
- /// System option with the internal name HotbarCrossCommon02.
+ /// UiConfig option with the internal name HotbarCrossCommon02.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon02", ConfigType.UInt)]
HotbarCrossCommon02,
///
- /// System option with the internal name HotbarCrossCommon03.
+ /// UiConfig option with the internal name HotbarCrossCommon03.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon03", ConfigType.UInt)]
HotbarCrossCommon03,
///
- /// System option with the internal name HotbarCrossCommon04.
+ /// UiConfig option with the internal name HotbarCrossCommon04.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon04", ConfigType.UInt)]
HotbarCrossCommon04,
///
- /// System option with the internal name HotbarCrossCommon05.
+ /// UiConfig option with the internal name HotbarCrossCommon05.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon05", ConfigType.UInt)]
HotbarCrossCommon05,
///
- /// System option with the internal name HotbarCrossCommon06.
+ /// UiConfig option with the internal name HotbarCrossCommon06.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon06", ConfigType.UInt)]
HotbarCrossCommon06,
///
- /// System option with the internal name HotbarCrossCommon07.
+ /// UiConfig option with the internal name HotbarCrossCommon07.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon07", ConfigType.UInt)]
HotbarCrossCommon07,
///
- /// System option with the internal name HotbarCrossCommon08.
+ /// UiConfig option with the internal name HotbarCrossCommon08.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossCommon08", ConfigType.UInt)]
HotbarCrossCommon08,
///
- /// System option with the internal name HotbarCrossHelpDisp.
+ /// UiConfig option with the internal name HotbarCrossHelpDisp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossHelpDisp", ConfigType.UInt)]
HotbarCrossHelpDisp,
///
- /// System option with the internal name HotbarCrossOperation.
+ /// UiConfig option with the internal name HotbarCrossOperation.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossOperation", ConfigType.UInt)]
HotbarCrossOperation,
///
- /// System option with the internal name HotbarCrossDisp.
+ /// UiConfig option with the internal name HotbarCrossDisp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossDisp", ConfigType.UInt)]
HotbarCrossDisp,
///
- /// System option with the internal name HotbarCrossLock.
+ /// UiConfig option with the internal name HotbarCrossLock.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossLock", ConfigType.UInt)]
HotbarCrossLock,
///
- /// System option with the internal name HotbarCrossUsePadGuide.
+ /// UiConfig option with the internal name HotbarCrossUsePadGuide.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossUsePadGuide", ConfigType.UInt)]
HotbarCrossUsePadGuide,
///
- /// System option with the internal name HotbarCrossActiveSet.
+ /// UiConfig option with the internal name HotbarCrossActiveSet.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossActiveSet", ConfigType.UInt)]
HotbarCrossActiveSet,
///
- /// System option with the internal name HotbarCrossActiveSetPvP.
+ /// UiConfig option with the internal name HotbarCrossActiveSetPvP.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossActiveSetPvP", ConfigType.UInt)]
HotbarCrossActiveSetPvP,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsAuto.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsAuto.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsAuto", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsAuto,
///
- /// System option with the internal name HotbarCrossSetChangeCustom.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustom.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustom", ConfigType.UInt)]
HotbarCrossSetChangeCustom,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet1.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet1.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet1", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet1,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet2.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet2.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet2", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet2,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet3.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet3.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet3", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet3,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet4.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet4.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet4", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet4,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet5.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet5.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet5", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet5,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet6.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet6.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet6", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet6,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet7.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet7.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet7", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet7,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet8.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet8.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet8", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet8,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSword.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSword.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSword", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSword,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet1.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet1.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet1", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet1,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet2.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet2.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet2", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet2,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet3.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet3.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet3", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet3,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet4.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet4.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet4", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet4,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet5.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet5.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet5", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet5,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet6.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet6.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet6", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet6,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet7.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet7.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet7", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet7,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet8.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet8.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet8", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet8,
///
- /// System option with the internal name HotbarCrossAdvancedSetting.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSetting.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSetting", ConfigType.UInt)]
HotbarCrossAdvancedSetting,
///
- /// System option with the internal name HotbarCrossAdvancedSettingLeft.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSettingLeft.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSettingLeft", ConfigType.UInt)]
HotbarCrossAdvancedSettingLeft,
///
- /// System option with the internal name HotbarCrossAdvancedSettingRight.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSettingRight.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSettingRight", ConfigType.UInt)]
HotbarCrossAdvancedSettingRight,
///
- /// System option with the internal name HotbarCrossSetPvpModeActive.
+ /// UiConfig option with the internal name HotbarCrossSetPvpModeActive.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetPvpModeActive", ConfigType.UInt)]
HotbarCrossSetPvpModeActive,
///
- /// System option with the internal name HotbarCrossSetChangeCustomPvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomPvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomPvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsAutoPvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsAutoPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsAutoPvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsAutoPvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet1Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet1Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet1Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet1Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet2Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet2Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet2Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet2Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet3Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet3Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet3Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet3Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet4Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet4Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet4Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet4Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet5Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet5Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet5Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet5Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet6Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet6Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet6Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet6Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet7Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet7Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet7Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet7Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomSet8Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomSet8Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomSet8Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomSet8Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordPvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordPvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordPvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet1Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet1Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet1Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet1Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet2Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet2Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet2Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet2Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet3Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet3Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet3Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet3Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet4Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet4Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet4Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet4Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet5Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet5Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet5Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet5Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet6Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet6Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet6Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet6Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet7Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet7Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet7Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet7Pvp,
///
- /// System option with the internal name HotbarCrossSetChangeCustomIsSwordSet8Pvp.
+ /// UiConfig option with the internal name HotbarCrossSetChangeCustomIsSwordSet8Pvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossSetChangeCustomIsSwordSet8Pvp", ConfigType.UInt)]
HotbarCrossSetChangeCustomIsSwordSet8Pvp,
///
- /// System option with the internal name HotbarCrossAdvancedSettingPvp.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSettingPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSettingPvp", ConfigType.UInt)]
HotbarCrossAdvancedSettingPvp,
///
- /// System option with the internal name HotbarCrossAdvancedSettingLeftPvp.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSettingLeftPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSettingLeftPvp", ConfigType.UInt)]
HotbarCrossAdvancedSettingLeftPvp,
///
- /// System option with the internal name HotbarCrossAdvancedSettingRightPvp.
+ /// UiConfig option with the internal name HotbarCrossAdvancedSettingRightPvp.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossAdvancedSettingRightPvp", ConfigType.UInt)]
HotbarCrossAdvancedSettingRightPvp,
///
- /// System option with the internal name HotbarWXHBEnable.
+ /// UiConfig option with the internal name HotbarWXHBEnable.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBEnable", ConfigType.UInt)]
HotbarWXHBEnable,
///
- /// System option with the internal name HotbarWXHBSetLeft.
+ /// UiConfig option with the internal name HotbarWXHBSetLeft.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBSetLeft", ConfigType.UInt)]
HotbarWXHBSetLeft,
///
- /// System option with the internal name HotbarWXHBSetRight.
+ /// UiConfig option with the internal name HotbarWXHBSetRight.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBSetRight", ConfigType.UInt)]
HotbarWXHBSetRight,
///
- /// System option with the internal name HotbarWXHBEnablePvP.
+ /// UiConfig option with the internal name HotbarWXHBEnablePvP.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBEnablePvP", ConfigType.UInt)]
HotbarWXHBEnablePvP,
///
- /// System option with the internal name HotbarWXHBSetLeftPvP.
+ /// UiConfig option with the internal name HotbarWXHBSetLeftPvP.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBSetLeftPvP", ConfigType.UInt)]
HotbarWXHBSetLeftPvP,
///
- /// System option with the internal name HotbarWXHBSetRightPvP.
+ /// UiConfig option with the internal name HotbarWXHBSetRightPvP.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBSetRightPvP", ConfigType.UInt)]
HotbarWXHBSetRightPvP,
///
- /// System option with the internal name HotbarWXHB8Button.
+ /// UiConfig option with the internal name HotbarWXHB8Button.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHB8Button", ConfigType.UInt)]
HotbarWXHB8Button,
///
- /// System option with the internal name HotbarWXHB8ButtonPvP.
+ /// UiConfig option with the internal name HotbarWXHB8ButtonPvP.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHB8ButtonPvP", ConfigType.UInt)]
HotbarWXHB8ButtonPvP,
///
- /// System option with the internal name HotbarWXHBSetInputTime.
+ /// UiConfig option with the internal name HotbarWXHBSetInputTime.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBSetInputTime", ConfigType.UInt)]
HotbarWXHBSetInputTime,
///
- /// System option with the internal name HotbarWXHBDisplay.
+ /// UiConfig option with the internal name HotbarWXHBDisplay.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBDisplay", ConfigType.UInt)]
HotbarWXHBDisplay,
///
- /// System option with the internal name HotbarWXHBFreeLayout.
+ /// UiConfig option with the internal name HotbarWXHBFreeLayout.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBFreeLayout", ConfigType.UInt)]
HotbarWXHBFreeLayout,
///
- /// System option with the internal name HotbarXHBActiveTransmissionAlpha.
+ /// UiConfig option with the internal name HotbarXHBActiveTransmissionAlpha.
/// This option is a UInt.
///
[GameConfigOption("HotbarXHBActiveTransmissionAlpha", ConfigType.UInt)]
HotbarXHBActiveTransmissionAlpha,
///
- /// System option with the internal name HotbarXHBAlphaDefault.
+ /// UiConfig option with the internal name HotbarXHBAlphaDefault.
/// This option is a UInt.
///
[GameConfigOption("HotbarXHBAlphaDefault", ConfigType.UInt)]
HotbarXHBAlphaDefault,
///
- /// System option with the internal name HotbarXHBAlphaActiveSet.
+ /// UiConfig option with the internal name HotbarXHBAlphaActiveSet.
/// This option is a UInt.
///
[GameConfigOption("HotbarXHBAlphaActiveSet", ConfigType.UInt)]
HotbarXHBAlphaActiveSet,
///
- /// System option with the internal name HotbarXHBAlphaInactiveSet.
+ /// UiConfig option with the internal name HotbarXHBAlphaInactiveSet.
/// This option is a UInt.
///
[GameConfigOption("HotbarXHBAlphaInactiveSet", ConfigType.UInt)]
HotbarXHBAlphaInactiveSet,
///
- /// System option with the internal name HotbarWXHBInputOnce.
+ /// UiConfig option with the internal name HotbarWXHBInputOnce.
/// This option is a UInt.
///
[GameConfigOption("HotbarWXHBInputOnce", ConfigType.UInt)]
HotbarWXHBInputOnce,
///
- /// System option with the internal name ExHotbarChangeHotbar1IsFashion.
+ /// UiConfig option with the internal name ExHotbarChangeHotbar1IsFashion.
/// This option is a UInt.
///
[GameConfigOption("ExHotbarChangeHotbar1IsFashion", ConfigType.UInt)]
ExHotbarChangeHotbar1IsFashion,
///
- /// System option with the internal name HotbarCrossUseExDirectionAutoSwitch.
+ /// UiConfig option with the internal name HotbarCrossUseExDirectionAutoSwitch.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossUseExDirectionAutoSwitch", ConfigType.UInt)]
HotbarCrossUseExDirectionAutoSwitch,
///
- /// System option with the internal name IdlingCameraSwitchType.
+ /// UiConfig option with the internal name IdlingCameraSwitchType.
/// This option is a UInt.
///
[GameConfigOption("IdlingCameraSwitchType", ConfigType.UInt)]
IdlingCameraSwitchType,
///
- /// System option with the internal name HotbarXHBEditEnable.
+ /// UiConfig option with the internal name HotbarXHBEditEnable.
/// This option is a UInt.
///
[GameConfigOption("HotbarXHBEditEnable", ConfigType.UInt)]
HotbarXHBEditEnable,
///
- /// System option with the internal name PlateType.
+ /// UiConfig option with the internal name HotbarContentsAction2ReverseOperation.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("HotbarContentsAction2ReverseOperation", ConfigType.UInt)]
+ HotbarContentsAction2ReverseOperation,
+
+ ///
+ /// UiConfig option with the internal name HotbarContentsAction2ReturnInitialSlot.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("HotbarContentsAction2ReturnInitialSlot", ConfigType.UInt)]
+ HotbarContentsAction2ReturnInitialSlot,
+
+ ///
+ /// UiConfig option with the internal name HotbarContentsAction2ReverseRotate.
+ /// This option is a UInt.
+ ///
+ [GameConfigOption("HotbarContentsAction2ReverseRotate", ConfigType.UInt)]
+ HotbarContentsAction2ReverseRotate,
+
+ ///
+ /// UiConfig option with the internal name PlateType.
/// This option is a UInt.
///
[GameConfigOption("PlateType", ConfigType.UInt)]
PlateType,
///
- /// System option with the internal name PlateDispHPBar.
+ /// UiConfig option with the internal name PlateDispHPBar.
/// This option is a UInt.
///
[GameConfigOption("PlateDispHPBar", ConfigType.UInt)]
PlateDispHPBar,
///
- /// System option with the internal name PlateDisableMaxHPBar.
+ /// UiConfig option with the internal name PlateDisableMaxHPBar.
/// This option is a UInt.
///
[GameConfigOption("PlateDisableMaxHPBar", ConfigType.UInt)]
PlateDisableMaxHPBar,
///
- /// System option with the internal name NamePlateHpSizeType.
+ /// UiConfig option with the internal name NamePlateHpSizeType.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpSizeType", ConfigType.UInt)]
NamePlateHpSizeType,
///
- /// System option with the internal name NamePlateColorSelf.
+ /// UiConfig option with the internal name NamePlateColorSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorSelf", ConfigType.UInt)]
NamePlateColorSelf,
///
- /// System option with the internal name NamePlateEdgeSelf.
+ /// UiConfig option with the internal name NamePlateEdgeSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeSelf", ConfigType.UInt)]
NamePlateEdgeSelf,
///
- /// System option with the internal name NamePlateDispTypeSelf.
+ /// UiConfig option with the internal name NamePlateDispTypeSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeSelf", ConfigType.UInt)]
NamePlateDispTypeSelf,
///
- /// System option with the internal name NamePlateNameTypeSelf.
+ /// UiConfig option with the internal name NamePlateNameTypeSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeSelf", ConfigType.UInt)]
NamePlateNameTypeSelf,
///
- /// System option with the internal name NamePlateHpTypeSelf.
+ /// UiConfig option with the internal name NamePlateHpTypeSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeSelf", ConfigType.UInt)]
NamePlateHpTypeSelf,
///
- /// System option with the internal name NamePlateColorSelfBuddy.
+ /// UiConfig option with the internal name NamePlateColorSelfBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorSelfBuddy", ConfigType.UInt)]
NamePlateColorSelfBuddy,
///
- /// System option with the internal name NamePlateEdgeSelfBuddy.
+ /// UiConfig option with the internal name NamePlateEdgeSelfBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeSelfBuddy", ConfigType.UInt)]
NamePlateEdgeSelfBuddy,
///
- /// System option with the internal name NamePlateDispTypeSelfBuddy.
+ /// UiConfig option with the internal name NamePlateDispTypeSelfBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeSelfBuddy", ConfigType.UInt)]
NamePlateDispTypeSelfBuddy,
///
- /// System option with the internal name NamePlateHpTypeSelfBuddy.
+ /// UiConfig option with the internal name NamePlateHpTypeSelfBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeSelfBuddy", ConfigType.UInt)]
NamePlateHpTypeSelfBuddy,
///
- /// System option with the internal name NamePlateColorSelfPet.
+ /// UiConfig option with the internal name NamePlateColorSelfPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorSelfPet", ConfigType.UInt)]
NamePlateColorSelfPet,
///
- /// System option with the internal name NamePlateEdgeSelfPet.
+ /// UiConfig option with the internal name NamePlateEdgeSelfPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeSelfPet", ConfigType.UInt)]
NamePlateEdgeSelfPet,
///
- /// System option with the internal name NamePlateDispTypeSelfPet.
+ /// UiConfig option with the internal name NamePlateDispTypeSelfPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeSelfPet", ConfigType.UInt)]
NamePlateDispTypeSelfPet,
///
- /// System option with the internal name NamePlateHpTypeSelfPet.
+ /// UiConfig option with the internal name NamePlateHpTypeSelfPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeSelfPet", ConfigType.UInt)]
NamePlateHpTypeSelfPet,
///
- /// System option with the internal name NamePlateColorParty.
+ /// UiConfig option with the internal name NamePlateColorParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorParty", ConfigType.UInt)]
NamePlateColorParty,
///
- /// System option with the internal name NamePlateEdgeParty.
+ /// UiConfig option with the internal name NamePlateEdgeParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeParty", ConfigType.UInt)]
NamePlateEdgeParty,
///
- /// System option with the internal name NamePlateDispTypeParty.
+ /// UiConfig option with the internal name NamePlateDispTypeParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeParty", ConfigType.UInt)]
NamePlateDispTypeParty,
///
- /// System option with the internal name NamePlateNameTypeParty.
+ /// UiConfig option with the internal name NamePlateNameTypeParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeParty", ConfigType.UInt)]
NamePlateNameTypeParty,
///
- /// System option with the internal name NamePlateHpTypeParty.
+ /// UiConfig option with the internal name NamePlateHpTypeParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeParty", ConfigType.UInt)]
NamePlateHpTypeParty,
///
- /// System option with the internal name NamePlateDispTypePartyPet.
+ /// UiConfig option with the internal name NamePlateDispTypePartyPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypePartyPet", ConfigType.UInt)]
NamePlateDispTypePartyPet,
///
- /// System option with the internal name NamePlateHpTypePartyPet.
+ /// UiConfig option with the internal name NamePlateHpTypePartyPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypePartyPet", ConfigType.UInt)]
NamePlateHpTypePartyPet,
///
- /// System option with the internal name NamePlateDispTypePartyBuddy.
+ /// UiConfig option with the internal name NamePlateDispTypePartyBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypePartyBuddy", ConfigType.UInt)]
NamePlateDispTypePartyBuddy,
///
- /// System option with the internal name NamePlateHpTypePartyBuddy.
+ /// UiConfig option with the internal name NamePlateHpTypePartyBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypePartyBuddy", ConfigType.UInt)]
NamePlateHpTypePartyBuddy,
///
- /// System option with the internal name NamePlateColorAlliance.
+ /// UiConfig option with the internal name NamePlateColorAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorAlliance", ConfigType.UInt)]
NamePlateColorAlliance,
///
- /// System option with the internal name NamePlateEdgeAlliance.
+ /// UiConfig option with the internal name NamePlateEdgeAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeAlliance", ConfigType.UInt)]
NamePlateEdgeAlliance,
///
- /// System option with the internal name NamePlateDispTypeAlliance.
+ /// UiConfig option with the internal name NamePlateDispTypeAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeAlliance", ConfigType.UInt)]
NamePlateDispTypeAlliance,
///
- /// System option with the internal name NamePlateNameTypeAlliance.
+ /// UiConfig option with the internal name NamePlateNameTypeAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeAlliance", ConfigType.UInt)]
NamePlateNameTypeAlliance,
///
- /// System option with the internal name NamePlateHpTypeAlliance.
+ /// UiConfig option with the internal name NamePlateHpTypeAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeAlliance", ConfigType.UInt)]
NamePlateHpTypeAlliance,
///
- /// System option with the internal name NamePlateDispTypeAlliancePet.
+ /// UiConfig option with the internal name NamePlateDispTypeAlliancePet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeAlliancePet", ConfigType.UInt)]
NamePlateDispTypeAlliancePet,
///
- /// System option with the internal name NamePlateHpTypeAlliancePet.
+ /// UiConfig option with the internal name NamePlateHpTypeAlliancePet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeAlliancePet", ConfigType.UInt)]
NamePlateHpTypeAlliancePet,
///
- /// System option with the internal name NamePlateColorOther.
+ /// UiConfig option with the internal name NamePlateColorOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorOther", ConfigType.UInt)]
NamePlateColorOther,
///
- /// System option with the internal name NamePlateEdgeOther.
+ /// UiConfig option with the internal name NamePlateEdgeOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeOther", ConfigType.UInt)]
NamePlateEdgeOther,
///
- /// System option with the internal name NamePlateDispTypeOther.
+ /// UiConfig option with the internal name NamePlateDispTypeOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeOther", ConfigType.UInt)]
NamePlateDispTypeOther,
///
- /// System option with the internal name NamePlateNameTypeOther.
+ /// UiConfig option with the internal name NamePlateNameTypeOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeOther", ConfigType.UInt)]
NamePlateNameTypeOther,
///
- /// System option with the internal name NamePlateHpTypeOther.
+ /// UiConfig option with the internal name NamePlateHpTypeOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeOther", ConfigType.UInt)]
NamePlateHpTypeOther,
///
- /// System option with the internal name NamePlateDispTypeOtherPet.
+ /// UiConfig option with the internal name NamePlateDispTypeOtherPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeOtherPet", ConfigType.UInt)]
NamePlateDispTypeOtherPet,
///
- /// System option with the internal name NamePlateHpTypeOtherPet.
+ /// UiConfig option with the internal name NamePlateHpTypeOtherPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeOtherPet", ConfigType.UInt)]
NamePlateHpTypeOtherPet,
///
- /// System option with the internal name NamePlateDispTypeOtherBuddy.
+ /// UiConfig option with the internal name NamePlateDispTypeOtherBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeOtherBuddy", ConfigType.UInt)]
NamePlateDispTypeOtherBuddy,
///
- /// System option with the internal name NamePlateHpTypeOtherBuddy.
+ /// UiConfig option with the internal name NamePlateHpTypeOtherBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeOtherBuddy", ConfigType.UInt)]
NamePlateHpTypeOtherBuddy,
///
- /// System option with the internal name NamePlateColorUnengagedEnemy.
+ /// UiConfig option with the internal name NamePlateColorUnengagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorUnengagedEnemy", ConfigType.UInt)]
NamePlateColorUnengagedEnemy,
///
- /// System option with the internal name NamePlateEdgeUnengagedEnemy.
+ /// UiConfig option with the internal name NamePlateEdgeUnengagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeUnengagedEnemy", ConfigType.UInt)]
NamePlateEdgeUnengagedEnemy,
///
- /// System option with the internal name NamePlateDispTypeUnengagedEnemy.
+ /// UiConfig option with the internal name NamePlateDispTypeUnengagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeUnengagedEnemy", ConfigType.UInt)]
NamePlateDispTypeUnengagedEnemy,
///
- /// System option with the internal name NamePlateHpTypeUnengagedEmemy.
+ /// UiConfig option with the internal name NamePlateHpTypeUnengagedEmemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeUnengagedEmemy", ConfigType.UInt)]
NamePlateHpTypeUnengagedEmemy,
///
- /// System option with the internal name NamePlateColorEngagedEnemy.
+ /// UiConfig option with the internal name NamePlateColorEngagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorEngagedEnemy", ConfigType.UInt)]
NamePlateColorEngagedEnemy,
///
- /// System option with the internal name NamePlateEdgeEngagedEnemy.
+ /// UiConfig option with the internal name NamePlateEdgeEngagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeEngagedEnemy", ConfigType.UInt)]
NamePlateEdgeEngagedEnemy,
///
- /// System option with the internal name NamePlateDispTypeEngagedEnemy.
+ /// UiConfig option with the internal name NamePlateDispTypeEngagedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeEngagedEnemy", ConfigType.UInt)]
NamePlateDispTypeEngagedEnemy,
///
- /// System option with the internal name NamePlateHpTypeEngagedEmemy.
+ /// UiConfig option with the internal name NamePlateHpTypeEngagedEmemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeEngagedEmemy", ConfigType.UInt)]
NamePlateHpTypeEngagedEmemy,
///
- /// System option with the internal name NamePlateColorClaimedEnemy.
+ /// UiConfig option with the internal name NamePlateColorClaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorClaimedEnemy", ConfigType.UInt)]
NamePlateColorClaimedEnemy,
///
- /// System option with the internal name NamePlateEdgeClaimedEnemy.
+ /// UiConfig option with the internal name NamePlateEdgeClaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeClaimedEnemy", ConfigType.UInt)]
NamePlateEdgeClaimedEnemy,
///
- /// System option with the internal name NamePlateDispTypeClaimedEnemy.
+ /// UiConfig option with the internal name NamePlateDispTypeClaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeClaimedEnemy", ConfigType.UInt)]
NamePlateDispTypeClaimedEnemy,
///
- /// System option with the internal name NamePlateHpTypeClaimedEmemy.
+ /// UiConfig option with the internal name NamePlateHpTypeClaimedEmemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeClaimedEmemy", ConfigType.UInt)]
NamePlateHpTypeClaimedEmemy,
///
- /// System option with the internal name NamePlateColorUnclaimedEnemy.
+ /// UiConfig option with the internal name NamePlateColorUnclaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorUnclaimedEnemy", ConfigType.UInt)]
NamePlateColorUnclaimedEnemy,
///
- /// System option with the internal name NamePlateEdgeUnclaimedEnemy.
+ /// UiConfig option with the internal name NamePlateEdgeUnclaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeUnclaimedEnemy", ConfigType.UInt)]
NamePlateEdgeUnclaimedEnemy,
///
- /// System option with the internal name NamePlateDispTypeUnclaimedEnemy.
+ /// UiConfig option with the internal name NamePlateDispTypeUnclaimedEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeUnclaimedEnemy", ConfigType.UInt)]
NamePlateDispTypeUnclaimedEnemy,
///
- /// System option with the internal name NamePlateHpTypeUnclaimedEmemy.
+ /// UiConfig option with the internal name NamePlateHpTypeUnclaimedEmemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeUnclaimedEmemy", ConfigType.UInt)]
NamePlateHpTypeUnclaimedEmemy,
///
- /// System option with the internal name NamePlateColorNpc.
+ /// UiConfig option with the internal name NamePlateColorNpc.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorNpc", ConfigType.UInt)]
NamePlateColorNpc,
///
- /// System option with the internal name NamePlateEdgeNpc.
+ /// UiConfig option with the internal name NamePlateEdgeNpc.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeNpc", ConfigType.UInt)]
NamePlateEdgeNpc,
///
- /// System option with the internal name NamePlateDispTypeNpc.
+ /// UiConfig option with the internal name NamePlateDispTypeNpc.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeNpc", ConfigType.UInt)]
NamePlateDispTypeNpc,
///
- /// System option with the internal name NamePlateHpTypeNpc.
+ /// UiConfig option with the internal name NamePlateHpTypeNpc.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeNpc", ConfigType.UInt)]
NamePlateHpTypeNpc,
///
- /// System option with the internal name NamePlateColorObject.
+ /// UiConfig option with the internal name NamePlateColorObject.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorObject", ConfigType.UInt)]
NamePlateColorObject,
///
- /// System option with the internal name NamePlateEdgeObject.
+ /// UiConfig option with the internal name NamePlateEdgeObject.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeObject", ConfigType.UInt)]
NamePlateEdgeObject,
///
- /// System option with the internal name NamePlateDispTypeObject.
+ /// UiConfig option with the internal name NamePlateDispTypeObject.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeObject", ConfigType.UInt)]
NamePlateDispTypeObject,
///
- /// System option with the internal name NamePlateHpTypeObject.
+ /// UiConfig option with the internal name NamePlateHpTypeObject.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeObject", ConfigType.UInt)]
NamePlateHpTypeObject,
///
- /// System option with the internal name NamePlateColorMinion.
+ /// UiConfig option with the internal name NamePlateColorMinion.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorMinion", ConfigType.UInt)]
NamePlateColorMinion,
///
- /// System option with the internal name NamePlateEdgeMinion.
+ /// UiConfig option with the internal name NamePlateEdgeMinion.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeMinion", ConfigType.UInt)]
NamePlateEdgeMinion,
///
- /// System option with the internal name NamePlateDispTypeMinion.
+ /// UiConfig option with the internal name NamePlateDispTypeMinion.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeMinion", ConfigType.UInt)]
NamePlateDispTypeMinion,
///
- /// System option with the internal name NamePlateColorOtherBuddy.
+ /// UiConfig option with the internal name NamePlateColorOtherBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorOtherBuddy", ConfigType.UInt)]
NamePlateColorOtherBuddy,
///
- /// System option with the internal name NamePlateEdgeOtherBuddy.
+ /// UiConfig option with the internal name NamePlateEdgeOtherBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeOtherBuddy", ConfigType.UInt)]
NamePlateEdgeOtherBuddy,
///
- /// System option with the internal name NamePlateColorOtherPet.
+ /// UiConfig option with the internal name NamePlateColorOtherPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorOtherPet", ConfigType.UInt)]
NamePlateColorOtherPet,
///
- /// System option with the internal name NamePlateEdgeOtherPet.
+ /// UiConfig option with the internal name NamePlateEdgeOtherPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeOtherPet", ConfigType.UInt)]
NamePlateEdgeOtherPet,
///
- /// System option with the internal name NamePlateNameTitleTypeSelf.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeSelf.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeSelf", ConfigType.UInt)]
NamePlateNameTitleTypeSelf,
///
- /// System option with the internal name NamePlateNameTitleTypeParty.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeParty", ConfigType.UInt)]
NamePlateNameTitleTypeParty,
///
- /// System option with the internal name NamePlateNameTitleTypeAlliance.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeAlliance.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeAlliance", ConfigType.UInt)]
NamePlateNameTitleTypeAlliance,
///
- /// System option with the internal name NamePlateNameTitleTypeOther.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeOther", ConfigType.UInt)]
NamePlateNameTitleTypeOther,
///
- /// System option with the internal name NamePlateNameTitleTypeFriend.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeFriend.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeFriend", ConfigType.UInt)]
NamePlateNameTitleTypeFriend,
///
- /// System option with the internal name NamePlateColorFriend.
+ /// UiConfig option with the internal name NamePlateColorFriend.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorFriend", ConfigType.UInt)]
NamePlateColorFriend,
///
- /// System option with the internal name NamePlateColorFriendEdge.
+ /// UiConfig option with the internal name NamePlateColorFriendEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorFriendEdge", ConfigType.UInt)]
NamePlateColorFriendEdge,
///
- /// System option with the internal name NamePlateDispTypeFriend.
+ /// UiConfig option with the internal name NamePlateDispTypeFriend.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeFriend", ConfigType.UInt)]
NamePlateDispTypeFriend,
///
- /// System option with the internal name NamePlateNameTypeFriend.
+ /// UiConfig option with the internal name NamePlateNameTypeFriend.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeFriend", ConfigType.UInt)]
NamePlateNameTypeFriend,
///
- /// System option with the internal name NamePlateHpTypeFriend.
+ /// UiConfig option with the internal name NamePlateHpTypeFriend.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeFriend", ConfigType.UInt)]
NamePlateHpTypeFriend,
///
- /// System option with the internal name NamePlateDispTypeFriendPet.
+ /// UiConfig option with the internal name NamePlateDispTypeFriendPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeFriendPet", ConfigType.UInt)]
NamePlateDispTypeFriendPet,
///
- /// System option with the internal name NamePlateHpTypeFriendPet.
+ /// UiConfig option with the internal name NamePlateHpTypeFriendPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeFriendPet", ConfigType.UInt)]
NamePlateHpTypeFriendPet,
///
- /// System option with the internal name NamePlateDispTypeFriendBuddy.
+ /// UiConfig option with the internal name NamePlateDispTypeFriendBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeFriendBuddy", ConfigType.UInt)]
NamePlateDispTypeFriendBuddy,
///
- /// System option with the internal name NamePlateHpTypeFriendBuddy.
+ /// UiConfig option with the internal name NamePlateHpTypeFriendBuddy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeFriendBuddy", ConfigType.UInt)]
NamePlateHpTypeFriendBuddy,
///
- /// System option with the internal name NamePlateColorLim.
+ /// UiConfig option with the internal name NamePlateColorLim.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorLim", ConfigType.UInt)]
NamePlateColorLim,
///
- /// System option with the internal name NamePlateColorLimEdge.
+ /// UiConfig option with the internal name NamePlateColorLimEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorLimEdge", ConfigType.UInt)]
NamePlateColorLimEdge,
///
- /// System option with the internal name NamePlateColorGri.
+ /// UiConfig option with the internal name NamePlateColorGri.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorGri", ConfigType.UInt)]
NamePlateColorGri,
///
- /// System option with the internal name NamePlateColorGriEdge.
+ /// UiConfig option with the internal name NamePlateColorGriEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorGriEdge", ConfigType.UInt)]
NamePlateColorGriEdge,
///
- /// System option with the internal name NamePlateColorUld.
+ /// UiConfig option with the internal name NamePlateColorUld.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorUld", ConfigType.UInt)]
NamePlateColorUld,
///
- /// System option with the internal name NamePlateColorUldEdge.
+ /// UiConfig option with the internal name NamePlateColorUldEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorUldEdge", ConfigType.UInt)]
NamePlateColorUldEdge,
///
- /// System option with the internal name NamePlateColorHousingFurniture.
+ /// UiConfig option with the internal name NamePlateColorHousingFurniture.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorHousingFurniture", ConfigType.UInt)]
NamePlateColorHousingFurniture,
///
- /// System option with the internal name NamePlateColorHousingFurnitureEdge.
+ /// UiConfig option with the internal name NamePlateColorHousingFurnitureEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorHousingFurnitureEdge", ConfigType.UInt)]
NamePlateColorHousingFurnitureEdge,
///
- /// System option with the internal name NamePlateDispTypeHousingFurniture.
+ /// UiConfig option with the internal name NamePlateDispTypeHousingFurniture.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeHousingFurniture", ConfigType.UInt)]
NamePlateDispTypeHousingFurniture,
///
- /// System option with the internal name NamePlateColorHousingField.
+ /// UiConfig option with the internal name NamePlateColorHousingField.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorHousingField", ConfigType.UInt)]
NamePlateColorHousingField,
///
- /// System option with the internal name NamePlateColorHousingFieldEdge.
+ /// UiConfig option with the internal name NamePlateColorHousingFieldEdge.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorHousingFieldEdge", ConfigType.UInt)]
NamePlateColorHousingFieldEdge,
///
- /// System option with the internal name NamePlateDispTypeHousingField.
+ /// UiConfig option with the internal name NamePlateDispTypeHousingField.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeHousingField", ConfigType.UInt)]
NamePlateDispTypeHousingField,
///
- /// System option with the internal name NamePlateNameTypePvPEnemy.
+ /// UiConfig option with the internal name NamePlateNameTypePvPEnemy.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypePvPEnemy", ConfigType.UInt)]
NamePlateNameTypePvPEnemy,
///
- /// System option with the internal name NamePlateDispTypeFeast.
+ /// UiConfig option with the internal name NamePlateDispTypeFeast.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeFeast", ConfigType.UInt)]
NamePlateDispTypeFeast,
///
- /// System option with the internal name NamePlateNameTypeFeast.
+ /// UiConfig option with the internal name NamePlateNameTypeFeast.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTypeFeast", ConfigType.UInt)]
NamePlateNameTypeFeast,
///
- /// System option with the internal name NamePlateHpTypeFeast.
+ /// UiConfig option with the internal name NamePlateHpTypeFeast.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeFeast", ConfigType.UInt)]
NamePlateHpTypeFeast,
///
- /// System option with the internal name NamePlateDispTypeFeastPet.
+ /// UiConfig option with the internal name NamePlateDispTypeFeastPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispTypeFeastPet", ConfigType.UInt)]
NamePlateDispTypeFeastPet,
///
- /// System option with the internal name NamePlateHpTypeFeastPet.
+ /// UiConfig option with the internal name NamePlateHpTypeFeastPet.
/// This option is a UInt.
///
[GameConfigOption("NamePlateHpTypeFeastPet", ConfigType.UInt)]
NamePlateHpTypeFeastPet,
///
- /// System option with the internal name NamePlateNameTitleTypeFeast.
+ /// UiConfig option with the internal name NamePlateNameTitleTypeFeast.
/// This option is a UInt.
///
[GameConfigOption("NamePlateNameTitleTypeFeast", ConfigType.UInt)]
NamePlateNameTitleTypeFeast,
///
- /// System option with the internal name NamePlateDispSize.
+ /// UiConfig option with the internal name NamePlateDispSize.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispSize", ConfigType.UInt)]
NamePlateDispSize,
///
- /// System option with the internal name NamePlateDispJobIcon.
+ /// UiConfig option with the internal name NamePlateDispJobIcon.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIcon", ConfigType.UInt)]
NamePlateDispJobIcon,
///
- /// System option with the internal name NamePlateDispJobIconType.
+ /// UiConfig option with the internal name NamePlateDispJobIconType.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIconType", ConfigType.UInt)]
NamePlateDispJobIconType,
///
- /// System option with the internal name NamePlateSetRoleColor.
+ /// UiConfig option with the internal name NamePlateSetRoleColor.
/// This option is a UInt.
///
[GameConfigOption("NamePlateSetRoleColor", ConfigType.UInt)]
NamePlateSetRoleColor,
///
- /// System option with the internal name NamePlateColorTank.
+ /// UiConfig option with the internal name NamePlateColorTank.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorTank", ConfigType.UInt)]
NamePlateColorTank,
///
- /// System option with the internal name NamePlateEdgeTank.
+ /// UiConfig option with the internal name NamePlateEdgeTank.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeTank", ConfigType.UInt)]
NamePlateEdgeTank,
///
- /// System option with the internal name NamePlateColorHealer.
+ /// UiConfig option with the internal name NamePlateColorHealer.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorHealer", ConfigType.UInt)]
NamePlateColorHealer,
///
- /// System option with the internal name NamePlateEdgeHealer.
+ /// UiConfig option with the internal name NamePlateEdgeHealer.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeHealer", ConfigType.UInt)]
NamePlateEdgeHealer,
///
- /// System option with the internal name NamePlateColorDps.
+ /// UiConfig option with the internal name NamePlateColorDps.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorDps", ConfigType.UInt)]
NamePlateColorDps,
///
- /// System option with the internal name NamePlateEdgeDps.
+ /// UiConfig option with the internal name NamePlateEdgeDps.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeDps", ConfigType.UInt)]
NamePlateEdgeDps,
///
- /// System option with the internal name NamePlateColorOtherClass.
+ /// UiConfig option with the internal name NamePlateColorOtherClass.
/// This option is a UInt.
///
[GameConfigOption("NamePlateColorOtherClass", ConfigType.UInt)]
NamePlateColorOtherClass,
///
- /// System option with the internal name NamePlateEdgeOtherClass.
+ /// UiConfig option with the internal name NamePlateEdgeOtherClass.
/// This option is a UInt.
///
[GameConfigOption("NamePlateEdgeOtherClass", ConfigType.UInt)]
NamePlateEdgeOtherClass,
///
- /// System option with the internal name NamePlateDispWorldTravel.
+ /// UiConfig option with the internal name NamePlateDispWorldTravel.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispWorldTravel", ConfigType.UInt)]
NamePlateDispWorldTravel,
///
- /// System option with the internal name NamePlateDispJobIconInPublicParty.
+ /// UiConfig option with the internal name NamePlateDispJobIconInPublicParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIconInPublicParty", ConfigType.UInt)]
NamePlateDispJobIconInPublicParty,
///
- /// System option with the internal name NamePlateDispJobIconInPublicOther.
+ /// UiConfig option with the internal name NamePlateDispJobIconInPublicOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIconInPublicOther", ConfigType.UInt)]
NamePlateDispJobIconInPublicOther,
///
- /// System option with the internal name NamePlateDispJobIconInInstanceParty.
+ /// UiConfig option with the internal name NamePlateDispJobIconInInstanceParty.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIconInInstanceParty", ConfigType.UInt)]
NamePlateDispJobIconInInstanceParty,
///
- /// System option with the internal name NamePlateDispJobIconInInstanceOther.
+ /// UiConfig option with the internal name NamePlateDispJobIconInInstanceOther.
/// This option is a UInt.
///
[GameConfigOption("NamePlateDispJobIconInInstanceOther", ConfigType.UInt)]
NamePlateDispJobIconInInstanceOther,
///
- /// System option with the internal name ActiveInfo.
+ /// UiConfig option with the internal name ActiveInfo.
/// This option is a UInt.
///
[GameConfigOption("ActiveInfo", ConfigType.UInt)]
ActiveInfo,
///
- /// System option with the internal name PartyList.
+ /// UiConfig option with the internal name PartyList.
/// This option is a UInt.
///
[GameConfigOption("PartyList", ConfigType.UInt)]
PartyList,
///
- /// System option with the internal name PartyListStatus.
+ /// UiConfig option with the internal name PartyListStatus.
/// This option is a UInt.
///
[GameConfigOption("PartyListStatus", ConfigType.UInt)]
PartyListStatus,
///
- /// System option with the internal name PartyListStatusTimer.
+ /// UiConfig option with the internal name PartyListStatusTimer.
/// This option is a UInt.
///
[GameConfigOption("PartyListStatusTimer", ConfigType.UInt)]
PartyListStatusTimer,
///
- /// System option with the internal name EnemyList.
+ /// UiConfig option with the internal name EnemyList.
/// This option is a UInt.
///
[GameConfigOption("EnemyList", ConfigType.UInt)]
EnemyList,
///
- /// System option with the internal name TargetInfo.
+ /// UiConfig option with the internal name TargetInfo.
/// This option is a UInt.
///
[GameConfigOption("TargetInfo", ConfigType.UInt)]
TargetInfo,
///
- /// System option with the internal name Gil.
+ /// UiConfig option with the internal name Gil.
/// This option is a UInt.
///
[GameConfigOption("Gil", ConfigType.UInt)]
Gil,
///
- /// System option with the internal name DTR.
+ /// UiConfig option with the internal name DTR.
/// This option is a UInt.
///
[GameConfigOption("DTR", ConfigType.UInt)]
DTR,
///
- /// System option with the internal name PlayerInfo.
+ /// UiConfig option with the internal name PlayerInfo.
/// This option is a UInt.
///
[GameConfigOption("PlayerInfo", ConfigType.UInt)]
PlayerInfo,
///
- /// System option with the internal name NaviMap.
+ /// UiConfig option with the internal name NaviMap.
/// This option is a UInt.
///
[GameConfigOption("NaviMap", ConfigType.UInt)]
NaviMap,
///
- /// System option with the internal name Help.
+ /// UiConfig option with the internal name Help.
/// This option is a UInt.
///
[GameConfigOption("Help", ConfigType.UInt)]
Help,
///
- /// System option with the internal name CrossMainHelp.
+ /// UiConfig option with the internal name CrossMainHelp.
/// This option is a UInt.
///
[GameConfigOption("CrossMainHelp", ConfigType.UInt)]
CrossMainHelp,
///
- /// System option with the internal name HousingLocatePreview.
+ /// UiConfig option with the internal name HousingLocatePreview.
/// This option is a UInt.
///
[GameConfigOption("HousingLocatePreview", ConfigType.UInt)]
HousingLocatePreview,
///
- /// System option with the internal name Log.
+ /// UiConfig option with the internal name Log.
/// This option is a UInt.
///
[GameConfigOption("Log", ConfigType.UInt)]
Log,
///
- /// System option with the internal name LogTell.
+ /// UiConfig option with the internal name LogTell.
/// This option is a UInt.
///
[GameConfigOption("LogTell", ConfigType.UInt)]
LogTell,
///
- /// System option with the internal name LogFontSize.
+ /// UiConfig option with the internal name LogFontSize.
/// This option is a UInt.
///
[GameConfigOption("LogFontSize", ConfigType.UInt)]
LogFontSize,
///
- /// System option with the internal name LogTabName2.
+ /// UiConfig option with the internal name LogTabName2.
/// This option is a String.
///
[GameConfigOption("LogTabName2", ConfigType.String)]
LogTabName2,
///
- /// System option with the internal name LogTabName3.
+ /// UiConfig option with the internal name LogTabName3.
/// This option is a String.
///
[GameConfigOption("LogTabName3", ConfigType.String)]
LogTabName3,
///
- /// System option with the internal name LogTabFilter0.
+ /// UiConfig option with the internal name LogTabFilter0.
/// This option is a UInt.
///
[GameConfigOption("LogTabFilter0", ConfigType.UInt)]
LogTabFilter0,
///
- /// System option with the internal name LogTabFilter1.
+ /// UiConfig option with the internal name LogTabFilter1.
/// This option is a UInt.
///
[GameConfigOption("LogTabFilter1", ConfigType.UInt)]
LogTabFilter1,
///
- /// System option with the internal name LogTabFilter2.
+ /// UiConfig option with the internal name LogTabFilter2.
/// This option is a UInt.
///
[GameConfigOption("LogTabFilter2", ConfigType.UInt)]
LogTabFilter2,
///
- /// System option with the internal name LogTabFilter3.
+ /// UiConfig option with the internal name LogTabFilter3.
/// This option is a UInt.
///
[GameConfigOption("LogTabFilter3", ConfigType.UInt)]
LogTabFilter3,
///
- /// System option with the internal name LogChatFilter.
+ /// UiConfig option with the internal name LogChatFilter.
/// This option is a UInt.
///
[GameConfigOption("LogChatFilter", ConfigType.UInt)]
LogChatFilter,
///
- /// System option with the internal name LogEnableErrMsgLv1.
+ /// UiConfig option with the internal name LogEnableErrMsgLv1.
/// This option is a UInt.
///
[GameConfigOption("LogEnableErrMsgLv1", ConfigType.UInt)]
LogEnableErrMsgLv1,
///
- /// System option with the internal name LogNameType.
+ /// UiConfig option with the internal name LogNameType.
/// This option is a UInt.
///
[GameConfigOption("LogNameType", ConfigType.UInt)]
LogNameType,
///
- /// System option with the internal name LogTimeDisp.
+ /// UiConfig option with the internal name LogTimeDisp.
/// This option is a UInt.
///
[GameConfigOption("LogTimeDisp", ConfigType.UInt)]
LogTimeDisp,
///
- /// System option with the internal name LogTimeSettingType.
+ /// UiConfig option with the internal name LogTimeSettingType.
/// This option is a UInt.
///
[GameConfigOption("LogTimeSettingType", ConfigType.UInt)]
LogTimeSettingType,
///
- /// System option with the internal name LogTimeDispType.
+ /// UiConfig option with the internal name LogTimeDispType.
/// This option is a UInt.
///
[GameConfigOption("LogTimeDispType", ConfigType.UInt)]
LogTimeDispType,
///
- /// System option with the internal name IsLogTell.
+ /// UiConfig option with the internal name IsLogTell.
/// This option is a UInt.
///
[GameConfigOption("IsLogTell", ConfigType.UInt)]
IsLogTell,
///
- /// System option with the internal name IsLogParty.
+ /// UiConfig option with the internal name IsLogParty.
/// This option is a UInt.
///
[GameConfigOption("IsLogParty", ConfigType.UInt)]
IsLogParty,
///
- /// System option with the internal name LogParty.
+ /// UiConfig option with the internal name LogParty.
/// This option is a UInt.
///
[GameConfigOption("LogParty", ConfigType.UInt)]
LogParty,
///
- /// System option with the internal name IsLogAlliance.
+ /// UiConfig option with the internal name IsLogAlliance.
/// This option is a UInt.
///
[GameConfigOption("IsLogAlliance", ConfigType.UInt)]
IsLogAlliance,
///
- /// System option with the internal name LogAlliance.
+ /// UiConfig option with the internal name LogAlliance.
/// This option is a UInt.
///
[GameConfigOption("LogAlliance", ConfigType.UInt)]
LogAlliance,
///
- /// System option with the internal name IsLogFc.
+ /// UiConfig option with the internal name IsLogFc.
/// This option is a UInt.
///
[GameConfigOption("IsLogFc", ConfigType.UInt)]
IsLogFc,
///
- /// System option with the internal name LogFc.
+ /// UiConfig option with the internal name LogFc.
/// This option is a UInt.
///
[GameConfigOption("LogFc", ConfigType.UInt)]
LogFc,
///
- /// System option with the internal name IsLogPvpTeam.
+ /// UiConfig option with the internal name IsLogPvpTeam.
/// This option is a UInt.
///
[GameConfigOption("IsLogPvpTeam", ConfigType.UInt)]
IsLogPvpTeam,
///
- /// System option with the internal name LogPvpTeam.
+ /// UiConfig option with the internal name LogPvpTeam.
/// This option is a UInt.
///
[GameConfigOption("LogPvpTeam", ConfigType.UInt)]
LogPvpTeam,
///
- /// System option with the internal name IsLogLs1.
+ /// UiConfig option with the internal name IsLogLs1.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs1", ConfigType.UInt)]
IsLogLs1,
///
- /// System option with the internal name LogLs1.
+ /// UiConfig option with the internal name LogLs1.
/// This option is a UInt.
///
[GameConfigOption("LogLs1", ConfigType.UInt)]
LogLs1,
///
- /// System option with the internal name IsLogLs2.
+ /// UiConfig option with the internal name IsLogLs2.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs2", ConfigType.UInt)]
IsLogLs2,
///
- /// System option with the internal name LogLs2.
+ /// UiConfig option with the internal name LogLs2.
/// This option is a UInt.
///
[GameConfigOption("LogLs2", ConfigType.UInt)]
LogLs2,
///
- /// System option with the internal name IsLogLs3.
+ /// UiConfig option with the internal name IsLogLs3.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs3", ConfigType.UInt)]
IsLogLs3,
///
- /// System option with the internal name LogLs3.
+ /// UiConfig option with the internal name LogLs3.
/// This option is a UInt.
///
[GameConfigOption("LogLs3", ConfigType.UInt)]
LogLs3,
///
- /// System option with the internal name IsLogLs4.
+ /// UiConfig option with the internal name IsLogLs4.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs4", ConfigType.UInt)]
IsLogLs4,
///
- /// System option with the internal name LogLs4.
+ /// UiConfig option with the internal name LogLs4.
/// This option is a UInt.
///
[GameConfigOption("LogLs4", ConfigType.UInt)]
LogLs4,
///
- /// System option with the internal name IsLogLs5.
+ /// UiConfig option with the internal name IsLogLs5.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs5", ConfigType.UInt)]
IsLogLs5,
///
- /// System option with the internal name LogLs5.
+ /// UiConfig option with the internal name LogLs5.
/// This option is a UInt.
///
[GameConfigOption("LogLs5", ConfigType.UInt)]
LogLs5,
///
- /// System option with the internal name IsLogLs6.
+ /// UiConfig option with the internal name IsLogLs6.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs6", ConfigType.UInt)]
IsLogLs6,
///
- /// System option with the internal name LogLs6.
+ /// UiConfig option with the internal name LogLs6.
/// This option is a UInt.
///
[GameConfigOption("LogLs6", ConfigType.UInt)]
LogLs6,
///
- /// System option with the internal name IsLogLs7.
+ /// UiConfig option with the internal name IsLogLs7.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs7", ConfigType.UInt)]
IsLogLs7,
///
- /// System option with the internal name LogLs7.
+ /// UiConfig option with the internal name LogLs7.
/// This option is a UInt.
///
[GameConfigOption("LogLs7", ConfigType.UInt)]
LogLs7,
///
- /// System option with the internal name IsLogLs8.
+ /// UiConfig option with the internal name IsLogLs8.
/// This option is a UInt.
///
[GameConfigOption("IsLogLs8", ConfigType.UInt)]
IsLogLs8,
///
- /// System option with the internal name LogLs8.
+ /// UiConfig option with the internal name LogLs8.
/// This option is a UInt.
///
[GameConfigOption("LogLs8", ConfigType.UInt)]
LogLs8,
///
- /// System option with the internal name IsLogBeginner.
+ /// UiConfig option with the internal name IsLogBeginner.
/// This option is a UInt.
///
[GameConfigOption("IsLogBeginner", ConfigType.UInt)]
IsLogBeginner,
///
- /// System option with the internal name LogBeginner.
+ /// UiConfig option with the internal name LogBeginner.
/// This option is a UInt.
///
[GameConfigOption("LogBeginner", ConfigType.UInt)]
LogBeginner,
///
- /// System option with the internal name IsLogCwls.
+ /// UiConfig option with the internal name IsLogCwls.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls", ConfigType.UInt)]
IsLogCwls,
///
- /// System option with the internal name IsLogCwls2.
+ /// UiConfig option with the internal name IsLogCwls2.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls2", ConfigType.UInt)]
IsLogCwls2,
///
- /// System option with the internal name IsLogCwls3.
+ /// UiConfig option with the internal name IsLogCwls3.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls3", ConfigType.UInt)]
IsLogCwls3,
///
- /// System option with the internal name IsLogCwls4.
+ /// UiConfig option with the internal name IsLogCwls4.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls4", ConfigType.UInt)]
IsLogCwls4,
///
- /// System option with the internal name IsLogCwls5.
+ /// UiConfig option with the internal name IsLogCwls5.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls5", ConfigType.UInt)]
IsLogCwls5,
///
- /// System option with the internal name IsLogCwls6.
+ /// UiConfig option with the internal name IsLogCwls6.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls6", ConfigType.UInt)]
IsLogCwls6,
///
- /// System option with the internal name IsLogCwls7.
+ /// UiConfig option with the internal name IsLogCwls7.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls7", ConfigType.UInt)]
IsLogCwls7,
///
- /// System option with the internal name IsLogCwls8.
+ /// UiConfig option with the internal name IsLogCwls8.
/// This option is a UInt.
///
[GameConfigOption("IsLogCwls8", ConfigType.UInt)]
IsLogCwls8,
///
- /// System option with the internal name LogCwls.
+ /// UiConfig option with the internal name LogCwls.
/// This option is a UInt.
///
[GameConfigOption("LogCwls", ConfigType.UInt)]
LogCwls,
///
- /// System option with the internal name LogCwls2.
+ /// UiConfig option with the internal name LogCwls2.
/// This option is a UInt.
///
[GameConfigOption("LogCwls2", ConfigType.UInt)]
LogCwls2,
///
- /// System option with the internal name LogCwls3.
+ /// UiConfig option with the internal name LogCwls3.
/// This option is a UInt.
///
[GameConfigOption("LogCwls3", ConfigType.UInt)]
LogCwls3,
///
- /// System option with the internal name LogCwls4.
+ /// UiConfig option with the internal name LogCwls4.
/// This option is a UInt.
///
[GameConfigOption("LogCwls4", ConfigType.UInt)]
LogCwls4,
///
- /// System option with the internal name LogCwls5.
+ /// UiConfig option with the internal name LogCwls5.
/// This option is a UInt.
///
[GameConfigOption("LogCwls5", ConfigType.UInt)]
LogCwls5,
///
- /// System option with the internal name LogCwls6.
+ /// UiConfig option with the internal name LogCwls6.
/// This option is a UInt.
///
[GameConfigOption("LogCwls6", ConfigType.UInt)]
LogCwls6,
///
- /// System option with the internal name LogCwls7.
+ /// UiConfig option with the internal name LogCwls7.
/// This option is a UInt.
///
[GameConfigOption("LogCwls7", ConfigType.UInt)]
LogCwls7,
///
- /// System option with the internal name LogCwls8.
+ /// UiConfig option with the internal name LogCwls8.
/// This option is a UInt.
///
[GameConfigOption("LogCwls8", ConfigType.UInt)]
LogCwls8,
///
- /// System option with the internal name LogRecastActionErrDisp.
+ /// UiConfig option with the internal name LogRecastActionErrDisp.
/// This option is a UInt.
///
[GameConfigOption("LogRecastActionErrDisp", ConfigType.UInt)]
LogRecastActionErrDisp,
///
- /// System option with the internal name LogPermeationRate.
+ /// UiConfig option with the internal name LogPermeationRate.
/// This option is a UInt.
///
[GameConfigOption("LogPermeationRate", ConfigType.UInt)]
LogPermeationRate,
///
- /// System option with the internal name LogFontSizeForm.
+ /// UiConfig option with the internal name LogFontSizeForm.
/// This option is a UInt.
///
[GameConfigOption("LogFontSizeForm", ConfigType.UInt)]
LogFontSizeForm,
///
- /// System option with the internal name LogItemLinkEnableType.
+ /// UiConfig option with the internal name LogItemLinkEnableType.
/// This option is a UInt.
///
[GameConfigOption("LogItemLinkEnableType", ConfigType.UInt)]
LogItemLinkEnableType,
///
- /// System option with the internal name LogFontSizeLog2.
+ /// UiConfig option with the internal name LogFontSizeLog2.
/// This option is a UInt.
///
[GameConfigOption("LogFontSizeLog2", ConfigType.UInt)]
LogFontSizeLog2,
///
- /// System option with the internal name LogTimeDispLog2.
+ /// UiConfig option with the internal name LogTimeDispLog2.
/// This option is a UInt.
///
[GameConfigOption("LogTimeDispLog2", ConfigType.UInt)]
LogTimeDispLog2,
///
- /// System option with the internal name LogPermeationRateLog2.
+ /// UiConfig option with the internal name LogPermeationRateLog2.
/// This option is a UInt.
///
[GameConfigOption("LogPermeationRateLog2", ConfigType.UInt)]
LogPermeationRateLog2,
///
- /// System option with the internal name LogFontSizeLog3.
+ /// UiConfig option with the internal name LogFontSizeLog3.
/// This option is a UInt.
///
[GameConfigOption("LogFontSizeLog3", ConfigType.UInt)]
LogFontSizeLog3,
///
- /// System option with the internal name LogTimeDispLog3.
+ /// UiConfig option with the internal name LogTimeDispLog3.
/// This option is a UInt.
///
[GameConfigOption("LogTimeDispLog3", ConfigType.UInt)]
LogTimeDispLog3,
///
- /// System option with the internal name LogPermeationRateLog3.
+ /// UiConfig option with the internal name LogPermeationRateLog3.
/// This option is a UInt.
///
[GameConfigOption("LogPermeationRateLog3", ConfigType.UInt)]
LogPermeationRateLog3,
///
- /// System option with the internal name LogFontSizeLog4.
+ /// UiConfig option with the internal name LogFontSizeLog4.
/// This option is a UInt.
///
[GameConfigOption("LogFontSizeLog4", ConfigType.UInt)]
LogFontSizeLog4,
///
- /// System option with the internal name LogTimeDispLog4.
+ /// UiConfig option with the internal name LogTimeDispLog4.
/// This option is a UInt.
///
[GameConfigOption("LogTimeDispLog4", ConfigType.UInt)]
LogTimeDispLog4,
///
- /// System option with the internal name LogPermeationRateLog4.
+ /// UiConfig option with the internal name LogPermeationRateLog4.
/// This option is a UInt.
///
[GameConfigOption("LogPermeationRateLog4", ConfigType.UInt)]
LogPermeationRateLog4,
///
- /// System option with the internal name LogFlyingHeightMaxErrDisp.
+ /// UiConfig option with the internal name LogFlyingHeightMaxErrDisp.
/// This option is a UInt.
///
[GameConfigOption("LogFlyingHeightMaxErrDisp", ConfigType.UInt)]
LogFlyingHeightMaxErrDisp,
///
- /// System option with the internal name LogCrossWorldName.
+ /// UiConfig option with the internal name LogCrossWorldName.
/// This option is a UInt.
///
[GameConfigOption("LogCrossWorldName", ConfigType.UInt)]
LogCrossWorldName,
///
- /// System option with the internal name LogDragResize.
+ /// UiConfig option with the internal name LogDragResize.
/// This option is a UInt.
///
[GameConfigOption("LogDragResize", ConfigType.UInt)]
LogDragResize,
///
- /// System option with the internal name LogNameIconType.
+ /// UiConfig option with the internal name LogNameIconType.
/// This option is a UInt.
///
[GameConfigOption("LogNameIconType", ConfigType.UInt)]
LogNameIconType,
///
- /// System option with the internal name LogDispClassJobName.
+ /// UiConfig option with the internal name LogDispClassJobName.
/// This option is a UInt.
///
[GameConfigOption("LogDispClassJobName", ConfigType.UInt)]
LogDispClassJobName,
///
- /// System option with the internal name LogSetRoleColor.
+ /// UiConfig option with the internal name LogSetRoleColor.
/// This option is a UInt.
///
[GameConfigOption("LogSetRoleColor", ConfigType.UInt)]
LogSetRoleColor,
///
- /// System option with the internal name LogColorRoleTank.
+ /// UiConfig option with the internal name LogColorRoleTank.
/// This option is a UInt.
///
[GameConfigOption("LogColorRoleTank", ConfigType.UInt)]
LogColorRoleTank,
///
- /// System option with the internal name LogColorRoleHealer.
+ /// UiConfig option with the internal name LogColorRoleHealer.
/// This option is a UInt.
///
[GameConfigOption("LogColorRoleHealer", ConfigType.UInt)]
LogColorRoleHealer,
///
- /// System option with the internal name LogColorRoleDPS.
+ /// UiConfig option with the internal name LogColorRoleDPS.
/// This option is a UInt.
///
[GameConfigOption("LogColorRoleDPS", ConfigType.UInt)]
LogColorRoleDPS,
///
- /// System option with the internal name LogColorOtherClass.
+ /// UiConfig option with the internal name LogColorOtherClass.
/// This option is a UInt.
///
[GameConfigOption("LogColorOtherClass", ConfigType.UInt)]
LogColorOtherClass,
///
- /// System option with the internal name ChatType.
+ /// UiConfig option with the internal name ChatType.
/// This option is a UInt.
///
[GameConfigOption("ChatType", ConfigType.UInt)]
ChatType,
///
- /// System option with the internal name ShopSell.
+ /// UiConfig option with the internal name ShopSell.
/// This option is a UInt.
///
[GameConfigOption("ShopSell", ConfigType.UInt)]
ShopSell,
///
- /// System option with the internal name ColorSay.
+ /// UiConfig option with the internal name ColorSay.
/// This option is a UInt.
///
[GameConfigOption("ColorSay", ConfigType.UInt)]
ColorSay,
///
- /// System option with the internal name ColorShout.
+ /// UiConfig option with the internal name ColorShout.
/// This option is a UInt.
///
[GameConfigOption("ColorShout", ConfigType.UInt)]
ColorShout,
///
- /// System option with the internal name ColorTell.
+ /// UiConfig option with the internal name ColorTell.
/// This option is a UInt.
///
[GameConfigOption("ColorTell", ConfigType.UInt)]
ColorTell,
///
- /// System option with the internal name ColorParty.
+ /// UiConfig option with the internal name ColorParty.
/// This option is a UInt.
///
[GameConfigOption("ColorParty", ConfigType.UInt)]
ColorParty,
///
- /// System option with the internal name ColorAlliance.
+ /// UiConfig option with the internal name ColorAlliance.
/// This option is a UInt.
///
[GameConfigOption("ColorAlliance", ConfigType.UInt)]
ColorAlliance,
///
- /// System option with the internal name ColorLS1.
+ /// UiConfig option with the internal name ColorLS1.
/// This option is a UInt.
///
[GameConfigOption("ColorLS1", ConfigType.UInt)]
ColorLS1,
///
- /// System option with the internal name ColorLS2.
+ /// UiConfig option with the internal name ColorLS2.
/// This option is a UInt.
///
[GameConfigOption("ColorLS2", ConfigType.UInt)]
ColorLS2,
///
- /// System option with the internal name ColorLS3.
+ /// UiConfig option with the internal name ColorLS3.
/// This option is a UInt.
///
[GameConfigOption("ColorLS3", ConfigType.UInt)]
ColorLS3,
///
- /// System option with the internal name ColorLS4.
+ /// UiConfig option with the internal name ColorLS4.
/// This option is a UInt.
///
[GameConfigOption("ColorLS4", ConfigType.UInt)]
ColorLS4,
///
- /// System option with the internal name ColorLS5.
+ /// UiConfig option with the internal name ColorLS5.
/// This option is a UInt.
///
[GameConfigOption("ColorLS5", ConfigType.UInt)]
ColorLS5,
///
- /// System option with the internal name ColorLS6.
+ /// UiConfig option with the internal name ColorLS6.
/// This option is a UInt.
///
[GameConfigOption("ColorLS6", ConfigType.UInt)]
ColorLS6,
///
- /// System option with the internal name ColorLS7.
+ /// UiConfig option with the internal name ColorLS7.
/// This option is a UInt.
///
[GameConfigOption("ColorLS7", ConfigType.UInt)]
ColorLS7,
///
- /// System option with the internal name ColorLS8.
+ /// UiConfig option with the internal name ColorLS8.
/// This option is a UInt.
///
[GameConfigOption("ColorLS8", ConfigType.UInt)]
ColorLS8,
///
- /// System option with the internal name ColorFCompany.
+ /// UiConfig option with the internal name ColorFCompany.
/// This option is a UInt.
///
[GameConfigOption("ColorFCompany", ConfigType.UInt)]
ColorFCompany,
///
- /// System option with the internal name ColorPvPGroup.
+ /// UiConfig option with the internal name ColorPvPGroup.
/// This option is a UInt.
///
[GameConfigOption("ColorPvPGroup", ConfigType.UInt)]
ColorPvPGroup,
///
- /// System option with the internal name ColorPvPGroupAnnounce.
+ /// UiConfig option with the internal name ColorPvPGroupAnnounce.
/// This option is a UInt.
///
[GameConfigOption("ColorPvPGroupAnnounce", ConfigType.UInt)]
ColorPvPGroupAnnounce,
///
- /// System option with the internal name ColorBeginner.
+ /// UiConfig option with the internal name ColorBeginner.
/// This option is a UInt.
///
[GameConfigOption("ColorBeginner", ConfigType.UInt)]
ColorBeginner,
///
- /// System option with the internal name ColorEmoteUser.
+ /// UiConfig option with the internal name ColorEmoteUser.
/// This option is a UInt.
///
[GameConfigOption("ColorEmoteUser", ConfigType.UInt)]
ColorEmoteUser,
///
- /// System option with the internal name ColorEmote.
+ /// UiConfig option with the internal name ColorEmote.
/// This option is a UInt.
///
[GameConfigOption("ColorEmote", ConfigType.UInt)]
ColorEmote,
///
- /// System option with the internal name ColorYell.
+ /// UiConfig option with the internal name ColorYell.
/// This option is a UInt.
///
[GameConfigOption("ColorYell", ConfigType.UInt)]
ColorYell,
///
- /// System option with the internal name ColorBeginnerAnnounce.
+ /// UiConfig option with the internal name ColorBeginnerAnnounce.
/// This option is a UInt.
///
[GameConfigOption("ColorBeginnerAnnounce", ConfigType.UInt)]
ColorBeginnerAnnounce,
///
- /// System option with the internal name ColorCWLS.
+ /// UiConfig option with the internal name ColorCWLS.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS", ConfigType.UInt)]
ColorCWLS,
///
- /// System option with the internal name ColorCWLS2.
+ /// UiConfig option with the internal name ColorCWLS2.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS2", ConfigType.UInt)]
ColorCWLS2,
///
- /// System option with the internal name ColorCWLS3.
+ /// UiConfig option with the internal name ColorCWLS3.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS3", ConfigType.UInt)]
ColorCWLS3,
///
- /// System option with the internal name ColorCWLS4.
+ /// UiConfig option with the internal name ColorCWLS4.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS4", ConfigType.UInt)]
ColorCWLS4,
///
- /// System option with the internal name ColorCWLS5.
+ /// UiConfig option with the internal name ColorCWLS5.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS5", ConfigType.UInt)]
ColorCWLS5,
///
- /// System option with the internal name ColorCWLS6.
+ /// UiConfig option with the internal name ColorCWLS6.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS6", ConfigType.UInt)]
ColorCWLS6,
///
- /// System option with the internal name ColorCWLS7.
+ /// UiConfig option with the internal name ColorCWLS7.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS7", ConfigType.UInt)]
ColorCWLS7,
///
- /// System option with the internal name ColorCWLS8.
+ /// UiConfig option with the internal name ColorCWLS8.
/// This option is a UInt.
///
[GameConfigOption("ColorCWLS8", ConfigType.UInt)]
ColorCWLS8,
///
- /// System option with the internal name ColorAttackSuccess.
+ /// UiConfig option with the internal name ColorAttackSuccess.
/// This option is a UInt.
///
[GameConfigOption("ColorAttackSuccess", ConfigType.UInt)]
ColorAttackSuccess,
///
- /// System option with the internal name ColorAttackFailure.
+ /// UiConfig option with the internal name ColorAttackFailure.
/// This option is a UInt.
///
[GameConfigOption("ColorAttackFailure", ConfigType.UInt)]
ColorAttackFailure,
///
- /// System option with the internal name ColorAction.
+ /// UiConfig option with the internal name ColorAction.
/// This option is a UInt.
///
[GameConfigOption("ColorAction", ConfigType.UInt)]
ColorAction,
///
- /// System option with the internal name ColorItem.
+ /// UiConfig option with the internal name ColorItem.
/// This option is a UInt.
///
[GameConfigOption("ColorItem", ConfigType.UInt)]
ColorItem,
///
- /// System option with the internal name ColorCureGive.
+ /// UiConfig option with the internal name ColorCureGive.
/// This option is a UInt.
///
[GameConfigOption("ColorCureGive", ConfigType.UInt)]
ColorCureGive,
///
- /// System option with the internal name ColorBuffGive.
+ /// UiConfig option with the internal name ColorBuffGive.
/// This option is a UInt.
///
[GameConfigOption("ColorBuffGive", ConfigType.UInt)]
ColorBuffGive,
///
- /// System option with the internal name ColorDebuffGive.
+ /// UiConfig option with the internal name ColorDebuffGive.
/// This option is a UInt.
///
[GameConfigOption("ColorDebuffGive", ConfigType.UInt)]
ColorDebuffGive,
///
- /// System option with the internal name ColorEcho.
+ /// UiConfig option with the internal name ColorEcho.
/// This option is a UInt.
///
[GameConfigOption("ColorEcho", ConfigType.UInt)]
ColorEcho,
///
- /// System option with the internal name ColorSysMsg.
+ /// UiConfig option with the internal name ColorSysMsg.
/// This option is a UInt.
///
[GameConfigOption("ColorSysMsg", ConfigType.UInt)]
ColorSysMsg,
///
- /// System option with the internal name ColorFCAnnounce.
+ /// UiConfig option with the internal name ColorFCAnnounce.
/// This option is a UInt.
///
[GameConfigOption("ColorFCAnnounce", ConfigType.UInt)]
ColorFCAnnounce,
///
- /// System option with the internal name ColorSysBattle.
+ /// UiConfig option with the internal name ColorSysBattle.
/// This option is a UInt.
///
[GameConfigOption("ColorSysBattle", ConfigType.UInt)]
ColorSysBattle,
///
- /// System option with the internal name ColorSysGathering.
+ /// UiConfig option with the internal name ColorSysGathering.
/// This option is a UInt.
///
[GameConfigOption("ColorSysGathering", ConfigType.UInt)]
ColorSysGathering,
///
- /// System option with the internal name ColorSysErr.
+ /// UiConfig option with the internal name ColorSysErr.
/// This option is a UInt.
///
[GameConfigOption("ColorSysErr", ConfigType.UInt)]
ColorSysErr,
///
- /// System option with the internal name ColorNpcSay.
+ /// UiConfig option with the internal name ColorNpcSay.
/// This option is a UInt.
///
[GameConfigOption("ColorNpcSay", ConfigType.UInt)]
ColorNpcSay,
///
- /// System option with the internal name ColorItemNotice.
+ /// UiConfig option with the internal name ColorItemNotice.
/// This option is a UInt.
///
[GameConfigOption("ColorItemNotice", ConfigType.UInt)]
ColorItemNotice,
///
- /// System option with the internal name ColorGrowup.
+ /// UiConfig option with the internal name ColorGrowup.
/// This option is a UInt.
///
[GameConfigOption("ColorGrowup", ConfigType.UInt)]
ColorGrowup,
///
- /// System option with the internal name ColorLoot.
+ /// UiConfig option with the internal name ColorLoot.
/// This option is a UInt.
///
[GameConfigOption("ColorLoot", ConfigType.UInt)]
ColorLoot,
///
- /// System option with the internal name ColorCraft.
+ /// UiConfig option with the internal name ColorCraft.
/// This option is a UInt.
///
[GameConfigOption("ColorCraft", ConfigType.UInt)]
ColorCraft,
///
- /// System option with the internal name ColorGathering.
+ /// UiConfig option with the internal name ColorGathering.
/// This option is a UInt.
///
[GameConfigOption("ColorGathering", ConfigType.UInt)]
ColorGathering,
///
- /// System option with the internal name ShopConfirm.
+ /// UiConfig option with the internal name ShopConfirm.
/// This option is a UInt.
///
[GameConfigOption("ShopConfirm", ConfigType.UInt)]
ShopConfirm,
///
- /// System option with the internal name ShopConfirmMateria.
+ /// UiConfig option with the internal name ShopConfirmMateria.
/// This option is a UInt.
///
[GameConfigOption("ShopConfirmMateria", ConfigType.UInt)]
ShopConfirmMateria,
///
- /// System option with the internal name ShopConfirmExRare.
+ /// UiConfig option with the internal name ShopConfirmExRare.
/// This option is a UInt.
///
[GameConfigOption("ShopConfirmExRare", ConfigType.UInt)]
ShopConfirmExRare,
///
- /// System option with the internal name ShopConfirmSpiritBondMax.
+ /// UiConfig option with the internal name ShopConfirmSpiritBondMax.
/// This option is a UInt.
///
[GameConfigOption("ShopConfirmSpiritBondMax", ConfigType.UInt)]
ShopConfirmSpiritBondMax,
///
- /// System option with the internal name ItemSortItemCategory.
+ /// UiConfig option with the internal name ItemSortItemCategory.
/// This option is a UInt.
///
[GameConfigOption("ItemSortItemCategory", ConfigType.UInt)]
ItemSortItemCategory,
///
- /// System option with the internal name ItemSortEquipLevel.
+ /// UiConfig option with the internal name ItemSortEquipLevel.
/// This option is a UInt.
///
[GameConfigOption("ItemSortEquipLevel", ConfigType.UInt)]
ItemSortEquipLevel,
///
- /// System option with the internal name ItemSortItemLevel.
+ /// UiConfig option with the internal name ItemSortItemLevel.
/// This option is a UInt.
///
[GameConfigOption("ItemSortItemLevel", ConfigType.UInt)]
ItemSortItemLevel,
///
- /// System option with the internal name ItemSortItemStack.
+ /// UiConfig option with the internal name ItemSortItemStack.
/// This option is a UInt.
///
[GameConfigOption("ItemSortItemStack", ConfigType.UInt)]
ItemSortItemStack,
///
- /// System option with the internal name ItemSortTidyingType.
+ /// UiConfig option with the internal name ItemSortTidyingType.
/// This option is a UInt.
///
[GameConfigOption("ItemSortTidyingType", ConfigType.UInt)]
ItemSortTidyingType,
///
- /// System option with the internal name ItemNoArmoryMaskOff.
+ /// UiConfig option with the internal name ItemNoArmoryMaskOff.
/// This option is a UInt.
///
[GameConfigOption("ItemNoArmoryMaskOff", ConfigType.UInt)]
ItemNoArmoryMaskOff,
///
- /// System option with the internal name ItemInventryStoreEnd.
+ /// UiConfig option with the internal name ItemInventryStoreEnd.
/// This option is a UInt.
///
[GameConfigOption("ItemInventryStoreEnd", ConfigType.UInt)]
ItemInventryStoreEnd,
///
- /// System option with the internal name InfoSettingDispWorldNameType.
+ /// UiConfig option with the internal name InfoSettingDispWorldNameType.
/// This option is a UInt.
///
[GameConfigOption("InfoSettingDispWorldNameType", ConfigType.UInt)]
InfoSettingDispWorldNameType,
///
- /// System option with the internal name TargetNamePlateNameType.
+ /// UiConfig option with the internal name TargetNamePlateNameType.
/// This option is a UInt.
///
[GameConfigOption("TargetNamePlateNameType", ConfigType.UInt)]
TargetNamePlateNameType,
///
- /// System option with the internal name FocusTargetNamePlateNameType.
+ /// UiConfig option with the internal name FocusTargetNamePlateNameType.
/// This option is a UInt.
///
[GameConfigOption("FocusTargetNamePlateNameType", ConfigType.UInt)]
FocusTargetNamePlateNameType,
///
- /// System option with the internal name ItemDetailTemporarilySwitch.
+ /// UiConfig option with the internal name ItemDetailTemporarilySwitch.
/// This option is a UInt.
///
[GameConfigOption("ItemDetailTemporarilySwitch", ConfigType.UInt)]
ItemDetailTemporarilySwitch,
///
- /// System option with the internal name ItemDetailTemporarilySwitchKey.
+ /// UiConfig option with the internal name ItemDetailTemporarilySwitchKey.
/// This option is a UInt.
///
[GameConfigOption("ItemDetailTemporarilySwitchKey", ConfigType.UInt)]
ItemDetailTemporarilySwitchKey,
///
- /// System option with the internal name ItemDetailTemporarilyHide.
+ /// UiConfig option with the internal name ItemDetailTemporarilyHide.
/// This option is a UInt.
///
[GameConfigOption("ItemDetailTemporarilyHide", ConfigType.UInt)]
ItemDetailTemporarilyHide,
///
- /// System option with the internal name ItemDetailTemporarilyHideKey.
+ /// UiConfig option with the internal name ItemDetailTemporarilyHideKey.
/// This option is a UInt.
///
[GameConfigOption("ItemDetailTemporarilyHideKey", ConfigType.UInt)]
ItemDetailTemporarilyHideKey,
///
- /// System option with the internal name ToolTipDispSize.
+ /// UiConfig option with the internal name ToolTipDispSize.
/// This option is a UInt.
///
[GameConfigOption("ToolTipDispSize", ConfigType.UInt)]
ToolTipDispSize,
///
- /// System option with the internal name RecommendLoginDisp.
+ /// UiConfig option with the internal name RecommendLoginDisp.
/// This option is a UInt.
///
[GameConfigOption("RecommendLoginDisp", ConfigType.UInt)]
RecommendLoginDisp,
///
- /// System option with the internal name RecommendAreaChangeDisp.
+ /// UiConfig option with the internal name RecommendAreaChangeDisp.
/// This option is a UInt.
///
[GameConfigOption("RecommendAreaChangeDisp", ConfigType.UInt)]
RecommendAreaChangeDisp,
///
- /// System option with the internal name PlayGuideLoginDisp.
+ /// UiConfig option with the internal name PlayGuideLoginDisp.
/// This option is a UInt.
///
[GameConfigOption("PlayGuideLoginDisp", ConfigType.UInt)]
PlayGuideLoginDisp,
///
- /// System option with the internal name PlayGuideAreaChangeDisp.
+ /// UiConfig option with the internal name PlayGuideAreaChangeDisp.
/// This option is a UInt.
///
[GameConfigOption("PlayGuideAreaChangeDisp", ConfigType.UInt)]
PlayGuideAreaChangeDisp,
///
- /// System option with the internal name MapPadOperationYReverse.
+ /// UiConfig option with the internal name MapPadOperationYReverse.
/// This option is a UInt.
///
[GameConfigOption("MapPadOperationYReverse", ConfigType.UInt)]
MapPadOperationYReverse,
///
- /// System option with the internal name MapPadOperationXReverse.
+ /// UiConfig option with the internal name MapPadOperationXReverse.
/// This option is a UInt.
///
[GameConfigOption("MapPadOperationXReverse", ConfigType.UInt)]
MapPadOperationXReverse,
///
- /// System option with the internal name MapDispSize.
+ /// UiConfig option with the internal name MapDispSize.
/// This option is a UInt.
///
[GameConfigOption("MapDispSize", ConfigType.UInt)]
MapDispSize,
///
- /// System option with the internal name FlyTextDispSize.
+ /// UiConfig option with the internal name FlyTextDispSize.
/// This option is a UInt.
///
[GameConfigOption("FlyTextDispSize", ConfigType.UInt)]
FlyTextDispSize,
///
- /// System option with the internal name PopUpTextDispSize.
+ /// UiConfig option with the internal name PopUpTextDispSize.
/// This option is a UInt.
///
[GameConfigOption("PopUpTextDispSize", ConfigType.UInt)]
PopUpTextDispSize,
///
- /// System option with the internal name DetailDispDelayType.
+ /// UiConfig option with the internal name DetailDispDelayType.
/// This option is a UInt.
///
[GameConfigOption("DetailDispDelayType", ConfigType.UInt)]
DetailDispDelayType,
///
- /// System option with the internal name PartyListSortTypeTank.
+ /// UiConfig option with the internal name PartyListSortTypeTank.
/// This option is a UInt.
///
[GameConfigOption("PartyListSortTypeTank", ConfigType.UInt)]
PartyListSortTypeTank,
///
- /// System option with the internal name PartyListSortTypeHealer.
+ /// UiConfig option with the internal name PartyListSortTypeHealer.
/// This option is a UInt.
///
[GameConfigOption("PartyListSortTypeHealer", ConfigType.UInt)]
PartyListSortTypeHealer,
///
- /// System option with the internal name PartyListSortTypeDps.
+ /// UiConfig option with the internal name PartyListSortTypeDps.
/// This option is a UInt.
///
[GameConfigOption("PartyListSortTypeDps", ConfigType.UInt)]
PartyListSortTypeDps,
///
- /// System option with the internal name PartyListSortTypeOther.
+ /// UiConfig option with the internal name PartyListSortTypeOther.
/// This option is a UInt.
///
[GameConfigOption("PartyListSortTypeOther", ConfigType.UInt)]
PartyListSortTypeOther,
///
- /// System option with the internal name RatioHpDisp.
+ /// UiConfig option with the internal name RatioHpDisp.
/// This option is a UInt.
///
[GameConfigOption("RatioHpDisp", ConfigType.UInt)]
RatioHpDisp,
///
- /// System option with the internal name BuffDispType.
+ /// UiConfig option with the internal name BuffDispType.
/// This option is a UInt.
///
[GameConfigOption("BuffDispType", ConfigType.UInt)]
BuffDispType,
///
- /// System option with the internal name ContentsFinderListSortType.
+ /// UiConfig option with the internal name ContentsFinderListSortType.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderListSortType", ConfigType.UInt)]
ContentsFinderListSortType,
///
- /// System option with the internal name ContentsFinderSupplyEnable.
+ /// UiConfig option with the internal name ContentsFinderSupplyEnable.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderSupplyEnable", ConfigType.UInt)]
ContentsFinderSupplyEnable,
///
- /// System option with the internal name EnemyListCastbarEnable.
+ /// UiConfig option with the internal name EnemyListCastbarEnable.
/// This option is a UInt.
///
[GameConfigOption("EnemyListCastbarEnable", ConfigType.UInt)]
EnemyListCastbarEnable,
///
- /// System option with the internal name AchievementAppealLoginDisp.
+ /// UiConfig option with the internal name AchievementAppealLoginDisp.
/// This option is a UInt.
///
[GameConfigOption("AchievementAppealLoginDisp", ConfigType.UInt)]
AchievementAppealLoginDisp,
///
- /// System option with the internal name ContentsFinderUseLangTypeJA.
+ /// UiConfig option with the internal name ContentsFinderUseLangTypeJA.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderUseLangTypeJA", ConfigType.UInt)]
ContentsFinderUseLangTypeJA,
///
- /// System option with the internal name ContentsFinderUseLangTypeEN.
+ /// UiConfig option with the internal name ContentsFinderUseLangTypeEN.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderUseLangTypeEN", ConfigType.UInt)]
ContentsFinderUseLangTypeEN,
///
- /// System option with the internal name ContentsFinderUseLangTypeDE.
+ /// UiConfig option with the internal name ContentsFinderUseLangTypeDE.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderUseLangTypeDE", ConfigType.UInt)]
ContentsFinderUseLangTypeDE,
///
- /// System option with the internal name ContentsFinderUseLangTypeFR.
+ /// UiConfig option with the internal name ContentsFinderUseLangTypeFR.
/// This option is a UInt.
///
[GameConfigOption("ContentsFinderUseLangTypeFR", ConfigType.UInt)]
ContentsFinderUseLangTypeFR,
///
- /// System option with the internal name ItemInventryWindowSizeType.
+ /// UiConfig option with the internal name ItemInventryWindowSizeType.
/// This option is a UInt.
///
[GameConfigOption("ItemInventryWindowSizeType", ConfigType.UInt)]
ItemInventryWindowSizeType,
///
- /// System option with the internal name ItemInventryRetainerWindowSizeType.
+ /// UiConfig option with the internal name ItemInventryRetainerWindowSizeType.
/// This option is a UInt.
///
[GameConfigOption("ItemInventryRetainerWindowSizeType", ConfigType.UInt)]
ItemInventryRetainerWindowSizeType,
///
- /// System option with the internal name BattleTalkShowFace.
+ /// UiConfig option with the internal name BattleTalkShowFace.
/// This option is a UInt.
///
[GameConfigOption("BattleTalkShowFace", ConfigType.UInt)]
BattleTalkShowFace,
///
- /// System option with the internal name BannerContentsDispType.
+ /// UiConfig option with the internal name BannerContentsDispType.
/// This option is a UInt.
///
[GameConfigOption("BannerContentsDispType", ConfigType.UInt)]
BannerContentsDispType,
///
- /// System option with the internal name BannerContentsNotice.
+ /// UiConfig option with the internal name BannerContentsNotice.
/// This option is a UInt.
///
[GameConfigOption("BannerContentsNotice", ConfigType.UInt)]
BannerContentsNotice,
///
- /// System option with the internal name MipDispType.
+ /// UiConfig option with the internal name MipDispType.
/// This option is a UInt.
///
[GameConfigOption("MipDispType", ConfigType.UInt)]
MipDispType,
///
- /// System option with the internal name BannerContentsOrderType.
+ /// UiConfig option with the internal name BannerContentsOrderType.
/// This option is a UInt.
///
[GameConfigOption("BannerContentsOrderType", ConfigType.UInt)]
BannerContentsOrderType,
///
- /// System option with the internal name CCProgressAllyFixLeftSide.
+ /// UiConfig option with the internal name CCProgressAllyFixLeftSide.
/// This option is a UInt.
///
[GameConfigOption("CCProgressAllyFixLeftSide", ConfigType.UInt)]
CCProgressAllyFixLeftSide,
///
- /// System option with the internal name CCMapAllyFixLeftSide.
+ /// UiConfig option with the internal name CCMapAllyFixLeftSide.
/// This option is a UInt.
///
[GameConfigOption("CCMapAllyFixLeftSide", ConfigType.UInt)]
CCMapAllyFixLeftSide,
///
- /// System option with the internal name DispCCCountDown.
+ /// UiConfig option with the internal name DispCCCountDown.
/// This option is a UInt.
///
[GameConfigOption("DispCCCountDown", ConfigType.UInt)]
DispCCCountDown,
///
- /// System option with the internal name EmoteTextType.
+ /// UiConfig option with the internal name EmoteTextType.
/// This option is a UInt.
///
[GameConfigOption("EmoteTextType", ConfigType.UInt)]
EmoteTextType,
///
- /// System option with the internal name IsEmoteSe.
+ /// UiConfig option with the internal name IsEmoteSe.
/// This option is a UInt.
///
[GameConfigOption("IsEmoteSe", ConfigType.UInt)]
IsEmoteSe,
///
- /// System option with the internal name EmoteSeType.
+ /// UiConfig option with the internal name EmoteSeType.
/// This option is a UInt.
///
[GameConfigOption("EmoteSeType", ConfigType.UInt)]
EmoteSeType,
///
- /// System option with the internal name PartyFinderNewArrivalDisp.
+ /// UiConfig option with the internal name PartyFinderNewArrivalDisp.
/// This option is a UInt.
///
[GameConfigOption("PartyFinderNewArrivalDisp", ConfigType.UInt)]
PartyFinderNewArrivalDisp,
///
- /// System option with the internal name GPoseTargetFilterNPCLookAt.
+ /// UiConfig option with the internal name GPoseTargetFilterNPCLookAt.
/// This option is a UInt.
///
[GameConfigOption("GPoseTargetFilterNPCLookAt", ConfigType.UInt)]
GPoseTargetFilterNPCLookAt,
///
- /// System option with the internal name GPoseMotionFilterAction.
+ /// UiConfig option with the internal name GPoseMotionFilterAction.
/// This option is a UInt.
///
[GameConfigOption("GPoseMotionFilterAction", ConfigType.UInt)]
GPoseMotionFilterAction,
///
- /// System option with the internal name LsListSortPriority.
+ /// UiConfig option with the internal name LsListSortPriority.
/// This option is a UInt.
///
[GameConfigOption("LsListSortPriority", ConfigType.UInt)]
LsListSortPriority,
///
- /// System option with the internal name FriendListSortPriority.
+ /// UiConfig option with the internal name FriendListSortPriority.
/// This option is a UInt.
///
[GameConfigOption("FriendListSortPriority", ConfigType.UInt)]
FriendListSortPriority,
///
- /// System option with the internal name FriendListFilterType.
+ /// UiConfig option with the internal name FriendListFilterType.
/// This option is a UInt.
///
[GameConfigOption("FriendListFilterType", ConfigType.UInt)]
FriendListFilterType,
///
- /// System option with the internal name FriendListSortType.
+ /// UiConfig option with the internal name FriendListSortType.
/// This option is a UInt.
///
[GameConfigOption("FriendListSortType", ConfigType.UInt)]
FriendListSortType,
///
- /// System option with the internal name LetterListFilterType.
+ /// UiConfig option with the internal name LetterListFilterType.
/// This option is a UInt.
///
[GameConfigOption("LetterListFilterType", ConfigType.UInt)]
LetterListFilterType,
///
- /// System option with the internal name LetterListSortType.
+ /// UiConfig option with the internal name LetterListSortType.
/// This option is a UInt.
///
[GameConfigOption("LetterListSortType", ConfigType.UInt)]
LetterListSortType,
///
- /// System option with the internal name ContentsReplayEnable.
+ /// UiConfig option with the internal name ContentsReplayEnable.
/// This option is a UInt.
///
[GameConfigOption("ContentsReplayEnable", ConfigType.UInt)]
ContentsReplayEnable,
///
- /// System option with the internal name MouseWheelOperationUp.
+ /// UiConfig option with the internal name MouseWheelOperationUp.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationUp", ConfigType.UInt)]
MouseWheelOperationUp,
///
- /// System option with the internal name MouseWheelOperationDown.
+ /// UiConfig option with the internal name MouseWheelOperationDown.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationDown", ConfigType.UInt)]
MouseWheelOperationDown,
///
- /// System option with the internal name MouseWheelOperationCtrlUp.
+ /// UiConfig option with the internal name MouseWheelOperationCtrlUp.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationCtrlUp", ConfigType.UInt)]
MouseWheelOperationCtrlUp,
///
- /// System option with the internal name MouseWheelOperationCtrlDown.
+ /// UiConfig option with the internal name MouseWheelOperationCtrlDown.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationCtrlDown", ConfigType.UInt)]
MouseWheelOperationCtrlDown,
///
- /// System option with the internal name MouseWheelOperationAltUp.
+ /// UiConfig option with the internal name MouseWheelOperationAltUp.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationAltUp", ConfigType.UInt)]
MouseWheelOperationAltUp,
///
- /// System option with the internal name MouseWheelOperationAltDown.
+ /// UiConfig option with the internal name MouseWheelOperationAltDown.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationAltDown", ConfigType.UInt)]
MouseWheelOperationAltDown,
///
- /// System option with the internal name MouseWheelOperationShiftUp.
+ /// UiConfig option with the internal name MouseWheelOperationShiftUp.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationShiftUp", ConfigType.UInt)]
MouseWheelOperationShiftUp,
///
- /// System option with the internal name MouseWheelOperationShiftDown.
+ /// UiConfig option with the internal name MouseWheelOperationShiftDown.
/// This option is a UInt.
///
[GameConfigOption("MouseWheelOperationShiftDown", ConfigType.UInt)]
MouseWheelOperationShiftDown,
///
- /// System option with the internal name TelepoTicketUseType.
+ /// UiConfig option with the internal name TelepoTicketUseType.
/// This option is a UInt.
///
[GameConfigOption("TelepoTicketUseType", ConfigType.UInt)]
TelepoTicketUseType,
///
- /// System option with the internal name TelepoTicketGilSetting.
+ /// UiConfig option with the internal name TelepoTicketGilSetting.
/// This option is a UInt.
///
[GameConfigOption("TelepoTicketGilSetting", ConfigType.UInt)]
TelepoTicketGilSetting,
///
- /// System option with the internal name TelepoCategoryType.
+ /// UiConfig option with the internal name TelepoCategoryType.
/// This option is a UInt.
///
[GameConfigOption("TelepoCategoryType", ConfigType.UInt)]
TelepoCategoryType,
///
- /// System option with the internal name HidePcAroundQuestProgressNpc.
+ /// UiConfig option with the internal name HidePcAroundQuestProgressNpc.
/// This option is a UInt.
///
[GameConfigOption("HidePcAroundQuestProgressNpc", ConfigType.UInt)]
HidePcAroundQuestProgressNpc,
///
- /// System option with the internal name HidePcAroundQuestProgressNpcIncludeParty.
+ /// UiConfig option with the internal name HidePcAroundQuestProgressNpcIncludeParty.
/// This option is a UInt.
///
[GameConfigOption("HidePcAroundQuestProgressNpcIncludeParty", ConfigType.UInt)]
HidePcAroundQuestProgressNpcIncludeParty,
///
- /// System option with the internal name HidePcAroundNpcAccessingQuest.
+ /// UiConfig option with the internal name HidePcAroundNpcAccessingQuest.
/// This option is a UInt.
///
[GameConfigOption("HidePcAroundNpcAccessingQuest", ConfigType.UInt)]
HidePcAroundNpcAccessingQuest,
///
- /// System option with the internal name HidePcAroundNpcAccessingQuestIncludeParty.
+ /// UiConfig option with the internal name HidePcAroundNpcAccessingQuestIncludeParty.
/// This option is a UInt.
///
[GameConfigOption("HidePcAroundNpcAccessingQuestIncludeParty", ConfigType.UInt)]
HidePcAroundNpcAccessingQuestIncludeParty,
///
- /// System option with the internal name PvPFrontlinesGCFree.
+ /// UiConfig option with the internal name PvPFrontlinesGCFree.
/// This option is a UInt.
///
[GameConfigOption("PvPFrontlinesGCFree", ConfigType.UInt)]
PvPFrontlinesGCFree,
-
- ///
- /// System option with the internal name PadMode.
- /// This option is a UInt.
- ///
- [GameConfigOption("PadMode", ConfigType.UInt)]
- PadMode,
}
diff --git a/Dalamud/Game/Config/UiControlOption.cs b/Dalamud/Game/Config/UiControlOption.cs
index 5d36ee84d..99fb44c3b 100644
--- a/Dalamud/Game/Config/UiControlOption.cs
+++ b/Dalamud/Game/Config/UiControlOption.cs
@@ -10,1267 +10,1267 @@
public enum UiControlOption
{
///
- /// System option with the internal name AutoChangePointOfView.
+ /// UiControl option with the internal name AutoChangePointOfView.
/// This option is a UInt.
///
[GameConfigOption("AutoChangePointOfView", ConfigType.UInt)]
AutoChangePointOfView,
///
- /// System option with the internal name KeyboardCameraInterpolationType.
+ /// UiControl option with the internal name KeyboardCameraInterpolationType.
/// This option is a UInt.
///
[GameConfigOption("KeyboardCameraInterpolationType", ConfigType.UInt)]
KeyboardCameraInterpolationType,
///
- /// System option with the internal name KeyboardCameraVerticalInterpolation.
+ /// UiControl option with the internal name KeyboardCameraVerticalInterpolation.
/// This option is a UInt.
///
[GameConfigOption("KeyboardCameraVerticalInterpolation", ConfigType.UInt)]
KeyboardCameraVerticalInterpolation,
///
- /// System option with the internal name TiltOffset.
+ /// UiControl option with the internal name TiltOffset.
/// This option is a Float.
///
[GameConfigOption("TiltOffset", ConfigType.Float)]
TiltOffset,
///
- /// System option with the internal name KeyboardSpeed.
+ /// UiControl option with the internal name KeyboardSpeed.
/// This option is a Float.
///
[GameConfigOption("KeyboardSpeed", ConfigType.Float)]
KeyboardSpeed,
///
- /// System option with the internal name PadSpeed.
+ /// UiControl option with the internal name PadSpeed.
/// This option is a Float.
///
[GameConfigOption("PadSpeed", ConfigType.Float)]
PadSpeed,
///
- /// System option with the internal name PadFpsXReverse.
+ /// UiControl option with the internal name PadFpsXReverse.
/// This option is a UInt.
///
[GameConfigOption("PadFpsXReverse", ConfigType.UInt)]
PadFpsXReverse,
///
- /// System option with the internal name PadFpsYReverse.
+ /// UiControl option with the internal name PadFpsYReverse.
/// This option is a UInt.
///
[GameConfigOption("PadFpsYReverse", ConfigType.UInt)]
PadFpsYReverse,
///
- /// System option with the internal name PadTpsXReverse.
+ /// UiControl option with the internal name PadTpsXReverse.
/// This option is a UInt.
///
[GameConfigOption("PadTpsXReverse", ConfigType.UInt)]
PadTpsXReverse,
///
- /// System option with the internal name PadTpsYReverse.
+ /// UiControl option with the internal name PadTpsYReverse.
/// This option is a UInt.
///
[GameConfigOption("PadTpsYReverse", ConfigType.UInt)]
PadTpsYReverse,
///
- /// System option with the internal name MouseFpsXReverse.
+ /// UiControl option with the internal name MouseFpsXReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseFpsXReverse", ConfigType.UInt)]
MouseFpsXReverse,
///
- /// System option with the internal name MouseFpsYReverse.
+ /// UiControl option with the internal name MouseFpsYReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseFpsYReverse", ConfigType.UInt)]
MouseFpsYReverse,
///
- /// System option with the internal name MouseTpsXReverse.
+ /// UiControl option with the internal name MouseTpsXReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseTpsXReverse", ConfigType.UInt)]
MouseTpsXReverse,
///
- /// System option with the internal name MouseTpsYReverse.
+ /// UiControl option with the internal name MouseTpsYReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseTpsYReverse", ConfigType.UInt)]
MouseTpsYReverse,
///
- /// System option with the internal name MouseCharaViewRotYReverse.
+ /// UiControl option with the internal name MouseCharaViewRotYReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseCharaViewRotYReverse", ConfigType.UInt)]
MouseCharaViewRotYReverse,
///
- /// System option with the internal name MouseCharaViewRotXReverse.
+ /// UiControl option with the internal name MouseCharaViewRotXReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseCharaViewRotXReverse", ConfigType.UInt)]
MouseCharaViewRotXReverse,
///
- /// System option with the internal name MouseCharaViewMoveYReverse.
+ /// UiControl option with the internal name MouseCharaViewMoveYReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseCharaViewMoveYReverse", ConfigType.UInt)]
MouseCharaViewMoveYReverse,
///
- /// System option with the internal name MouseCharaViewMoveXReverse.
+ /// UiControl option with the internal name MouseCharaViewMoveXReverse.
/// This option is a UInt.
///
[GameConfigOption("MouseCharaViewMoveXReverse", ConfigType.UInt)]
MouseCharaViewMoveXReverse,
///
- /// System option with the internal name PADCharaViewRotYReverse.
+ /// UiControl option with the internal name PADCharaViewRotYReverse.
/// This option is a UInt.
///
[GameConfigOption("PADCharaViewRotYReverse", ConfigType.UInt)]
PADCharaViewRotYReverse,
///
- /// System option with the internal name PADCharaViewRotXReverse.
+ /// UiControl option with the internal name PADCharaViewRotXReverse.
/// This option is a UInt.
///
[GameConfigOption("PADCharaViewRotXReverse", ConfigType.UInt)]
PADCharaViewRotXReverse,
///
- /// System option with the internal name PADCharaViewMoveYReverse.
+ /// UiControl option with the internal name PADCharaViewMoveYReverse.
/// This option is a UInt.
///
[GameConfigOption("PADCharaViewMoveYReverse", ConfigType.UInt)]
PADCharaViewMoveYReverse,
///
- /// System option with the internal name PADCharaViewMoveXReverse.
+ /// UiControl option with the internal name PADCharaViewMoveXReverse.
/// This option is a UInt.
///
[GameConfigOption("PADCharaViewMoveXReverse", ConfigType.UInt)]
PADCharaViewMoveXReverse,
///
- /// System option with the internal name FlyingControlType.
+ /// UiControl option with the internal name FlyingControlType.
/// This option is a UInt.
///
[GameConfigOption("FlyingControlType", ConfigType.UInt)]
FlyingControlType,
///
- /// System option with the internal name FlyingLegacyAutorun.
+ /// UiControl option with the internal name FlyingLegacyAutorun.
/// This option is a UInt.
///
[GameConfigOption("FlyingLegacyAutorun", ConfigType.UInt)]
FlyingLegacyAutorun,
///
- /// System option with the internal name AutoFaceTargetOnAction.
+ /// UiControl option with the internal name AutoFaceTargetOnAction.
/// This option is a UInt.
///
[GameConfigOption("AutoFaceTargetOnAction", ConfigType.UInt)]
AutoFaceTargetOnAction,
///
- /// System option with the internal name SelfClick.
+ /// UiControl option with the internal name SelfClick.
/// This option is a UInt.
///
[GameConfigOption("SelfClick", ConfigType.UInt)]
SelfClick,
///
- /// System option with the internal name NoTargetClickCancel.
+ /// UiControl option with the internal name NoTargetClickCancel.
/// This option is a UInt.
///
[GameConfigOption("NoTargetClickCancel", ConfigType.UInt)]
NoTargetClickCancel,
///
- /// System option with the internal name AutoTarget.
+ /// UiControl option with the internal name AutoTarget.
/// This option is a UInt.
///
[GameConfigOption("AutoTarget", ConfigType.UInt)]
AutoTarget,
///
- /// System option with the internal name TargetTypeSelect.
+ /// UiControl option with the internal name TargetTypeSelect.
/// This option is a UInt.
///
[GameConfigOption("TargetTypeSelect", ConfigType.UInt)]
TargetTypeSelect,
///
- /// System option with the internal name AutoLockOn.
+ /// UiControl option with the internal name AutoLockOn.
/// This option is a UInt.
///
[GameConfigOption("AutoLockOn", ConfigType.UInt)]
AutoLockOn,
///
- /// System option with the internal name CircleBattleModeAutoChange.
+ /// UiControl option with the internal name CircleBattleModeAutoChange.
/// This option is a UInt.
///
[GameConfigOption("CircleBattleModeAutoChange", ConfigType.UInt)]
CircleBattleModeAutoChange,
///
- /// System option with the internal name CircleIsCustom.
+ /// UiControl option with the internal name CircleIsCustom.
/// This option is a UInt.
///
[GameConfigOption("CircleIsCustom", ConfigType.UInt)]
CircleIsCustom,
///
- /// System option with the internal name CircleSwordDrawnIsActive.
+ /// UiControl option with the internal name CircleSwordDrawnIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnIsActive", ConfigType.UInt)]
CircleSwordDrawnIsActive,
///
- /// System option with the internal name CircleSwordDrawnNonPartyPc.
+ /// UiControl option with the internal name CircleSwordDrawnNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnNonPartyPc", ConfigType.UInt)]
CircleSwordDrawnNonPartyPc,
///
- /// System option with the internal name CircleSwordDrawnParty.
+ /// UiControl option with the internal name CircleSwordDrawnParty.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnParty", ConfigType.UInt)]
CircleSwordDrawnParty,
///
- /// System option with the internal name CircleSwordDrawnEnemy.
+ /// UiControl option with the internal name CircleSwordDrawnEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnEnemy", ConfigType.UInt)]
CircleSwordDrawnEnemy,
///
- /// System option with the internal name CircleSwordDrawnAggro.
+ /// UiControl option with the internal name CircleSwordDrawnAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnAggro", ConfigType.UInt)]
CircleSwordDrawnAggro,
///
- /// System option with the internal name CircleSwordDrawnNpcOrObject.
+ /// UiControl option with the internal name CircleSwordDrawnNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnNpcOrObject", ConfigType.UInt)]
CircleSwordDrawnNpcOrObject,
///
- /// System option with the internal name CircleSwordDrawnMinion.
+ /// UiControl option with the internal name CircleSwordDrawnMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnMinion", ConfigType.UInt)]
CircleSwordDrawnMinion,
///
- /// System option with the internal name CircleSwordDrawnDutyEnemy.
+ /// UiControl option with the internal name CircleSwordDrawnDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnDutyEnemy", ConfigType.UInt)]
CircleSwordDrawnDutyEnemy,
///
- /// System option with the internal name CircleSwordDrawnPet.
+ /// UiControl option with the internal name CircleSwordDrawnPet.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnPet", ConfigType.UInt)]
CircleSwordDrawnPet,
///
- /// System option with the internal name CircleSwordDrawnAlliance.
+ /// UiControl option with the internal name CircleSwordDrawnAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnAlliance", ConfigType.UInt)]
CircleSwordDrawnAlliance,
///
- /// System option with the internal name CircleSwordDrawnMark.
+ /// UiControl option with the internal name CircleSwordDrawnMark.
/// This option is a UInt.
///
[GameConfigOption("CircleSwordDrawnMark", ConfigType.UInt)]
CircleSwordDrawnMark,
///
- /// System option with the internal name CircleSheathedIsActive.
+ /// UiControl option with the internal name CircleSheathedIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedIsActive", ConfigType.UInt)]
CircleSheathedIsActive,
///
- /// System option with the internal name CircleSheathedNonPartyPc.
+ /// UiControl option with the internal name CircleSheathedNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedNonPartyPc", ConfigType.UInt)]
CircleSheathedNonPartyPc,
///
- /// System option with the internal name CircleSheathedParty.
+ /// UiControl option with the internal name CircleSheathedParty.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedParty", ConfigType.UInt)]
CircleSheathedParty,
///
- /// System option with the internal name CircleSheathedEnemy.
+ /// UiControl option with the internal name CircleSheathedEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedEnemy", ConfigType.UInt)]
CircleSheathedEnemy,
///
- /// System option with the internal name CircleSheathedAggro.
+ /// UiControl option with the internal name CircleSheathedAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedAggro", ConfigType.UInt)]
CircleSheathedAggro,
///
- /// System option with the internal name CircleSheathedNpcOrObject.
+ /// UiControl option with the internal name CircleSheathedNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedNpcOrObject", ConfigType.UInt)]
CircleSheathedNpcOrObject,
///
- /// System option with the internal name CircleSheathedMinion.
+ /// UiControl option with the internal name CircleSheathedMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedMinion", ConfigType.UInt)]
CircleSheathedMinion,
///
- /// System option with the internal name CircleSheathedDutyEnemy.
+ /// UiControl option with the internal name CircleSheathedDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedDutyEnemy", ConfigType.UInt)]
CircleSheathedDutyEnemy,
///
- /// System option with the internal name CircleSheathedPet.
+ /// UiControl option with the internal name CircleSheathedPet.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedPet", ConfigType.UInt)]
CircleSheathedPet,
///
- /// System option with the internal name CircleSheathedAlliance.
+ /// UiControl option with the internal name CircleSheathedAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedAlliance", ConfigType.UInt)]
CircleSheathedAlliance,
///
- /// System option with the internal name CircleSheathedMark.
+ /// UiControl option with the internal name CircleSheathedMark.
/// This option is a UInt.
///
[GameConfigOption("CircleSheathedMark", ConfigType.UInt)]
CircleSheathedMark,
///
- /// System option with the internal name CircleClickIsActive.
+ /// UiControl option with the internal name CircleClickIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleClickIsActive", ConfigType.UInt)]
CircleClickIsActive,
///
- /// System option with the internal name CircleClickNonPartyPc.
+ /// UiControl option with the internal name CircleClickNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleClickNonPartyPc", ConfigType.UInt)]
CircleClickNonPartyPc,
///
- /// System option with the internal name CircleClickParty.
+ /// UiControl option with the internal name CircleClickParty.
/// This option is a UInt.
///
[GameConfigOption("CircleClickParty", ConfigType.UInt)]
CircleClickParty,
///
- /// System option with the internal name CircleClickEnemy.
+ /// UiControl option with the internal name CircleClickEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleClickEnemy", ConfigType.UInt)]
CircleClickEnemy,
///
- /// System option with the internal name CircleClickAggro.
+ /// UiControl option with the internal name CircleClickAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleClickAggro", ConfigType.UInt)]
CircleClickAggro,
///
- /// System option with the internal name CircleClickNpcOrObject.
+ /// UiControl option with the internal name CircleClickNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleClickNpcOrObject", ConfigType.UInt)]
CircleClickNpcOrObject,
///
- /// System option with the internal name CircleClickMinion.
+ /// UiControl option with the internal name CircleClickMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleClickMinion", ConfigType.UInt)]
CircleClickMinion,
///
- /// System option with the internal name CircleClickDutyEnemy.
+ /// UiControl option with the internal name CircleClickDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleClickDutyEnemy", ConfigType.UInt)]
CircleClickDutyEnemy,
///
- /// System option with the internal name CircleClickPet.
+ /// UiControl option with the internal name CircleClickPet.
/// This option is a UInt.
///
[GameConfigOption("CircleClickPet", ConfigType.UInt)]
CircleClickPet,
///
- /// System option with the internal name CircleClickAlliance.
+ /// UiControl option with the internal name CircleClickAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleClickAlliance", ConfigType.UInt)]
CircleClickAlliance,
///
- /// System option with the internal name CircleClickMark.
+ /// UiControl option with the internal name CircleClickMark.
/// This option is a UInt.
///
[GameConfigOption("CircleClickMark", ConfigType.UInt)]
CircleClickMark,
///
- /// System option with the internal name CircleXButtonIsActive.
+ /// UiControl option with the internal name CircleXButtonIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonIsActive", ConfigType.UInt)]
CircleXButtonIsActive,
///
- /// System option with the internal name CircleXButtonNonPartyPc.
+ /// UiControl option with the internal name CircleXButtonNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonNonPartyPc", ConfigType.UInt)]
CircleXButtonNonPartyPc,
///
- /// System option with the internal name CircleXButtonParty.
+ /// UiControl option with the internal name CircleXButtonParty.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonParty", ConfigType.UInt)]
CircleXButtonParty,
///
- /// System option with the internal name CircleXButtonEnemy.
+ /// UiControl option with the internal name CircleXButtonEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonEnemy", ConfigType.UInt)]
CircleXButtonEnemy,
///
- /// System option with the internal name CircleXButtonAggro.
+ /// UiControl option with the internal name CircleXButtonAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonAggro", ConfigType.UInt)]
CircleXButtonAggro,
///
- /// System option with the internal name CircleXButtonNpcOrObject.
+ /// UiControl option with the internal name CircleXButtonNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonNpcOrObject", ConfigType.UInt)]
CircleXButtonNpcOrObject,
///
- /// System option with the internal name CircleXButtonMinion.
+ /// UiControl option with the internal name CircleXButtonMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonMinion", ConfigType.UInt)]
CircleXButtonMinion,
///
- /// System option with the internal name CircleXButtonDutyEnemy.
+ /// UiControl option with the internal name CircleXButtonDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonDutyEnemy", ConfigType.UInt)]
CircleXButtonDutyEnemy,
///
- /// System option with the internal name CircleXButtonPet.
+ /// UiControl option with the internal name CircleXButtonPet.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonPet", ConfigType.UInt)]
CircleXButtonPet,
///
- /// System option with the internal name CircleXButtonAlliance.
+ /// UiControl option with the internal name CircleXButtonAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonAlliance", ConfigType.UInt)]
CircleXButtonAlliance,
///
- /// System option with the internal name CircleXButtonMark.
+ /// UiControl option with the internal name CircleXButtonMark.
/// This option is a UInt.
///
[GameConfigOption("CircleXButtonMark", ConfigType.UInt)]
CircleXButtonMark,
///
- /// System option with the internal name CircleYButtonIsActive.
+ /// UiControl option with the internal name CircleYButtonIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonIsActive", ConfigType.UInt)]
CircleYButtonIsActive,
///
- /// System option with the internal name CircleYButtonNonPartyPc.
+ /// UiControl option with the internal name CircleYButtonNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonNonPartyPc", ConfigType.UInt)]
CircleYButtonNonPartyPc,
///
- /// System option with the internal name CircleYButtonParty.
+ /// UiControl option with the internal name CircleYButtonParty.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonParty", ConfigType.UInt)]
CircleYButtonParty,
///
- /// System option with the internal name CircleYButtonEnemy.
+ /// UiControl option with the internal name CircleYButtonEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonEnemy", ConfigType.UInt)]
CircleYButtonEnemy,
///
- /// System option with the internal name CircleYButtonAggro.
+ /// UiControl option with the internal name CircleYButtonAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonAggro", ConfigType.UInt)]
CircleYButtonAggro,
///
- /// System option with the internal name CircleYButtonNpcOrObject.
+ /// UiControl option with the internal name CircleYButtonNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonNpcOrObject", ConfigType.UInt)]
CircleYButtonNpcOrObject,
///
- /// System option with the internal name CircleYButtonMinion.
+ /// UiControl option with the internal name CircleYButtonMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonMinion", ConfigType.UInt)]
CircleYButtonMinion,
///
- /// System option with the internal name CircleYButtonDutyEnemy.
+ /// UiControl option with the internal name CircleYButtonDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonDutyEnemy", ConfigType.UInt)]
CircleYButtonDutyEnemy,
///
- /// System option with the internal name CircleYButtonPet.
+ /// UiControl option with the internal name CircleYButtonPet.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonPet", ConfigType.UInt)]
CircleYButtonPet,
///
- /// System option with the internal name CircleYButtonAlliance.
+ /// UiControl option with the internal name CircleYButtonAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonAlliance", ConfigType.UInt)]
CircleYButtonAlliance,
///
- /// System option with the internal name CircleYButtonMark.
+ /// UiControl option with the internal name CircleYButtonMark.
/// This option is a UInt.
///
[GameConfigOption("CircleYButtonMark", ConfigType.UInt)]
CircleYButtonMark,
///
- /// System option with the internal name CircleBButtonIsActive.
+ /// UiControl option with the internal name CircleBButtonIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonIsActive", ConfigType.UInt)]
CircleBButtonIsActive,
///
- /// System option with the internal name CircleBButtonNonPartyPc.
+ /// UiControl option with the internal name CircleBButtonNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonNonPartyPc", ConfigType.UInt)]
CircleBButtonNonPartyPc,
///
- /// System option with the internal name CircleBButtonParty.
+ /// UiControl option with the internal name CircleBButtonParty.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonParty", ConfigType.UInt)]
CircleBButtonParty,
///
- /// System option with the internal name CircleBButtonEnemy.
+ /// UiControl option with the internal name CircleBButtonEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonEnemy", ConfigType.UInt)]
CircleBButtonEnemy,
///
- /// System option with the internal name CircleBButtonAggro.
+ /// UiControl option with the internal name CircleBButtonAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonAggro", ConfigType.UInt)]
CircleBButtonAggro,
///
- /// System option with the internal name CircleBButtonNpcOrObject.
+ /// UiControl option with the internal name CircleBButtonNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonNpcOrObject", ConfigType.UInt)]
CircleBButtonNpcOrObject,
///
- /// System option with the internal name CircleBButtonMinion.
+ /// UiControl option with the internal name CircleBButtonMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonMinion", ConfigType.UInt)]
CircleBButtonMinion,
///
- /// System option with the internal name CircleBButtonDutyEnemy.
+ /// UiControl option with the internal name CircleBButtonDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonDutyEnemy", ConfigType.UInt)]
CircleBButtonDutyEnemy,
///
- /// System option with the internal name CircleBButtonPet.
+ /// UiControl option with the internal name CircleBButtonPet.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonPet", ConfigType.UInt)]
CircleBButtonPet,
///
- /// System option with the internal name CircleBButtonAlliance.
+ /// UiControl option with the internal name CircleBButtonAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonAlliance", ConfigType.UInt)]
CircleBButtonAlliance,
///
- /// System option with the internal name CircleBButtonMark.
+ /// UiControl option with the internal name CircleBButtonMark.
/// This option is a UInt.
///
[GameConfigOption("CircleBButtonMark", ConfigType.UInt)]
CircleBButtonMark,
///
- /// System option with the internal name CircleAButtonIsActive.
+ /// UiControl option with the internal name CircleAButtonIsActive.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonIsActive", ConfigType.UInt)]
CircleAButtonIsActive,
///
- /// System option with the internal name CircleAButtonNonPartyPc.
+ /// UiControl option with the internal name CircleAButtonNonPartyPc.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonNonPartyPc", ConfigType.UInt)]
CircleAButtonNonPartyPc,
///
- /// System option with the internal name CircleAButtonParty.
+ /// UiControl option with the internal name CircleAButtonParty.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonParty", ConfigType.UInt)]
CircleAButtonParty,
///
- /// System option with the internal name CircleAButtonEnemy.
+ /// UiControl option with the internal name CircleAButtonEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonEnemy", ConfigType.UInt)]
CircleAButtonEnemy,
///
- /// System option with the internal name CircleAButtonAggro.
+ /// UiControl option with the internal name CircleAButtonAggro.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonAggro", ConfigType.UInt)]
CircleAButtonAggro,
///
- /// System option with the internal name CircleAButtonNpcOrObject.
+ /// UiControl option with the internal name CircleAButtonNpcOrObject.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonNpcOrObject", ConfigType.UInt)]
CircleAButtonNpcOrObject,
///
- /// System option with the internal name CircleAButtonMinion.
+ /// UiControl option with the internal name CircleAButtonMinion.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonMinion", ConfigType.UInt)]
CircleAButtonMinion,
///
- /// System option with the internal name CircleAButtonDutyEnemy.
+ /// UiControl option with the internal name CircleAButtonDutyEnemy.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonDutyEnemy", ConfigType.UInt)]
CircleAButtonDutyEnemy,
///
- /// System option with the internal name CircleAButtonPet.
+ /// UiControl option with the internal name CircleAButtonPet.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonPet", ConfigType.UInt)]
CircleAButtonPet,
///
- /// System option with the internal name CircleAButtonAlliance.
+ /// UiControl option with the internal name CircleAButtonAlliance.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonAlliance", ConfigType.UInt)]
CircleAButtonAlliance,
///
- /// System option with the internal name CircleAButtonMark.
+ /// UiControl option with the internal name CircleAButtonMark.
/// This option is a UInt.
///
[GameConfigOption("CircleAButtonMark", ConfigType.UInt)]
CircleAButtonMark,
///
- /// System option with the internal name GroundTargetType.
+ /// UiControl option with the internal name GroundTargetType.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetType", ConfigType.UInt)]
GroundTargetType,
///
- /// System option with the internal name GroundTargetCursorSpeed.
+ /// UiControl option with the internal name GroundTargetCursorSpeed.
/// This option is a UInt.
///
[GameConfigOption("GroundTargetCursorSpeed", ConfigType.UInt)]
GroundTargetCursorSpeed,
///
- /// System option with the internal name TargetCircleType.
+ /// UiControl option with the internal name TargetCircleType.
/// This option is a UInt.
///
[GameConfigOption("TargetCircleType", ConfigType.UInt)]
TargetCircleType,
///
- /// System option with the internal name TargetLineType.
+ /// UiControl option with the internal name TargetLineType.
/// This option is a UInt.
///
[GameConfigOption("TargetLineType", ConfigType.UInt)]
TargetLineType,
///
- /// System option with the internal name LinkLineType.
+ /// UiControl option with the internal name LinkLineType.
/// This option is a UInt.
///
[GameConfigOption("LinkLineType", ConfigType.UInt)]
LinkLineType,
///
- /// System option with the internal name ObjectBorderingType.
+ /// UiControl option with the internal name ObjectBorderingType.
/// This option is a UInt.
///
[GameConfigOption("ObjectBorderingType", ConfigType.UInt)]
ObjectBorderingType,
///
- /// System option with the internal name MoveMode.
+ /// UiControl option with the internal name MoveMode.
/// This option is a UInt.
///
[GameConfigOption("MoveMode", ConfigType.UInt)]
MoveMode,
///
- /// System option with the internal name HotbarDisp.
+ /// UiControl option with the internal name HotbarDisp.
/// This option is a UInt.
///
[GameConfigOption("HotbarDisp", ConfigType.UInt)]
HotbarDisp,
///
- /// System option with the internal name HotbarEmptyVisible.
+ /// UiControl option with the internal name HotbarEmptyVisible.
/// This option is a UInt.
///
[GameConfigOption("HotbarEmptyVisible", ConfigType.UInt)]
HotbarEmptyVisible,
///
- /// System option with the internal name HotbarNoneSlotDisp01.
+ /// UiControl option with the internal name HotbarNoneSlotDisp01.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp01", ConfigType.UInt)]
HotbarNoneSlotDisp01,
///
- /// System option with the internal name HotbarNoneSlotDisp02.
+ /// UiControl option with the internal name HotbarNoneSlotDisp02.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp02", ConfigType.UInt)]
HotbarNoneSlotDisp02,
///
- /// System option with the internal name HotbarNoneSlotDisp03.
+ /// UiControl option with the internal name HotbarNoneSlotDisp03.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp03", ConfigType.UInt)]
HotbarNoneSlotDisp03,
///
- /// System option with the internal name HotbarNoneSlotDisp04.
+ /// UiControl option with the internal name HotbarNoneSlotDisp04.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp04", ConfigType.UInt)]
HotbarNoneSlotDisp04,
///
- /// System option with the internal name HotbarNoneSlotDisp05.
+ /// UiControl option with the internal name HotbarNoneSlotDisp05.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp05", ConfigType.UInt)]
HotbarNoneSlotDisp05,
///
- /// System option with the internal name HotbarNoneSlotDisp06.
+ /// UiControl option with the internal name HotbarNoneSlotDisp06.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp06", ConfigType.UInt)]
HotbarNoneSlotDisp06,
///
- /// System option with the internal name HotbarNoneSlotDisp07.
+ /// UiControl option with the internal name HotbarNoneSlotDisp07.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp07", ConfigType.UInt)]
HotbarNoneSlotDisp07,
///
- /// System option with the internal name HotbarNoneSlotDisp08.
+ /// UiControl option with the internal name HotbarNoneSlotDisp08.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp08", ConfigType.UInt)]
HotbarNoneSlotDisp08,
///
- /// System option with the internal name HotbarNoneSlotDisp09.
+ /// UiControl option with the internal name HotbarNoneSlotDisp09.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp09", ConfigType.UInt)]
HotbarNoneSlotDisp09,
///
- /// System option with the internal name HotbarNoneSlotDisp10.
+ /// UiControl option with the internal name HotbarNoneSlotDisp10.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDisp10", ConfigType.UInt)]
HotbarNoneSlotDisp10,
///
- /// System option with the internal name HotbarNoneSlotDispEX.
+ /// UiControl option with the internal name HotbarNoneSlotDispEX.
/// This option is a UInt.
///
[GameConfigOption("HotbarNoneSlotDispEX", ConfigType.UInt)]
HotbarNoneSlotDispEX,
///
- /// System option with the internal name ExHotbarSetting.
+ /// UiControl option with the internal name ExHotbarSetting.
/// This option is a UInt.
///
[GameConfigOption("ExHotbarSetting", ConfigType.UInt)]
ExHotbarSetting,
///
- /// System option with the internal name HotbarExHotbarUseSetting.
+ /// UiControl option with the internal name HotbarExHotbarUseSetting.
/// This option is a UInt.
///
[GameConfigOption("HotbarExHotbarUseSetting", ConfigType.UInt)]
HotbarExHotbarUseSetting,
///
- /// System option with the internal name HotbarCrossUseEx.
+ /// UiControl option with the internal name HotbarCrossUseEx.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossUseEx", ConfigType.UInt)]
HotbarCrossUseEx,
///
- /// System option with the internal name HotbarCrossUseExDirection.
+ /// UiControl option with the internal name HotbarCrossUseExDirection.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossUseExDirection", ConfigType.UInt)]
HotbarCrossUseExDirection,
///
- /// System option with the internal name HotbarCrossDispType.
+ /// UiControl option with the internal name HotbarCrossDispType.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossDispType", ConfigType.UInt)]
HotbarCrossDispType,
///
- /// System option with the internal name PartyListSoloOff.
+ /// UiControl option with the internal name PartyListSoloOff.
/// This option is a UInt.
///
[GameConfigOption("PartyListSoloOff", ConfigType.UInt)]
PartyListSoloOff,
///
- /// System option with the internal name HowTo.
+ /// UiControl option with the internal name HowTo.
/// This option is a UInt.
///
[GameConfigOption("HowTo", ConfigType.UInt)]
HowTo,
///
- /// System option with the internal name HousingFurnitureBindConfirm.
+ /// UiControl option with the internal name HousingFurnitureBindConfirm.
/// This option is a UInt.
///
[GameConfigOption("HousingFurnitureBindConfirm", ConfigType.UInt)]
HousingFurnitureBindConfirm,
///
- /// System option with the internal name DirectChat.
+ /// UiControl option with the internal name DirectChat.
/// This option is a UInt.
///
[GameConfigOption("DirectChat", ConfigType.UInt)]
DirectChat,
///
- /// System option with the internal name CharaParamDisp.
+ /// UiControl option with the internal name CharaParamDisp.
/// This option is a UInt.
///
[GameConfigOption("CharaParamDisp", ConfigType.UInt)]
CharaParamDisp,
///
- /// System option with the internal name LimitBreakGaugeDisp.
+ /// UiControl option with the internal name LimitBreakGaugeDisp.
/// This option is a UInt.
///
[GameConfigOption("LimitBreakGaugeDisp", ConfigType.UInt)]
LimitBreakGaugeDisp,
///
- /// System option with the internal name ScenarioTreeDisp.
+ /// UiControl option with the internal name ScenarioTreeDisp.
/// This option is a UInt.
///
[GameConfigOption("ScenarioTreeDisp", ConfigType.UInt)]
ScenarioTreeDisp,
///
- /// System option with the internal name ScenarioTreeCompleteDisp.
+ /// UiControl option with the internal name ScenarioTreeCompleteDisp.
/// This option is a UInt.
///
[GameConfigOption("ScenarioTreeCompleteDisp", ConfigType.UInt)]
ScenarioTreeCompleteDisp,
///
- /// System option with the internal name HotbarCrossDispAlways.
+ /// UiControl option with the internal name HotbarCrossDispAlways.
/// This option is a UInt.
///
[GameConfigOption("HotbarCrossDispAlways", ConfigType.UInt)]
HotbarCrossDispAlways,
///
- /// System option with the internal name ExpDisp.
+ /// UiControl option with the internal name ExpDisp.
/// This option is a UInt.
///
[GameConfigOption("ExpDisp", ConfigType.UInt)]
ExpDisp,
///
- /// System option with the internal name InventryStatusDisp.
+ /// UiControl option with the internal name InventryStatusDisp.
/// This option is a UInt.
///
[GameConfigOption("InventryStatusDisp", ConfigType.UInt)]
InventryStatusDisp,
///
- /// System option with the internal name DutyListDisp.
+ /// UiControl option with the internal name DutyListDisp.
/// This option is a UInt.
///
[GameConfigOption("DutyListDisp", ConfigType.UInt)]
DutyListDisp,
///
- /// System option with the internal name NaviMapDisp.
+ /// UiControl option with the internal name NaviMapDisp.
/// This option is a UInt.
///
[GameConfigOption("NaviMapDisp", ConfigType.UInt)]
NaviMapDisp,
///
- /// System option with the internal name GilStatusDisp.
+ /// UiControl option with the internal name GilStatusDisp.
/// This option is a UInt.
///
[GameConfigOption("GilStatusDisp", ConfigType.UInt)]
GilStatusDisp,
///
- /// System option with the internal name InfoSettingDisp.
+ /// UiControl option with the internal name InfoSettingDisp.
/// This option is a UInt.
///
[GameConfigOption("InfoSettingDisp", ConfigType.UInt)]
InfoSettingDisp,
///
- /// System option with the internal name InfoSettingDispType.
+ /// UiControl option with the internal name InfoSettingDispType.
/// This option is a UInt.
///
[GameConfigOption("InfoSettingDispType", ConfigType.UInt)]
InfoSettingDispType,
///
- /// System option with the internal name TargetInfoDisp.
+ /// UiControl option with the internal name TargetInfoDisp.
/// This option is a UInt.
///
[GameConfigOption("TargetInfoDisp", ConfigType.UInt)]
TargetInfoDisp,
///
- /// System option with the internal name EnemyListDisp.
+ /// UiControl option with the internal name EnemyListDisp.
/// This option is a UInt.
///
[GameConfigOption("EnemyListDisp", ConfigType.UInt)]
EnemyListDisp,
///
- /// System option with the internal name FocusTargetDisp.
+ /// UiControl option with the internal name FocusTargetDisp.
/// This option is a UInt.
///
[GameConfigOption("FocusTargetDisp", ConfigType.UInt)]
FocusTargetDisp,
///
- /// System option with the internal name ItemDetailDisp.
+ /// UiControl option with the internal name ItemDetailDisp.
/// This option is a UInt.
///
[GameConfigOption("ItemDetailDisp", ConfigType.UInt)]
ItemDetailDisp,
///
- /// System option with the internal name ActionDetailDisp.
+ /// UiControl option with the internal name ActionDetailDisp.
/// This option is a UInt.
///
[GameConfigOption("ActionDetailDisp", ConfigType.UInt)]
ActionDetailDisp,
///
- /// System option with the internal name DetailTrackingType.
+ /// UiControl option with the internal name DetailTrackingType.
/// This option is a UInt.
///
[GameConfigOption("DetailTrackingType", ConfigType.UInt)]
DetailTrackingType,
///
- /// System option with the internal name ToolTipDisp.
+ /// UiControl option with the internal name ToolTipDisp.
/// This option is a UInt.
///
[GameConfigOption("ToolTipDisp", ConfigType.UInt)]
ToolTipDisp,
///
- /// System option with the internal name MapPermeationRate.
+ /// UiControl option with the internal name MapPermeationRate.
/// This option is a UInt.
///
[GameConfigOption("MapPermeationRate", ConfigType.UInt)]
MapPermeationRate,
///
- /// System option with the internal name MapOperationType.
+ /// UiControl option with the internal name MapOperationType.
/// This option is a UInt.
///
[GameConfigOption("MapOperationType", ConfigType.UInt)]
MapOperationType,
///
- /// System option with the internal name PartyListDisp.
+ /// UiControl option with the internal name PartyListDisp.
/// This option is a UInt.
///
[GameConfigOption("PartyListDisp", ConfigType.UInt)]
PartyListDisp,
///
- /// System option with the internal name PartyListNameType.
+ /// UiControl option with the internal name PartyListNameType.
/// This option is a UInt.
///
[GameConfigOption("PartyListNameType", ConfigType.UInt)]
PartyListNameType,
///
- /// System option with the internal name FlyTextDisp.
+ /// UiControl option with the internal name FlyTextDisp.
/// This option is a UInt.
///
[GameConfigOption("FlyTextDisp", ConfigType.UInt)]
FlyTextDisp,
///
- /// System option with the internal name MapPermeationMode.
+ /// UiControl option with the internal name MapPermeationMode.
/// This option is a UInt.
///
[GameConfigOption("MapPermeationMode", ConfigType.UInt)]
MapPermeationMode,
///
- /// System option with the internal name AllianceList1Disp.
+ /// UiControl option with the internal name AllianceList1Disp.
/// This option is a UInt.
///
[GameConfigOption("AllianceList1Disp", ConfigType.UInt)]
AllianceList1Disp,
///
- /// System option with the internal name AllianceList2Disp.
+ /// UiControl option with the internal name AllianceList2Disp.
/// This option is a UInt.
///
[GameConfigOption("AllianceList2Disp", ConfigType.UInt)]
AllianceList2Disp,
///
- /// System option with the internal name TargetInfoSelfBuff.
+ /// UiControl option with the internal name TargetInfoSelfBuff.
/// This option is a UInt.
///
[GameConfigOption("TargetInfoSelfBuff", ConfigType.UInt)]
TargetInfoSelfBuff,
///
- /// System option with the internal name PopUpTextDisp.
+ /// UiControl option with the internal name PopUpTextDisp.
/// This option is a UInt.
///
[GameConfigOption("PopUpTextDisp", ConfigType.UInt)]
PopUpTextDisp,
///
- /// System option with the internal name ContentsInfoDisp.
+ /// UiControl option with the internal name ContentsInfoDisp.
/// This option is a UInt.
///
[GameConfigOption("ContentsInfoDisp", ConfigType.UInt)]
ContentsInfoDisp,
///
- /// System option with the internal name DutyListHideWhenCntInfoDisp.
+ /// UiControl option with the internal name DutyListHideWhenCntInfoDisp.
/// This option is a UInt.
///
[GameConfigOption("DutyListHideWhenCntInfoDisp", ConfigType.UInt)]
DutyListHideWhenCntInfoDisp,
///
- /// System option with the internal name DutyListNumDisp.
+ /// UiControl option with the internal name DutyListNumDisp.
/// This option is a UInt.
///
[GameConfigOption("DutyListNumDisp", ConfigType.UInt)]
DutyListNumDisp,
///
- /// System option with the internal name InInstanceContentDutyListDisp.
+ /// UiControl option with the internal name InInstanceContentDutyListDisp.
/// This option is a UInt.
///
[GameConfigOption("InInstanceContentDutyListDisp", ConfigType.UInt)]
InInstanceContentDutyListDisp,
///
- /// System option with the internal name InPublicContentDutyListDisp.
+ /// UiControl option with the internal name InPublicContentDutyListDisp.
/// This option is a UInt.
///
[GameConfigOption("InPublicContentDutyListDisp", ConfigType.UInt)]
InPublicContentDutyListDisp,
///
- /// System option with the internal name ContentsInfoJoiningRequestDisp.
+ /// UiControl option with the internal name ContentsInfoJoiningRequestDisp.
/// This option is a UInt.
///
[GameConfigOption("ContentsInfoJoiningRequestDisp", ConfigType.UInt)]
ContentsInfoJoiningRequestDisp,
///
- /// System option with the internal name ContentsInfoJoiningRequestSituationDisp.
+ /// UiControl option with the internal name ContentsInfoJoiningRequestSituationDisp.
/// This option is a UInt.
///
[GameConfigOption("ContentsInfoJoiningRequestSituationDisp", ConfigType.UInt)]
ContentsInfoJoiningRequestSituationDisp,
///
- /// System option with the internal name HotbarDispSetNum.
+ /// UiControl option with the internal name HotbarDispSetNum.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispSetNum", ConfigType.UInt)]
HotbarDispSetNum,
///
- /// System option with the internal name HotbarDispSetChangeType.
+ /// UiControl option with the internal name HotbarDispSetChangeType.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispSetChangeType", ConfigType.UInt)]
HotbarDispSetChangeType,
///
- /// System option with the internal name HotbarDispSetDragType.
+ /// UiControl option with the internal name HotbarDispSetDragType.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispSetDragType", ConfigType.UInt)]
HotbarDispSetDragType,
///
- /// System option with the internal name MainCommandType.
+ /// UiControl option with the internal name MainCommandType.
/// This option is a UInt.
///
[GameConfigOption("MainCommandType", ConfigType.UInt)]
MainCommandType,
///
- /// System option with the internal name MainCommandDisp.
+ /// UiControl option with the internal name MainCommandDisp.
/// This option is a UInt.
///
[GameConfigOption("MainCommandDisp", ConfigType.UInt)]
MainCommandDisp,
///
- /// System option with the internal name MainCommandDragShortcut.
+ /// UiControl option with the internal name MainCommandDragShortcut.
/// This option is a UInt.
///
[GameConfigOption("MainCommandDragShortcut", ConfigType.UInt)]
MainCommandDragShortcut,
///
- /// System option with the internal name HotbarDispLookNum.
+ /// UiControl option with the internal name HotbarDispLookNum.
/// This option is a UInt.
///
[GameConfigOption("HotbarDispLookNum", ConfigType.UInt)]
diff --git a/Dalamud/Game/DutyState/DutyState.cs b/Dalamud/Game/DutyState/DutyState.cs
index 3a3afbab0..4d719685b 100644
--- a/Dalamud/Game/DutyState/DutyState.cs
+++ b/Dalamud/Game/DutyState/DutyState.cs
@@ -1,10 +1,11 @@
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
+using Dalamud.Utility;
namespace Dalamud.Game.DutyState;
@@ -81,33 +82,33 @@ internal unsafe class DutyState : IInternalDisposableService, IDutyState
// Duty Commenced
case 0x4000_0001:
this.IsDutyStarted = true;
- this.DutyStarted?.Invoke(this, this.clientState.TerritoryType);
+ this.DutyStarted?.InvokeSafely(this, this.clientState.TerritoryType);
break;
// Party Wipe
case 0x4000_0005:
this.IsDutyStarted = false;
- this.DutyWiped?.Invoke(this, this.clientState.TerritoryType);
+ this.DutyWiped?.InvokeSafely(this, this.clientState.TerritoryType);
break;
// Duty Recommence
case 0x4000_0006:
this.IsDutyStarted = true;
- this.DutyRecommenced?.Invoke(this, this.clientState.TerritoryType);
+ this.DutyRecommenced?.InvokeSafely(this, this.clientState.TerritoryType);
break;
// Duty Completed Flytext Shown
case 0x4000_0002 when !this.CompletedThisTerritory:
this.IsDutyStarted = false;
this.CompletedThisTerritory = true;
- this.DutyCompleted?.Invoke(this, this.clientState.TerritoryType);
+ this.DutyCompleted?.InvokeSafely(this, this.clientState.TerritoryType);
break;
// Duty Completed
case 0x4000_0003 when !this.CompletedThisTerritory:
this.IsDutyStarted = false;
this.CompletedThisTerritory = true;
- this.DutyCompleted?.Invoke(this, this.clientState.TerritoryType);
+ this.DutyCompleted?.InvokeSafely(this, this.clientState.TerritoryType);
break;
}
}
diff --git a/Dalamud/Game/DutyState/DutyStateAddressResolver.cs b/Dalamud/Game/DutyState/DutyStateAddressResolver.cs
index 01a0d39b7..1bca93efb 100644
--- a/Dalamud/Game/DutyState/DutyStateAddressResolver.cs
+++ b/Dalamud/Game/DutyState/DutyStateAddressResolver.cs
@@ -16,6 +16,6 @@ internal class DutyStateAddressResolver : BaseAddressResolver
/// The signature scanner to facilitate setup.
protected override void Setup64Bit(ISigScanner sig)
{
- this.ContentDirectorNetworkMessage = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 33 FF 48 8B D9 41 0F B7 08");
+ this.ContentDirectorNetworkMessage = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 33 FF 48 8B D9 41 0F B7 08"); // unnamed in cs
}
}
diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs
index 07942f780..82c7f5f6c 100644
--- a/Dalamud/Game/Framework.cs
+++ b/Dalamud/Game/Framework.cs
@@ -2,7 +2,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -16,6 +15,8 @@ using Dalamud.Logging.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+using CSFramework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
+
namespace Dalamud.Game;
///
@@ -31,11 +32,9 @@ internal sealed class Framework : IInternalDisposableService, IFramework
private readonly Stopwatch updateStopwatch = new();
private readonly HitchDetector hitchDetector;
- private readonly Hook updateHook;
- private readonly Hook destroyHook;
+ private readonly Hook updateHook;
+ private readonly Hook destroyHook;
- private readonly FrameworkAddressResolver addressResolver;
-
[ServiceManager.ServiceDependency]
private readonly GameLifecycle lifecycle = Service.Get();
@@ -51,13 +50,10 @@ internal sealed class Framework : IInternalDisposableService, IFramework
private ulong tickCounter;
[ServiceManager.ServiceConstructor]
- private Framework(TargetSigScanner sigScanner)
+ private unsafe Framework()
{
this.hitchDetector = new HitchDetector("FrameworkUpdate", this.configuration.FrameworkUpdateHitch);
- this.addressResolver = new FrameworkAddressResolver();
- this.addressResolver.Setup(sigScanner);
-
this.frameworkDestroy = new();
this.frameworkThreadTaskScheduler = new();
this.FrameworkThreadTaskFactory = new(
@@ -66,23 +62,13 @@ internal sealed class Framework : IInternalDisposableService, IFramework
TaskContinuationOptions.None,
this.frameworkThreadTaskScheduler);
- this.updateHook = Hook.FromAddress(this.addressResolver.TickAddress, this.HandleFrameworkUpdate);
- this.destroyHook = Hook.FromAddress(this.addressResolver.DestroyAddress, this.HandleFrameworkDestroy);
+ this.updateHook = Hook.FromAddress((nint)CSFramework.StaticVirtualTablePointer->Tick, this.HandleFrameworkUpdate);
+ this.destroyHook = Hook.FromAddress((nint)CSFramework.StaticVirtualTablePointer->Destroy, this.HandleFrameworkDestroy);
this.updateHook.Enable();
this.destroyHook.Enable();
}
- ///
- /// A delegate type used during the native Framework::destroy.
- ///
- /// The native Framework address.
- /// A value indicating if the call was successful.
- public delegate bool OnRealDestroyDelegate(IntPtr framework);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate bool OnUpdateDetour(IntPtr framework);
-
///
public event IFramework.OnUpdateDelegate? Update;
@@ -390,7 +376,7 @@ internal sealed class Framework : IInternalDisposableService, IFramework
}
}
- private bool HandleFrameworkUpdate(IntPtr framework)
+ private unsafe bool HandleFrameworkUpdate(CSFramework* thisPtr)
{
this.frameworkThreadTaskScheduler.BoundThread ??= Thread.CurrentThread;
@@ -483,10 +469,10 @@ internal sealed class Framework : IInternalDisposableService, IFramework
this.hitchDetector.Stop();
original:
- return this.updateHook.OriginalDisposeSafe(framework);
+ return this.updateHook.OriginalDisposeSafe(thisPtr);
}
- private bool HandleFrameworkDestroy(IntPtr framework)
+ private unsafe bool HandleFrameworkDestroy(CSFramework* thisPtr)
{
this.frameworkDestroy.Cancel();
this.DispatchUpdateEvents = false;
@@ -504,7 +490,7 @@ internal sealed class Framework : IInternalDisposableService, IFramework
ServiceManager.WaitForServiceUnload();
Log.Information("Framework::Destroy OK!");
- return this.destroyHook.OriginalDisposeSafe(framework);
+ return this.destroyHook.OriginalDisposeSafe(thisPtr);
}
}
diff --git a/Dalamud/Game/FrameworkAddressResolver.cs b/Dalamud/Game/FrameworkAddressResolver.cs
deleted file mode 100644
index 8ea371f2c..000000000
--- a/Dalamud/Game/FrameworkAddressResolver.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-namespace Dalamud.Game;
-
-///
-/// The address resolver for the class.
-///
-internal sealed class FrameworkAddressResolver : BaseAddressResolver
-{
- ///
- /// Gets the address for the function that is called once the Framework is destroyed.
- ///
- public IntPtr DestroyAddress { get; private set; }
-
- ///
- /// Gets the address for the function that is called once the Framework is free'd.
- ///
- public IntPtr FreeAddress { get; private set; }
-
- ///
- /// Gets the function that is called every tick.
- ///
- public IntPtr TickAddress { get; private set; }
-
- ///
- protected override void Setup64Bit(ISigScanner sig)
- {
- this.SetupFramework(sig);
- }
-
- private void SetupFramework(ISigScanner scanner)
- {
- this.DestroyAddress =
- scanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 3D ?? ?? ?? ?? 48 8B D9 48 85 FF");
-
- this.FreeAddress =
- scanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B D9 48 8B 0D ?? ?? ?? ?? 48 85 C9");
-
- this.TickAddress =
- scanner.ScanText("40 53 48 83 EC 20 FF 81 ?? ?? ?? ?? 48 8B D9 48 8D 4C 24 ??");
- }
-}
diff --git a/Dalamud/Game/Gui/ChatGui.cs b/Dalamud/Game/Gui/ChatGui.cs
index 6779f32a8..791cbb97a 100644
--- a/Dalamud/Game/Gui/ChatGui.cs
+++ b/Dalamud/Game/Gui/ChatGui.cs
@@ -14,8 +14,20 @@ using Dalamud.Logging.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+
+using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.System.String;
+using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
+using FFXIVClientStructs.FFXIV.Component.GUI;
+
+using Lumina.Text;
+using Lumina.Text.Payloads;
+using Lumina.Text.ReadOnly;
+
+using LSeStringBuilder = Lumina.Text.SeStringBuilder;
+using SeString = Dalamud.Game.Text.SeStringHandling.SeString;
+using SeStringBuilder = Dalamud.Game.Text.SeStringHandling.SeStringBuilder;
namespace Dalamud.Game.Gui;
@@ -27,14 +39,12 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
{
private static readonly ModuleLog Log = new("ChatGui");
- private readonly ChatGuiAddressResolver address;
-
private readonly Queue chatQueue = new();
private readonly Dictionary<(string PluginName, uint CommandId), Action> dalamudLinkHandlers = new();
private readonly Hook printMessageHook;
- private readonly Hook populateItemLinkHook;
- private readonly Hook interactableLinkClickedHook;
+ private readonly Hook inventoryItemCopyHook;
+ private readonly Hook handleLinkClickHook;
[ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service.Get();
@@ -42,29 +52,20 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
private ImmutableDictionary<(string PluginName, uint CommandId), Action>? dalamudLinkHandlersCopy;
[ServiceManager.ServiceConstructor]
- private ChatGui(TargetSigScanner sigScanner)
+ private ChatGui()
{
- this.address = new ChatGuiAddressResolver();
- this.address.Setup(sigScanner);
-
- this.printMessageHook = Hook.FromAddress((nint)RaptureLogModule.Addresses.PrintMessage.Value, this.HandlePrintMessageDetour);
- this.populateItemLinkHook = Hook.FromAddress(this.address.PopulateItemLinkObject, this.HandlePopulateItemLinkDetour);
- this.interactableLinkClickedHook = Hook.FromAddress(this.address.InteractableLinkClicked, this.InteractableLinkClickedDetour);
+ this.printMessageHook = Hook.FromAddress(RaptureLogModule.Addresses.PrintMessage.Value, this.HandlePrintMessageDetour);
+ this.inventoryItemCopyHook = Hook.FromAddress((nint)InventoryItem.StaticVirtualTablePointer->Copy, this.InventoryItemCopyDetour);
+ this.handleLinkClickHook = Hook.FromAddress(LogViewer.Addresses.HandleLinkClick.Value, this.HandleLinkClickDetour);
this.printMessageHook.Enable();
- this.populateItemLinkHook.Enable();
- this.interactableLinkClickedHook.Enable();
+ this.inventoryItemCopyHook.Enable();
+ this.handleLinkClickHook.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate uint PrintMessageDelegate(RaptureLogModule* manager, XivChatType chatType, Utf8String* sender, Utf8String* message, int timestamp, byte silent);
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void PopulateItemLinkDelegate(IntPtr linkObjectPtr, IntPtr itemInfoPtr);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void InteractableLinkClickedDelegate(IntPtr managerPtr, IntPtr messagePtr);
-
///
public event IChatGui.OnMessageDelegate? ChatMessage;
@@ -78,7 +79,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
public event IChatGui.OnMessageUnhandledDelegate? ChatMessageUnhandled;
///
- public int LastLinkedItemId { get; private set; }
+ public uint LastLinkedItemId { get; private set; }
///
public byte LastLinkedItemFlags { get; private set; }
@@ -106,10 +107,12 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
void IInternalDisposableService.DisposeService()
{
this.printMessageHook.Dispose();
- this.populateItemLinkHook.Dispose();
- this.interactableLinkClickedHook.Dispose();
+ this.inventoryItemCopyHook.Dispose();
+ this.handleLinkClickHook.Dispose();
}
+ #region DalamudSeString
+
///
public void Print(XivChatEntry chat)
{
@@ -140,43 +143,74 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
this.PrintTagged(message, XivChatType.Urgent, messageTag, tagColor);
}
+ #endregion
+
+ #region LuminaSeString
+
+ ///
+ public void Print(ReadOnlySpan message, string? messageTag = null, ushort? tagColor = null)
+ {
+ this.PrintTagged(message, this.configuration.GeneralChatType, messageTag, tagColor);
+ }
+
+ ///
+ public void PrintError(ReadOnlySpan message, string? messageTag = null, ushort? tagColor = null)
+ {
+ this.PrintTagged(message, XivChatType.Urgent, messageTag, tagColor);
+ }
+
+ #endregion
+
///
/// Process a chat queue.
///
public void UpdateQueue()
{
- while (this.chatQueue.Count > 0)
- {
- var chat = this.chatQueue.Dequeue();
- var replacedMessage = new SeStringBuilder();
+ if (this.chatQueue.Count == 0)
+ return;
- // Normalize Unicode NBSP to the built-in one, as the former won't renderl
- foreach (var payload in chat.Message.Payloads)
+ var sb = LSeStringBuilder.SharedPool.Get();
+ Span namebuf = stackalloc byte[256];
+ using var sender = new Utf8String();
+ using var message = new Utf8String();
+ while (this.chatQueue.TryDequeue(out var chat))
+ {
+ sb.Clear();
+ foreach (var c in UtfEnumerator.From(chat.MessageBytes, UtfEnumeratorFlags.Utf8SeString))
{
- if (payload is TextPayload { Text: not null } textPayload)
- {
- var split = textPayload.Text.Split("\u202f"); // NARROW NO-BREAK SPACE
- for (var i = 0; i < split.Length; i++)
- {
- replacedMessage.AddText(split[i]);
- if (i + 1 < split.Length)
- replacedMessage.Add(new RawPayload([0x02, (byte)Lumina.Text.Payloads.PayloadType.Indent, 0x01, 0x03]));
- }
- }
+ if (c.IsSeStringPayload)
+ sb.Append((ReadOnlySeStringSpan)chat.MessageBytes.AsSpan(c.ByteOffset, c.ByteLength));
+ else if (c.Value.IntValue == 0x202F)
+ sb.BeginMacro(MacroCode.NonBreakingSpace).EndMacro();
else
- {
- replacedMessage.Add(payload);
- }
+ sb.Append(c);
}
- var sender = Utf8String.FromSequence(chat.Name.Encode());
- var message = Utf8String.FromSequence(replacedMessage.BuiltString.Encode());
+ if (chat.NameBytes.Length + 1 < namebuf.Length)
+ {
+ chat.NameBytes.AsSpan().CopyTo(namebuf);
+ namebuf[chat.NameBytes.Length] = 0;
+ sender.SetString(namebuf);
+ }
+ else
+ {
+ sender.SetString(chat.NameBytes.NullTerminate());
+ }
- this.HandlePrintMessageDetour(RaptureLogModule.Instance(), chat.Type, sender, message, chat.Timestamp, (byte)(chat.Silent ? 1 : 0));
+ message.SetString(sb.GetViewAsSpan());
- sender->Dtor(true);
- message->Dtor(true);
+ var targetChannel = chat.Type ?? this.configuration.GeneralChatType;
+
+ this.HandlePrintMessageDetour(
+ RaptureLogModule.Instance(),
+ targetChannel,
+ &sender,
+ &message,
+ chat.Timestamp,
+ (byte)(chat.Silent ? 1 : 0));
}
+
+ LSeStringBuilder.SharedPool.Return(sb);
}
///
@@ -229,29 +263,6 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
}
}
- private void PrintTagged(string message, XivChatType channel, string? tag, ushort? color)
- {
- var builder = new SeStringBuilder();
-
- if (!tag.IsNullOrEmpty())
- {
- if (color is not null)
- {
- builder.AddUiForeground($"[{tag}] ", color.Value);
- }
- else
- {
- builder.AddText($"[{tag}] ");
- }
- }
-
- this.Print(new XivChatEntry
- {
- Message = builder.AddText(message).Build(),
- Type = channel,
- });
- }
-
private void PrintTagged(SeString message, XivChatType channel, string? tag, ushort? color)
{
var builder = new SeStringBuilder();
@@ -275,21 +286,47 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
});
}
- private void HandlePopulateItemLinkDetour(IntPtr linkObjectPtr, IntPtr itemInfoPtr)
+ private void PrintTagged(ReadOnlySpan message, XivChatType channel, string? tag, ushort? color)
{
+ var sb = LSeStringBuilder.SharedPool.Get();
+
+ if (!tag.IsNullOrEmpty())
+ {
+ if (color is not null)
+ {
+ sb.PushColorType(color.Value);
+ sb.Append($"[{tag}] ");
+ sb.PopColorType();
+ }
+ else
+ {
+ sb.Append($"[{tag}] ");
+ }
+ }
+
+ this.Print(new XivChatEntry
+ {
+ MessageBytes = sb.Append((ReadOnlySeStringSpan)message).ToArray(),
+ Type = channel,
+ });
+
+ LSeStringBuilder.SharedPool.Return(sb);
+ }
+
+ private void InventoryItemCopyDetour(InventoryItem* thisPtr, InventoryItem* otherPtr)
+ {
+ this.inventoryItemCopyHook.Original(thisPtr, otherPtr);
+
try
{
- this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
+ this.LastLinkedItemId = otherPtr->ItemId;
+ this.LastLinkedItemFlags = (byte)otherPtr->Flags;
- this.LastLinkedItemId = Marshal.ReadInt32(itemInfoPtr, 8);
- this.LastLinkedItemFlags = Marshal.ReadByte(itemInfoPtr, 0x14);
-
- // Log.Verbose($"HandlePopulateItemLinkDetour {linkObjectPtr} {itemInfoPtr} - linked:{this.LastLinkedItemId}");
+ // Log.Verbose($"InventoryItemCopyDetour {thisPtr} {otherPtr} - linked:{this.LastLinkedItemId}");
}
catch (Exception ex)
{
- Log.Error(ex, "Exception onPopulateItemLink hook.");
- this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
+ Log.Error(ex, "Exception in InventoryItemCopyHook");
}
}
@@ -299,58 +336,57 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
try
{
- var originalSenderData = sender->AsSpan().ToArray();
- var originalMessageData = message->AsSpan().ToArray();
+ var parsedSender = SeString.Parse(sender->AsSpan());
+ var parsedMessage = SeString.Parse(message->AsSpan());
- var parsedSender = SeString.Parse(originalSenderData);
- var parsedMessage = SeString.Parse(originalMessageData);
+ var terminatedSender = parsedSender.EncodeWithNullTerminator();
+ var terminatedMessage = parsedMessage.EncodeWithNullTerminator();
// Call events
var isHandled = false;
- var invocationList = this.CheckMessageHandled!.GetInvocationList();
- foreach (var @delegate in invocationList)
+ if (this.CheckMessageHandled is { } handledCallback)
{
- try
- {
- var messageHandledDelegate = @delegate as IChatGui.OnCheckMessageHandledDelegate;
- messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
- }
- catch (Exception e)
- {
- Log.Error(e, "Could not invoke registered OnCheckMessageHandledDelegate for {Name}", @delegate.Method.Name);
- }
- }
-
- if (!isHandled)
- {
- invocationList = this.ChatMessage!.GetInvocationList();
- foreach (var @delegate in invocationList)
+ foreach (var action in handledCallback.GetInvocationList().Cast())
{
try
{
- var messageHandledDelegate = @delegate as IChatGui.OnMessageDelegate;
- messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
+ action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
}
catch (Exception e)
{
- Log.Error(e, "Could not invoke registered OnMessageDelegate for {Name}", @delegate.Method.Name);
+ Log.Error(e, "Could not invoke registered OnCheckMessageHandledDelegate for {Name}", action.Method);
}
}
}
- var possiblyModifiedSenderData = parsedSender.Encode();
- var possiblyModifiedMessageData = parsedMessage.Encode();
-
- if (!Util.FastByteArrayCompare(originalSenderData, possiblyModifiedSenderData))
+ if (!isHandled && this.ChatMessage is { } callback)
{
- Log.Verbose($"HandlePrintMessageDetour Sender modified: {SeString.Parse(originalSenderData)} -> {parsedSender}");
+ foreach (var action in callback.GetInvocationList().Cast())
+ {
+ try
+ {
+ action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Could not invoke registered OnMessageDelegate for {Name}", action.Method);
+ }
+ }
+ }
+
+ var possiblyModifiedSenderData = parsedSender.EncodeWithNullTerminator();
+ var possiblyModifiedMessageData = parsedMessage.EncodeWithNullTerminator();
+
+ if (!terminatedSender.SequenceEqual(possiblyModifiedSenderData))
+ {
+ Log.Verbose($"HandlePrintMessageDetour Sender modified: {SeString.Parse(terminatedSender)} -> {parsedSender}");
sender->SetString(possiblyModifiedSenderData);
}
- if (!Util.FastByteArrayCompare(originalMessageData, possiblyModifiedMessageData))
+ if (!terminatedMessage.SequenceEqual(possiblyModifiedMessageData))
{
- Log.Verbose($"HandlePrintMessageDetour Message modified: {SeString.Parse(originalMessageData)} -> {parsedMessage}");
+ Log.Verbose($"HandlePrintMessageDetour Message modified: {SeString.Parse(terminatedMessage)} -> {parsedMessage}");
message->SetString(possiblyModifiedMessageData);
}
@@ -374,42 +410,57 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
return messageId;
}
- private void InteractableLinkClickedDetour(IntPtr managerPtr, IntPtr messagePtr)
+ private void HandleLinkClickDetour(LogViewer* thisPtr, LinkData* linkData)
{
+ if (linkData == null || linkData->Payload == null || (Payload.EmbeddedInfoType)(linkData->LinkType + 1) != Payload.EmbeddedInfoType.DalamudLink)
+ {
+ this.handleLinkClickHook.Original(thisPtr, linkData);
+ return;
+ }
+
+ Log.Verbose($"InteractableLinkClicked: {Payload.EmbeddedInfoType.DalamudLink}");
+
+ var sb = LSeStringBuilder.SharedPool.Get();
try
{
- var interactableType = (Payload.EmbeddedInfoType)(Marshal.ReadByte(messagePtr, 0x1B) + 1);
+ var seStringSpan = new ReadOnlySeStringSpan(linkData->Payload);
- if (interactableType != Payload.EmbeddedInfoType.DalamudLink)
+ // read until link terminator
+ foreach (var payload in seStringSpan)
{
- this.interactableLinkClickedHook.Original(managerPtr, messagePtr);
- return;
+ sb.Append(payload);
+
+ if (payload.Type == ReadOnlySePayloadType.Macro &&
+ payload.MacroCode == MacroCode.Link &&
+ payload.TryGetExpression(out var expr1) &&
+ expr1.TryGetInt(out var expr1Val) &&
+ expr1Val == (int)LinkMacroPayloadType.Terminator)
+ {
+ break;
+ }
}
- Log.Verbose($"InteractableLinkClicked: {Payload.EmbeddedInfoType.DalamudLink}");
+ var seStr = SeString.Parse(sb.ToArray());
+ if (seStr.Payloads.Count == 0 || seStr.Payloads[0] is not DalamudLinkPayload link)
+ return;
- var payloadPtr = Marshal.ReadIntPtr(messagePtr, 0x10);
- var seStr = MemoryHelper.ReadSeStringNullTerminated(payloadPtr);
- var terminatorIndex = seStr.Payloads.IndexOf(RawPayload.LinkTerminator);
- var payloads = terminatorIndex >= 0 ? seStr.Payloads.Take(terminatorIndex + 1).ToList() : seStr.Payloads;
- if (payloads.Count == 0) return;
- var linkPayload = payloads[0];
- if (linkPayload is DalamudLinkPayload link)
+ if (this.RegisteredLinkHandlers.TryGetValue((link.Plugin, link.CommandId), out var value))
{
- if (this.RegisteredLinkHandlers.TryGetValue((link.Plugin, link.CommandId), out var value))
- {
- Log.Verbose($"Sending DalamudLink to {link.Plugin}: {link.CommandId}");
- value.Invoke(link.CommandId, new SeString(payloads));
- }
- else
- {
- Log.Debug($"No DalamudLink registered for {link.Plugin} with ID of {link.CommandId}");
- }
+ Log.Verbose($"Sending DalamudLink to {link.Plugin}: {link.CommandId}");
+ value.Invoke(link.CommandId, seStr);
+ }
+ else
+ {
+ Log.Debug($"No DalamudLink registered for {link.Plugin} with ID of {link.CommandId}");
}
}
catch (Exception ex)
{
- Log.Error(ex, "Exception on InteractableLinkClicked hook");
+ Log.Error(ex, "Exception in HandleLinkClickDetour");
+ }
+ finally
+ {
+ LSeStringBuilder.SharedPool.Return(sb);
}
}
}
@@ -451,7 +502,7 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
public event IChatGui.OnMessageUnhandledDelegate? ChatMessageUnhandled;
///
- public int LastLinkedItemId => this.chatGuiService.LastLinkedItemId;
+ public uint LastLinkedItemId => this.chatGuiService.LastLinkedItemId;
///
public byte LastLinkedItemFlags => this.chatGuiService.LastLinkedItemFlags;
@@ -493,6 +544,14 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
public void PrintError(SeString message, string? messageTag = null, ushort? tagColor = null)
=> this.chatGuiService.PrintError(message, messageTag, tagColor);
+ ///
+ public void Print(ReadOnlySpan message, string? messageTag = null, ushort? tagColor = null)
+ => this.chatGuiService.Print(message, messageTag, tagColor);
+
+ ///
+ public void PrintError(ReadOnlySpan message, string? messageTag = null, ushort? tagColor = null)
+ => this.chatGuiService.PrintError(message, messageTag, tagColor);
+
private void OnMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.ChatMessage?.Invoke(type, timestamp, ref sender, ref message, ref isHandled);
diff --git a/Dalamud/Game/Gui/ChatGuiAddressResolver.cs b/Dalamud/Game/Gui/ChatGuiAddressResolver.cs
deleted file mode 100644
index 366e79fc6..000000000
--- a/Dalamud/Game/Gui/ChatGuiAddressResolver.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace Dalamud.Game.Gui;
-
-///
-/// The address resolver for the class.
-///
-internal sealed class ChatGuiAddressResolver : BaseAddressResolver
-{
- ///
- /// Gets the address of the native PopulateItemLinkObject method.
- ///
- public IntPtr PopulateItemLinkObject { get; private set; }
-
- ///
- /// Gets the address of the native InteractableLinkClicked method.
- ///
- public IntPtr InteractableLinkClicked { get; private set; }
-
- ///
- protected override void Setup64Bit(ISigScanner sig)
- {
- // PopulateItemLinkObject = sig.ScanText("48 89 5C 24 08 57 48 83 EC 20 80 7A 06 00 48 8B DA 48 8B F9 74 14 48 8B CA E8 32 03 00 00 48 8B C8 E8 FA F2 B0 FF 8B C8 EB 1D 0F B6 42 14 8B 4A");
-
- // PopulateItemLinkObject = sig.ScanText( "48 89 5C 24 08 57 48 83 EC 20 80 7A 06 00 48 8B DA 48 8B F9 74 14 48 8B CA E8 32 03 00 00 48 8B C8 E8 ?? ?? B0 FF 8B C8 EB 1D 0F B6 42 14 8B 4A"); 5.0
- this.PopulateItemLinkObject = sig.ScanText("E8 ?? ?? ?? ?? 8B 4E FC");
-
- this.InteractableLinkClicked = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 4B ?? E8 ?? ?? ?? ?? 33 D2");
- }
-}
diff --git a/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs b/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs
index 604af5ac7..fb78e6b80 100644
--- a/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs
+++ b/Dalamud/Game/Gui/ContextMenu/ContextMenu.cs
@@ -47,9 +47,9 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
}
private delegate ushort AtkModuleVf22OpenAddonByAgentDelegate(AtkModule* module, byte* addonName, int valueCount, AtkValue* values, AgentInterface* agent, nint a7, bool a8);
-
+
private delegate bool AddonContextMenuOnMenuSelectedDelegate(AddonContextMenu* addon, int selectedIdx, byte a3);
-
+
private delegate ushort RaptureAtkModuleOpenAddonDelegate(RaptureAtkModule* a1, uint addonNameId, uint valueCount, AtkValue* values, AgentInterface* parentAgent, ulong unk, ushort parentAddonId, int unk2);
///
@@ -92,16 +92,22 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
///
void IInternalDisposableService.DisposeService()
{
+ this.atkModuleVf22OpenAddonByAgentHook.Dispose();
+ this.addonContextMenuOnMenuSelectedHook.Dispose();
+
var manager = RaptureAtkUnitManager.Instance();
+ if (manager == null)
+ return;
+
var menu = manager->GetAddonByName("ContextMenu");
var submenu = manager->GetAddonByName("AddonContextSub");
+ if (menu == null || submenu == null)
+ return;
+
if (menu->IsVisible)
menu->FireCallbackInt(-1);
if (submenu->IsVisible)
submenu->FireCallbackInt(-1);
-
- this.atkModuleVf22OpenAddonByAgentHook.Dispose();
- this.addonContextMenuOnMenuSelectedHook.Dispose();
}
///
diff --git a/Dalamud/Game/Gui/ContextMenu/MenuItem.cs b/Dalamud/Game/Gui/ContextMenu/MenuItem.cs
index 9b7cc2bc1..df1cb54a7 100644
--- a/Dalamud/Game/Gui/ContextMenu/MenuItem.cs
+++ b/Dalamud/Game/Gui/ContextMenu/MenuItem.cs
@@ -1,7 +1,7 @@
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.Gui.ContextMenu;
diff --git a/Dalamud/Game/Gui/ContextMenu/MenuTargetDefault.cs b/Dalamud/Game/Gui/ContextMenu/MenuTargetDefault.cs
index 26365ab14..f09b3e105 100644
--- a/Dalamud/Game/Gui/ContextMenu/MenuTargetDefault.cs
+++ b/Dalamud/Game/Gui/ContextMenu/MenuTargetDefault.cs
@@ -1,11 +1,12 @@
+using Dalamud.Data;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
-using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.Network.Structures.InfoProxy;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.Gui.ContextMenu;
@@ -46,7 +47,7 @@ public sealed unsafe class MenuTargetDefault : MenuTarget
///
/// Gets the home world id of the target.
///
- public ExcelResolver TargetHomeWorld => new((uint)this.Context->TargetHomeWorldId);
+ public RowRef TargetHomeWorld => LuminaUtils.CreateRef((uint)this.Context->TargetHomeWorldId);
///
/// Gets the currently targeted character. Only shows up for specific targets, like friends, party finder listings, or party members.
diff --git a/Dalamud/Game/Gui/Dtr/DtrBar.cs b/Dalamud/Game/Gui/Dtr/DtrBar.cs
index 55b2573f0..c6208fb2f 100644
--- a/Dalamud/Game/Gui/Dtr/DtrBar.cs
+++ b/Dalamud/Game/Gui/Dtr/DtrBar.cs
@@ -1,6 +1,7 @@
-using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Linq;
+using System.Threading;
using Dalamud.Configuration.Internal;
using Dalamud.Game.Addon.Events;
@@ -10,6 +11,7 @@ using Dalamud.Game.Text.SeStringHandling;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
+using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Graphics;
@@ -28,7 +30,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
private const uint BaseNodeId = 1000;
private static readonly ModuleLog Log = new("DtrBar");
-
+
[ServiceManager.ServiceDependency]
private readonly Framework framework = Service.Get();
@@ -48,13 +50,15 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
private readonly AddonLifecycleEventListener dtrPostRequestedUpdateListener;
private readonly AddonLifecycleEventListener dtrPreFinalizeListener;
- private readonly ConcurrentBag newEntries = new();
- private readonly List entries = new();
+ private readonly ReaderWriterLockSlim entriesLock = new();
+ private readonly List entries = [];
private readonly Dictionary> eventHandles = new();
+ private ImmutableList? entriesReadOnlyCopy;
+
private Utf8String* emptyString;
-
+
private uint runningNodeIds = BaseNodeId;
private float entryStartPos = float.NaN;
@@ -68,55 +72,157 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
this.addonLifecycle.RegisterListener(this.dtrPostDrawListener);
this.addonLifecycle.RegisterListener(this.dtrPostRequestedUpdateListener);
this.addonLifecycle.RegisterListener(this.dtrPreFinalizeListener);
-
+
this.framework.Update += this.Update;
- this.configuration.DtrOrder ??= new List();
- this.configuration.DtrIgnore ??= new List();
+ this.configuration.DtrOrder ??= [];
+ this.configuration.DtrIgnore ??= [];
this.configuration.QueueSave();
}
- ///
- /// Event type fired each time a DtrEntry was removed.
- ///
- /// The title of the bar entry.
- internal delegate void DtrEntryRemovedDelegate(string title);
-
- ///
- /// Event fired each time a DtrEntry was removed.
- ///
- internal event DtrEntryRemovedDelegate? DtrEntryRemoved;
-
///
- public IReadOnlyList Entries => this.entries;
-
- ///
- public IDtrBarEntry Get(string title, SeString? text = null)
+ public IReadOnlyList Entries
{
- if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title))
- throw new ArgumentException("An entry with the same title already exists.");
-
- var entry = new DtrBarEntry(this.configuration, title, null);
- entry.Text = text;
-
- // Add the entry to the end of the order list, if it's not there already.
- if (!this.configuration.DtrOrder!.Contains(title))
- this.configuration.DtrOrder!.Add(title);
-
- this.newEntries.Add(entry);
-
- return entry;
- }
-
- ///
- public void Remove(string title)
- {
- if (this.entries.FirstOrDefault(entry => entry.Title == title) is { } dtrBarEntry)
+ get
{
- dtrBarEntry.Remove();
+ var erc = this.entriesReadOnlyCopy;
+ if (erc is null)
+ {
+ this.entriesLock.EnterReadLock();
+ this.entriesReadOnlyCopy = erc = [..this.entries];
+ this.entriesLock.ExitReadLock();
+ }
+
+ return erc;
}
}
+ ///
+ /// Get a DTR bar entry.
+ /// This allows you to add your own text, and users to sort it.
+ ///
+ /// Plugin that owns the DTR bar, or null if owned by Dalamud.
+ /// A user-friendly name for sorting.
+ /// The text the entry shows.
+ /// The entry object used to update, hide and remove the entry.
+ /// Thrown when an entry with the specified title exists.
+ public IDtrBarEntry Get(LocalPlugin? plugin, string title, SeString? text = null)
+ {
+ this.entriesLock.EnterUpgradeableReadLock();
+
+ foreach (var existingEntry in this.entries)
+ {
+ if (existingEntry.Title == title)
+ {
+ if (existingEntry.ShouldBeRemoved)
+ {
+ if (plugin == existingEntry.OwnerPlugin)
+ {
+ Log.Debug(
+ "Reviving entry: {what}; owner: {plugin}({pluginId})",
+ title,
+ plugin?.InternalName,
+ plugin?.EffectiveWorkingPluginId);
+ }
+ else
+ {
+ Log.Debug(
+ "Reviving entry: {what}; old owner: {old}({oldId}); new owner: {new}({newId})",
+ title,
+ existingEntry.OwnerPlugin?.InternalName,
+ existingEntry.OwnerPlugin?.EffectiveWorkingPluginId,
+ plugin?.InternalName,
+ plugin?.EffectiveWorkingPluginId);
+ existingEntry.OwnerPlugin = plugin;
+ }
+
+ existingEntry.ShouldBeRemoved = false;
+ }
+
+ this.entriesLock.ExitUpgradeableReadLock();
+ if (plugin == existingEntry.OwnerPlugin)
+ return existingEntry;
+
+ Log.Debug(
+ "Entry already has a different owner: {what}; owner: {old}({oldId}); requester: {new}({newId})",
+ title,
+ existingEntry.OwnerPlugin?.InternalName,
+ existingEntry.OwnerPlugin?.EffectiveWorkingPluginId,
+ plugin?.InternalName,
+ plugin?.EffectiveWorkingPluginId);
+ throw new ArgumentException("An entry with the same title already exists.");
+ }
+ }
+
+ this.entriesLock.EnterWriteLock();
+ var entry = new DtrBarEntry(this.configuration, title, null) { Text = text, OwnerPlugin = plugin };
+ this.entries.Add(entry);
+ Log.Debug(
+ "Adding entry: {what}; owner: {owner}({id})",
+ title,
+ plugin?.InternalName,
+ plugin?.EffectiveWorkingPluginId);
+
+ // Add the entry to the end of the order list, if it's not there already.
+ var dtrOrder = this.configuration.DtrOrder ??= [];
+ if (!dtrOrder.Contains(entry.Title))
+ dtrOrder.Add(entry.Title);
+ this.ApplySortUnsafe(dtrOrder);
+
+ this.entriesReadOnlyCopy = null;
+ this.entriesLock.ExitWriteLock();
+
+ this.entriesLock.ExitUpgradeableReadLock();
+ return entry;
+ }
+
+ ///
+ public IDtrBarEntry Get(string title, SeString? text = null) => this.Get(null, title, text);
+
+ ///
+ /// Removes a DTR bar entry from the system.
+ ///
+ /// Plugin that owns the DTR bar, or null if owned by Dalamud.
+ /// Title of the entry to remove, or null to remove all entries under the plugin.
+ /// Remove operation is not immediate. If you try to add right after removing, the operation may fail.
+ ///
+ public void Remove(LocalPlugin? plugin, string? title)
+ {
+ this.entriesLock.EnterUpgradeableReadLock();
+
+ foreach (var entry in this.entries)
+ {
+ if ((title is null || entry.Title == title) && (plugin is null || entry.OwnerPlugin == plugin))
+ {
+ if (!entry.Added)
+ {
+ Log.Debug("Removing entry immediately because it is not added yet: {what}", entry.Title);
+ this.entriesLock.EnterWriteLock();
+ this.RemoveEntry(entry);
+ this.entries.Remove(entry);
+ this.entriesReadOnlyCopy = null;
+ this.entriesLock.ExitWriteLock();
+ }
+ else if (!entry.ShouldBeRemoved)
+ {
+ Log.Debug("Queueing entry for removal: {what}", entry.Title);
+ entry.Remove();
+ }
+ else
+ {
+ Log.Debug("Entry is already marked for removal: {what}", entry.Title);
+ }
+
+ break;
+ }
+ }
+
+ this.entriesLock.ExitUpgradeableReadLock();
+ }
+
+ ///
+ public void Remove(string title) => this.Remove(null, title);
+
///
void IInternalDisposableService.DisposeService()
{
@@ -124,10 +230,17 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
this.addonLifecycle.UnregisterListener(this.dtrPostRequestedUpdateListener);
this.addonLifecycle.UnregisterListener(this.dtrPreFinalizeListener);
- foreach (var entry in this.entries)
- this.RemoveEntry(entry);
+ this.framework.RunOnFrameworkThread(
+ () =>
+ {
+ this.entriesLock.EnterWriteLock();
+ foreach (var entry in this.entries)
+ this.RemoveEntry(entry);
+ this.entries.Clear();
+ this.entriesReadOnlyCopy = null;
+ this.entriesLock.ExitWriteLock();
+ }).Wait();
- this.entries.Clear();
this.framework.Update -= this.Update;
if (this.emptyString != null)
@@ -137,23 +250,6 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
}
}
- ///
- /// Remove nodes marked as "should be removed" from the bar.
- ///
- internal void HandleRemovedNodes()
- {
- foreach (var data in this.entries)
- {
- if (data.ShouldBeRemoved)
- {
- this.RemoveEntry(data);
- this.DtrEntryRemoved?.Invoke(data.Title);
- }
- }
-
- this.entries.RemoveAll(d => d.ShouldBeRemoved);
- }
-
///
/// Remove native resources for the specified entry.
///
@@ -174,7 +270,17 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
///
/// The title to check for.
/// Whether or not an entry with that title is registered.
- internal bool HasEntry(string title) => this.entries.Any(x => x.Title == title);
+ internal bool HasEntry(string title)
+ {
+ var found = false;
+
+ this.entriesLock.EnterReadLock();
+ for (var i = 0; i < this.entries.Count && !found; i++)
+ found = this.entries[i].Title == title;
+ this.entriesLock.ExitReadLock();
+
+ return found;
+ }
///
/// Dirty the DTR bar entry with the specified title.
@@ -183,24 +289,37 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
/// Whether the entry was found.
internal bool MakeDirty(string title)
{
- var entry = this.entries.FirstOrDefault(x => x.Title == title);
- if (entry == null)
- return false;
+ var found = false;
- entry.Dirty = true;
- return true;
+ this.entriesLock.EnterReadLock();
+ for (var i = 0; i < this.entries.Count && !found; i++)
+ {
+ found = this.entries[i].Title == title;
+ if (found)
+ this.entries[i].Dirty = true;
+ }
+
+ this.entriesLock.ExitReadLock();
+
+ return found;
}
///
/// Reapply the DTR entry ordering from .
///
internal void ApplySort()
+ {
+ this.entriesLock.EnterWriteLock();
+ this.ApplySortUnsafe(this.configuration.DtrOrder ??= []);
+ this.entriesLock.ExitWriteLock();
+ }
+
+ private void ApplySortUnsafe(List dtrOrder)
{
// Sort the current entry list, based on the order in the configuration.
- var positions = this.configuration
- .DtrOrder!
- .Select(entry => (entry, index: this.configuration.DtrOrder!.IndexOf(entry)))
- .ToDictionary(x => x.entry, x => x.index);
+ var positions = dtrOrder
+ .Select(entry => (entry, index: dtrOrder.IndexOf(entry)))
+ .ToDictionary(x => x.entry, x => x.index);
this.entries.Sort((x, y) =>
{
@@ -208,15 +327,13 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var yPos = positions.TryGetValue(y.Title, out var yIndex) ? yIndex : int.MaxValue;
return xPos.CompareTo(yPos);
});
+ this.entriesReadOnlyCopy = null;
}
private AtkUnitBase* GetDtr() => (AtkUnitBase*)this.gameGui.GetAddonByName("_DTR").ToPointer();
private void Update(IFramework unused)
{
- this.HandleRemovedNodes();
- this.HandleAddedNodes();
-
var dtr = this.GetDtr();
if (dtr == null || dtr->RootNode == null || dtr->RootNode->ChildNode == null) return;
@@ -236,14 +353,28 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var runningXPos = this.entryStartPos;
- foreach (var data in this.entries)
+ this.entriesLock.EnterUpgradeableReadLock();
+ for (var i = 0; i < this.entries.Count; i++)
{
- if (!data.Added)
+ var data = this.entries[i];
+ if (data.ShouldBeRemoved)
{
- data.Added = this.AddNode(data.TextNode);
- data.Dirty = true;
+ Log.Debug("Removing entry from Framework.Update: {what}", data.Title);
+ this.entriesLock.EnterWriteLock();
+ this.entries.RemoveAt(i);
+ this.RemoveEntry(data);
+ this.entriesReadOnlyCopy = null;
+ this.entriesLock.ExitWriteLock();
+ i--;
+ continue;
}
+ if (!data.Added)
+ data.Added = this.AddNode(data);
+
+ if (!data.Added || data.TextNode is null) // TextNode check is unnecessary, but just in case.
+ continue;
+
var isHide = !data.Shown || data.UserHidden;
var node = data.TextNode;
var nodeHidden = !node->AtkResNode.IsVisible();
@@ -290,23 +421,10 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
data.Dirty = false;
}
+
+ this.entriesLock.ExitUpgradeableReadLock();
}
- private void HandleAddedNodes()
- {
- if (!this.newEntries.IsEmpty)
- {
- foreach (var newEntry in this.newEntries)
- {
- newEntry.TextNode = this.MakeNode(++this.runningNodeIds);
- this.entries.Add(newEntry);
- }
-
- this.newEntries.Clear();
- this.ApplySort();
- }
- }
-
private void FixCollision(AddonEvent eventType, AddonArgs addonInfo)
{
var addon = (AtkUnitBase*)addonInfo.Addon;
@@ -316,7 +434,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var additionalWidth = 0;
AtkResNode* collisionNode = null;
- foreach (var index in Enumerable.Range(0, addon->UldManager.NodeListCount))
+ for (var index = 0; index < addon->UldManager.NodeListCount; index++)
{
var node = addon->UldManager.NodeList[index];
if (node->IsVisible())
@@ -382,22 +500,20 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
private void RecreateNodes()
{
this.runningNodeIds = BaseNodeId;
- if (this.entries.Any())
- {
- this.eventHandles.Clear();
- }
+ this.entriesLock.EnterReadLock();
+ this.eventHandles.Clear();
foreach (var entry in this.entries)
- {
- entry.TextNode = this.MakeNode(++this.runningNodeIds);
entry.Added = false;
- }
+ this.entriesLock.ExitReadLock();
}
- private bool AddNode(AtkTextNode* node)
+ private bool AddNode(DtrBarEntry data)
{
var dtr = this.GetDtr();
- if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null || node == null) return false;
+ if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null) return false;
+
+ var node = data.TextNode = this.MakeNode(++this.runningNodeIds);
this.eventHandles.TryAdd(node->AtkResNode.NodeId, new List());
this.eventHandles[node->AtkResNode.NodeId].AddRange(new List
@@ -406,7 +522,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseOut, this.DtrEventHandler),
this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseClick, this.DtrEventHandler),
});
-
+
var lastChild = dtr->RootNode->ChildNode;
while (lastChild->PrevSiblingNode != null) lastChild = lastChild->PrevSiblingNode;
Log.Debug($"Found last sibling: {(ulong)lastChild:X}");
@@ -420,6 +536,8 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
dtr->UldManager.UpdateDrawNodeList();
dtr->UpdateCollisionNodeList(false);
Log.Debug("Updated node draw list");
+
+ data.Dirty = true;
return true;
}
@@ -472,7 +590,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
if (this.emptyString == null)
this.emptyString = Utf8String.FromString(" ");
-
+
newTextNode->SetText(this.emptyString->StringPtr);
newTextNode->TextColor = new ByteColor { R = 255, G = 255, B = 255, A = 255 };
@@ -491,13 +609,21 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
return newTextNode;
}
-
+
private void DtrEventHandler(AddonEventType atkEventType, IntPtr atkUnitBase, IntPtr atkResNode)
{
var addon = (AtkUnitBase*)atkUnitBase;
var node = (AtkResNode*)atkResNode;
- if (this.entries.FirstOrDefault(entry => entry.TextNode == node) is not { } dtrBarEntry) return;
+ DtrBarEntry? dtrBarEntry = null;
+ this.entriesLock.EnterReadLock();
+ foreach (var entry in this.entries)
+ {
+ if (entry.TextNode == node)
+ dtrBarEntry = entry;
+ }
+
+ this.entriesLock.ExitReadLock();
if (dtrBarEntry is { Tooltip: not null })
{
@@ -506,7 +632,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
case AddonEventType.MouseOver:
AtkStage.Instance()->TooltipManager.ShowTooltip(addon->Id, node, dtrBarEntry.Tooltip.Encode());
break;
-
+
case AddonEventType.MouseOut:
AtkStage.Instance()->TooltipManager.HideTooltip(addon->Id);
break;
@@ -520,11 +646,11 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
case AddonEventType.MouseOver:
this.uiEventManager.SetCursor(AddonCursorType.Clickable);
break;
-
+
case AddonEventType.MouseOut:
this.uiEventManager.ResetCursor();
break;
-
+
case AddonEventType.MouseClick:
dtrBarEntry.OnClick.Invoke();
break;
@@ -541,58 +667,25 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
#pragma warning disable SA1015
[ResolveVia]
#pragma warning restore SA1015
-internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
+internal sealed class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
{
+ private readonly LocalPlugin plugin;
+
[ServiceManager.ServiceDependency]
private readonly DtrBar dtrBarService = Service.Get();
- private readonly Dictionary pluginEntries = new();
-
- ///
- /// Initializes a new instance of the class.
- ///
- internal DtrBarPluginScoped()
- {
- this.dtrBarService.DtrEntryRemoved += this.OnDtrEntryRemoved;
- }
+ [ServiceManager.ServiceConstructor]
+ private DtrBarPluginScoped(LocalPlugin plugin) => this.plugin = plugin;
///
public IReadOnlyList Entries => this.dtrBarService.Entries;
///
- void IInternalDisposableService.DisposeService()
- {
- this.dtrBarService.DtrEntryRemoved -= this.OnDtrEntryRemoved;
-
- foreach (var entry in this.pluginEntries)
- {
- entry.Value.Remove();
- }
-
- this.pluginEntries.Clear();
- }
+ void IInternalDisposableService.DisposeService() => this.dtrBarService.Remove(this.plugin, null);
///
- public IDtrBarEntry Get(string title, SeString? text = null)
- {
- // If we already have a known entry for this plugin, return it.
- if (this.pluginEntries.TryGetValue(title, out var existingEntry)) return existingEntry;
+ public IDtrBarEntry Get(string title, SeString? text = null) => this.dtrBarService.Get(this.plugin, title, text);
- return this.pluginEntries[title] = this.dtrBarService.Get(title, text);
- }
-
///
- public void Remove(string title)
- {
- if (this.pluginEntries.TryGetValue(title, out var existingEntry))
- {
- existingEntry.Remove();
- this.pluginEntries.Remove(title);
- }
- }
-
- private void OnDtrEntryRemoved(string title)
- {
- this.pluginEntries.Remove(title);
- }
+ public void Remove(string title) => this.dtrBarService.Remove(this.plugin, title);
}
diff --git a/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs b/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs
index fc5210fda..49a2cbb73 100644
--- a/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs
+++ b/Dalamud/Game/Gui/Dtr/DtrBarEntry.cs
@@ -1,7 +1,6 @@
-using System.Linq;
-
-using Dalamud.Configuration.Internal;
+using Dalamud.Configuration.Internal;
using Dalamud.Game.Text.SeStringHandling;
+using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.System.String;
@@ -27,12 +26,12 @@ public interface IReadOnlyDtrBarEntry
///
/// Gets the text of this entry.
///
- public SeString Text { get; }
+ public SeString? Text { get; }
///
/// Gets a tooltip to be shown when the user mouses over the dtr entry.
///
- public SeString Tooltip { get; }
+ public SeString? Tooltip { get; }
///
/// Gets a value indicating whether this entry should be shown.
@@ -86,7 +85,7 @@ public interface IDtrBarEntry : IReadOnlyDtrBarEntry
///
/// Class representing an entry in the server info bar.
///
-public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
+internal sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
{
private readonly DalamudConfiguration configuration;
@@ -146,7 +145,7 @@ public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
}
///
- [Api10ToDo("Maybe make this config scoped to internalname?")]
+ [Api12ToDo("Maybe make this config scoped to internalname?")]
public bool UserHidden => this.configuration.DtrIgnore?.Contains(this.Title) ?? false;
///
@@ -160,9 +159,9 @@ public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
internal Utf8String* Storage { get; set; }
///
- /// Gets a value indicating whether this entry should be removed.
+ /// Gets or sets a value indicating whether this entry should be removed.
///
- internal bool ShouldBeRemoved { get; private set; }
+ internal bool ShouldBeRemoved { get; set; }
///
/// Gets or sets a value indicating whether this entry is dirty.
@@ -174,6 +173,11 @@ public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
///
internal bool Added { get; set; }
+ ///
+ /// Gets or sets the plugin that owns this entry.
+ ///
+ internal LocalPlugin? OwnerPlugin { get; set; }
+
///
public bool TriggerClickAction()
{
diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
index 623bc51b3..cbf166cfc 100644
--- a/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
+++ b/Dalamud/Game/Gui/FlyText/FlyTextGui.cs
@@ -1,3 +1,4 @@
+using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
@@ -8,6 +9,9 @@ using Dalamud.IoC.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Component.GUI;
+
using Serilog;
namespace Dalamud.Game.Gui.FlyText;
@@ -19,62 +23,21 @@ namespace Dalamud.Game.Gui.FlyText;
internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
{
///
- /// The native function responsible for adding fly text to the UI. See .
+ /// The hook that fires when the game creates a fly text element.
///
- private readonly AddFlyTextDelegate addFlyTextNative;
-
- ///
- /// The hook that fires when the game creates a fly text element. See .
- ///
- private readonly Hook createFlyTextHook;
+ private readonly Hook createFlyTextHook;
[ServiceManager.ServiceConstructor]
- private FlyTextGui(TargetSigScanner sigScanner)
+ private unsafe FlyTextGui(TargetSigScanner sigScanner)
{
- this.Address = new FlyTextGuiAddressResolver();
- this.Address.Setup(sigScanner);
-
- this.addFlyTextNative = Marshal.GetDelegateForFunctionPointer(this.Address.AddFlyText);
- this.createFlyTextHook = Hook.FromAddress(this.Address.CreateFlyText, this.CreateFlyTextDetour);
+ this.createFlyTextHook = Hook.FromAddress(AddonFlyText.Addresses.CreateFlyText.Value, this.CreateFlyTextDetour);
this.createFlyTextHook.Enable();
}
- ///
- /// Private delegate for the native CreateFlyText function's hook.
- ///
- private delegate IntPtr CreateFlyTextDelegate(
- IntPtr addonFlyText,
- FlyTextKind kind,
- int val1,
- int val2,
- IntPtr text2,
- uint color,
- uint icon,
- uint damageTypeIcon,
- IntPtr text1,
- float yOffset);
-
- ///
- /// Private delegate for the native AddFlyText function pointer.
- ///
- private delegate void AddFlyTextDelegate(
- IntPtr addonFlyText,
- uint actorIndex,
- uint messageMax,
- IntPtr numbers,
- uint offsetNum,
- uint offsetNumMax,
- IntPtr strings,
- uint offsetStr,
- uint offsetStrMax,
- int unknown);
-
///
public event IFlyTextGui.OnFlyTextCreatedDelegate? FlyTextCreated;
- private FlyTextGuiAddressResolver Address { get; }
-
///
/// Disposes of managed and unmanaged resources.
///
@@ -87,26 +50,16 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
public unsafe void AddFlyText(FlyTextKind kind, uint actorIndex, uint val1, uint val2, SeString text1, SeString text2, uint color, uint icon, uint damageTypeIcon)
{
// Known valid flytext region within the atk arrays
- var numIndex = 30;
- var strIndex = 27;
var numOffset = 161u;
var strOffset = 28u;
- // Get the UI module and flytext addon pointers
- var gameGui = Service.GetNullable();
- if (gameGui == null)
- return;
-
- var ui = (FFXIVClientStructs.FFXIV.Client.UI.UIModule*)gameGui.GetUIModule();
- var flytext = gameGui.GetAddonByName("_FlyText");
-
- if (ui == null || flytext == IntPtr.Zero)
+ var flytext = (AddonFlyText*)RaptureAtkUnitManager.Instance()->GetAddonByName("_FlyText");
+ if (flytext == null)
return;
// Get the number and string arrays we need
- var atkArrayDataHolder = ui->GetRaptureAtkModule()->AtkModule.AtkArrayDataHolder;
- var numArray = atkArrayDataHolder._NumberArrays[numIndex];
- var strArray = atkArrayDataHolder._StringArrays[strIndex];
+ var numArray = AtkStage.Instance()->GetNumberArrayData(NumberArrayType.FlyText);
+ var strArray = AtkStage.Instance()->GetStringArrayData(StringArrayType.FlyText);
// Write the values to the arrays using a known valid flytext region
numArray->IntArray[numOffset + 0] = 1; // Some kind of "Enabled" flag for this section
@@ -120,66 +73,47 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
numArray->IntArray[numOffset + 8] = 0; // Unknown
numArray->IntArray[numOffset + 9] = 0; // Unknown, has something to do with yOffset
- strArray->SetValue((int)strOffset + 0, text1.Encode(), false, true, false);
- strArray->SetValue((int)strOffset + 1, text2.Encode(), false, true, false);
-
- this.addFlyTextNative(
- flytext,
- actorIndex,
- 1,
- (IntPtr)numArray,
- numOffset,
- 10,
- (IntPtr)strArray,
- strOffset,
- 2,
- 0);
+ strArray->SetValue((int)strOffset + 0, text1.EncodeWithNullTerminator(), false, true, false);
+ strArray->SetValue((int)strOffset + 1, text2.EncodeWithNullTerminator(), false, true, false);
+
+ flytext->AddFlyText(actorIndex, 1, numArray, numOffset, 10, strArray, strOffset, 2, 0);
}
- private static byte[] Terminate(byte[] source)
- {
- var terminated = new byte[source.Length + 1];
- Array.Copy(source, 0, terminated, 0, source.Length);
- terminated[^1] = 0;
-
- return terminated;
- }
-
- private IntPtr CreateFlyTextDetour(
- IntPtr addonFlyText,
- FlyTextKind kind,
+ private unsafe nint CreateFlyTextDetour(
+ AddonFlyText* thisPtr,
+ int kind,
int val1,
int val2,
- IntPtr text2,
+ byte* text2,
uint color,
uint icon,
uint damageTypeIcon,
- IntPtr text1,
+ byte* text1,
float yOffset)
{
- var retVal = IntPtr.Zero;
+ var retVal = nint.Zero;
try
{
Log.Verbose("[FlyText] Enter CreateFlyText detour!");
var handled = false;
- var tmpKind = kind;
+ var tmpKind = (FlyTextKind)kind;
var tmpVal1 = val1;
var tmpVal2 = val2;
- var tmpText1 = text1 == IntPtr.Zero ? string.Empty : MemoryHelper.ReadSeStringNullTerminated(text1);
- var tmpText2 = text2 == IntPtr.Zero ? string.Empty : MemoryHelper.ReadSeStringNullTerminated(text2);
+ var tmpText1 = text1 == null ? string.Empty : MemoryHelper.ReadSeStringNullTerminated((nint)text1);
+ var tmpText2 = text2 == null ? string.Empty : MemoryHelper.ReadSeStringNullTerminated((nint)text2);
var tmpColor = color;
var tmpIcon = icon;
var tmpDamageTypeIcon = damageTypeIcon;
var tmpYOffset = yOffset;
- var cmpText1 = tmpText1.ToString();
- var cmpText2 = tmpText2.ToString();
+ var originalText1 = tmpText1.EncodeWithNullTerminator();
+ var originalText2 = tmpText2.EncodeWithNullTerminator();
- Log.Verbose($"[FlyText] Called with addonFlyText({addonFlyText.ToInt64():X}) " +
+ Log.Verbose($"[FlyText] Called with addonFlyText({(nint)thisPtr:X}) " +
$"kind({kind}) val1({val1}) val2({val2}) damageTypeIcon({damageTypeIcon}) " +
- $"text1({text1.ToInt64():X}, \"{tmpText1}\") text2({text2.ToInt64():X}, \"{tmpText2}\") " +
+ $"text1({(nint)text1:X}, \"{tmpText1}\") text2({(nint)text2:X}, \"{tmpText2}\") " +
$"color({color:X}) icon({icon}) yOffset({yOffset})");
Log.Verbose("[FlyText] Calling flytext events!");
this.FlyTextCreated?.Invoke(
@@ -204,12 +138,15 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
return IntPtr.Zero;
}
+ var maybeModifiedText1 = tmpText1.EncodeWithNullTerminator();
+ var maybeModifiedText2 = tmpText2.EncodeWithNullTerminator();
+
// Check if any values have changed
- var dirty = tmpKind != kind ||
+ var dirty = (int)tmpKind != kind ||
tmpVal1 != val1 ||
tmpVal2 != val2 ||
- tmpText1.ToString() != cmpText1 ||
- tmpText2.ToString() != cmpText2 ||
+ !maybeModifiedText1.SequenceEqual(originalText1) ||
+ !maybeModifiedText2.SequenceEqual(originalText2) ||
tmpDamageTypeIcon != damageTypeIcon ||
tmpColor != color ||
tmpIcon != icon ||
@@ -219,28 +156,26 @@ internal sealed class FlyTextGui : IInternalDisposableService, IFlyTextGui
if (!dirty)
{
Log.Verbose("[FlyText] Calling flytext with original args.");
- return this.createFlyTextHook.Original(addonFlyText, kind, val1, val2, text2, color, icon,
+ return this.createFlyTextHook.Original(thisPtr, kind, val1, val2, text2, color, icon,
damageTypeIcon, text1, yOffset);
}
- var terminated1 = Terminate(tmpText1.Encode());
- var terminated2 = Terminate(tmpText2.Encode());
- var pText1 = Marshal.AllocHGlobal(terminated1.Length);
- var pText2 = Marshal.AllocHGlobal(terminated2.Length);
- Marshal.Copy(terminated1, 0, pText1, terminated1.Length);
- Marshal.Copy(terminated2, 0, pText2, terminated2.Length);
+ var pText1 = Marshal.AllocHGlobal(maybeModifiedText1.Length);
+ var pText2 = Marshal.AllocHGlobal(maybeModifiedText2.Length);
+ Marshal.Copy(maybeModifiedText1, 0, pText1, maybeModifiedText1.Length);
+ Marshal.Copy(maybeModifiedText2, 0, pText2, maybeModifiedText2.Length);
Log.Verbose("[FlyText] Allocated and set strings.");
retVal = this.createFlyTextHook.Original(
- addonFlyText,
- tmpKind,
+ thisPtr,
+ (int)tmpKind,
tmpVal1,
tmpVal2,
- pText2,
+ (byte*)pText2,
tmpColor,
tmpIcon,
tmpDamageTypeIcon,
- pText1,
+ (byte*)pText1,
tmpYOffset);
Log.Verbose("[FlyText] Returned from original. Delaying free task.");
diff --git a/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs b/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs
deleted file mode 100644
index aa7c8026f..000000000
--- a/Dalamud/Game/Gui/FlyText/FlyTextGuiAddressResolver.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace Dalamud.Game.Gui.FlyText;
-
-///
-/// An address resolver for the class.
-///
-internal class FlyTextGuiAddressResolver : BaseAddressResolver
-{
- ///
- /// Gets the address of the native AddFlyText method, which occurs
- /// when the game adds fly text elements to the UI. Multiple fly text
- /// elements can be added in a single AddFlyText call.
- ///
- public IntPtr AddFlyText { get; private set; }
-
- ///
- /// Gets the address of the native CreateFlyText method, which occurs
- /// when the game creates a new fly text element. This method is called
- /// once per fly text element, and can be called multiple times per
- /// AddFlyText call.
- ///
- public IntPtr CreateFlyText { get; private set; }
-
- ///
- protected override void Setup64Bit(ISigScanner sig)
- {
- this.AddFlyText = sig.ScanText("E8 ?? ?? ?? ?? FF C7 41 D1 C7");
- this.CreateFlyText = sig.ScanText("E8 ?? ?? ?? ?? 48 8B F8 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 18");
- }
-}
diff --git a/Dalamud/Game/Gui/FlyText/FlyTextKind.cs b/Dalamud/Game/Gui/FlyText/FlyTextKind.cs
index 3727fd0f8..0edbd09ee 100644
--- a/Dalamud/Game/Gui/FlyText/FlyTextKind.cs
+++ b/Dalamud/Game/Gui/FlyText/FlyTextKind.cs
@@ -92,214 +92,232 @@ public enum FlyTextKind : int
///
IslandExp = 15,
+ ///
+ /// Val1 in serif font next to all caps condensed font Text1 with Text2 in sans-serif as subtitle.
+ /// Added in 7.2, usage currently unknown.
+ ///
+ Unknown16 = 16,
+
+ ///
+ /// Val1 in serif font, Text2 in sans-serif as subtitle.
+ /// Added in 7.2, usage currently unknown.
+ ///
+ Unknown17 = 17,
+
+ ///
+ /// Val1 in serif font, Text2 in sans-serif as subtitle.
+ /// Added in 7.2, usage currently unknown.
+ ///
+ Unknown18 = 18,
+
///
/// Sans-serif Text1 next to serif Val1 with all caps condensed font MP with Text2 in sans-serif as subtitle.
///
- MpDrain = 16,
+ MpDrain = 19,
///
/// Currently not used by the game.
/// Sans-serif Text1 next to serif Val1 with all caps condensed font TP with Text2 in sans-serif as subtitle.
///
- NamedTp = 17,
+ NamedTp = 20,
///
/// Val1 in serif font, Text2 in sans-serif as subtitle with sans-serif Text1 to the left of the Val1.
///
- Healing = 18,
+ Healing = 21,
///
/// Sans-serif Text1 next to serif Val1 with all caps condensed font MP with Text2 in sans-serif as subtitle.
///
- MpRegen = 19,
+ MpRegen = 22,
///
/// Currently not used by the game.
/// Sans-serif Text1 next to serif Val1 with all caps condensed font TP with Text2 in sans-serif as subtitle.
///
- NamedTp2 = 20,
+ NamedTp2 = 23,
///
/// Sans-serif Text1 next to serif Val1 with all caps condensed font EP with Text2 in sans-serif as subtitle.
///
- EpRegen = 21,
+ EpRegen = 24,
///
/// Sans-serif Text1 next to serif Val1 with all caps condensed font CP with Text2 in sans-serif as subtitle.
///
- CpRegen = 22,
+ CpRegen = 25,
///
/// Sans-serif Text1 next to serif Val1 with all caps condensed font GP with Text2 in sans-serif as subtitle.
///
- GpRegen = 23,
+ GpRegen = 26,
///
/// Displays nothing.
///
- None = 24,
+ None = 27,
///
/// All caps serif INVULNERABLE.
///
- Invulnerable = 25,
+ Invulnerable = 28,
///
/// All caps sans-serif condensed font INTERRUPTED!
/// Does a large bounce effect on appearance.
/// Does not scroll up or down the screen.
///
- Interrupted = 26,
+ Interrupted = 29,
///
/// Val1 in serif font.
///
- CraftingProgress = 27,
+ CraftingProgress = 30,
///
/// Val1 in serif font.
///
- CraftingQuality = 28,
+ CraftingQuality = 31,
///
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle. Does a bigger bounce effect on appearance.
///
- CraftingQualityCrit = 29,
+ CraftingQualityCrit = 32,
///
/// Currently not used by the game.
/// Val1 in serif font.
///
- AutoAttackNoText3 = 30,
+ AutoAttackNoText3 = 33,
///
/// CriticalHit with sans-serif Text1 to the left of the Val1 (2).
///
- HealingCrit = 31,
+ HealingCrit = 34,
///
/// Currently not used by the game.
/// Same as DamageCrit with a MP in condensed font to the right of Val1.
/// Does a jiggle effect to the right on appearance.
///
- NamedCriticalHitWithMp = 32,
+ NamedCriticalHitWithMp = 35,
///
/// Currently not used by the game.
/// Same as DamageCrit with a TP in condensed font to the right of Val1.
/// Does a jiggle effect to the right on appearance.
///
- NamedCriticalHitWithTp = 33,
+ NamedCriticalHitWithTp = 36,
///
/// Icon next to sans-serif Text1 with sans-serif "has no effect!" to the right.
///
- DebuffNoEffect = 34,
+ DebuffNoEffect = 37,
///
/// Icon next to sans-serif slightly faded Text1.
///
- BuffFading = 35,
+ BuffFading = 38,
///
/// Icon next to sans-serif slightly faded Text1.
///
- DebuffFading = 36,
+ DebuffFading = 39,
///
/// Text1 in sans-serif font.
///
- Named = 37,
+ Named = 40,
///
/// Icon next to sans-serif Text1 with sans-serif "(fully resisted)" to the right.
///
- DebuffResisted = 38,
+ DebuffResisted = 41,
///
/// All caps serif 'INCAPACITATED!'.
///
- Incapacitated = 39,
+ Incapacitated = 42,
///
/// Text1 with sans-serif "(fully resisted)" to the right.
///
- FullyResisted = 40,
+ FullyResisted = 43,
///
/// Text1 with sans-serif "has no effect!" to the right.
///
- HasNoEffect = 41,
+ HasNoEffect = 44,
///
/// Val1 in serif font, Text2 in sans-serif as subtitle with sans-serif Text1 to the left of the Val1.
///
- HpDrain = 42,
+ HpDrain = 45,
///
/// Currently not used by the game.
/// Sans-serif Text1 next to serif Val1 with all caps condensed font MP with Text2 in sans-serif as subtitle.
///
- NamedMp3 = 43,
+ NamedMp3 = 46,
///
/// Currently not used by the game.
/// Sans-serif Text1 next to serif Val1 with all caps condensed font TP with Text2 in sans-serif as subtitle.
///
- NamedTp3 = 44,
+ NamedTp3 = 47,
///
/// Icon next to sans-serif Text1 with serif "INVULNERABLE!" beneath the Text1.
///
- DebuffInvulnerable = 45,
+ DebuffInvulnerable = 48,
///
/// All caps serif RESIST.
///
- Resist = 46,
+ Resist = 49,
///
/// Icon with an item icon outline next to sans-serif Text1.
///
- LootedItem = 47,
+ LootedItem = 50,
///
/// Val1 in serif font.
///
- Collectability = 48,
+ Collectability = 51,
///
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle.
/// Does a bigger bounce effect on appearance.
///
- CollectabilityCrit = 49,
+ CollectabilityCrit = 52,
///
/// All caps serif REFLECT.
///
- Reflect = 50,
+ Reflect = 53,
///
/// All caps serif REFLECTED.
///
- Reflected = 51,
+ Reflected = 54,
///
/// Val1 in serif font, Text2 in sans-serif as subtitle.
/// Does a bounce effect on appearance.
///
- CraftingQualityDh = 52,
+ CraftingQualityDh = 55,
///
/// Currently not used by the game.
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle.
/// Does a bigger bounce effect on appearance.
///
- CriticalHit4 = 53,
+ CriticalHit4 = 56,
///
/// Val1 in even larger serif font with 2 exclamations, Text2 in sans-serif as subtitle.
/// Does a large bounce effect on appearance. Does not scroll up or down the screen.
///
- CraftingQualityCritDh = 54,
+ CraftingQualityCritDh = 57,
}
diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs
index 80463a119..d3fe444ea 100644
--- a/Dalamud/Game/Gui/GameGui.cs
+++ b/Dalamud/Game/Gui/GameGui.cs
@@ -1,4 +1,3 @@
-using System.Numerics;
using System.Runtime.InteropServices;
using Dalamud.Game.Text.SeStringHandling.Payloads;
@@ -10,6 +9,7 @@ using Dalamud.Logging.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
+using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Control;
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.System.String;
@@ -17,8 +17,8 @@ using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Common.Component.BGCollision;
using FFXIVClientStructs.FFXIV.Component.GUI;
+
using ImGuiNET;
-using SharpDX;
using Vector2 = System.Numerics.Vector2;
using Vector3 = System.Numerics.Vector3;
@@ -33,20 +33,16 @@ namespace Dalamud.Game.Gui;
internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
{
private static readonly ModuleLog Log = new("GameGui");
-
+
private readonly GameGuiAddressResolver address;
- private readonly Hook setGlobalBgmHook;
- private readonly Hook handleItemHoverHook;
- private readonly Hook handleItemOutHook;
- private readonly Hook handleActionHoverHook;
- private readonly Hook handleActionOutHook;
+ private readonly Hook handleItemHoverHook;
+ private readonly Hook handleItemOutHook;
+ private readonly Hook handleActionHoverHook;
+ private readonly Hook handleActionOutHook;
private readonly Hook handleImmHook;
- private readonly Hook toggleUiHideHook;
- private readonly Hook utf8StringFromSequenceHook;
-
- private GetUIMapObjectDelegate? getUIMapObject;
- private OpenMapWithFlagDelegate? openMapWithFlag;
+ private readonly Hook setUiVisibilityHook;
+ private readonly Hook utf8StringFromSequenceHook;
[ServiceManager.ServiceConstructor]
private GameGui(TargetSigScanner sigScanner)
@@ -55,68 +51,34 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
this.address.Setup(sigScanner);
Log.Verbose("===== G A M E G U I =====");
- Log.Verbose($"GameGuiManager address {Util.DescribeAddress(this.address.BaseAddress)}");
- Log.Verbose($"SetGlobalBgm address {Util.DescribeAddress(this.address.SetGlobalBgm)}");
- Log.Verbose($"HandleItemHover address {Util.DescribeAddress(this.address.HandleItemHover)}");
- Log.Verbose($"HandleItemOut address {Util.DescribeAddress(this.address.HandleItemOut)}");
Log.Verbose($"HandleImm address {Util.DescribeAddress(this.address.HandleImm)}");
- this.setGlobalBgmHook = Hook.FromAddress(this.address.SetGlobalBgm, this.HandleSetGlobalBgmDetour);
+ this.handleItemHoverHook = Hook.FromAddress((nint)AgentItemDetail.StaticVirtualTablePointer->Update, this.HandleItemHoverDetour);
+ this.handleItemOutHook = Hook.FromAddress((nint)AgentItemDetail.StaticVirtualTablePointer->ReceiveEvent, this.HandleItemOutDetour);
- this.handleItemHoverHook = Hook.FromAddress(this.address.HandleItemHover, this.HandleItemHoverDetour);
- this.handleItemOutHook = Hook.FromAddress(this.address.HandleItemOut, this.HandleItemOutDetour);
-
- this.handleActionHoverHook = Hook.FromAddress(this.address.HandleActionHover, this.HandleActionHoverDetour);
- this.handleActionOutHook = Hook.FromAddress(this.address.HandleActionOut, this.HandleActionOutDetour);
+ this.handleActionHoverHook = Hook.FromAddress(AgentActionDetail.Addresses.HandleActionHover.Value, this.HandleActionHoverDetour);
+ this.handleActionOutHook = Hook.FromAddress((nint)AgentActionDetail.StaticVirtualTablePointer->ReceiveEvent, this.HandleActionOutDetour);
this.handleImmHook = Hook.FromAddress(this.address.HandleImm, this.HandleImmDetour);
- this.toggleUiHideHook = Hook.FromAddress(this.address.ToggleUiHide, this.ToggleUiHideDetour);
+ this.setUiVisibilityHook = Hook.FromAddress((nint)RaptureAtkModule.StaticVirtualTablePointer->SetUiVisibility, this.SetUiVisibilityDetour);
- this.utf8StringFromSequenceHook = Hook.FromAddress(this.address.Utf8StringFromSequence, this.Utf8StringFromSequenceDetour);
+ this.utf8StringFromSequenceHook = Hook.FromAddress(Utf8String.Addresses.Ctor_FromSequence.Value, this.Utf8StringFromSequenceDetour);
- this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.handleImmHook.Enable();
- this.toggleUiHideHook.Enable();
+ this.setUiVisibilityHook.Enable();
this.handleActionHoverHook.Enable();
this.handleActionOutHook.Enable();
this.utf8StringFromSequenceHook.Enable();
}
// Hooked delegates
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate Utf8String* Utf8StringFromSequenceDelegate(Utf8String* thisPtr, byte* sourcePtr, nuint sourceLen);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetUIMapObjectDelegate(IntPtr uiObject);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
- private delegate bool OpenMapWithFlagDelegate(IntPtr uiMapObject, string flag);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr SetGlobalBgmDelegate(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr HandleItemHoverDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr HandleItemOutDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void HandleActionHoverDelegate(IntPtr hoverState, HoverActionKind a2, uint a3, int a4, byte a5);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr HandleActionOutDelegate(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4);
-
+
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate char HandleImmDelegate(IntPtr framework, char a2, byte a3);
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, bool uiVisible);
-
///
public event EventHandler? UiHideToggled;
@@ -137,33 +99,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
///
public bool OpenMapWithMapLink(MapLinkPayload mapLink)
- {
- var uiModule = this.GetUIModule();
-
- if (uiModule == IntPtr.Zero)
- {
- Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
- return false;
- }
-
- this.getUIMapObject ??= this.address.GetVirtualFunction(uiModule, 0, 8);
-
- var uiMapObjectPtr = this.getUIMapObject(uiModule);
-
- if (uiMapObjectPtr == IntPtr.Zero)
- {
- Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
- return false;
- }
-
- this.openMapWithFlag ??= this.address.GetVirtualFunction(uiMapObjectPtr, 0, 63);
-
- var mapLinkString = mapLink.DataString;
-
- Log.Debug($"OpenMapWithMapLink: Opening Map Link: {mapLinkString}");
-
- return this.openMapWithFlag(uiMapObjectPtr, mapLinkString);
- }
+ => RaptureAtkModule.Instance()->OpenMapWithMapLink(mapLink.DataString);
///
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos)
@@ -188,7 +124,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
inView = false;
return false;
}
-
+
pCoords *= MathF.Abs(1.0f / pCoords.W);
screenPos = new Vector2(pCoords.X, pCoords.Y);
@@ -216,7 +152,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
worldPos = default;
return false;
}
-
+
var camera = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CameraManager.Instance()->CurrentCamera;
if (camera == null)
{
@@ -271,7 +207,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
///
public IntPtr FindAgentInterface(void* addon) => this.FindAgentInterface((IntPtr)addon);
-
+
///
public IntPtr FindAgentInterface(IntPtr addonPtr)
{
@@ -311,36 +247,33 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
///
void IInternalDisposableService.DisposeService()
{
- this.setGlobalBgmHook.Dispose();
this.handleItemHoverHook.Dispose();
this.handleItemOutHook.Dispose();
this.handleImmHook.Dispose();
- this.toggleUiHideHook.Dispose();
+ this.setUiVisibilityHook.Dispose();
this.handleActionHoverHook.Dispose();
this.handleActionOutHook.Dispose();
this.utf8StringFromSequenceHook.Dispose();
}
///
- /// Indicates if the game is on the title screen.
+ /// Indicates if the game is in the lobby scene (title screen, chara select, chara make, aesthetician etc.).
///
- /// A value indicating whether or not the game is on the title screen.
- internal bool IsOnTitleScreen()
- {
- var charaSelect = this.GetAddonByName("CharaSelect");
- var charaMake = this.GetAddonByName("CharaMake");
- var titleDcWorldMap = this.GetAddonByName("TitleDCWorldMap");
- if (charaMake != nint.Zero || charaSelect != nint.Zero || titleDcWorldMap != nint.Zero)
- return false;
-
- return !Service.Get().IsLoggedIn;
- }
+ /// A value indicating whether or not the game is in the lobby scene.
+ internal bool IsInLobby() => RaptureAtkModule.Instance()->CurrentUIScene.StartsWith("LobbyMain"u8);
///
- /// Set the current background music.
+ /// Sets the current background music.
///
- /// The background music key.
- internal void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
+ /// The BGM row id.
+ /// The BGM scene index. Defaults to MiniGame scene to avoid conflicts.
+ internal void SetBgm(ushort bgmId, uint sceneId = 2) => BGMSystem.SetBGM(bgmId, sceneId);
+
+ ///
+ /// Resets the current background music.
+ ///
+ /// The BGM scene index.
+ internal void ResetBgm(uint sceneId = 2) => BGMSystem.Instance()->ResetBGM(sceneId);
///
/// Reset the stored "UI hide" state.
@@ -350,93 +283,63 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
this.GameUiHidden = false;
}
- private IntPtr HandleSetGlobalBgmDetour(ushort bgmKey, byte a2, uint a3, uint a4, uint a5, byte a6)
+ private void HandleItemHoverDetour(AgentItemDetail* thisPtr, uint frameCount)
{
- var retVal = this.setGlobalBgmHook.Original(bgmKey, a2, a3, a4, a5, a6);
+ this.handleItemHoverHook.Original(thisPtr, frameCount);
- Log.Verbose("SetGlobalBgm: {0} {1} {2} {3} {4} {5} -> {6}", bgmKey, a2, a3, a4, a5, a6, retVal);
+ if (!thisPtr->IsAgentActive())
+ return;
- return retVal;
+ var itemId = (ulong)thisPtr->ItemId;
+ if (this.HoveredItem == itemId)
+ return;
+
+ this.HoveredItem = itemId;
+ this.HoveredItemChanged?.InvokeSafely(this, itemId);
+
+ Log.Verbose($"HoveredItem changed: {itemId}");
}
- private IntPtr HandleItemHoverDetour(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4)
+ private AtkValue* HandleItemOutDetour(AgentItemDetail* thisPtr, AtkValue* returnValue, AtkValue* values, uint valueCount, ulong eventKind)
{
- var retVal = this.handleItemHoverHook.Original(hoverState, a2, a3, a4);
+ var ret = this.handleItemOutHook.Original(thisPtr, returnValue, values, valueCount, eventKind);
- if (retVal.ToInt64() == 22)
+ if (values != null && valueCount == 1 && values->Int == -1)
{
- var itemId = (ulong)Marshal.ReadInt32(hoverState, 0x138);
- this.HoveredItem = itemId;
+ this.HoveredItem = 0;
+ this.HoveredItemChanged?.InvokeSafely(this, 0ul);
- this.HoveredItemChanged?.InvokeSafely(this, itemId);
-
- Log.Verbose($"HoverItemId:{itemId} this:{hoverState.ToInt64()}");
+ Log.Verbose("HoveredItem changed: 0");
}
- return retVal;
+ return ret;
}
- private IntPtr HandleItemOutDetour(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4)
- {
- var retVal = this.handleItemOutHook.Original(hoverState, a2, a3, a4);
-
- if (a3 != IntPtr.Zero && a4 == 1)
- {
- var a3Val = Marshal.ReadByte(a3, 0x8);
-
- if (a3Val == 255)
- {
- this.HoveredItem = 0ul;
-
- try
- {
- this.HoveredItemChanged?.Invoke(this, 0ul);
- }
- catch (Exception e)
- {
- Log.Error(e, "Could not dispatch HoveredItemChanged event.");
- }
-
- Log.Verbose("HoverItemId: 0");
- }
- }
-
- return retVal;
- }
-
- private void HandleActionHoverDetour(IntPtr hoverState, HoverActionKind actionKind, uint actionId, int a4, byte a5)
+ private void HandleActionHoverDetour(AgentActionDetail* hoverState, FFXIVClientStructs.FFXIV.Client.UI.Agent.ActionKind actionKind, uint actionId, int a4, byte a5)
{
this.handleActionHoverHook.Original(hoverState, actionKind, actionId, a4, a5);
- this.HoveredAction.ActionKind = actionKind;
+ this.HoveredAction.ActionKind = (HoverActionKind)actionKind;
this.HoveredAction.BaseActionID = actionId;
- this.HoveredAction.ActionID = (uint)Marshal.ReadInt32(hoverState, 0x3C);
+ this.HoveredAction.ActionID = hoverState->ActionId;
this.HoveredActionChanged?.InvokeSafely(this, this.HoveredAction);
- Log.Verbose($"HoverActionId: {actionKind}/{actionId} this:{hoverState.ToInt64():X}");
+ Log.Verbose($"HoverActionId: {actionKind}/{actionId} this:{(nint)hoverState:X}");
}
- private IntPtr HandleActionOutDetour(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4)
+ private AtkValue* HandleActionOutDetour(AgentActionDetail* agentActionDetail, AtkValue* a2, AtkValue* a3, uint a4, ulong a5)
{
- var retVal = this.handleActionOutHook.Original(agentActionDetail, a2, a3, a4);
+ var retVal = this.handleActionOutHook.Original(agentActionDetail, a2, a3, a4, a5);
- if (a3 != IntPtr.Zero && a4 == 1)
+ if (a3 != null && a4 == 1)
{
- var a3Val = Marshal.ReadByte(a3, 0x8);
+ var a3Val = a3->Int;
if (a3Val == 255)
{
this.HoveredAction.ActionKind = HoverActionKind.None;
this.HoveredAction.BaseActionID = 0;
this.HoveredAction.ActionID = 0;
-
- try
- {
- this.HoveredActionChanged?.Invoke(this, this.HoveredAction);
- }
- catch (Exception e)
- {
- Log.Error(e, "Could not dispatch HoveredActionChanged event.");
- }
+ this.HoveredActionChanged?.InvokeSafely(this, this.HoveredAction);
Log.Verbose("HoverActionId: 0");
}
@@ -445,16 +348,14 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
return retVal;
}
- private IntPtr ToggleUiHideDetour(IntPtr thisPtr, bool unknownByte)
+ private unsafe void SetUiVisibilityDetour(RaptureAtkModule* thisPtr, bool uiVisible)
{
- var result = this.toggleUiHideHook.Original(thisPtr, unknownByte);
+ this.setUiVisibilityHook.Original(thisPtr, uiVisible);
this.GameUiHidden = !RaptureAtkModule.Instance()->IsUiVisible;
this.UiHideToggled?.InvokeSafely(this, this.GameUiHidden);
- Log.Debug("UiHide toggled: {0}", this.GameUiHidden);
-
- return result;
+ Log.Debug("GameUiHidden: {0}", this.GameUiHidden);
}
private char HandleImmDetour(IntPtr framework, char a2, byte a3)
@@ -501,13 +402,13 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
this.gameGuiService.HoveredItemChanged += this.HoveredItemForward;
this.gameGuiService.HoveredActionChanged += this.HoveredActionForward;
}
-
+
///
public event EventHandler? UiHideToggled;
-
+
///
public event EventHandler? HoveredItemChanged;
-
+
///
public event EventHandler? HoveredActionChanged;
@@ -523,7 +424,7 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
///
public HoveredAction HoveredAction => this.gameGuiService.HoveredAction;
-
+
///
void IInternalDisposableService.DisposeService()
{
@@ -535,7 +436,7 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
this.HoveredItemChanged = null;
this.HoveredActionChanged = null;
}
-
+
///
public bool OpenMapWithMapLink(MapLinkPayload mapLink)
=> this.gameGuiService.OpenMapWithMapLink(mapLink);
@@ -543,7 +444,7 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
///
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos)
=> this.gameGuiService.WorldToScreen(worldPos, out screenPos);
-
+
///
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView)
=> this.gameGuiService.WorldToScreen(worldPos, out screenPos, out inView);
@@ -555,26 +456,26 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui
///
public IntPtr GetUIModule()
=> this.gameGuiService.GetUIModule();
-
+
///
public IntPtr GetAddonByName(string name, int index = 1)
=> this.gameGuiService.GetAddonByName(name, index);
-
+
///
public IntPtr FindAgentInterface(string addonName)
=> this.gameGuiService.FindAgentInterface(addonName);
-
+
///
- public unsafe IntPtr FindAgentInterface(void* addon)
+ public unsafe IntPtr FindAgentInterface(void* addon)
=> this.gameGuiService.FindAgentInterface(addon);
///
- public IntPtr FindAgentInterface(IntPtr addonPtr)
+ public IntPtr FindAgentInterface(IntPtr addonPtr)
=> this.gameGuiService.FindAgentInterface(addonPtr);
private void UiHideToggledForward(object sender, bool toggled) => this.UiHideToggled?.Invoke(sender, toggled);
-
+
private void HoveredItemForward(object sender, ulong itemId) => this.HoveredItemChanged?.Invoke(sender, itemId);
-
+
private void HoveredActionForward(object sender, HoveredAction hoverAction) => this.HoveredActionChanged?.Invoke(sender, hoverAction);
}
diff --git a/Dalamud/Game/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Gui/GameGuiAddressResolver.cs
index 5b02a2d09..92b89c5a9 100644
--- a/Dalamud/Game/Gui/GameGuiAddressResolver.cs
+++ b/Dalamud/Game/Gui/GameGuiAddressResolver.cs
@@ -5,62 +5,14 @@ namespace Dalamud.Game.Gui;
///
internal sealed class GameGuiAddressResolver : BaseAddressResolver
{
- ///
- /// Gets the base address of the native GuiManager class.
- ///
- public IntPtr BaseAddress { get; private set; }
-
- ///
- /// Gets the address of the native SetGlobalBgm method.
- ///
- public IntPtr SetGlobalBgm { get; private set; }
-
- ///
- /// Gets the address of the native HandleItemHover method.
- ///
- public IntPtr HandleItemHover { get; private set; }
-
- ///
- /// Gets the address of the native HandleItemOut method.
- ///
- public IntPtr HandleItemOut { get; private set; }
-
- ///
- /// Gets the address of the native HandleActionHover method.
- ///
- public IntPtr HandleActionHover { get; private set; }
-
- ///
- /// Gets the address of the native HandleActionOut method.
- ///
- public IntPtr HandleActionOut { get; private set; }
-
///
/// Gets the address of the native HandleImm method.
///
public IntPtr HandleImm { get; private set; }
- ///
- /// Gets the address of the native ToggleUiHide method.
- ///
- public IntPtr ToggleUiHide { get; private set; }
-
- ///
- /// Gets the address of the native Utf8StringFromSequence method.
- ///
- public IntPtr Utf8StringFromSequence { get; private set; }
-
///
protected override void Setup64Bit(ISigScanner sig)
{
- this.SetGlobalBgm = sig.ScanText("E8 ?? ?? ?? ?? 8B 2F");
- this.HandleItemHover = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 6C 24 48 48 8B 74 24 50 4C 89 B7 08 01 00 00");
- this.HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
- this.HandleActionHover = sig.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 83 F8 0F");
- this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
- this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09");
-
- this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 44 0F B6 81");
- this.Utf8StringFromSequence = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8D 41 22 66 C7 41 ?? ?? ?? 48 89 01 49 8B D8");
+ this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09"); // unnamed in CS
}
}
diff --git a/Dalamud/Game/Gui/HoverActionKind.cs b/Dalamud/Game/Gui/HoverActionKind.cs
index 90ff9d46c..ef8fe6400 100644
--- a/Dalamud/Game/Gui/HoverActionKind.cs
+++ b/Dalamud/Game/Gui/HoverActionKind.cs
@@ -14,35 +14,140 @@ public enum HoverActionKind
///
/// A regular action is hovered.
///
- Action = 21,
+ Action = 28,
+
+ ///
+ /// A crafting action is hovered.
+ ///
+ CraftingAction = 29,
///
/// A general action is hovered.
///
- GeneralAction = 23,
+ GeneralAction = 30,
///
/// A companion order type of action is hovered.
///
- CompanionOrder = 24,
+ CompanionOrder = 31, // Game Term: BuddyOrder
///
/// A main command type of action is hovered.
///
- MainCommand = 25,
+ MainCommand = 32,
///
/// An extras command type of action is hovered.
///
- ExtraCommand = 26,
+ ExtraCommand = 33,
+
+ ///
+ /// A companion action is hovered.
+ ///
+ Companion = 34,
///
/// A pet order type of action is hovered.
///
- PetOrder = 28,
+ PetOrder = 35,
///
/// A trait is hovered.
///
- Trait = 29,
+ Trait = 36,
+
+ ///
+ /// A buddy action is hovered.
+ ///
+ BuddyAction = 37,
+
+ ///
+ /// A company action is hovered.
+ ///
+ CompanyAction = 38,
+
+ ///
+ /// A mount is hovered.
+ ///
+ Mount = 39,
+
+ ///
+ /// A chocobo race action is hovered.
+ ///
+ ChocoboRaceAction = 40,
+
+ ///
+ /// A chocobo race item is hovered.
+ ///
+ ChocoboRaceItem = 41,
+
+ ///
+ /// A deep dungeon equipment is hovered.
+ ///
+ DeepDungeonEquipment = 42,
+
+ ///
+ /// A deep dungeon equipment 2 is hovered.
+ ///
+ DeepDungeonEquipment2 = 43,
+
+ ///
+ /// A deep dungeon item is hovered.
+ ///
+ DeepDungeonItem = 44,
+
+ ///
+ /// A quick chat is hovered.
+ ///
+ QuickChat = 45,
+
+ ///
+ /// An action combo route is hovered.
+ ///
+ ActionComboRoute = 46,
+
+ ///
+ /// A pvp trait is hovered.
+ ///
+ PvPSelectTrait = 47,
+
+ ///
+ /// A squadron action is hovered.
+ ///
+ BgcArmyAction = 48,
+
+ ///
+ /// A perform action is hovered.
+ ///
+ Perform = 49,
+
+ ///
+ /// A deep dungeon magic stone is hovered.
+ ///
+ DeepDungeonMagicStone = 50,
+
+ ///
+ /// A deep dungeon demiclone is hovered.
+ ///
+ DeepDungeonDemiclone = 51,
+
+ ///
+ /// An eureka magia action is hovered.
+ ///
+ EurekaMagiaAction = 52,
+
+ ///
+ /// An island sanctuary temporary item is hovered.
+ ///
+ MYCTemporaryItem = 53,
+
+ ///
+ /// An ornament is hovered.
+ ///
+ Ornament = 54,
+
+ ///
+ /// Glasses are hovered.
+ ///
+ Glasses = 55,
}
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
index 28e2c36eb..32192ad21 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateGui.cs
@@ -1,14 +1,16 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
-using Dalamud.Game.Addon.Lifecycle;
-using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Game.ClientState.Objects;
+using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Component.GUI;
+
+using Serilog;
namespace Dalamud.Game.Gui.NamePlate;
@@ -18,16 +20,6 @@ namespace Dalamud.Game.Gui.NamePlate;
[ServiceManager.EarlyLoadedService]
internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
{
- ///
- /// The index for the number array used by the NamePlate addon.
- ///
- public const int NumberArrayIndex = 5;
-
- ///
- /// The index for the string array used by the NamePlate addon.
- ///
- public const int StringArrayIndex = 4;
-
///
/// The index for of the FullUpdate entry in the NamePlate number array.
///
@@ -38,60 +30,59 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
///
internal static readonly nint EmptyStringPointer = CreateEmptyStringPointer();
- [ServiceManager.ServiceDependency]
- private readonly AddonLifecycle addonLifecycle = Service.Get();
-
[ServiceManager.ServiceDependency]
private readonly GameGui gameGui = Service.Get();
[ServiceManager.ServiceDependency]
private readonly ObjectTable objectTable = Service.Get();
- private readonly AddonLifecycleEventListener preRequestedUpdateListener;
+ private readonly NamePlateGuiAddressResolver address;
+
+ private readonly Hook onRequestedUpdateHook;
private NamePlateUpdateContext? context;
private NamePlateUpdateHandler[] updateHandlers = [];
[ServiceManager.ServiceConstructor]
- private NamePlateGui()
+ private unsafe NamePlateGui(TargetSigScanner sigScanner)
{
- this.preRequestedUpdateListener = new AddonLifecycleEventListener(
- AddonEvent.PreRequestedUpdate,
- "NamePlate",
- this.OnPreRequestedUpdate);
+ this.address = new NamePlateGuiAddressResolver();
+ this.address.Setup(sigScanner);
- this.addonLifecycle.RegisterListener(this.preRequestedUpdateListener);
+ this.onRequestedUpdateHook = Hook.FromAddress(
+ this.address.OnRequestedUpdate,
+ this.OnRequestedUpdateDetour);
+ this.onRequestedUpdateHook.Enable();
}
///
public event INamePlateGui.OnPlateUpdateDelegate? OnNamePlateUpdate;
+ ///
+ public event INamePlateGui.OnPlateUpdateDelegate? OnPostNamePlateUpdate;
+
///
public event INamePlateGui.OnPlateUpdateDelegate? OnDataUpdate;
+ ///
+ public event INamePlateGui.OnPlateUpdateDelegate? OnPostDataUpdate;
+
///
public unsafe void RequestRedraw()
{
- var addon = this.gameGui.GetAddonByName("NamePlate");
- if (addon != 0)
+ var addon = (AddonNamePlate*)this.gameGui.GetAddonByName("NamePlate");
+ if (addon != null)
{
- var raptureAtkModule = RaptureAtkModule.Instance();
- if (raptureAtkModule == null)
- {
- return;
- }
-
- ((AddonNamePlate*)addon)->DoFullUpdate = 1;
- var namePlateNumberArrayData = raptureAtkModule->AtkArrayDataHolder.NumberArrays[NumberArrayIndex];
- namePlateNumberArrayData->SetValue(NumberArrayFullUpdateIndex, 1);
+ addon->DoFullUpdate = 1;
+ AtkStage.Instance()->GetNumberArrayData(NumberArrayType.NamePlate)->SetValue(NumberArrayFullUpdateIndex, 1);
}
}
///
void IInternalDisposableService.DisposeService()
{
- this.addonLifecycle.UnregisterListener(this.preRequestedUpdateListener);
+ this.onRequestedUpdateHook.Dispose();
}
///
@@ -144,65 +135,124 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
this.updateHandlers = handlers.ToArray();
}
- private void OnPreRequestedUpdate(AddonEvent type, AddonArgs args)
+ private unsafe void OnRequestedUpdateDetour(
+ AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
{
- if (this.OnDataUpdate == null && this.OnNamePlateUpdate == null)
- {
- return;
- }
+ var calledOriginal = false;
- var reqArgs = (AddonRequestedUpdateArgs)args;
- if (this.context == null)
+ try
{
- this.context = new NamePlateUpdateContext(this.objectTable, reqArgs);
- this.CreateHandlers(this.context);
- }
- else
- {
- this.context.ResetState(reqArgs);
- }
-
- var activeNamePlateCount = this.context.ActiveNamePlateCount;
- if (activeNamePlateCount == 0)
- return;
-
- var activeHandlers = this.updateHandlers[..activeNamePlateCount];
-
- if (this.context.IsFullUpdate)
- {
- foreach (var handler in activeHandlers)
+ if (this.OnDataUpdate == null && this.OnNamePlateUpdate == null && this.OnPostDataUpdate == null &&
+ this.OnPostNamePlateUpdate == null)
{
- handler.ResetState();
+ return;
}
- this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, activeHandlers);
- if (this.context.HasParts)
- this.ApplyBuilders(activeHandlers);
- }
- else
- {
- var udpatedHandlers = new List(activeNamePlateCount);
- foreach (var handler in activeHandlers)
+ if (this.context == null)
{
- handler.ResetState();
- if (handler.IsUpdating)
- udpatedHandlers.Add(handler);
+ this.context = new NamePlateUpdateContext(this.objectTable);
+ this.CreateHandlers(this.context);
}
- if (this.OnDataUpdate is not null)
+ this.context.ResetState(addon, numberArrayData, stringArrayData);
+
+ var activeNamePlateCount = this.context!.ActiveNamePlateCount;
+ if (activeNamePlateCount == 0)
+ return;
+
+ var activeHandlers = this.updateHandlers[..activeNamePlateCount];
+
+ if (this.context.IsFullUpdate)
{
+ foreach (var handler in activeHandlers)
+ {
+ handler.ResetState();
+ }
+
this.OnDataUpdate?.Invoke(this.context, activeHandlers);
- this.OnNamePlateUpdate?.Invoke(this.context, udpatedHandlers);
+ this.OnNamePlateUpdate?.Invoke(this.context, activeHandlers);
+
if (this.context.HasParts)
this.ApplyBuilders(activeHandlers);
+
+ try
+ {
+ calledOriginal = true;
+ this.onRequestedUpdateHook.Original.Invoke(addon, numberArrayData, stringArrayData);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
+ }
+
+ this.OnPostNamePlateUpdate?.Invoke(this.context, activeHandlers);
+ this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
}
- else if (udpatedHandlers.Count != 0)
+ else
{
- var changedHandlersSpan = udpatedHandlers.ToArray().AsSpan();
- this.OnNamePlateUpdate?.Invoke(this.context, udpatedHandlers);
- if (this.context.HasParts)
- this.ApplyBuilders(changedHandlersSpan);
+ var updatedHandlers = new List(activeNamePlateCount);
+ foreach (var handler in activeHandlers)
+ {
+ handler.ResetState();
+ if (handler.IsUpdating)
+ updatedHandlers.Add(handler);
+ }
+
+ if (this.OnDataUpdate is not null)
+ {
+ this.OnDataUpdate?.Invoke(this.context, activeHandlers);
+ this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+
+ if (this.context.HasParts)
+ this.ApplyBuilders(activeHandlers);
+
+ try
+ {
+ calledOriginal = true;
+ this.onRequestedUpdateHook.Original.Invoke(addon, numberArrayData, stringArrayData);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
+ }
+
+ this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+ this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
+ }
+ else if (updatedHandlers.Count != 0)
+ {
+ this.OnNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+
+ if (this.context.HasParts)
+ this.ApplyBuilders(updatedHandlers);
+
+ try
+ {
+ calledOriginal = true;
+ this.onRequestedUpdateHook.Original.Invoke(addon, numberArrayData, stringArrayData);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
+ }
+
+ this.OnPostNamePlateUpdate?.Invoke(this.context, updatedHandlers);
+ this.OnPostDataUpdate?.Invoke(this.context, activeHandlers);
+ }
+ }
+ }
+ finally
+ {
+ if (!calledOriginal)
+ {
+ try
+ {
+ this.onRequestedUpdateHook.Original.Invoke(addon, numberArrayData, stringArrayData);
+ }
+ catch (Exception e)
+ {
+ Log.Error(e, "Caught exception when calling original AddonNamePlate OnRequestedUpdate.");
+ }
}
}
}
@@ -217,6 +267,17 @@ internal sealed class NamePlateGui : IInternalDisposableService, INamePlateGui
}
}
}
+
+ private void ApplyBuilders(List handlers)
+ {
+ foreach (var handler in handlers)
+ {
+ if (handler.PartsContainer is { } container)
+ {
+ container.ApplyBuilders(handler);
+ }
+ }
+ }
}
///
@@ -239,6 +300,7 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
{
if (this.OnNamePlateUpdateScoped == null)
this.parentService.OnNamePlateUpdate += this.OnNamePlateUpdateForward;
+
this.OnNamePlateUpdateScoped += value;
}
@@ -250,6 +312,25 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
}
}
+ ///
+ public event INamePlateGui.OnPlateUpdateDelegate? OnPostNamePlateUpdate
+ {
+ add
+ {
+ if (this.OnPostNamePlateUpdateScoped == null)
+ this.parentService.OnPostNamePlateUpdate += this.OnPostNamePlateUpdateForward;
+
+ this.OnPostNamePlateUpdateScoped += value;
+ }
+
+ remove
+ {
+ this.OnPostNamePlateUpdateScoped -= value;
+ if (this.OnPostNamePlateUpdateScoped == null)
+ this.parentService.OnPostNamePlateUpdate -= this.OnPostNamePlateUpdateForward;
+ }
+ }
+
///
public event INamePlateGui.OnPlateUpdateDelegate? OnDataUpdate
{
@@ -257,6 +338,7 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
{
if (this.OnDataUpdateScoped == null)
this.parentService.OnDataUpdate += this.OnDataUpdateForward;
+
this.OnDataUpdateScoped += value;
}
@@ -268,10 +350,33 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
}
}
+ ///
+ public event INamePlateGui.OnPlateUpdateDelegate? OnPostDataUpdate
+ {
+ add
+ {
+ if (this.OnPostDataUpdateScoped == null)
+ this.parentService.OnPostDataUpdate += this.OnPostDataUpdateForward;
+
+ this.OnPostDataUpdateScoped += value;
+ }
+
+ remove
+ {
+ this.OnPostDataUpdateScoped -= value;
+ if (this.OnPostDataUpdateScoped == null)
+ this.parentService.OnPostDataUpdate -= this.OnPostDataUpdateForward;
+ }
+ }
+
private event INamePlateGui.OnPlateUpdateDelegate? OnNamePlateUpdateScoped;
+ private event INamePlateGui.OnPlateUpdateDelegate? OnPostNamePlateUpdateScoped;
+
private event INamePlateGui.OnPlateUpdateDelegate? OnDataUpdateScoped;
+ private event INamePlateGui.OnPlateUpdateDelegate? OnPostDataUpdateScoped;
+
///
public void RequestRedraw()
{
@@ -284,8 +389,14 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
this.parentService.OnNamePlateUpdate -= this.OnNamePlateUpdateForward;
this.OnNamePlateUpdateScoped = null;
+ this.parentService.OnPostNamePlateUpdate -= this.OnPostNamePlateUpdateForward;
+ this.OnPostNamePlateUpdateScoped = null;
+
this.parentService.OnDataUpdate -= this.OnDataUpdateForward;
this.OnDataUpdateScoped = null;
+
+ this.parentService.OnPostDataUpdate -= this.OnPostDataUpdateForward;
+ this.OnPostDataUpdateScoped = null;
}
private void OnNamePlateUpdateForward(
@@ -294,9 +405,21 @@ internal class NamePlateGuiPluginScoped : IInternalDisposableService, INamePlate
this.OnNamePlateUpdateScoped?.Invoke(context, handlers);
}
+ private void OnPostNamePlateUpdateForward(
+ INamePlateUpdateContext context, IReadOnlyList handlers)
+ {
+ this.OnPostNamePlateUpdateScoped?.Invoke(context, handlers);
+ }
+
private void OnDataUpdateForward(
INamePlateUpdateContext context, IReadOnlyList handlers)
{
this.OnDataUpdateScoped?.Invoke(context, handlers);
}
+
+ private void OnPostDataUpdateForward(
+ INamePlateUpdateContext context, IReadOnlyList handlers)
+ {
+ this.OnPostDataUpdateScoped?.Invoke(context, handlers);
+ }
}
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateGuiAddressResolver.cs b/Dalamud/Game/Gui/NamePlate/NamePlateGuiAddressResolver.cs
new file mode 100644
index 000000000..450e1fa9f
--- /dev/null
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateGuiAddressResolver.cs
@@ -0,0 +1,20 @@
+namespace Dalamud.Game.Gui.NamePlate;
+
+///
+/// An address resolver for the class.
+///
+internal class NamePlateGuiAddressResolver : BaseAddressResolver
+{
+ ///
+ /// Gets the address of the AddonNamePlate OnRequestedUpdate method. We need to use a hook for this because
+ /// AddonNamePlate.Show calls OnRequestedUpdate directly, bypassing the AddonLifecycle callsite hook.
+ ///
+ public IntPtr OnRequestedUpdate { get; private set; }
+
+ ///
+ protected override void Setup64Bit(ISigScanner sig)
+ {
+ this.OnRequestedUpdate = sig.ScanText(
+ "4C 8B DC 41 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 49 8B 40 20");
+ }
+}
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateUpdateContext.cs b/Dalamud/Game/Gui/NamePlate/NamePlateUpdateContext.cs
index b8a4a9bd8..0a6fe801f 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateUpdateContext.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateUpdateContext.cs
@@ -1,7 +1,7 @@
-using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Game.ClientState.Objects;
using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Client.UI.Arrays;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Gui.NamePlate;
@@ -54,13 +54,11 @@ internal unsafe class NamePlateUpdateContext : INamePlateUpdateContext
/// Initializes a new instance of the class.
///
/// An object table.
- /// The addon lifecycle arguments for the update request.
- internal NamePlateUpdateContext(ObjectTable objectTable, AddonRequestedUpdateArgs args)
+ internal NamePlateUpdateContext(ObjectTable objectTable)
{
this.ObjectTable = objectTable;
this.RaptureAtkModule = FFXIVClientStructs.FFXIV.Client.UI.RaptureAtkModule.Instance();
this.Ui3DModule = UIModule.Instance()->GetUI3DModule();
- this.ResetState(args);
}
///
@@ -127,7 +125,7 @@ internal unsafe class NamePlateUpdateContext : INamePlateUpdateContext
///
/// Gets a pointer to the NamePlate addon's number array entries as a struct.
///
- internal AddonNamePlate.NamePlateIntArrayData* NumberStruct { get; private set; }
+ internal NamePlateNumberArray* NumberStruct { get; private set; }
///
/// Gets or sets a value indicating whether any handler in the current context has instantiated a part builder.
@@ -137,13 +135,15 @@ internal unsafe class NamePlateUpdateContext : INamePlateUpdateContext
///
/// Resets the state of the context based on the provided addon lifecycle arguments.
///
- /// The addon lifecycle arguments for the update request.
- internal void ResetState(AddonRequestedUpdateArgs args)
+ /// A pointer to the addon.
+ /// A pointer to the global number array data struct.
+ /// A pointer to the global string array data struct.
+ public void ResetState(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
{
- this.Addon = (AddonNamePlate*)args.Addon;
- this.NumberData = ((NumberArrayData**)args.NumberArrayData)![NamePlateGui.NumberArrayIndex];
- this.NumberStruct = (AddonNamePlate.NamePlateIntArrayData*)this.NumberData->IntArray;
- this.StringData = ((StringArrayData**)args.StringArrayData)![NamePlateGui.StringArrayIndex];
+ this.Addon = (AddonNamePlate*)addon;
+ this.NumberData = AtkStage.Instance()->GetNumberArrayData(NumberArrayType.NamePlate);
+ this.NumberStruct = (NamePlateNumberArray*)this.NumberData->IntArray;
+ this.StringData = AtkStage.Instance()->GetStringArrayData(StringArrayType.NamePlate);
this.HasParts = false;
this.ActiveNamePlateCount = this.NumberStruct->ActiveNamePlateCount;
diff --git a/Dalamud/Game/Gui/NamePlate/NamePlateUpdateHandler.cs b/Dalamud/Game/Gui/NamePlate/NamePlateUpdateHandler.cs
index 99429d932..185be9d24 100644
--- a/Dalamud/Game/Gui/NamePlate/NamePlateUpdateHandler.cs
+++ b/Dalamud/Game/Gui/NamePlate/NamePlateUpdateHandler.cs
@@ -1,4 +1,4 @@
-using System.Runtime.CompilerServices;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -7,6 +7,7 @@ using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Text.SeStringHandling;
using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Client.UI.Arrays;
using FFXIVClientStructs.Interop;
namespace Dalamud.Game.Gui.NamePlate;
@@ -328,9 +329,22 @@ internal unsafe class NamePlateUpdateHandler : INamePlateUpdateHandler
public ulong GameObjectId => this.gameObjectId ??= this.NamePlateInfo->ObjectId;
///
- public IGameObject? GameObject => this.gameObject ??= this.context.ObjectTable.CreateObjectReference(
- (nint)this.context.Ui3DModule->NamePlateObjectInfoPointers[
- this.ArrayIndex].Value->GameObject);
+ public IGameObject? GameObject
+ {
+ get
+ {
+ if (this.GameObjectId == 0xE0000000)
+ {
+ // Skipping Ui3DModule lookup for invalid nameplate (NamePlateInfo->ObjectId is 0xE0000000). This
+ // prevents crashes around certain Doman Reconstruction cutscenes.
+ return null;
+ }
+
+ return this.gameObject ??= this.context.ObjectTable[
+ this.context.Ui3DModule->NamePlateObjectInfoPointers[this.ArrayIndex]
+ .Value->GameObject->ObjectIndex];
+ }
+ }
///
public IBattleChara? BattleChara => this.GameObject as IBattleChara;
@@ -490,7 +504,7 @@ internal unsafe class NamePlateUpdateHandler : INamePlateUpdateHandler
private AddonNamePlate.NamePlateObject* NamePlateObject =>
&this.context.Addon->NamePlateObjectArray[this.NamePlateIndex];
- private AddonNamePlate.NamePlateIntArrayData.NamePlateObjectIntArrayData* ObjectData =>
+ private NamePlateNumberArray.NamePlateObjectIntArrayData* ObjectData =>
this.context.NumberStruct->ObjectData.GetPointer(this.ArrayIndex);
///
diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs
deleted file mode 100644
index 0b267694c..000000000
--- a/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Dalamud.Game.Gui.PartyFinder;
-
-///
-/// The address resolver for the class.
-///
-internal class PartyFinderAddressResolver : BaseAddressResolver
-{
- ///
- /// Gets the address of the native ReceiveListing method.
- ///
- public IntPtr ReceiveListing { get; private set; }
-
- ///
- protected override void Setup64Bit(ISigScanner sig)
- {
- this.ReceiveListing = sig.ScanText("40 53 41 57 48 83 EC ?? 48 8B D9 4C 8B FA");
- }
-}
diff --git a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
index ef4055b29..0b25a87be 100644
--- a/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
+++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
@@ -7,6 +7,8 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
+using FFXIVClientStructs.FFXIV.Client.UI.Info;
+
using Serilog;
namespace Dalamud.Game.Gui.PartyFinder;
@@ -15,12 +17,11 @@ namespace Dalamud.Game.Gui.PartyFinder;
/// This class handles interacting with the native PartyFinder window.
///
[ServiceManager.EarlyLoadedService]
-internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderGui
+internal sealed unsafe class PartyFinderGui : IInternalDisposableService, IPartyFinderGui
{
- private readonly PartyFinderAddressResolver address;
private readonly nint memory;
- private readonly Hook receiveListingHook;
+ private readonly Hook receiveListingHook;
///
/// Initializes a new instance of the class.
@@ -29,18 +30,12 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG
[ServiceManager.ServiceConstructor]
private PartyFinderGui(TargetSigScanner sigScanner)
{
- this.address = new PartyFinderAddressResolver();
- this.address.Setup(sigScanner);
-
this.memory = Marshal.AllocHGlobal(PartyFinderPacket.PacketSize);
- this.receiveListingHook = Hook.FromAddress(this.address.ReceiveListing, this.HandleReceiveListingDetour);
+ this.receiveListingHook = Hook.FromAddress(InfoProxyCrossRealm.Addresses.ReceiveListing.Value, this.HandleReceiveListingDetour);
this.receiveListingHook.Enable();
}
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void ReceiveListingDelegate(nint managerPtr, nint data);
-
///
public event IPartyFinderGui.PartyFinderListingEventDelegate? ReceiveListing;
@@ -61,18 +56,18 @@ internal sealed class PartyFinderGui : IInternalDisposableService, IPartyFinderG
}
}
- private void HandleReceiveListingDetour(nint managerPtr, nint data)
+ private void HandleReceiveListingDetour(InfoProxyCrossRealm* infoProxy, nint packet)
{
try
{
- this.HandleListingEvents(data);
+ this.HandleListingEvents(packet);
}
catch (Exception ex)
{
Log.Error(ex, "Exception on ReceiveListing hook.");
}
- this.receiveListingHook.Original(managerPtr, data);
+ this.receiveListingHook.Original(infoProxy, packet);
}
private void HandleListingEvents(nint data)
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs
index ff2a3ce2a..475892205 100644
--- a/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs
+++ b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs
@@ -4,160 +4,160 @@ namespace Dalamud.Game.Gui.PartyFinder.Types;
/// Job flags for the class.
///
[Flags]
-public enum JobFlags
+public enum JobFlags : ulong
{
///
/// Gladiator (GLD).
///
- Gladiator = 1 << 1,
+ Gladiator = 1ul << 1,
///
/// Pugilist (PGL).
///
- Pugilist = 1 << 2,
+ Pugilist = 1ul << 2,
///
/// Marauder (MRD).
///
- Marauder = 1 << 3,
+ Marauder = 1ul << 3,
///
/// Lancer (LNC).
///
- Lancer = 1 << 4,
+ Lancer = 1ul << 4,
///
/// Archer (ARC).
///
- Archer = 1 << 5,
+ Archer = 1ul << 5,
///
/// Conjurer (CNJ).
///
- Conjurer = 1 << 6,
+ Conjurer = 1ul << 6,
///
/// Thaumaturge (THM).
///
- Thaumaturge = 1 << 7,
+ Thaumaturge = 1ul << 7,
///
/// Paladin (PLD).
///
- Paladin = 1 << 8,
+ Paladin = 1ul << 8,
///
/// Monk (MNK).
///
- Monk = 1 << 9,
+ Monk = 1ul << 9,
///
/// Warrior (WAR).
///
- Warrior = 1 << 10,
+ Warrior = 1ul << 10,
///
/// Dragoon (DRG).
///
- Dragoon = 1 << 11,
+ Dragoon = 1ul << 11,
///
/// Bard (BRD).
///
- Bard = 1 << 12,
+ Bard = 1ul << 12,
///
/// White mage (WHM).
///
- WhiteMage = 1 << 13,
+ WhiteMage = 1ul << 13,
///
/// Black mage (BLM).
///
- BlackMage = 1 << 14,
+ BlackMage = 1ul << 14,
///
/// Arcanist (ACN).
///
- Arcanist = 1 << 15,
+ Arcanist = 1ul << 15,
///
/// Summoner (SMN).
///
- Summoner = 1 << 16,
+ Summoner = 1ul << 16,
///
/// Scholar (SCH).
///
- Scholar = 1 << 17,
+ Scholar = 1ul << 17,
///
/// Rogue (ROG).
///
- Rogue = 1 << 18,
+ Rogue = 1ul << 18,
///
/// Ninja (NIN).
///
- Ninja = 1 << 19,
+ Ninja = 1ul << 19,
///
/// Machinist (MCH).
///
- Machinist = 1 << 20,
+ Machinist = 1ul << 20,
///
/// Dark Knight (DRK).
///
- DarkKnight = 1 << 21,
+ DarkKnight = 1ul << 21,
///
/// Astrologian (AST).
///
- Astrologian = 1 << 22,
+ Astrologian = 1ul << 22,
///
/// Samurai (SAM).
///
- Samurai = 1 << 23,
+ Samurai = 1ul << 23,
///
/// Red mage (RDM).
///
- RedMage = 1 << 24,
+ RedMage = 1ul << 24,
///
/// Blue mage (BLM).
///
- BlueMage = 1 << 25,
+ BlueMage = 1ul << 25,
///
/// Gunbreaker (GNB).
///
- Gunbreaker = 1 << 26,
+ Gunbreaker = 1ul << 26,
///
/// Dancer (DNC).
///
- Dancer = 1 << 27,
+ Dancer = 1ul << 27,
///
/// Reaper (RPR).
///
- Reaper = 1 << 28,
+ Reaper = 1ul << 28,
///
/// Sage (SGE).
///
- Sage = 1 << 29,
+ Sage = 1ul << 29,
///
/// Viper (VPR).
///
- Viper = 1 << 30,
+ Viper = 1ul << 30,
///
/// Pictomancer (PCT).
///
- Pictomancer = 1 << 31,
+ Pictomancer = 1ul << 31,
}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs b/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs
index ba72021ba..1c78c871b 100644
--- a/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs
+++ b/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs
@@ -1,5 +1,5 @@
using Dalamud.Plugin.Services;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.Gui.PartyFinder.Types;
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
index 3461841ab..09de07e0d 100644
--- a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
+++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
@@ -5,7 +5,8 @@ using Dalamud.Data;
using Dalamud.Game.Gui.PartyFinder.Internal;
using Dalamud.Game.Text.SeStringHandling;
-using Lumina.Excel.GeneratedSheets;
+using Lumina.Excel;
+using Lumina.Excel.Sheets;
namespace Dalamud.Game.Gui.PartyFinder.Types;
@@ -48,7 +49,7 @@ public interface IPartyFinderListing
///
/// Gets a list of the classes/jobs that are currently present in the party.
///
- IReadOnlyCollection> JobsPresent { get; }
+ IReadOnlyCollection> JobsPresent { get; }
///
/// Gets the ID assigned to this listing by the game's server.
@@ -73,17 +74,17 @@ public interface IPartyFinderListing
///
/// Gets the world that this listing was created on.
///
- Lazy World { get; }
+ RowRef World { get; }
///
/// Gets the home world of the listing's host.
///
- Lazy HomeWorld { get; }
+ RowRef HomeWorld { get; }
///
/// Gets the current world of the listing's host.
///
- Lazy CurrentWorld { get; }
+ RowRef CurrentWorld { get; }
///
/// Gets the Party Finder category this listing is listed under.
@@ -98,7 +99,7 @@ public interface IPartyFinderListing
///
/// Gets the duty this listing is for. May be null for non-duty listings.
///
- Lazy Duty { get; }
+ RowRef Duty { get; }
///
/// Gets the type of duty this listing is for.
@@ -216,12 +217,12 @@ internal class PartyFinderListing : IPartyFinderListing
this.ContentId = listing.ContentId;
this.Name = SeString.Parse(listing.Name.TakeWhile(b => b != 0).ToArray());
this.Description = SeString.Parse(listing.Description.TakeWhile(b => b != 0).ToArray());
- this.World = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.World));
- this.HomeWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.HomeWorld));
- this.CurrentWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.CurrentWorld));
+ this.World = LuminaUtils.CreateRef(listing.World);
+ this.HomeWorld = LuminaUtils.CreateRef(listing.HomeWorld);
+ this.CurrentWorld = LuminaUtils.CreateRef(listing.CurrentWorld);
this.Category = (DutyCategory)listing.Category;
this.RawDuty = listing.Duty;
- this.Duty = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.Duty));
+ this.Duty = LuminaUtils.CreateRef(listing.Duty);
this.DutyType = (DutyType)listing.DutyType;
this.BeginnersWelcome = listing.BeginnersWelcome == 1;
this.SecondsRemaining = listing.SecondsRemaining;
@@ -231,10 +232,7 @@ internal class PartyFinderListing : IPartyFinderListing
this.SlotsFilled = listing.NumSlotsFilled;
this.LastPatchHotfixTimestamp = listing.LastPatchHotfixTimestamp;
this.JobsPresent = listing.JobsPresent
- .Select(id => new Lazy(
- () => id == 0
- ? null
- : dataManager.GetExcelSheet().GetRow(id)))
+ .Select(id => LuminaUtils.CreateRef(id))
.ToArray();
}
@@ -251,13 +249,13 @@ internal class PartyFinderListing : IPartyFinderListing
public SeString Description { get; }
///
- public Lazy World { get; }
+ public RowRef World { get; }
///
- public Lazy HomeWorld { get; }
+ public RowRef HomeWorld { get; }
///
- public Lazy CurrentWorld { get; }
+ public RowRef CurrentWorld { get; }
///
public DutyCategory Category { get; }
@@ -266,7 +264,7 @@ internal class PartyFinderListing : IPartyFinderListing
public ushort RawDuty { get; }
///
- public Lazy Duty { get; }
+ public RowRef