From b262fd7e9d2b217397550fd3933b79d5b9f877fb Mon Sep 17 00:00:00 2001
From: Mino <1381835+Minoost@users.noreply.github.com>
Date: Thu, 12 Mar 2020 20:23:47 +0900
Subject: [PATCH] Add Nuke Build (and temporary nuke Dalamud, heh)
---
.nuke | 1 +
Dalamud.Bootstrap/Crypto/Blowfish.cs | 1 +
Dalamud.Bootstrap/Dalamud.Bootstrap.csproj | 5 +
.../SqexArg/ArgumentContainer.cs | 8 +-
Dalamud.sln | 112 +---
Dalamud/Configuration/DalamudConfiguration.cs | 42 --
Dalamud/Configuration/IPluginConfiguration.cs | 13 -
Dalamud/Dalamud.cs | 575 -----------------
Dalamud/Dalamud.csproj | 7 +-
Dalamud/DalamudStartInfo.cs | 23 -
Dalamud/Data/DataManager.cs | 145 -----
.../TransientSheet/ContentFinderCondition.cs | 610 ------------------
Dalamud/DiscordBot/DiscordBotManager.cs | 317 ---------
.../DiscordBot/DiscordFeatureConfiguration.cs | 49 --
Dalamud/EntryPoint.cs | 7 -
Dalamud/Game/Chat/SeStringHandling/Payload.cs | 225 -------
.../Game/Chat/SeStringHandling/PayloadType.cs | 35 -
.../SeStringHandling/Payloads/ItemPayload.cs | 126 ----
.../Payloads/PlayerPayload.cs | 85 ---
.../SeStringHandling/Payloads/RawPayload.cs | 51 --
.../Payloads/StatusPayload.cs | 64 --
.../SeStringHandling/Payloads/TextPayload.cs | 75 ---
.../Game/Chat/SeStringHandling/SeString.cs | 84 ---
Dalamud/Game/Chat/XivChatEntry.cs | 15 -
Dalamud/Game/Chat/XivChatType.cs | 139 ----
Dalamud/Game/ChatHandlers.cs | 215 ------
Dalamud/Game/ClientState/Actors/ActorTable.cs | 106 ---
Dalamud/Game/ClientState/Actors/ObjectKind.cs | 69 --
Dalamud/Game/ClientState/Actors/Position3.cs | 10 -
.../ClientState/Actors/Resolvers/ClassJob.cs | 31 -
.../ClientState/Actors/Resolvers/World.cs | 31 -
.../Game/ClientState/Actors/Types/Actor.cs | 40 --
.../Game/ClientState/Actors/Types/Chara.cs | 44 --
.../Actors/Types/NonPlayer/BattleNpc.cs | 22 -
.../Types/NonPlayer/BattleNpcSubKind.cs | 21 -
.../ClientState/Actors/Types/NonPlayer/Npc.cs | 17 -
.../Actors/Types/PlayerCharacter.cs | 24 -
Dalamud/Game/ClientState/ClientState.cs | 84 ---
.../ClientState/ClientStateAddressResolver.cs | 21 -
Dalamud/Game/ClientState/JobGauge.cs | 20 -
Dalamud/Game/ClientState/Structs/Actor.cs | 32 -
.../ClientState/Structs/JobGauge/ASTGauge.cs | 26 -
.../ClientState/Structs/JobGauge/BLMGauge.cs | 34 -
.../ClientState/Structs/JobGauge/BRDGauge.cs | 16 -
.../ClientState/Structs/JobGauge/DNCGauge.cs | 25 -
.../ClientState/Structs/JobGauge/DRGGauge.cs | 16 -
.../ClientState/Structs/JobGauge/DRKGauge.cs | 20 -
.../ClientState/Structs/JobGauge/GNBGauge.cs | 16 -
.../ClientState/Structs/JobGauge/JobEnums.cs | 67 --
.../ClientState/Structs/JobGauge/MCHGauge.cs | 27 -
.../ClientState/Structs/JobGauge/MNKGauge.cs | 21 -
.../ClientState/Structs/JobGauge/NINGauge.cs | 17 -
.../ClientState/Structs/JobGauge/PLDGauge.cs | 14 -
.../ClientState/Structs/JobGauge/RDMGauge.cs | 15 -
.../ClientState/Structs/JobGauge/SAMGauge.cs | 16 -
.../ClientState/Structs/JobGauge/SCHGauge.cs | 17 -
.../ClientState/Structs/JobGauge/SMNGauge.cs | 31 -
.../ClientState/Structs/JobGauge/WARGauge.cs | 14 -
.../ClientState/Structs/JobGauge/WHMGauge.cs | 16 -
Dalamud/Game/Command/CommandInfo.cs | 36 --
Dalamud/Game/Command/CommandManager.cs | 143 ----
Dalamud/Game/Internal/AntiDebug.cs | 39 --
Dalamud/Game/Internal/BaseAddressResolver.cs | 48 --
.../DXGI/ISwapChainAddressResolver.cs | 7 -
.../Internal/DXGI/SwapChainSigResolver.cs | 32 -
.../Internal/DXGI/SwapChainVtableResolver.cs | 98 ---
Dalamud/Game/Internal/Framework.cs | 122 ----
.../Game/Internal/FrameworkAddressResolver.cs | 39 --
Dalamud/Game/Internal/Gui/ChatGui.cs | 209 ------
.../Internal/Gui/ChatGuiAddressResolver.cs | 94 ---
Dalamud/Game/Internal/Gui/GameGui.cs | 55 --
.../Internal/Gui/GameGuiAddressResolver.cs | 31 -
Dalamud/Game/Internal/Gui/TargetManager.cs | 54 --
.../Gui/TargetManagerAddressResolver.cs | 15 -
Dalamud/Game/Internal/Libc/LibcFunction.cs | 46 --
.../Libc/LibcFunctionAddressResolver.cs | 16 -
Dalamud/Game/Internal/Libc/OwnedStdString.cs | 68 --
Dalamud/Game/Internal/Libc/StdString.cs | 49 --
Dalamud/Game/Internal/Network/GameNetwork.cs | 112 ----
.../Network/GameNetworkAddressResolver.cs | 13 -
.../Game/Internal/Resource/ResourceManager.cs | 146 -----
.../ResourceManagerAddressResolver.cs | 20 -
.../Game/Network/MarketBoardItemRequest.cs | 16 -
.../IMarketBoardUploader.cs | 8 -
.../Universalis/UniversalisHistoryEntry.cs | 29 -
.../UniversalisHistoryUploadRequest.cs | 18 -
.../UniversalisItemListingsEntry.cs | 48 --
.../UniversalisItemListingsUploadRequest.cs | 18 -
.../Universalis/UniversalisItemMateria.cs | 11 -
.../UniversalisMarketBoardUploader.cs | 117 ----
.../UniversalisTaxUploadRequest.cs | 41 --
Dalamud/Game/Network/NetworkHandlers.cs | 246 -------
.../Structures/MarketBoardCurrentOfferings.cs | 115 ----
.../Network/Structures/MarketBoardHistory.cs | 57 --
.../Game/Network/Structures/MarketTaxRate.cs | 41 --
Dalamud/Game/Network/WinSockHandlers.cs | 55 --
Dalamud/Game/SigScanner.cs | 251 -------
Dalamud/Hooking/Hook.cs | 112 ----
Dalamud/Interface/DalamudDataWindow.cs | 82 ---
Dalamud/Interface/DalamudLogWindow.cs | 84 ---
Dalamud/Interface/InterfaceManager.cs | 210 ------
Dalamud/Interface/SerilogEventSink.cs | 48 --
Dalamud/Interface/UiBuilder.cs | 67 --
Dalamud/Plugin/DalamudPluginInterface.cs | 147 -----
Dalamud/Plugin/Features/IHasConfigUi.cs | 16 -
Dalamud/Plugin/Features/IHasUi.cs | 21 -
Dalamud/Plugin/IDalamudPlugin.cs | 25 -
Dalamud/Plugin/PluginDefinition.cs | 17 -
Dalamud/Plugin/PluginInstallerWindow.cs | 231 -------
Dalamud/Plugin/PluginManager.cs | 119 ----
Dalamud/Resources/eye.png | Bin 50593 -> 0 bytes
Dalamud/UIRes/NotoSansCJKjp-Medium.otf | Bin 17411676 -> 0 bytes
Dalamud/UIRes/logo.png | Bin 78986 -> 0 bytes
Dalamud/Util.cs | 76 ---
Dalamud/XivApi.cs | 96 ---
build.cmd | 6 +
build.ps1 | 68 ++
build.sh | 62 ++
build/.editorconfig | 11 +
build/Build.csproj | 16 +
build/Build.csproj.DotSettings | 24 +
build/DalamudBuild.cs | 71 ++
122 files changed, 287 insertions(+), 7894 deletions(-)
create mode 100644 .nuke
delete mode 100644 Dalamud/Configuration/DalamudConfiguration.cs
delete mode 100644 Dalamud/Configuration/IPluginConfiguration.cs
delete mode 100644 Dalamud/Dalamud.cs
delete mode 100644 Dalamud/DalamudStartInfo.cs
delete mode 100644 Dalamud/Data/DataManager.cs
delete mode 100644 Dalamud/Data/TransientSheet/ContentFinderCondition.cs
delete mode 100644 Dalamud/DiscordBot/DiscordBotManager.cs
delete mode 100644 Dalamud/DiscordBot/DiscordFeatureConfiguration.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/PayloadType.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs
delete mode 100644 Dalamud/Game/Chat/SeStringHandling/SeString.cs
delete mode 100644 Dalamud/Game/Chat/XivChatEntry.cs
delete mode 100644 Dalamud/Game/Chat/XivChatType.cs
delete mode 100644 Dalamud/Game/ChatHandlers.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/ActorTable.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/ObjectKind.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Position3.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Resolvers/ClassJob.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Resolvers/World.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/Actor.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/Chara.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpcSubKind.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
delete mode 100644 Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
delete mode 100644 Dalamud/Game/ClientState/ClientState.cs
delete mode 100644 Dalamud/Game/ClientState/ClientStateAddressResolver.cs
delete mode 100644 Dalamud/Game/ClientState/JobGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/Actor.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/ASTGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/BLMGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/DNCGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/DRGGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/DRKGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/GNBGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/JobEnums.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/MCHGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/MNKGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/NINGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/PLDGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/RDMGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/SAMGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/SCHGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/SMNGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/WARGauge.cs
delete mode 100644 Dalamud/Game/ClientState/Structs/JobGauge/WHMGauge.cs
delete mode 100644 Dalamud/Game/Command/CommandInfo.cs
delete mode 100644 Dalamud/Game/Command/CommandManager.cs
delete mode 100644 Dalamud/Game/Internal/AntiDebug.cs
delete mode 100644 Dalamud/Game/Internal/BaseAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs
delete mode 100644 Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
delete mode 100644 Dalamud/Game/Internal/Framework.cs
delete mode 100644 Dalamud/Game/Internal/FrameworkAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Gui/ChatGui.cs
delete mode 100644 Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Gui/GameGui.cs
delete mode 100644 Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Gui/TargetManager.cs
delete mode 100644 Dalamud/Game/Internal/Gui/TargetManagerAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Libc/LibcFunction.cs
delete mode 100644 Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Libc/OwnedStdString.cs
delete mode 100644 Dalamud/Game/Internal/Libc/StdString.cs
delete mode 100644 Dalamud/Game/Internal/Network/GameNetwork.cs
delete mode 100644 Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs
delete mode 100644 Dalamud/Game/Internal/Resource/ResourceManager.cs
delete mode 100644 Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardItemRequest.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
delete mode 100644 Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs
delete mode 100644 Dalamud/Game/Network/NetworkHandlers.cs
delete mode 100644 Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs
delete mode 100644 Dalamud/Game/Network/Structures/MarketBoardHistory.cs
delete mode 100644 Dalamud/Game/Network/Structures/MarketTaxRate.cs
delete mode 100644 Dalamud/Game/Network/WinSockHandlers.cs
delete mode 100644 Dalamud/Game/SigScanner.cs
delete mode 100644 Dalamud/Hooking/Hook.cs
delete mode 100644 Dalamud/Interface/DalamudDataWindow.cs
delete mode 100644 Dalamud/Interface/DalamudLogWindow.cs
delete mode 100644 Dalamud/Interface/InterfaceManager.cs
delete mode 100644 Dalamud/Interface/SerilogEventSink.cs
delete mode 100644 Dalamud/Interface/UiBuilder.cs
delete mode 100644 Dalamud/Plugin/DalamudPluginInterface.cs
delete mode 100644 Dalamud/Plugin/Features/IHasConfigUi.cs
delete mode 100644 Dalamud/Plugin/Features/IHasUi.cs
delete mode 100644 Dalamud/Plugin/IDalamudPlugin.cs
delete mode 100644 Dalamud/Plugin/PluginDefinition.cs
delete mode 100644 Dalamud/Plugin/PluginInstallerWindow.cs
delete mode 100644 Dalamud/Plugin/PluginManager.cs
delete mode 100644 Dalamud/Resources/eye.png
delete mode 100644 Dalamud/UIRes/NotoSansCJKjp-Medium.otf
delete mode 100644 Dalamud/UIRes/logo.png
delete mode 100644 Dalamud/Util.cs
delete mode 100644 Dalamud/XivApi.cs
create mode 100755 build.cmd
create mode 100644 build.ps1
create mode 100755 build.sh
create mode 100644 build/.editorconfig
create mode 100644 build/Build.csproj
create mode 100644 build/Build.csproj.DotSettings
create mode 100644 build/DalamudBuild.cs
diff --git a/.nuke b/.nuke
new file mode 100644
index 000000000..c37461139
--- /dev/null
+++ b/.nuke
@@ -0,0 +1 @@
+Dalamud.sln
\ No newline at end of file
diff --git a/Dalamud.Bootstrap/Crypto/Blowfish.cs b/Dalamud.Bootstrap/Crypto/Blowfish.cs
index 2b3b41469..8d58c1cbb 100644
--- a/Dalamud.Bootstrap/Crypto/Blowfish.cs
+++ b/Dalamud.Bootstrap/Crypto/Blowfish.cs
@@ -1,4 +1,5 @@
using System;
+using System.Buffers.Binary;
using System.Runtime.CompilerServices;
namespace Dalamud.Bootstrap.Crypto
diff --git a/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj b/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
index a28f10736..388b565ca 100644
--- a/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
+++ b/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
@@ -5,8 +5,13 @@
preview
enable
true
+ true
+
+
+
+
diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentContainer.cs b/Dalamud.Bootstrap/SqexArg/ArgumentContainer.cs
index c6e9216bb..4bd85fdad 100644
--- a/Dalamud.Bootstrap/SqexArg/ArgumentContainer.cs
+++ b/Dalamud.Bootstrap/SqexArg/ArgumentContainer.cs
@@ -26,14 +26,14 @@ namespace Dalamud.Bootstrap.SqexArg
}
var checksum = argument[^5];
- var payload = argument[11..^5]
- .Replace(; // encoded in url-safe variant of base64
+ var payload = argument[11..^5];
// decode
- Convert.FromBase64String();
- container = new ArgumentContainer(payload, checksum);
+ //Convert.FromBase64String();
+ //container = new ArgumentContainer(payload, checksum);
+ container = null;
return true;
}
}
diff --git a/Dalamud.sln b/Dalamud.sln
index 83bb6fe78..fd0389e44 100644
--- a/Dalamud.sln
+++ b/Dalamud.sln
@@ -7,22 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud", "Dalamud\Dalamud.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Injector", "Dalamud.Injector\Dalamud.Injector.csproj", "{5B832F73-5F54-4ADC-870F-D0095EF72C9A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImGuiScene", "lib\ImGuiScene\ImGuiScene\ImGuiScene.csproj", "{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDL2-CS", "lib\ImGuiScene\deps\SDL2-CS\SDL2-CS.csproj", "{85480198-8711-4355-830E-72FD794AD3F6}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImGui.NET-472", "lib\ImGuiScene\deps\ImGui.NET\src\ImGui.NET-472\ImGui.NET-472.csproj", "{0483026E-C6CE-4B1A-AA68-46544C08140B}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interface", "Interface", "{E15BDA6D-E881-4482-94BA-BE5527E917FF}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DiscordNet", "DiscordNet", "{E1F3D3F5-7820-4A62-A16A-53260375A781}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Rest", "lib\Discord.Net\src\Discord.Net.Rest\Discord.Net.Rest.csproj", "{10E4E5CB-F51E-42EC-B98C-FBCE839D4624}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Core", "lib\Discord.Net\src\Discord.Net.Core\Discord.Net.Core.csproj", "{B46F33B5-9702-434E-A92C-8DE5CF7164E3}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.WebSocket", "lib\Discord.Net\src\Discord.Net.WebSocket\Discord.Net.WebSocket.csproj", "{AACDC15A-56F8-458F-9C73-DE89F60466AE}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{E9868930-4223-4D57-8F31-84E580E4B24B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CoreHook", "CoreHook", "{CE78D902-02B5-4C7B-A46A-D44BD2F4C622}"
@@ -39,9 +23,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreHook.IPC", "lib\CoreHoo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CoreHook.Memory", "lib\CoreHook\src\CoreHook.Memory\CoreHook.Memory.csproj", "{ED4FFE13-5F83-42B9-8847-E7C4D7A988E8}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Bootstrap", "Dalamud.Bootstrap\Dalamud.Bootstrap.csproj", "{19032128-E336-460F-B6E4-EAF6055589E5}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Bootstrap", "Dalamud.Bootstrap\Dalamud.Bootstrap.csproj", "{19032128-E336-460F-B6E4-EAF6055589E5}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.Testing", "Dalamud.Testing\Dalamud.Testing.csproj", "{0A99A6B3-12E2-4197-A6F3-9211B6D4D824}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Testing", "Dalamud.Testing\Dalamud.Testing.csproj", "{0A99A6B3-12E2-4197-A6F3-9211B6D4D824}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Build", "build\Build.csproj", "{A6BB70E8-7F14-410F-A296-1B4495F6F069}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -77,78 +63,6 @@ Global
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x64.Build.0 = Release|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x86.ActiveCfg = Release|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x86.Build.0 = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x64.ActiveCfg = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x64.Build.0 = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x86.Build.0 = Debug|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|Any CPU.Build.0 = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x64.ActiveCfg = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x64.Build.0 = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x86.ActiveCfg = Release|Any CPU
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x86.Build.0 = Release|Any CPU
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|x64.ActiveCfg = Debug|x64
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|x64.Build.0 = Debug|x64
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|x86.ActiveCfg = Debug|x86
- {85480198-8711-4355-830E-72FD794AD3F6}.Debug|x86.Build.0 = Debug|x86
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|Any CPU.Build.0 = Release|Any CPU
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|x64.ActiveCfg = Release|x64
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|x64.Build.0 = Release|x64
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|x86.ActiveCfg = Release|x86
- {85480198-8711-4355-830E-72FD794AD3F6}.Release|x86.Build.0 = Release|x86
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x64.ActiveCfg = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x64.Build.0 = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x86.ActiveCfg = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x86.Build.0 = Debug|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|Any CPU.Build.0 = Release|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x64.ActiveCfg = Release|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x64.Build.0 = Release|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x86.ActiveCfg = Release|Any CPU
- {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x86.Build.0 = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|x64.ActiveCfg = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|x64.Build.0 = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|x86.ActiveCfg = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Debug|x86.Build.0 = Debug|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|Any CPU.Build.0 = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|x64.ActiveCfg = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|x64.Build.0 = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|x86.ActiveCfg = Release|Any CPU
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624}.Release|x86.Build.0 = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|x64.ActiveCfg = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|x64.Build.0 = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|x86.ActiveCfg = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Debug|x86.Build.0 = Debug|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|Any CPU.Build.0 = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|x64.ActiveCfg = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|x64.Build.0 = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|x86.ActiveCfg = Release|Any CPU
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3}.Release|x86.Build.0 = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|x64.ActiveCfg = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|x64.Build.0 = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|x86.ActiveCfg = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Debug|x86.Build.0 = Debug|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|Any CPU.Build.0 = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x64.ActiveCfg = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x64.Build.0 = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x86.ActiveCfg = Release|Any CPU
- {AACDC15A-56F8-458F-9C73-DE89F60466AE}.Release|x86.Build.0 = Release|Any CPU
{441EE8F0-AD8E-479B-9F68-12D157F080AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{441EE8F0-AD8E-479B-9F68-12D157F080AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{441EE8F0-AD8E-479B-9F68-12D157F080AF}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -245,19 +159,21 @@ Global
{0A99A6B3-12E2-4197-A6F3-9211B6D4D824}.Release|x64.Build.0 = Release|Any CPU
{0A99A6B3-12E2-4197-A6F3-9211B6D4D824}.Release|x86.ActiveCfg = Release|Any CPU
{0A99A6B3-12E2-4197-A6F3-9211B6D4D824}.Release|x86.Build.0 = Release|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Debug|x64.Build.0 = Debug|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Debug|x86.Build.0 = Debug|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Release|x64.ActiveCfg = Release|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Release|x64.Build.0 = Release|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Release|x86.ActiveCfg = Release|Any CPU
+ {A6BB70E8-7F14-410F-A296-1B4495F6F069}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {C0E7E797-4FBF-4F46-BC57-463F3719BA7A} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
- {85480198-8711-4355-830E-72FD794AD3F6} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
- {0483026E-C6CE-4B1A-AA68-46544C08140B} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
- {E15BDA6D-E881-4482-94BA-BE5527E917FF} = {E9868930-4223-4D57-8F31-84E580E4B24B}
- {E1F3D3F5-7820-4A62-A16A-53260375A781} = {E9868930-4223-4D57-8F31-84E580E4B24B}
- {10E4E5CB-F51E-42EC-B98C-FBCE839D4624} = {E1F3D3F5-7820-4A62-A16A-53260375A781}
- {B46F33B5-9702-434E-A92C-8DE5CF7164E3} = {E1F3D3F5-7820-4A62-A16A-53260375A781}
- {AACDC15A-56F8-458F-9C73-DE89F60466AE} = {E1F3D3F5-7820-4A62-A16A-53260375A781}
{CE78D902-02B5-4C7B-A46A-D44BD2F4C622} = {E9868930-4223-4D57-8F31-84E580E4B24B}
{441EE8F0-AD8E-479B-9F68-12D157F080AF} = {CE78D902-02B5-4C7B-A46A-D44BD2F4C622}
{91CB76FC-8E4B-4B4C-B5AD-D681866A2188} = {CE78D902-02B5-4C7B-A46A-D44BD2F4C622}
diff --git a/Dalamud/Configuration/DalamudConfiguration.cs b/Dalamud/Configuration/DalamudConfiguration.cs
deleted file mode 100644
index 486948b11..000000000
--- a/Dalamud/Configuration/DalamudConfiguration.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Dalamud.Configuration;
-using Dalamud.DiscordBot;
-using Newtonsoft.Json;
-
-namespace Dalamud
-{
- [Serializable]
- public class DalamudConfiguration
- {
- public DiscordFeatureConfiguration DiscordFeatureConfig { get; set; }
-
- public bool OptOutMbCollection { get; set; } = false;
-
- public List BadWords { get; set; }
-
- public enum PreferredRole
- {
- None,
- All,
- Tank,
- Dps,
- Healer
- }
-
- public Dictionary PreferredRoleReminders { get; set; }
-
- public string LastVersion { get; set; }
-
- public Dictionary PluginConfigurations { get; set; }
-
- public static DalamudConfiguration Load(string path) {
- return JsonConvert.DeserializeObject(File.ReadAllText(path));
- }
-
- public void Save(string path) {
- File.WriteAllText(path, JsonConvert.SerializeObject(this));
- }
- }
-}
diff --git a/Dalamud/Configuration/IPluginConfiguration.cs b/Dalamud/Configuration/IPluginConfiguration.cs
deleted file mode 100644
index f2a782960..000000000
--- a/Dalamud/Configuration/IPluginConfiguration.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Configuration
-{
- public interface IPluginConfiguration
- {
- int Version { get; set; }
- }
-}
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
deleted file mode 100644
index 20a4fe595..000000000
--- a/Dalamud/Dalamud.cs
+++ /dev/null
@@ -1,575 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Dalamud.Data;
-using Dalamud.DiscordBot;
-using Dalamud.Game;
-using Dalamud.Game.Chat;
-using Dalamud.Game.ClientState;
-using Dalamud.Game.ClientState.Actors.Types;
-using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
-using Dalamud.Game.Command;
-using Dalamud.Game.Internal;
-using Dalamud.Game.Internal.Gui;
-using Dalamud.Game.Network;
-using Dalamud.Interface;
-using Dalamud.Plugin;
-using ImGuiNET;
-using Serilog;
-
-namespace Dalamud {
- public sealed class Dalamud : IDisposable {
- private readonly string baseDirectory;
-
- private readonly ManualResetEvent unloadSignal;
-
- private readonly ProcessModule targetModule;
-
- public readonly SigScanner SigScanner;
-
- public readonly Framework Framework;
-
- public readonly CommandManager CommandManager;
-
- public readonly ChatHandlers ChatHandlers;
-
- public readonly NetworkHandlers NetworkHandlers;
-
- public readonly DiscordBotManager BotManager;
-
- public readonly PluginManager PluginManager;
-
- public readonly ClientState ClientState;
-
- public readonly DalamudStartInfo StartInfo;
-
- public readonly DalamudConfiguration Configuration;
-
- private readonly WinSockHandlers WinSock2;
-
- public readonly InterfaceManager InterfaceManager;
-
- public readonly DataManager Data;
-
- private readonly string assemblyVersion = Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
-
- public Dalamud(DalamudStartInfo info) {
- this.StartInfo = info;
- this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath);
-
- this.baseDirectory = info.WorkingDirectory;
-
- this.unloadSignal = new ManualResetEvent(false);
-
- // Initialize the process information.
- this.targetModule = Process.GetCurrentProcess().MainModule;
- this.SigScanner = new SigScanner(this.targetModule, true);
-
- // Initialize game subsystem
- this.Framework = new Framework(this.SigScanner, this);
-
- // Initialize managers. Basically handlers for the logic
- this.CommandManager = new CommandManager(this, info.Language);
- SetupCommands();
-
- this.ChatHandlers = new ChatHandlers(this);
- this.NetworkHandlers = new NetworkHandlers(this, this.Configuration.OptOutMbCollection);
-
- this.Data = new DataManager(this.StartInfo.Language);
- this.Data.Initialize();
-
- this.ClientState = new ClientState(this, info, this.SigScanner, this.targetModule);
-
- this.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig);
-
- this.PluginManager = new PluginManager(this, info.PluginDirectory);
-
- this.WinSock2 = new WinSockHandlers();
-
- try {
- this.InterfaceManager = new InterfaceManager(this, this.SigScanner);
- this.InterfaceManager.OnDraw += BuildDalamudUi;
- } catch (Exception e) {
- Log.Information(e, "Could not init interface.");
- }
- }
-
- public void Start() {
- try {
- this.InterfaceManager?.Enable();
- } catch (Exception e) {
- Log.Information("Could not enable interface.");
- }
-
- this.Framework.Enable();
-
- this.BotManager.Start();
-
- try {
- this.PluginManager.LoadPlugins();
- } catch (Exception ex) {
- this.Framework.Gui.Chat.PrintError(
- "[XIVLAUNCHER] There was an error loading additional plugins. Please check the log for more details.");
- Log.Error(ex, "Plugin load failed.");
- }
- }
-
- public void Unload() {
- this.unloadSignal.Set();
- }
-
- public void WaitForUnload() {
- this.unloadSignal.WaitOne();
- }
-
- public void Dispose() {
- try
- {
- this.PluginManager.UnloadPlugins();
- }
- catch (Exception ex)
- {
- Framework.Gui.Chat.PrintError(
- "[XIVLAUNCHER] There was an error unloading additional plugins. Please check the log for more details.");
- Log.Error(ex, "Plugin unload failed.");
- }
-
- this.InterfaceManager.Dispose();
-
- Framework.Dispose();
-
- this.BotManager.Dispose();
-
- this.unloadSignal.Dispose();
-
- this.WinSock2.Dispose();
-
- this.SigScanner.Dispose();
- }
-
- #region Interface
-
- private bool isImguiDrawDemoWindow = false;
-
-#if DEBUG
- private bool isImguiDrawDevMenu = true;
-#else
- private bool isImguiDrawDevMenu = false;
-#endif
-
- private bool isImguiDrawLogWindow = false;
- private bool isImguiDrawDataWindow = false;
- private bool isImguiDrawPluginWindow = false;
-
- private DalamudLogWindow logWindow;
- private DalamudDataWindow dataWindow;
- private PluginInstallerWindow pluginWindow;
-
- private void BuildDalamudUi()
- {
- if (this.isImguiDrawDevMenu)
- {
- if (ImGui.BeginMainMenuBar())
- {
- if (ImGui.BeginMenu("Dalamud"))
- {
- ImGui.MenuItem("Draw Dalamud dev menu", "", ref this.isImguiDrawDevMenu);
- ImGui.Separator();
- if (ImGui.MenuItem("Open Log window"))
- {
- this.logWindow = new DalamudLogWindow();
- this.isImguiDrawLogWindow = true;
- }
- if (ImGui.MenuItem("Open Data window"))
- {
- this.dataWindow = new DalamudDataWindow(this.Data);
- this.isImguiDrawDataWindow = true;
- }
- ImGui.MenuItem("Draw ImGui demo", "", ref this.isImguiDrawDemoWindow);
- ImGui.Separator();
- if (ImGui.MenuItem("Unload Dalamud"))
- {
- Unload();
- }
- if (ImGui.MenuItem("Kill game"))
- {
- Process.GetCurrentProcess().Kill();
- }
- ImGui.Separator();
- ImGui.MenuItem(this.assemblyVersion, false);
-
- ImGui.EndMenu();
- }
-
- if (ImGui.BeginMenu("Plugins"))
- {
- if (ImGui.MenuItem("Open Plugin installer"))
- {
- this.pluginWindow = new PluginInstallerWindow(this.PluginManager, this.StartInfo.PluginDirectory);
- this.isImguiDrawPluginWindow = true;
- }
- if (ImGui.MenuItem("Print plugin info")) {
- foreach (var plugin in this.PluginManager.Plugins) {
- // TODO: some more here, state maybe?
- Log.Information($"{plugin.Plugin.Name}");
- }
- }
- if (ImGui.MenuItem("Reload plugins"))
- {
- OnPluginReloadCommand(string.Empty, string.Empty);
- }
- ImGui.EndMenu();
- }
-
- ImGui.EndMainMenuBar();
- }
- }
-
- if (this.isImguiDrawLogWindow)
- {
- this.isImguiDrawLogWindow = this.logWindow != null && this.logWindow.Draw();
-
- if (this.isImguiDrawLogWindow == false)
- {
- this.logWindow?.Dispose();
- }
- }
-
- if (this.isImguiDrawDataWindow)
- {
- this.isImguiDrawDataWindow = this.dataWindow != null && this.dataWindow.Draw();
- }
-
- if (this.isImguiDrawPluginWindow)
- {
- this.isImguiDrawPluginWindow = this.pluginWindow != null && this.pluginWindow.Draw();
- }
-
- if (this.isImguiDrawDemoWindow)
- ImGui.ShowDemoWindow();
- }
-
- #endregion
-
- private void SetupCommands() {
- CommandManager.AddHandler("/xldclose", new CommandInfo(OnUnloadCommand) {
- HelpMessage = "Unloads XIVLauncher in-game addon.",
- ShowInHelp = false
- });
-
- CommandManager.AddHandler("/xldreloadplugins", new CommandInfo(OnPluginReloadCommand) {
- HelpMessage = "Reloads all plugins.",
- ShowInHelp = false
- });
-
- CommandManager.AddHandler("/xldsay", new CommandInfo(OnCommandDebugSay) {
- HelpMessage = "Print to chat.",
- ShowInHelp = false
- });
-
- CommandManager.AddHandler("/xlhelp", new CommandInfo(OnHelpCommand) {
- HelpMessage = "Shows list of commands available."
- });
-
- CommandManager.AddHandler("/xlmute", new CommandInfo(OnBadWordsAddCommand) {
- HelpMessage = "Mute a word or sentence from appearing in chat. Usage: /xlmute "
- });
-
- CommandManager.AddHandler("/xlmutelist", new CommandInfo(OnBadWordsListCommand) {
- HelpMessage = "List muted words or sentences."
- });
-
- CommandManager.AddHandler("/xlunmute", new CommandInfo(OnBadWordsRemoveCommand) {
- HelpMessage = "Unmute a word or sentence. Usage: /xlunmute "
- });
-
- CommandManager.AddHandler("/xldstate", new CommandInfo(OnDebugPrintGameStateCommand) {
- HelpMessage = "Print parsed game state",
- ShowInHelp = false
- });
-
- CommandManager.AddHandler("/ll", new CommandInfo(OnLastLinkCommand) {
- HelpMessage = "Open the last posted link in your default browser."
- });
-
- CommandManager.AddHandler("/xlbotjoin", new CommandInfo(OnBotJoinCommand) {
- HelpMessage = "Add the XIVLauncher discord bot you set up to your server."
- });
-
- CommandManager.AddHandler("/xlbgmset", new CommandInfo(OnBgmSetCommand)
- {
- HelpMessage = "Set the Game background music. Usage: /xlbgmset "
- });
-
- CommandManager.AddHandler("/xlitem", new CommandInfo(OnItemLinkCommand)
- {
- HelpMessage = "Link an item by name. Usage: /xlitem - . For matching an item exactly, use /xlitem +
- "
- });
-
-#if DEBUG
- CommandManager.AddHandler("/xldzpi", new CommandInfo(OnDebugZoneDownInjectCommand)
- {
- HelpMessage = "Inject zone down channel",
- ShowInHelp = false
- });
-#endif
-
- CommandManager.AddHandler("/xlbonus", new CommandInfo(OnRouletteBonusNotifyCommand)
- {
- HelpMessage = "Notify when a roulette has a bonus you specified. Run without parameters for more info. Usage: /xlbonus "
- });
-
- CommandManager.AddHandler("/xldev", new CommandInfo(OnDebugDrawDevMenu) {
- HelpMessage = "Draw dev menu DEBUG",
- ShowInHelp = false
- });
- }
-
- private void OnUnloadCommand(string command, string arguments) {
- Framework.Gui.Chat.Print("Unloading...");
- Unload();
- }
-
- private void OnHelpCommand(string command, string arguments) {
- var showDebug = arguments.Contains("debug");
-
- Framework.Gui.Chat.Print("Available commands:");
- foreach (var cmd in CommandManager.Commands) {
- if (!cmd.Value.ShowInHelp && !showDebug)
- continue;
-
- Framework.Gui.Chat.Print($"{cmd.Key}: {cmd.Value.HelpMessage}");
- }
- }
-
- private void OnCommandDebugSay(string command, string arguments) {
- var parts = arguments.Split();
-
- var chatType = (XivChatType) int.Parse(parts[0]);
- var msg = string.Join(" ", parts.Take(1).ToArray());
-
- Framework.Gui.Chat.PrintChat(new XivChatEntry {
- MessageBytes = Encoding.UTF8.GetBytes(msg),
- Name = "Xiv Launcher",
- Type = chatType
- });
- }
-
- private void OnPluginReloadCommand(string command, string arguments) {
- Framework.Gui.Chat.Print("Reloading...");
-
- try {
- this.PluginManager.UnloadPlugins();
- this.PluginManager.LoadPlugins();
-
- Framework.Gui.Chat.Print("OK");
- } catch (Exception ex) {
- Framework.Gui.Chat.PrintError("Reload failed.");
- Log.Error(ex, "Plugin reload failed.");
- }
- }
-
- private void OnBadWordsAddCommand(string command, string arguments) {
- if (this.Configuration.BadWords == null)
- this.Configuration.BadWords = new List();
-
- this.Configuration.BadWords.Add(arguments);
-
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
-
- Framework.Gui.Chat.Print($"Muted \"{arguments}\".");
- }
-
- private void OnBadWordsListCommand(string command, string arguments) {
- if (this.Configuration.BadWords == null)
- this.Configuration.BadWords = new List();
-
- if (this.Configuration.BadWords.Count == 0) {
- Framework.Gui.Chat.Print("No muted words or sentences.");
- return;
- }
-
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
-
- foreach (var word in this.Configuration.BadWords) Framework.Gui.Chat.Print($"\"{word}\"");
- }
-
- private void OnBadWordsRemoveCommand(string command, string arguments) {
- if (this.Configuration.BadWords == null)
- this.Configuration.BadWords = new List();
-
- this.Configuration.BadWords.RemoveAll(x => x == arguments);
-
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
-
- Framework.Gui.Chat.Print($"Unmuted \"{arguments}\".");
- }
-
- private void OnLastLinkCommand(string command, string arguments) {
- if (string.IsNullOrEmpty(ChatHandlers.LastLink)) {
- Framework.Gui.Chat.Print("No last link...");
- return;
- }
-
- Framework.Gui.Chat.Print("Opening " + ChatHandlers.LastLink);
- Process.Start(ChatHandlers.LastLink);
- }
-
- private void OnDebugPrintGameStateCommand(string command, string arguments) {
- Framework.Gui.Chat.Print(this.ClientState.Actors.Length + " entries");
- Framework.Gui.Chat.Print(this.ClientState.LocalPlayer.Name);
- Framework.Gui.Chat.Print(this.ClientState.LocalPlayer.CurrentWorld.Name);
- Framework.Gui.Chat.Print(this.ClientState.LocalPlayer.HomeWorld.Name);
- Framework.Gui.Chat.Print(this.ClientState.LocalContentId.ToString("X"));
- Framework.Gui.Chat.Print(Framework.Gui.Chat.LastLinkedItemId.ToString());
-
- for (var i = 0; i < this.ClientState.Actors.Length; i++) {
- var actor = this.ClientState.Actors[i];
-
- Log.Debug(actor.Name);
- Framework.Gui.Chat.Print(
- $"{i} - {actor.Name} - {actor.Position.X} {actor.Position.Y} {actor.Position.Z}");
-
- if (actor is Npc npc)
- Framework.Gui.Chat.Print($"DataId: {npc.DataId}");
-
- if (actor is Chara chara)
- Framework.Gui.Chat.Print(
- $"Level: {chara.Level} ClassJob: {chara.ClassJob.Name} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}");
- }
- }
- private void OnBotJoinCommand(string command, string arguments) {
- if (this.BotManager != null && this.BotManager.IsConnected)
- Process.Start(
- $"https://discordapp.com/oauth2/authorize?client_id={this.BotManager.UserId}&scope=bot&permissions=117760");
- else
- Framework.Gui.Chat.Print(
- "The XIVLauncher discord bot was not set up correctly or could not connect to discord. Please check the settings and the FAQ.");
- }
-
- private void OnBgmSetCommand(string command, string arguments)
- {
- Framework.Gui.SetBgm(ushort.Parse(arguments));
- }
-
- private void OnItemLinkCommand(string command, string arguments) {
- var exactSearch = false;
- if (arguments.StartsWith("+"))
- {
- exactSearch = true;
- arguments = arguments.Substring(1);
- }
-
- Task.Run(async () => {
- try {
- dynamic results = await XivApi.Search(arguments, "Item", 1, exactSearch);
- var itemId = (short) results.Results[0].ID;
- var itemName = (string)results.Results[0].Name;
-
- var hexData = new byte[] {
- 0x02, 0x13, 0x06, 0xFE, 0xFF, 0xF3, 0xF3, 0xF3, 0x03, 0x02, 0x27, 0x07, 0x03, 0xF2, 0x3A, 0x2F,
- 0x02, 0x01, 0x03, 0x02, 0x13, 0x06, 0xFE, 0xFF, 0xFF, 0x7B, 0x1A, 0x03, 0xEE, 0x82, 0xBB, 0x02,
- 0x13, 0x02, 0xEC, 0x03
- };
-
- var endTag = new byte[] {
- 0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03, 0x02, 0x13, 0x02, 0xEC, 0x03
- };
-
- BitConverter.GetBytes(itemId).Reverse().ToArray().CopyTo(hexData, 14);
-
- hexData = hexData.Concat(Encoding.UTF8.GetBytes(itemName)).Concat(endTag).ToArray();
-
- Framework.Gui.Chat.PrintChat(new XivChatEntry {
- MessageBytes = hexData
- });
- }
- catch {
- Framework.Gui.Chat.PrintError("Could not find item.");
- }
-
- });
- }
-
-#if DEBUG
- private void OnDebugZoneDownInjectCommand(string command, string arguments) {
- var data = File.ReadAllBytes(arguments);
-
- Framework.Network.InjectZoneProtoPacket(data);
- Framework.Gui.Chat.Print($"{arguments} OK with {data.Length} bytes");
- }
-#endif
-
- private void OnRouletteBonusNotifyCommand(string command, string arguments)
- {
- if (this.Configuration.DiscordFeatureConfig.CfPreferredRoleChannel == null)
- Framework.Gui.Chat.PrintError("You have not set up a discord channel for these notifications - you will only receive them in chat. To do this, please use the XIVLauncher in-game settings.");
-
- if (string.IsNullOrEmpty(arguments))
- goto InvalidArgs;
-
- var argParts = arguments.Split();
- if (argParts.Length < 2)
- goto InvalidArgs;
-
-
- if (this.Configuration.PreferredRoleReminders == null)
- this.Configuration.PreferredRoleReminders = new Dictionary();
-
- var rouletteIndex = RouletteSlugToKey(argParts[0]);
-
- if (rouletteIndex == 0)
- goto InvalidArgs;
-
- if (!Enum.TryParse(argParts[1].First().ToString().ToUpper() + argParts[1].ToLower().Substring(1), out DalamudConfiguration.PreferredRole role))
- goto InvalidArgs;
-
- if (this.Configuration.PreferredRoleReminders.ContainsKey(rouletteIndex))
- this.Configuration.PreferredRoleReminders[rouletteIndex] = role;
- else
- this.Configuration.PreferredRoleReminders.Add(rouletteIndex, role);
-
- Framework.Gui.Chat.Print($"Set bonus notifications for {argParts[0]}({rouletteIndex}) to {role}");
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
-
- return;
-
- InvalidArgs:
- Framework.Gui.Chat.PrintError("Unrecognized arguments.");
- Framework.Gui.Chat.Print("Possible values for roulette: leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\n" +
- "Possible values for role: tank, dps, healer, all, none/reset");
- }
-
- private void OnDebugDrawDevMenu(string command, string arguments) {
- this.isImguiDrawDevMenu = true;
- }
-
- private int RouletteSlugToKey(string slug) => slug.ToLower() switch {
- "leveling" => 1,
- "506070" => 2,
- "msq" => 3,
- "guildhests" => 4,
- "expert" => 5,
- "trials" => 6,
- "mentor" => 8,
- "alliance" => 9,
- "normal" => 10,
- _ => 0
- };
-
- private DalamudConfiguration.PreferredRole RoleNameToPreferredRole(string name) => name.ToLower() switch
- {
- "Tank" => DalamudConfiguration.PreferredRole.Tank,
- "Healer" => DalamudConfiguration.PreferredRole.Healer,
- "Dps" => DalamudConfiguration.PreferredRole.Dps,
- "All" => DalamudConfiguration.PreferredRole.All,
- _ => DalamudConfiguration.PreferredRole.None
- };
- }
-}
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index 257e33532..4cd4a60e2 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -5,15 +5,16 @@
preview
true
enable
+ true
-
+
+
-
-
+
diff --git a/Dalamud/DalamudStartInfo.cs b/Dalamud/DalamudStartInfo.cs
deleted file mode 100644
index 16d43e5fa..000000000
--- a/Dalamud/DalamudStartInfo.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using Dalamud.DiscordBot;
-
-namespace Dalamud {
- [Serializable]
- public sealed class DalamudStartInfo
- {
- public string WorkingDirectory;
- public string ConfigurationPath;
-
- public string PluginDirectory;
- public string DefaultPluginDirectory;
- public ClientLanguage Language;
- }
-
- public enum ClientLanguage
- {
- Japanese,
- English,
- German,
- French
- }
-}
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
deleted file mode 100644
index 8f676efae..000000000
--- a/Dalamud/Data/DataManager.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Lumina.Data;
-using Lumina.Excel;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using Serilog;
-using LuminaOptions = Lumina.LuminaOptions;
-using ParsedFilePath = Lumina.ParsedFilePath;
-
-namespace Dalamud.Data
-{
- ///
- /// This class provides data for Dalamud-internal features, but can also be used by plugins if needed.
- ///
- public class DataManager {
- private const string DataBaseUrl = "https://goaaats.github.io/ffxiv/tools/launcher/addons/Hooks/Data/";
-
- public ReadOnlyDictionary ServerOpCodes { get; private set; }
-
- ///
- /// An object which gives access to any of the game's sheet data.
- ///
- public ExcelModule Excel => this.gameData?.Excel;
-
- ///
- /// Indicates whether Game Data is ready to be read.
- ///
- public bool IsDataReady { get; private set; }
-
- ///
- /// A object which gives access to any excel/game data.
- ///
- private Lumina.Lumina gameData;
-
- private ClientLanguage language;
-
- public DataManager(ClientLanguage language)
- {
- // Set up default values so plugins do not null-reference when data is being loaded.
- this.ServerOpCodes = new ReadOnlyDictionary(new Dictionary());
-
- this.language = language;
- }
-
- public async Task Initialize()
- {
- try
- {
- Log.Verbose("Starting data download...");
-
- using var client = new HttpClient()
- {
- BaseAddress = new Uri(DataBaseUrl)
- };
-
- var opCodeDict =
- JsonConvert.DeserializeObject>(
- await client.GetStringAsync(DataBaseUrl + "serveropcode.json"));
- this.ServerOpCodes = new ReadOnlyDictionary(opCodeDict);
-
- Log.Verbose("Loaded {0} ServerOpCodes.", opCodeDict.Count);
-
-
- var luminaOptions = new LuminaOptions
- {
- CacheFileResources = true
- };
-
- switch (this.language)
- {
- case ClientLanguage.Japanese:
- luminaOptions.DefaultExcelLanguage = Language.Japanese;
- break;
- case ClientLanguage.English:
- luminaOptions.DefaultExcelLanguage = Language.English;
- break;
- case ClientLanguage.German:
- luminaOptions.DefaultExcelLanguage = Language.German;
- break;
- case ClientLanguage.French:
- luminaOptions.DefaultExcelLanguage = Language.French;
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(this.language), "Unknown Language: " + this.language);
- }
-
- gameData = new Lumina.Lumina(Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "sqpack"), luminaOptions);
-
- Log.Information("Lumina is ready: {0}", gameData.DataPath);
-
- IsDataReady = true;
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Could not download data.");
- }
- }
-
- #region Lumina Wrappers
-
- ///
- /// Get an with the given Excel sheet row type.
- ///
- /// The excel sheet type to get.
- /// The , giving access to game rows.
- public ExcelSheet GetExcelSheet() where T : IExcelRow
- {
- return this.Excel.GetSheet();
- }
-
- ///
- /// Get a with the given path.
- ///
- /// The path inside of the game files.
- /// The of the file.
- public FileResource GetFile(string path)
- {
- return this.GetFile(path);
- }
-
- ///
- /// Get a with the given path, of the given type.
- ///
- /// The type of resource
- /// The path inside of the game files.
- /// The of the file.
- public T GetFile(string path) where T : FileResource
- {
- ParsedFilePath filePath = Lumina.Lumina.ParseFilePath(path);
- if (filePath == null)
- return default(T);
- Repository repository;
- return this.gameData.Repositories.TryGetValue(filePath.Repository, out repository) ? repository.GetFile(filePath.Category, filePath) : default(T);
- }
-
- #endregion
- }
-}
diff --git a/Dalamud/Data/TransientSheet/ContentFinderCondition.cs b/Dalamud/Data/TransientSheet/ContentFinderCondition.cs
deleted file mode 100644
index c8b56bfd2..000000000
--- a/Dalamud/Data/TransientSheet/ContentFinderCondition.cs
+++ /dev/null
@@ -1,610 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Lumina.Excel;
-
-namespace Dalamud.Data.TransientSheet
-{
- [SheetName("ContentFinderCondition")]
- public class ContentFinderCondition : IExcelRow
- {
- // column defs from Thu, 13 Feb 2020 20:46:12 GMT
-
- /* offset: 002c col: 0
- * name: ShortCode
- * type:
- */
-
- /* offset: 0048 col: 1
- * name: TerritoryType
- * type:
- */
-
- /* offset: 0054 col: 2
- * name: ContentLinkType
- * type:
- */
-
- /* offset: 004a col: 3
- * name: Content
- * type:
- */
-
- /* offset: 0061 col: 4
- * name: PvP
- * type:
- */
-
- /* offset: 0055 col: 5
- * no SaintCoinach definition found
- */
-
- /* offset: 0030 col: 6
- * no SaintCoinach definition found
- */
-
- /* offset: 0034 col: 7
- * no SaintCoinach definition found
- */
-
- /* offset: 0056 col: 8
- * name: AcceptClassJobCategory
- * type:
- */
-
- /* offset: 0057 col: 9
- * name: ContentMemberType
- * type:
- */
-
- /* offset: 0058 col: 10
- * no SaintCoinach definition found
- */
-
- /* offset: 0059 col: 11
- * no SaintCoinach definition found
- */
-
- /* offset: 005a col: 12
- * no SaintCoinach definition found
- */
-
- /* offset: 0038 col: 13
- * name: UnlockQuest
- * type:
- */
-
- /* offset: 004c col: 14
- * no SaintCoinach definition found
- */
-
- /* offset: 005b col: 15
- * name: ClassJobLevel{Required}
- * type:
- */
-
- /* offset: 005c col: 16
- * name: ClassJobLevel{Sync}
- * type:
- */
-
- /* offset: 004e col: 17
- * name: ItemLevel{Required}
- * type:
- */
-
- /* offset: 0050 col: 18
- * name: ItemLevel{Sync}
- * type:
- */
-
- /* offset: 0061 col: 19
- * name: AllowUndersized
- * type:
- */
-
- /* offset: 0061 col: 20
- * name: AllowReplacement
- * type:
- */
-
- /* offset: 0061 col: 21
- * no SaintCoinach definition found
- */
-
- /* offset: 0061 col: 22
- * no SaintCoinach definition found
- */
-
- /* offset: 0061 col: 23
- * no SaintCoinach definition found
- */
-
- /* offset: 005d col: 24
- * no SaintCoinach definition found
- */
-
- /* offset: 0061 col: 25
- * no SaintCoinach definition found
- */
-
- /* offset: 0061 col: 26
- * name: HighEndDuty
- * type:
- */
-
- /* offset: 0062 col: 27
- * no SaintCoinach definition found
- */
-
- /* offset: 0062 col: 28
- * no SaintCoinach definition found
- */
-
- /* offset: 0062 col: 29
- * no SaintCoinach definition found
- */
-
- /* offset: 0062 col: 30
- * name: DutyRecorderAllowed
- * type:
- */
-
- /* offset: 0062 col: 31
- * no SaintCoinach definition found
- */
-
- /* offset: 0062 col: 32
- * no SaintCoinach definition found
- */
-
- /* offset: 0062 col: 33
- * no SaintCoinach definition found
- */
-
- /* offset: 0000 col: 34
- * name: Name
- * type:
- */
-
- /* offset: 005e col: 35
- * name: ContentType
- * type:
- */
-
- /* offset: 005f col: 36
- * name: TransientKey
- * type:
- */
-
- /* offset: 003c col: 37
- * name: Transient
- * type:
- */
-
- /* offset: 0052 col: 38
- * name: SortKey
- * type:
- */
-
- /* offset: 0040 col: 39
- * name: Image
- * type:
- */
-
- /* offset: 0044 col: 40
- * name: Icon
- * type:
- */
-
- /* offset: 0060 col: 41
- * no SaintCoinach definition found
- */
-
- /* offset: 0004 col: 42
- * name: LevelingRoulette
- * type:
- */
-
- /* offset: 0005 col: 43
- * name: Level50/60Roulette
- * type:
- */
-
- /* offset: 0006 col: 44
- * name: MSQRoulette
- * type:
- */
-
- /* offset: 0007 col: 45
- * name: GuildHestRoulette
- * type:
- */
-
- /* offset: 0008 col: 46
- * name: ExpertRoulette
- * type:
- */
-
- /* offset: 0009 col: 47
- * name: TrialRoulette
- * type:
- */
-
- /* offset: 000a col: 48
- * name: DailyFrontlineChallenge
- * type:
- */
-
- /* offset: 000b col: 49
- * name: Level70Roulette
- * type:
- */
-
- /* offset: 000c col: 50
- * name: MentorRoulette
- * type:
- */
-
- /* offset: 000d col: 51
- * no SaintCoinach definition found
- */
-
- /* offset: 000e col: 52
- * no SaintCoinach definition found
- */
-
- /* offset: 000f col: 53
- * no SaintCoinach definition found
- */
-
- /* offset: 0010 col: 54
- * no SaintCoinach definition found
- */
-
- /* offset: 0011 col: 55
- * no SaintCoinach definition found
- */
-
- /* offset: 0012 col: 56
- * name: AllianceRoulette
- * type:
- */
-
- /* offset: 0013 col: 57
- * no SaintCoinach definition found
- */
-
- /* offset: 0014 col: 58
- * name: NormalRaidRoulette
- * type:
- */
-
- /* offset: 0015 col: 59
- * no SaintCoinach definition found
- */
-
- /* offset: 0016 col: 60
- * no SaintCoinach definition found
- */
-
- /* offset: 0017 col: 61
- * no SaintCoinach definition found
- */
-
- /* offset: 0018 col: 62
- * no SaintCoinach definition found
- */
-
- /* offset: 0019 col: 63
- * no SaintCoinach definition found
- */
-
- /* offset: 001a col: 64
- * no SaintCoinach definition found
- */
-
- /* offset: 001b col: 65
- * no SaintCoinach definition found
- */
-
- /* offset: 001c col: 66
- * no SaintCoinach definition found
- */
-
- /* offset: 001d col: 67
- * no SaintCoinach definition found
- */
-
- /* offset: 001e col: 68
- * no SaintCoinach definition found
- */
-
- /* offset: 001f col: 69
- * no SaintCoinach definition found
- */
-
- /* offset: 0020 col: 70
- * no SaintCoinach definition found
- */
-
- /* offset: 0021 col: 71
- * no SaintCoinach definition found
- */
-
- /* offset: 0022 col: 72
- * no SaintCoinach definition found
- */
-
- /* offset: 0023 col: 73
- * no SaintCoinach definition found
- */
-
- /* offset: 0024 col: 74
- * no SaintCoinach definition found
- */
-
- /* offset: 0025 col: 75
- * no SaintCoinach definition found
- */
-
- /* offset: 0026 col: 76
- * no SaintCoinach definition found
- */
-
- /* offset: 0027 col: 77
- * no SaintCoinach definition found
- */
-
- /* offset: 0028 col: 78
- * no SaintCoinach definition found
- */
-
- /* offset: 0029 col: 79
- * no SaintCoinach definition found
- */
-
- /* offset: 002a col: 80
- * no SaintCoinach definition found
- */
-
-
-
- // col: 34 offset: 0000
- public string Name;
-
- // col: 42 offset: 0004
- public bool LevelingRoulette;
-
- // col: 43 offset: 0005
- public bool Level5060Roulette;
-
- // col: 44 offset: 0006
- public bool MSQRoulette;
-
- // col: 45 offset: 0007
- public bool GuildHestRoulette;
-
- // col: 46 offset: 0008
- public bool ExpertRoulette;
-
- // col: 47 offset: 0009
- public bool TrialRoulette;
-
- // col: 48 offset: 000a
- public bool DailyFrontlineChallenge;
-
- // col: 49 offset: 000b
- public bool Level70Roulette;
-
- // col: 50 offset: 000c
- public bool MentorRoulette;
-
- // col: 51 offset: 000d
- public bool unknownd;
-
- // col: 52 offset: 000e
- public bool unknowne;
-
- // col: 53 offset: 000f
- public bool unknownf;
-
- // col: 54 offset: 0010
- public bool unknown10;
-
- // col: 55 offset: 0011
- public bool unknown11;
-
- // col: 56 offset: 0012
- public bool AllianceRoulette;
-
- // col: 57 offset: 0013
- public bool unknown13;
-
- // col: 58 offset: 0014
- public bool NormalRaidRoulette;
-
- // col: 59 offset: 0015
- public bool unknown15;
-
- // col: 60 offset: 0016
- public bool unknown16;
-
- // col: 61 offset: 0017
- public bool unknown17;
-
- // col: 62 offset: 0018
- public bool unknown18;
-
- // col: 63 offset: 0019
- public bool unknown19;
-
- // col: 64 offset: 001a
- public bool unknown1a;
-
- // col: 65 offset: 001b
- public bool unknown1b;
-
- // col: 66 offset: 001c
- public bool unknown1c;
-
- // col: 67 offset: 001d
- public bool unknown1d;
-
- // col: 68 offset: 001e
- public bool unknown1e;
-
- // col: 69 offset: 001f
- public bool unknown1f;
-
- // col: 70 offset: 0020
- public bool unknown20;
-
- // col: 71 offset: 0021
- public bool unknown21;
-
- // col: 72 offset: 0022
- public bool unknown22;
-
- // col: 73 offset: 0023
- public bool unknown23;
-
- // col: 74 offset: 0024
- public bool unknown24;
-
- // col: 75 offset: 0025
- public bool unknown25;
-
- // col: 76 offset: 0026
- public bool unknown26;
-
- // col: 77 offset: 0027
- public bool unknown27;
-
- // col: 78 offset: 0028
- public bool unknown28;
-
- // col: 79 offset: 0029
- public bool unknown29;
-
- // col: 80 offset: 002a
- public bool unknown2a;
-
- // col: 00 offset: 002c
- public string ShortCode;
-
- // col: 06 offset: 0030
- public uint unknown30;
-
- // col: 07 offset: 0034
- public uint unknown34;
-
- // col: 13 offset: 0038
- public uint UnlockQuest;
-
- // col: 37 offset: 003c
- public uint Transient;
-
- // col: 39 offset: 0040
- public uint Image;
-
- // col: 40 offset: 0044
- public uint Icon;
-
- // col: 01 offset: 0048
- public ushort TerritoryType;
-
- // col: 03 offset: 004a
- public ushort Content;
-
- // col: 14 offset: 004c
- public ushort unknown4c;
-
- // col: 17 offset: 004e
- public ushort ItemLevelRequired;
-
- // col: 18 offset: 0050
- public ushort ItemLevelSync;
-
- // col: 38 offset: 0052
- public ushort SortKey;
-
- // col: 02 offset: 0054
- public byte ContentLinkType;
-
- // col: 05 offset: 0055
- public byte unknown55;
-
- // col: 08 offset: 0056
- public byte AcceptClassJobCategory;
-
- // col: 09 offset: 0057
- public byte ContentMemberType;
-
- // col: 10 offset: 0058
- public byte unknown58;
-
- // col: 11 offset: 0059
- public byte unknown59;
-
- // col: 12 offset: 005a
- public byte unknown5a;
-
- // col: 15 offset: 005b
- public byte ClassJobLevelRequired;
-
- // col: 16 offset: 005c
- public byte ClassJobLevelSync;
-
- // col: 24 offset: 005d
- public byte unknown5d;
-
- // col: 35 offset: 005e
- public byte ContentType;
-
- // col: 36 offset: 005f
- public byte TransientKey;
-
- // col: 41 offset: 0060
- public sbyte unknown60;
-
- // col: 04 offset: 0061
- private byte packed61;
- public bool PvP => (packed61 & 0x1) == 0x1;
- public bool AllowUndersized => (packed61 & 0x2) == 0x2;
- public bool AllowReplacement => (packed61 & 0x4) == 0x4;
- public bool unknown61_8 => (packed61 & 0x8) == 0x8;
- public bool unknown61_10 => (packed61 & 0x10) == 0x10;
- public bool unknown61_20 => (packed61 & 0x20) == 0x20;
- public bool unknown61_40 => (packed61 & 0x40) == 0x40;
- public bool HighEndDuty => (packed61 & 0x80) == 0x80;
-
- // col: 27 offset: 0062
- private byte packed62;
- public bool unknown62_1 => (packed62 & 0x1) == 0x1;
- public bool unknown62_2 => (packed62 & 0x2) == 0x2;
- public bool unknown62_4 => (packed62 & 0x4) == 0x4;
- public bool DutyRecorderAllowed => (packed62 & 0x8) == 0x8;
- public bool unknown62_10 => (packed62 & 0x10) == 0x10;
- public bool unknown62_20 => (packed62 & 0x20) == 0x20;
- public bool unknown62_40 => (packed62 & 0x40) == 0x40;
-
-
- public int RowId { get; set; }
- public int SubRowId { get; set; }
-
- public void PopulateData(RowParser parser)
- {
- RowId = parser.Row;
- SubRowId = parser.SubRow;
-
- // col: 34 offset: 0000
- Name = parser.ReadOffset(0x0);
-
- // col: 39 offset: 0040
- Image = parser.ReadOffset(0x40);
- }
- }
-}
diff --git a/Dalamud/DiscordBot/DiscordBotManager.cs b/Dalamud/DiscordBot/DiscordBotManager.cs
deleted file mode 100644
index 6b68961cc..000000000
--- a/Dalamud/DiscordBot/DiscordBotManager.cs
+++ /dev/null
@@ -1,317 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO.Ports;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-using Dalamud.Data.TransientSheet;
-using Dalamud.Game.Chat;
-using Dalamud.Game.Chat.SeStringHandling;
-using Dalamud.Game.Chat.SeStringHandling.Payloads;
-using Dalamud.Game.Internal.Libc;
-using Discord;
-using Discord.WebSocket;
-using Newtonsoft.Json.Linq;
-using Serilog;
-
-namespace Dalamud.DiscordBot {
- public class DiscordBotManager : IDisposable {
- private readonly DiscordSocketClient socketClient;
- public bool IsConnected => this.socketClient.ConnectionState == ConnectionState.Connected && this.isReady;
- public ulong UserId => this.socketClient.CurrentUser.Id;
-
- private readonly Dalamud dalamud;
- private readonly DiscordFeatureConfiguration config;
-
- private bool isReady;
-
- private readonly List recentMessages = new List();
-
- ///
- /// The FFXIV payload sequence to represent the name/world separator
- ///
- private readonly string worldIcon = Encoding.UTF8.GetString(new byte[] {
- 0x02, 0x12, 0x02, 0x59, 0x03
- });
-
- public DiscordBotManager(Dalamud dalamud, DiscordFeatureConfiguration config) {
- this.dalamud = dalamud;
- this.config = config;
- config.OwnerUserId = 123830058426040321;
-
- this.socketClient = new DiscordSocketClient();
- this.socketClient.Ready += SocketClientOnReady;
- this.dalamud.NetworkHandlers.ProcessCfPop += ProcessCfPop;
- }
-
- private XivChatType GetChatTypeBySlug(string slug) {
- var selectedType = XivChatType.None;
- foreach (var chatType in Enum.GetValues(typeof(XivChatType)).Cast()) {
- var details = chatType.GetDetails();
-
- if (details == null)
- continue;
-
- if (slug == details.Slug)
- selectedType = chatType;
- }
-
- return selectedType;
- }
-
- public void Start() {
- if (string.IsNullOrEmpty(this.config.Token)) {
- Log.Error("Discord token is null or empty.");
- return;
- }
-
- try {
- this.socketClient.LoginAsync(TokenType.Bot, this.config.Token).GetAwaiter().GetResult();
- this.socketClient.StartAsync().GetAwaiter().GetResult();
- } catch (Exception ex) {
- Log.Error(ex, "Discord bot login failed.");
- this.dalamud.Framework.Gui.Chat.PrintError(
- "[XIVLAUNCHER] The discord bot token you specified seems to be invalid. Please check the guide linked on the settings page for more details.");
- }
- }
-
- private Task SocketClientOnReady() {
- Log.Information("Discord bot connected as " + this.socketClient.CurrentUser);
- this.isReady = true;
-
- this.socketClient.SetGameAsync("FINAL FANTASY XIV").GetAwaiter().GetResult();
-
- return Task.CompletedTask;
- }
-
- public async Task ProcessCfPop(ContentFinderCondition cfc) {
- if (!this.IsConnected)
- return;
-
- var contentName = cfc.Name;
-
- if (this.config.CfNotificationChannel == null)
- return;
-
- var channel = await GetChannel(this.config.CfNotificationChannel);
-
- var iconFolder = (cfc.Image / 1000) * 1000;
-
- var embedBuilder = new EmbedBuilder {
- Title = "Duty is ready: " + contentName,
- Timestamp = DateTimeOffset.Now,
- Color = new Color(0x297c00),
- ImageUrl = "https://xivapi.com" + $"/i/{iconFolder}/{cfc.Image}.png"
- };
-
- await channel.SendMessageAsync(embed: embedBuilder.Build());
- }
-
- public async Task ProcessCfPreferredRoleChange(string rouletteName, string prevRoleName, string currentRoleName)
- {
- if (this.config.CfPreferredRoleChannel == null)
- return;
-
- var channel = await GetChannel(this.config.CfPreferredRoleChannel);
-
- var world = string.Empty;
-
- if (this.dalamud.ClientState.Actors.Length > 0)
- world = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Name;
-
- var embedBuilder = new EmbedBuilder
- {
- Title = "Roulette bonus changed: " + rouletteName,
- Description = $"From {prevRoleName} to {currentRoleName}",
- Footer = new EmbedFooterBuilder {
- Text = $"On {world} | XIVLauncher"
- },
- Timestamp = DateTimeOffset.Now,
- Color = new Color(0xf5aa42),
- };
-
- await channel.SendMessageAsync(embed: embedBuilder.Build());
- }
-
- public async Task ProcessRetainerSale(int itemId, int amount, bool isHq) {
- if (this.config.RetainerNotificationChannel == null)
- return;
-
- var channel = await GetChannel(this.config.RetainerNotificationChannel);
-
- dynamic item = XivApi.GetItem(itemId).GetAwaiter().GetResult();
-
- var character = this.dalamud.ClientState.LocalPlayer;
- var characterInfo = await GetCharacterInfo(character.Name, character.HomeWorld.Name);
-
- var embedBuilder = new EmbedBuilder {
- Title = (isHq ? "<:hq:593406013651156994> " : "") + item.Name,
- Url = "https://www.garlandtools.org/db/#item/" + itemId,
- Description = "Sold " + amount,
- Timestamp = DateTimeOffset.Now,
- Color = new Color(0xd89b0d),
- ThumbnailUrl = "https://xivapi.com" + item.Icon,
- Footer = new EmbedFooterBuilder {
- Text = $"XIVLauncher | {character.Name}",
- IconUrl = characterInfo.AvatarUrl
- }
- };
-
- await channel.SendMessageAsync(embed: embedBuilder.Build());
- }
-
- public async Task ProcessChatMessage(XivChatType type, StdString message, StdString sender) {
- // Special case for outgoing tells, these should be sent under Incoming tells
- var wasOutgoingTell = false;
- if (type == XivChatType.TellOutgoing) {
- type = XivChatType.TellIncoming;
- wasOutgoingTell = true;
- }
-
- var chatTypeConfigs =
- this.config.ChatTypeConfigurations.Where(typeConfig => typeConfig.ChatType == type);
-
- if (!chatTypeConfigs.Any())
- return;
-
- var chatTypeDetail = type.GetDetails();
- var channels = chatTypeConfigs.Select(c => GetChannel(c.Channel).GetAwaiter().GetResult());
-
-
- var parsedSender = SeString.Parse(sender.RawData);
- var playerLink = parsedSender.Payloads.FirstOrDefault(x => x.Type == PayloadType.Player) as PlayerPayload;
-
- string senderName;
- string senderWorld;
-
- if (playerLink == null) {
- // chat messages from the local player do not include a player link, and are just the raw name
- // but we should still track other instances to know if this is ever an issue otherwise
- if (parsedSender.TextValue != this.dalamud.ClientState.LocalPlayer.Name)
- {
- Log.Error("playerLink was null. Sender: {0}", BitConverter.ToString(sender.RawData));
- }
-
- senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : parsedSender.TextValue;
- senderWorld = this.dalamud.ClientState.LocalPlayer.HomeWorld.Name;
- } else {
- playerLink.Resolve();
-
- senderName = wasOutgoingTell ? this.dalamud.ClientState.LocalPlayer.Name : playerLink.PlayerName;
- senderWorld = playerLink.ServerName;
- }
-
- var rawMessage = SeString.Parse(message.RawData).TextValue;
-
- var avatarUrl = string.Empty;
- var lodestoneId = string.Empty;
-
- if (!this.config.DisableEmbeds) {
- var searchResult = await GetCharacterInfo(senderName, senderWorld);
-
- lodestoneId = searchResult.LodestoneId;
- avatarUrl = searchResult.AvatarUrl;
- }
-
- Thread.Sleep(this.config.ChatDelayMs);
-
- var name = wasOutgoingTell
- ? "You"
- : senderName + (string.IsNullOrEmpty(senderWorld) || string.IsNullOrEmpty(senderName)
- ? ""
- : $" on {senderWorld}");
-
- for (var chatTypeIndex = 0; chatTypeIndex < chatTypeConfigs.Count(); chatTypeIndex++) {
- if (!this.config.DisableEmbeds) {
- var embedBuilder = new EmbedBuilder
- {
- Author = new EmbedAuthorBuilder
- {
- IconUrl = avatarUrl,
- Name = name,
- Url = !string.IsNullOrEmpty(lodestoneId) ? "https://eu.finalfantasyxiv.com/lodestone/character/" + lodestoneId : null
- },
- Description = rawMessage,
- Timestamp = DateTimeOffset.Now,
- Footer = new EmbedFooterBuilder { Text = type.GetDetails().FancyName },
- Color = new Color((uint)(chatTypeConfigs.ElementAt(chatTypeIndex).Color & 0xFFFFFF))
- };
-
- if (this.config.CheckForDuplicateMessages)
- {
- var recentMsg = this.recentMessages.FirstOrDefault(
- msg => msg.Embeds.FirstOrDefault(
- embed => embed.Description == embedBuilder.Description &&
- embed.Author.HasValue &&
- embed.Author.Value.Name == embedBuilder.Author.Name &&
- embed.Timestamp.HasValue &&
- Math.Abs(
- (embed.Timestamp.Value.ToUniversalTime().Date -
- embedBuilder
- .Timestamp.Value.ToUniversalTime().Date)
- .Milliseconds) < 15000)
- != null);
-
- if (recentMsg != null)
- {
- Log.Verbose("Duplicate message: [{0}] {1}", embedBuilder.Author.Name, embedBuilder.Description);
- this.recentMessages.Remove(recentMsg);
- return;
- }
- }
-
- await channels.ElementAt(chatTypeIndex).SendMessageAsync(embed: embedBuilder.Build());
- } else {
- var simpleMessage = $"{name}: {rawMessage}";
-
- if (this.config.CheckForDuplicateMessages) {
- var recentMsg = this.recentMessages.FirstOrDefault(
- msg => msg.Content == simpleMessage);
-
- if (recentMsg != null)
- {
- Log.Verbose("Duplicate message: {0}", simpleMessage);
- this.recentMessages.Remove(recentMsg);
- return;
- }
- }
-
- await channels.ElementAt(chatTypeIndex).SendMessageAsync($"**[{chatTypeDetail.Slug}]{name}**: {rawMessage}");
- }
- }
- }
-
- private async Task<(string LodestoneId, string AvatarUrl)> GetCharacterInfo(string name, string worldName) {
- try
- {
- dynamic charCandidates = await XivApi.GetCharacterSearch(name, worldName);
-
- if (charCandidates.Results.Count > 0)
- {
- var avatarUrl = charCandidates.Results[0].Avatar;
- var lodestoneId = charCandidates.Results[0].ID;
-
- return (lodestoneId, avatarUrl);
- }
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Could not get XIVAPI character search result.");
- }
-
- return (null, null);
- }
-
- private async Task GetChannel(ChannelConfiguration channelConfig) {
- if (channelConfig.Type == ChannelType.Guild)
- return this.socketClient.GetGuild(channelConfig.GuildId).GetTextChannel(channelConfig.ChannelId);
- return await this.socketClient.GetUser(channelConfig.ChannelId).GetOrCreateDMChannelAsync();
- }
-
- public void Dispose() {
- this.socketClient.LogoutAsync().GetAwaiter().GetResult();
- }
- }
-}
diff --git a/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs b/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs
deleted file mode 100644
index 551f3d8ad..000000000
--- a/Dalamud/DiscordBot/DiscordFeatureConfiguration.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.Chat;
-
-namespace Dalamud.DiscordBot
-{
- public enum ChannelType {
- Guild,
- User
- }
-
- [Serializable]
- public class ChannelConfiguration {
- public ChannelType Type { get; set; }
-
- public ulong GuildId { get; set; }
- public ulong ChannelId { get; set; }
- }
-
- [Serializable]
- public class ChatTypeConfiguration {
- public XivChatType ChatType { get; set; }
-
- public ChannelConfiguration Channel { get; set; }
- public int Color { get; set; }
- }
-
- [Serializable]
- public class DiscordFeatureConfiguration
- {
- public string Token { get; set; }
-
- public bool CheckForDuplicateMessages { get; set; }
- public int ChatDelayMs { get; set; }
-
- public bool DisableEmbeds { get; set; }
-
- public ulong OwnerUserId { get; set; }
-
- public List ChatTypeConfigurations { get; set; }
-
- public ChannelConfiguration CfNotificationChannel { get; set; }
- public ChannelConfiguration CfPreferredRoleChannel { get; set; }
- public ChannelConfiguration RetainerNotificationChannel { get; set; }
- }
-}
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index e7e8404f4..37ecdb5a6 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -1,14 +1,7 @@
-using System;
using CoreHook;
namespace Dalamud
{
- ///
- ///
- ///
- ///
- ///
- ///
public sealed class EntryPoint : IEntryPoint
{
public EntryPoint(IContext context, string rootDirectory) { }
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payload.cs b/Dalamud/Game/Chat/SeStringHandling/Payload.cs
deleted file mode 100644
index fbbaf2ab8..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payload.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.Chat.SeStringHandling.Payloads;
-using Serilog;
-
-namespace Dalamud.Game.Chat.SeStringHandling
-{
- ///
- /// This class represents a parsed SeString payload.
- ///
- public abstract class Payload
- {
- public abstract PayloadType Type { get; }
-
- public abstract void Resolve();
-
- public abstract byte[] Encode();
-
- protected abstract void ProcessChunkImpl(BinaryReader reader, long endOfStream);
-
- public static Payload Process(BinaryReader reader)
- {
- if ((byte)reader.PeekChar() != START_BYTE)
- {
- return ProcessText(reader);
- }
- else
- {
- return ProcessChunk(reader);
- }
- }
-
- private static Payload ProcessChunk(BinaryReader reader)
- {
- Payload payload = null;
-
- reader.ReadByte(); // START_BYTE
- var chunkType = (SeStringChunkType)reader.ReadByte();
- var chunkLen = GetInteger(reader);
-
- var packetStart = reader.BaseStream.Position;
-
- switch (chunkType)
- {
- case SeStringChunkType.Interactable:
- {
- var subType = (EmbeddedInfoType)reader.ReadByte();
- switch (subType)
- {
- case EmbeddedInfoType.PlayerName:
- payload = new PlayerPayload();
- break;
-
- case EmbeddedInfoType.ItemLink:
- payload = new ItemPayload();
- break;
-
- case EmbeddedInfoType.Status:
- payload = new StatusPayload();
- break;
-
- case EmbeddedInfoType.LinkTerminator:
- // this has no custom handling and so needs to fallthrough to ensure it is captured
- default:
- Log.Verbose("Unhandled EmbeddedInfoType: {0}", subType);
- // rewind so we capture the Interactable byte in the raw data
- reader.BaseStream.Seek(-1, SeekOrigin.Current);
- payload = new RawPayload((byte)chunkType);
- break;
- }
- }
- break;
- default:
- Log.Verbose("Unhandled SeStringChunkType: {0}", chunkType);
- payload = new RawPayload((byte)chunkType);
- break;
- }
-
- payload?.ProcessChunkImpl(reader, reader.BaseStream.Position + chunkLen - 1);
-
- // read through the rest of the packet
- var readBytes = (int)(reader.BaseStream.Position - packetStart);
- reader.ReadBytes(chunkLen - readBytes + 1); // +1 for the END_BYTE marker
-
- return payload;
- }
-
- private static Payload ProcessText(BinaryReader reader)
- {
- var payload = new TextPayload();
- payload.ProcessChunkImpl(reader, reader.BaseStream.Length);
-
- return payload;
- }
-
- #region parse constants and helpers
-
- protected const byte START_BYTE = 0x02;
- protected const byte END_BYTE = 0x03;
-
- protected enum SeStringChunkType
- {
- Interactable = 0x27
- }
-
- protected enum EmbeddedInfoType
- {
- PlayerName = 0x01,
- ItemLink = 0x03,
- Status = 0x09,
-
- LinkTerminator = 0xCF // not clear but seems to always follow a link
- }
-
- protected enum IntegerType
- {
- Byte = 0xF0,
- ByteTimes256 = 0xF1,
- Int16 = 0xF2,
- Int16Plus1Million = 0xF6,
- Int24 = 0xFA,
- Int32 = 0xFE
- }
-
- // made protected, unless we actually want to use it externally
- // in which case it should probably go live somewhere else
- protected static int GetInteger(BinaryReader input)
- {
- var t = input.ReadByte();
- var type = (IntegerType)t;
- return GetInteger(input, type);
- }
-
- private static int GetInteger(BinaryReader input, IntegerType type)
- {
- const byte ByteLengthCutoff = 0xF0;
-
- var t = (byte)type;
- if (t < ByteLengthCutoff)
- return t - 1;
-
- switch (type)
- {
- case IntegerType.Byte:
- return input.ReadByte();
- case IntegerType.ByteTimes256:
- return input.ReadByte() * 256;
- case IntegerType.Int16:
- {
- var v = 0;
- v |= input.ReadByte() << 8;
- v |= input.ReadByte();
- return v;
- }
- case IntegerType.Int16Plus1Million:
- {
- var v = 0;
- v |= input.ReadByte() << 16;
- v |= input.ReadByte() << 8;
- v |= input.ReadByte();
- // need the actual value since it's used as a flag
- // v -= 1000000;
- return v;
- }
- case IntegerType.Int24:
- {
- var v = 0;
- v |= input.ReadByte() << 16;
- v |= input.ReadByte() << 8;
- v |= input.ReadByte();
- return v;
- }
- case IntegerType.Int32:
- {
- var v = 0;
- v |= input.ReadByte() << 24;
- v |= input.ReadByte() << 16;
- v |= input.ReadByte() << 8;
- v |= input.ReadByte();
- return v;
- }
- default:
- throw new NotSupportedException();
- }
- }
-
- protected static byte[] MakeInteger(int value)
- {
- // clearly the epitome of efficiency
-
- var bytesPadded = BitConverter.GetBytes(value);
- Array.Reverse(bytesPadded);
- return bytesPadded.SkipWhile(b => b == 0x00).ToArray();
- }
-
- protected static IntegerType GetTypeForIntegerBytes(byte[] bytes)
- {
- // not the most scientific, exists mainly for laziness
-
- if (bytes.Length == 1)
- {
- return IntegerType.Byte;
- }
- else if (bytes.Length == 2)
- {
- return IntegerType.Int16;
- }
- else if (bytes.Length == 3)
- {
- return IntegerType.Int24;
- }
- else if (bytes.Length == 4)
- {
- return IntegerType.Int32;
- }
-
- throw new NotSupportedException();
- }
- #endregion
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/PayloadType.cs b/Dalamud/Game/Chat/SeStringHandling/PayloadType.cs
deleted file mode 100644
index 6576e0524..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/PayloadType.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Chat.SeStringHandling
-{
- ///
- /// All parsed types of SeString payloads.
- ///
- public enum PayloadType
- {
- ///
- /// An SeString payload representing a player link.
- ///
- Player,
- ///
- /// An SeString payload representing an Item link.
- ///
- Item,
- ///
- /// An SeString payload representing an Status Effect link.
- ///
- Status,
- ///
- /// An SeString payload representing raw, typed text.
- ///
- RawText,
- ///
- /// An SeString payload representing any data we don't handle.
- ///
- Unknown
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs
deleted file mode 100644
index 1a1dc0bb7..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Chat.SeStringHandling.Payloads
-{
- public class ItemPayload : Payload
- {
- public override PayloadType Type => PayloadType.Item;
-
- public int ItemId { get; private set; }
- public string ItemName { get; private set; } = string.Empty;
- public bool IsHQ { get; private set; } = false;
-
- public ItemPayload() { }
-
- public ItemPayload(int itemId, bool isHQ)
- {
- ItemId = itemId;
- IsHQ = isHQ;
- }
-
- public override void Resolve()
- {
- if (string.IsNullOrEmpty(ItemName))
- {
- dynamic item = XivApi.GetItem(ItemId).GetAwaiter().GetResult();
- ItemName = item.Name;
- }
- }
-
- public override byte[] Encode()
- {
- var actualItemId = IsHQ ? ItemId + 1000000 : ItemId;
- var idBytes = MakeInteger(actualItemId);
- bool hasName = !string.IsNullOrEmpty(ItemName);
-
- var itemIdFlag = IsHQ ? IntegerType.Int16Plus1Million : IntegerType.Int16;
-
- var chunkLen = idBytes.Length + 5;
- if (hasName)
- {
- // 1 additional unknown byte compared to the nameless version, 1 byte for the name length, and then the name itself
- chunkLen += (1 + 1 + ItemName.Length);
- if (IsHQ)
- {
- chunkLen += 4; // unicode representation of the HQ symbol is 3 bytes, preceded by a space
- }
- }
-
- var bytes = new List()
- {
- START_BYTE,
- (byte)SeStringChunkType.Interactable, (byte)chunkLen, (byte)EmbeddedInfoType.ItemLink,
- (byte)itemIdFlag
- };
- bytes.AddRange(idBytes);
- // unk
- bytes.AddRange(new byte[] { 0x02, 0x01 });
-
- // Links don't have to include the name, but if they do, it requires additional work
- if (hasName)
- {
- var nameLen = ItemName.Length + 1;
- if (IsHQ)
- {
- nameLen += 4; // space plus 3 bytes for HQ symbol
- }
-
- bytes.AddRange(new byte[]
- {
- 0xFF, // unk
- (byte)nameLen
- });
- bytes.AddRange(Encoding.UTF8.GetBytes(ItemName));
-
- if (IsHQ)
- {
- // space and HQ symbol
- bytes.AddRange(new byte[] { 0x20, 0xEE, 0x80, 0xBC });
- }
- }
-
- bytes.Add(END_BYTE);
-
- return bytes.ToArray();
- }
-
- public override string ToString()
- {
- return $"{Type} - ItemId: {ItemId}, ItemName: {ItemName}, IsHQ: {IsHQ}";
- }
-
- protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
- {
- ItemId = GetInteger(reader);
-
- if (ItemId > 1000000)
- {
- ItemId -= 1000000;
- IsHQ = true;
- }
-
- if (reader.BaseStream.Position + 3 < endOfStream)
- {
- // unk
- reader.ReadBytes(3);
-
- var itemNameLen = GetInteger(reader);
- var itemNameBytes = reader.ReadBytes(itemNameLen);
-
- // HQ items have the HQ symbol as part of the name, but since we already recorded
- // the HQ flag, we want just the bare name
- if (IsHQ)
- {
- itemNameBytes = itemNameBytes.Take(itemNameLen - 4).ToArray();
- }
-
- ItemName = Encoding.UTF8.GetString(itemNameBytes);
- }
- }
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs
deleted file mode 100644
index 15f555445..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Chat.SeStringHandling.Payloads
-{
- public class PlayerPayload : Payload
- {
- public override PayloadType Type => PayloadType.Player;
-
- public string PlayerName { get; private set; }
- public int ServerId { get; private set; }
- public string ServerName { get; private set; } = String.Empty;
-
- public PlayerPayload() { }
-
- public PlayerPayload(string playerName, int serverId)
- {
- PlayerName = playerName;
- ServerId = serverId;
- }
-
- public override void Resolve()
- {
- if (string.IsNullOrEmpty(ServerName))
- {
- dynamic server = XivApi.Get($"World/{ServerId}").GetAwaiter().GetResult();
- ServerName = server.Name;
- }
- }
-
- public override byte[] Encode()
- {
- var chunkLen = PlayerName.Length + 7;
- var bytes = new List()
- {
- START_BYTE,
- (byte)SeStringChunkType.Interactable, (byte)chunkLen, (byte)EmbeddedInfoType.PlayerName,
- /* unk */ 0x01,
- (byte)(ServerId+1), // I didn't want to deal with single-byte values in MakeInteger, so we have to do the +1 manually
- /* unk */0x01, /* unk */0xFF, // these sometimes vary but are frequently this
- (byte)(PlayerName.Length+1)
- };
-
- bytes.AddRange(Encoding.UTF8.GetBytes(PlayerName));
- bytes.Add(END_BYTE);
-
- // encoded names are followed by the name in plain text again
- // use the payload parsing for consistency, as this is technically a new chunk
- bytes.AddRange(new TextPayload(PlayerName).Encode());
-
- // unsure about this entire packet, but it seems to always follow a name
- bytes.AddRange(new byte[]
- {
- START_BYTE, (byte)SeStringChunkType.Interactable, 0x07, (byte)EmbeddedInfoType.LinkTerminator,
- 0x01, 0x01, 0x01, 0xFF, 0x01,
- END_BYTE
- });
-
- return bytes.ToArray();
- }
-
- public override string ToString()
- {
- return $"{Type} - PlayerName: {PlayerName}, ServerId: {ServerId}, ServerName: {ServerName}";
- }
-
- protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
- {
- // unk
- reader.ReadByte();
-
- ServerId = GetInteger(reader);
-
- // unk
- reader.ReadBytes(2);
-
- var nameLen = GetInteger(reader);
- PlayerName = Encoding.UTF8.GetString(reader.ReadBytes(nameLen));
- }
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs
deleted file mode 100644
index 77480291b..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Dalamud.Game.Chat.SeStringHandling.Payloads
-{
- public class RawPayload : Payload
- {
- public override PayloadType Type => PayloadType.Unknown;
-
- public byte ChunkType { get; private set; }
- public byte[] Data { get; private set; }
-
- public RawPayload(byte chunkType)
- {
- ChunkType = chunkType;
- }
-
- public override void Resolve()
- {
- // nothing to do
- }
-
- public override byte[] Encode()
- {
- var chunkLen = Data.Length + 1;
-
- var bytes = new List()
- {
- START_BYTE,
- ChunkType,
- (byte)chunkLen
- };
- bytes.AddRange(Data);
-
- bytes.Add(END_BYTE);
-
- return bytes.ToArray();
- }
-
- public override string ToString()
- {
- return $"{Type} - Chunk type: {ChunkType:X}, Data: {BitConverter.ToString(Data).Replace("-", " ")}";
- }
-
- protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
- {
- Data = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position + 1));
- }
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs
deleted file mode 100644
index 4169ac42a..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Chat.SeStringHandling.Payloads
-{
- public class StatusPayload : Payload
- {
- public override PayloadType Type => PayloadType.Status;
-
- public int StatusId { get; private set; }
-
- public string StatusName { get; private set; } = string.Empty;
-
- public StatusPayload() { }
-
- public StatusPayload(int statusId)
- {
- StatusId = statusId;
- }
-
- public override void Resolve()
- {
- if (string.IsNullOrEmpty(StatusName))
- {
- dynamic status = XivApi.Get($"Status/{StatusId}").GetAwaiter().GetResult();
- //Console.WriteLine($"Resolved status {StatusId} to {status.Name}");
- StatusName = status.Name;
- }
- }
-
- public override byte[] Encode()
- {
- var idBytes = MakeInteger(StatusId);
- var idPrefix = GetTypeForIntegerBytes(idBytes);
-
- var chunkLen = idBytes.Length + 8;
- var bytes = new List()
- {
- START_BYTE, (byte)SeStringChunkType.Interactable, (byte)chunkLen, (byte)EmbeddedInfoType.Status,
- (byte)idPrefix
- };
-
- bytes.AddRange(idBytes);
- // unk
- bytes.AddRange(new byte[] { 0x01, 0x01, 0xFF, 0x02, 0x20, END_BYTE });
-
- return bytes.ToArray();
- }
-
- public override string ToString()
- {
- return $"{Type} - StatusId: {StatusId}, StatusName: {StatusName}";
- }
-
- protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
- {
- StatusId = GetInteger(reader);
- }
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs
deleted file mode 100644
index 161cd82db..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Chat.SeStringHandling.Payloads
-{
- public class TextPayload : Payload
- {
- public override PayloadType Type => PayloadType.RawText;
-
- private string textConverted = null;
-
- ///
- /// The Text of this text payload as an UTF-8 converted string.
- /// Don't rely on this for accurate representation of SE payload data, please check RawData instead.
- ///
- public string Text {
- get { return this.textConverted ??= Encoding.UTF8.GetString(RawData); }
- set {
- this.textConverted = value;
- RawData = Encoding.UTF8.GetBytes(value);
- }
- }
-
- ///
- /// The raw unconverted data of this text payload.
- ///
- public byte[] RawData { get; set; }
-
- public TextPayload() { }
-
- public TextPayload(string text)
- {
- Text = text;
- }
-
- public override void Resolve()
- {
- // nothing to do
- }
-
- public override byte[] Encode()
- {
- return Encoding.UTF8.GetBytes(Text);
- }
-
- public override string ToString()
- {
- return $"{Type} - Text: {Text}";
- }
-
- protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
- {
- var text = new List();
-
- while (reader.BaseStream.Position < endOfStream)
- {
- if ((byte)reader.PeekChar() == START_BYTE)
- break;
-
- // not the most efficient, but the easiest
- text.Add(reader.ReadByte());
- }
-
- if (text.Count > 0)
- {
- // TODO: handling of the game's assorted special unicode characters
- Text = Encoding.UTF8.GetString(text.ToArray());
- }
- }
- }
-}
diff --git a/Dalamud/Game/Chat/SeStringHandling/SeString.cs b/Dalamud/Game/Chat/SeStringHandling/SeString.cs
deleted file mode 100644
index 156612214..000000000
--- a/Dalamud/Game/Chat/SeStringHandling/SeString.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.Chat.SeStringHandling.Payloads;
-
-namespace Dalamud.Game.Chat.SeStringHandling
-{
- ///
- /// This class represents a parsed SeString.
- ///
- public class SeString
- {
- public List Payloads { get; }
-
- public SeString(List payloads)
- {
- Payloads = payloads;
- }
-
- ///
- /// Helper function to get all raw text from a message as a single joined string
- ///
- ///
- /// All the raw text from the contained payloads, joined into a single string
- ///
- public string TextValue
- {
- get {
- var sb = new StringBuilder();
- foreach (var p in Payloads)
- {
- if (p.Type == PayloadType.RawText)
- {
- sb.Append(((TextPayload)p).Text);
- }
- }
-
- return sb.ToString();
- }
- }
-
- ///
- /// Parse an array of bytes to a SeString.
- ///
- ///
- ///
- public static SeString Parse(byte[] bytes)
- {
- var payloads = new List();
-
- using (var stream = new MemoryStream(bytes)) {
- using var reader = new BinaryReader(stream);
-
- while (stream.Position < bytes.Length)
- {
- var payload = Payload.Process(reader);
- if (payload != null)
- payloads.Add(payload);
- }
- }
-
- return new SeString(payloads);
- }
-
- ///
- /// Encode a parsed/created SeString to an array of bytes, to be used for injection.
- ///
- ///
- /// The bytes of the message.
- public byte[] Encode()
- {
- var messageBytes = new List();
- foreach (var p in Payloads)
- {
- messageBytes.AddRange(p.Encode());
- }
-
- return messageBytes.ToArray();
- }
- }
-}
diff --git a/Dalamud/Game/Chat/XivChatEntry.cs b/Dalamud/Game/Chat/XivChatEntry.cs
deleted file mode 100644
index 3f4075535..000000000
--- a/Dalamud/Game/Chat/XivChatEntry.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Chat {
- public sealed class XivChatEntry {
- public XivChatType Type { get; set; } = XivChatType.Debug;
-
- public uint SenderId { get; set; }
-
- public string Name { get; set; } = string.Empty;
-
- public byte[] MessageBytes { get; set; }
-
- public IntPtr Parameters { get; set; }
- }
-}
diff --git a/Dalamud/Game/Chat/XivChatType.cs b/Dalamud/Game/Chat/XivChatType.cs
deleted file mode 100644
index 4a457cf3f..000000000
--- a/Dalamud/Game/Chat/XivChatType.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Dalamud.Game.Chat {
- ///
- /// The FFXIV chat types as seen in the LogKind ex table.
- ///
- public enum XivChatType : ushort {
- None = 0,
- Debug = 1,
-
- [XivChatTypeInfo("Urgent", "urgent", 0xFF9400D3)]
- Urgent = 2,
-
- [XivChatTypeInfo("Notice", "notice", 0xFF9400D3)]
- Notice = 3,
-
- [XivChatTypeInfo("Say", "say", 0xFFFFFFFF)]
- Say = 10,
-
- [XivChatTypeInfo("Shout", "shout", 0xFFFF4500)]
- Shout = 11,
- TellOutgoing = 12,
-
- [XivChatTypeInfo("Tell", "tell", 0xFFFF69B4)]
- TellIncoming = 13,
-
- [XivChatTypeInfo("Party", "party", 0xFF1E90FF)]
- Party = 14,
-
- [XivChatTypeInfo("Alliance", "alliance", 0xFFFF4500)]
- Alliance = 15,
-
- [XivChatTypeInfo("Linkshell 1", "ls1", 0xFF228B22)]
- Ls1 = 16,
-
- [XivChatTypeInfo("Linkshell 2", "ls2", 0xFF228B22)]
- Ls2 = 17,
-
- [XivChatTypeInfo("Linkshell 3", "ls3", 0xFF228B22)]
- Ls3 = 18,
-
- [XivChatTypeInfo("Linkshell 4", "ls4", 0xFF228B22)]
- Ls4 = 19,
-
- [XivChatTypeInfo("Linkshell 5", "ls5", 0xFF228B22)]
- Ls5 = 20,
-
- [XivChatTypeInfo("Linkshell 6", "ls6", 0xFF228B22)]
- Ls6 = 21,
-
- [XivChatTypeInfo("Linkshell 7", "ls7", 0xFF228B22)]
- Ls7 = 22,
-
- [XivChatTypeInfo("Linkshell 8", "ls8", 0xFF228B22)]
- Ls8 = 23,
-
- [XivChatTypeInfo("Free Company", "fc", 0xFF00BFFF)]
- FreeCompany = 24,
-
- [XivChatTypeInfo("Novice Network", "nn", 0xFF8B4513)]
- NoviceNetwork = 27,
-
- [XivChatTypeInfo("Custom Emotes", "emote", 0xFF8B4513)]
- CustomEmote = 28,
- [XivChatTypeInfo("Standard Emotes", "emote", 0xFF8B4513)]
- StandardEmote = 29,
-
- [XivChatTypeInfo("Yell", "yell", 0xFFFFFF00)]
- Yell = 30,
-
- [XivChatTypeInfo("Party", "party", 0xFF1E90FF)]
- CrossParty = 32,
-
- [XivChatTypeInfo("PvP Team", "pvpt", 0xFFF4A460)]
- PvPTeam = 36,
-
- [XivChatTypeInfo("Crossworld Linkshell 1", "cw1", 0xFF1E90FF)]
- CrossLinkShell1 = 37,
-
- [XivChatTypeInfo("Echo", "echo", 0xFF808080)]
- Echo = 56,
- SystemError = 58,
- GatheringSystemMessage = 60,
- // not sure if this is used for anything else
- RetainerSale = 71,
-
- [XivChatTypeInfo("Crossworld Linkshell 2", "cw2", 0xFF1E90FF)]
- CrossLinkShell2 = 101,
-
- [XivChatTypeInfo("Crossworld Linkshell 3", "cw3", 0xFF1E90FF)]
- CrossLinkShell3 = 102,
-
- [XivChatTypeInfo("Crossworld Linkshell 4", "cw4", 0xFF1E90FF)]
- CrossLinkShell4 = 103,
-
- [XivChatTypeInfo("Crossworld Linkshell 5", "cw5", 0xFF1E90FF)]
- CrossLinkShell5 = 104,
-
- [XivChatTypeInfo("Crossworld Linkshell 6", "cw6", 0xFF1E90FF)]
- CrossLinkShell6 = 105,
-
- [XivChatTypeInfo("Crossworld Linkshell 7", "cw7", 0xFF1E90FF)]
- CrossLinkShell7 = 106,
-
- [XivChatTypeInfo("Crossworld Linkshell 8", "cw8", 0xFF1E90FF)]
- CrossLinkShell8 = 107
- }
-
- public static class XivChatTypeExtensions {
- public static XivChatTypeInfoAttribute GetDetails(this XivChatType p) {
- return p.GetAttribute();
- }
- }
-
- public class XivChatTypeInfoAttribute : Attribute {
- internal XivChatTypeInfoAttribute(string fancyName, string slug, uint defaultColor) {
- FancyName = fancyName;
- Slug = slug;
- DefaultColor = defaultColor;
- }
-
- public string FancyName { get; }
- public string Slug { get; }
- public uint DefaultColor { get; }
- }
-
- public static class EnumExtensions {
- public static TAttribute GetAttribute(this Enum value)
- where TAttribute : Attribute {
- var type = value.GetType();
- var name = Enum.GetName(type, value);
- return type.GetField(name) // I prefer to get attributes this way
- .GetCustomAttributes(false)
- .OfType()
- .SingleOrDefault();
- }
- }
-}
diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs
deleted file mode 100644
index 6a78f44d1..000000000
--- a/Dalamud/Game/ChatHandlers.cs
+++ /dev/null
@@ -1,215 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Dalamud.Game.Chat;
-using Dalamud.Game.Chat.SeStringHandling;
-using Dalamud.Game.Chat.SeStringHandling.Payloads;
-using Dalamud.Game.Internal.Libc;
-using Serilog;
-
-namespace Dalamud.Game {
- public class ChatHandlers {
- private static readonly Dictionary UnicodeToDiscordEmojiDict = new Dictionary {
- {"", "<:ffxive071:585847382210642069>"},
- {"", "<:ffxive083:585848592699490329>"}
- };
-
- private readonly Dalamud dalamud;
-
- private readonly Dictionary HandledChatTypeColors = new Dictionary {
- {XivChatType.CrossParty, Color.DodgerBlue},
- {XivChatType.Party, Color.DodgerBlue},
- {XivChatType.FreeCompany, Color.DeepSkyBlue},
- {XivChatType.CrossLinkShell1, Color.ForestGreen},
- {XivChatType.CrossLinkShell2, Color.ForestGreen},
- {XivChatType.CrossLinkShell3, Color.ForestGreen},
- {XivChatType.CrossLinkShell4, Color.ForestGreen},
- {XivChatType.CrossLinkShell5, Color.ForestGreen},
- {XivChatType.CrossLinkShell6, Color.ForestGreen},
- {XivChatType.CrossLinkShell7, Color.ForestGreen},
- {XivChatType.CrossLinkShell8, Color.ForestGreen},
- {XivChatType.Ls1, Color.ForestGreen},
- {XivChatType.Ls2, Color.ForestGreen},
- {XivChatType.Ls3, Color.ForestGreen},
- {XivChatType.Ls4, Color.ForestGreen},
- {XivChatType.Ls5, Color.ForestGreen},
- {XivChatType.Ls6, Color.ForestGreen},
- {XivChatType.Ls7, Color.ForestGreen},
- {XivChatType.Ls8, Color.ForestGreen},
- {XivChatType.TellIncoming, Color.HotPink},
- {XivChatType.PvPTeam, Color.SandyBrown},
- {XivChatType.Urgent, Color.DarkViolet},
- {XivChatType.NoviceNetwork, Color.SaddleBrown},
- {XivChatType.Echo, Color.Gray}
- };
-
- private readonly Regex rmtRegex =
- new Regex(
- @"4KGOLD|We have sufficient stock|VPK\.OM|Gil for free|www\.so9\.com|Fast & Convenient|Cheap & Safety Guarantee|【Code|A O A U E|igfans|4KGOLD\.COM|Cheapest Gil with|pvp and bank on google|Selling Cheap GIL|ff14mogstation\.com|Cheap Gil 1000k|gilsforyou|server 1000K =|gils_selling|E A S Y\.C O M|bonus code|mins delivery guarantee|Sell cheap NA",
- RegexOptions.Compiled);
-
- private readonly Regex urlRegex =
- new Regex(@"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?",
- RegexOptions.Compiled);
-
- private readonly Dictionary retainerSaleRegexes = new Dictionary() {
- {
- 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 bool hasSeenLoadingMsg;
-
- public ChatHandlers(Dalamud dalamud) {
- this.dalamud = dalamud;
-
- dalamud.Framework.Gui.Chat.OnChatMessageRaw += OnChatMessage;
- }
-
-
- public string LastLink { get; private set; }
-
- private void OnChatMessage(XivChatType type, uint senderId, ref StdString sender,
- ref StdString message, ref bool isHandled) {
-
- if (type == XivChatType.Notice && !this.hasSeenLoadingMsg) {
- var assemblyVersion = Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
-
- this.dalamud.Framework.Gui.Chat.Print($"XIVLauncher in-game addon v{assemblyVersion} loaded.");
-
- foreach (var plugin in this.dalamud.PluginManager.Plugins) {
- this.dalamud.Framework.Gui.Chat.Print($" -> {plugin.Plugin.Name} v{plugin.GetType().Assembly.GetName().Version} loaded.");
- }
-
- this.hasSeenLoadingMsg = true;
-
- if (string.IsNullOrEmpty(this.dalamud.Configuration.LastVersion) || !assemblyVersion.StartsWith(this.dalamud.Configuration.LastVersion)) {
- this.dalamud.Framework.Gui.Chat.PrintChat(new XivChatEntry {
- MessageBytes = Encoding.UTF8.GetBytes("The In-Game addon has been updated or was reinstalled successfully! Please check the discord for a full changelog."),
- Type = XivChatType.Urgent
- });
-
- this.dalamud.Configuration.LastVersion = assemblyVersion;
- this.dalamud.Configuration.Save(this.dalamud.StartInfo.ConfigurationPath);
- }
- }
-
-#if !DEBUG && false
- if (!this.hasSeenLoadingMsg)
- return;
-#endif
-
- var matched = this.rmtRegex.IsMatch(message.Value);
- if (matched) {
- // This seems to be a RMT ad - let's not show it
- Log.Debug("Handled RMT ad");
- isHandled = true;
- return;
- }
-
- var messageVal = message.Value;
- var senderVal = sender.Value;
-
- if (this.dalamud.Configuration.BadWords != null &&
- this.dalamud.Configuration.BadWords.Any(x => messageVal.Contains(x))) {
- // This seems to be in the user block list - let's not show it
- Log.Debug("Blocklist triggered");
- isHandled = true;
- return;
- }
-
- if (type == XivChatType.RetainerSale)
- {
- foreach (var regex in retainerSaleRegexes[dalamud.StartInfo.Language])
- {
- var matchInfo = regex.Match(message.Value);
-
- // 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 =
- SeString.Parse(message.RawData).Payloads.First(x => x.Type == PayloadType.Item) as ItemPayload;
-
- if (itemLink == null) {
- Log.Error("itemLink was null. Msg: {0}", BitConverter.ToString(message.RawData));
- break;
- }
-
- Log.Debug($"Probable retainer sale: {message}, decoded item {itemLink.ItemId}, 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(",", "").Replace(".", ""), out var itemValue))
- continue;
-
- Task.Run(() => this.dalamud.BotManager.ProcessRetainerSale(itemLink.ItemId, itemValue, itemLink.IsHQ));
- break;
- }
- }
-
- var messageCopy = message;
- var senderCopy = sender;
- Task.Run(() => this.dalamud.BotManager.ProcessChatMessage(type, messageCopy, senderCopy));
-
- // Handle all of this with SeString some day
- if ((this.HandledChatTypeColors.ContainsKey(type) || type == XivChatType.Say || type == XivChatType.Shout ||
- type == XivChatType.Alliance || type == XivChatType.TellOutgoing || type == XivChatType.Yell) && !message.Value.Contains((char)0x02)) {
- var italicsStart = message.Value.IndexOf("*");
- var italicsEnd = message.Value.IndexOf("*", italicsStart + 1);
-
- var messageString = message.Value;
-
- while (italicsEnd != -1) {
- var it = MakeItalics(
- messageString.Substring(italicsStart, italicsEnd - italicsStart + 1).Replace("*", ""));
- messageString = messageString.Remove(italicsStart, italicsEnd - italicsStart + 1);
- messageString = messageString.Insert(italicsStart, it);
- italicsStart = messageString.IndexOf("*");
- italicsEnd = messageString.IndexOf("*", italicsStart + 1);
- }
-
- message.RawData = Encoding.UTF8.GetBytes(messageString);
- }
-
-
- var linkMatch = this.urlRegex.Match(message.Value);
- if (linkMatch.Value.Length > 0)
- LastLink = linkMatch.Value;
- }
-
- private static string MakeItalics(string text) {
- return Encoding.UTF8.GetString(new byte[] {0x02, 0x1A, 0x02, 0x02, 0x03}) + text +
- Encoding.UTF8.GetString(new byte[] {0x02, 0x1A, 0x02, 0x01, 0x03});
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/ActorTable.cs b/Dalamud/Game/ClientState/Actors/ActorTable.cs
deleted file mode 100644
index 586404fd1..000000000
--- a/Dalamud/Game/ClientState/Actors/ActorTable.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-using System.Collections;
-using System.Runtime.InteropServices;
-using Dalamud.Game.ClientState.Actors.Types;
-using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
-using Serilog;
-
-namespace Dalamud.Game.ClientState.Actors {
- ///
- /// This collection represents the currently spawned FFXIV actors.
- ///
- public class ActorTable : ICollection {
- private ClientStateAddressResolver Address { get; }
-
- ///
- /// Set up the actor table collection.
- ///
- /// Client state address resolver.
- public ActorTable(ClientStateAddressResolver addressResolver) {
- Address = addressResolver;
-
- Log.Verbose("Actor table address {ActorTable}", Address.ActorTable);
- }
-
- ///
- /// Get an actor at the specified spawn index.
- ///
- /// Spawn index.
- /// at the specified spawn index.
- public Actor this[int index] {
- get {
- if (index > Length)
- return null;
-
- //Log.Information("Trying to get actor at {0}", index);
- var tblIndex = Address.ActorTable + 8 + index * 8;
-
- var offset = Marshal.ReadIntPtr(tblIndex);
-
- //Log.Information("Actor at {0}", offset.ToString());
-
- if (offset == IntPtr.Zero)
- return null;
-
- try {
- var actorStruct = Marshal.PtrToStructure(offset);
-
- //Log.Debug("ActorTable[{0}]: {1} - {2} - {3}", index, tblIndex.ToString("X"), offset.ToString("X"),
- // actorStruct.ObjectKind.ToString());
-
- switch (actorStruct.ObjectKind)
- {
- case ObjectKind.Player: return new PlayerCharacter(actorStruct);
- case ObjectKind.BattleNpc: return new BattleNpc(actorStruct);
- default: return new Actor(actorStruct);
- }
- } catch (AccessViolationException) {
- return null;
- }
- }
- }
-
- private class ActorTableEnumerator : IEnumerator {
- private readonly ActorTable table;
-
- private int currentIndex;
-
- public ActorTableEnumerator(ActorTable table) {
- this.table = table;
- }
-
- public bool MoveNext() {
- this.currentIndex++;
- return this.currentIndex != this.table.Length;
- }
-
- public void Reset() {
- this.currentIndex = 0;
- }
-
- public object Current => this.table[this.currentIndex];
- }
-
- public IEnumerator GetEnumerator() {
- return new ActorTableEnumerator(this);
- }
-
- ///
- /// The amount of currently spawned actors.
- ///
- public int Length => Marshal.ReadInt32(Address.ActorTable);
-
- int ICollection.Count => Length;
-
- bool ICollection.IsSynchronized => false;
-
- object ICollection.SyncRoot => this;
-
- void ICollection.CopyTo(Array array, int index) {
- for (var i = 0; i < Length; i++) {
- array.SetValue(this[i], index);
- index++;
- }
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/ObjectKind.cs b/Dalamud/Game/ClientState/Actors/ObjectKind.cs
deleted file mode 100644
index 48af1fdfb..000000000
--- a/Dalamud/Game/ClientState/Actors/ObjectKind.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-namespace Dalamud.Game.ClientState.Actors {
- ///
- /// Enum describing possible entity kinds.
- ///
- public enum ObjectKind : byte {
- ///
- /// Invalid actor.
- ///
- None = 0x00,
-
- ///
- /// Objects representing player characters.
- ///
- Player = 0x01,
-
- ///
- /// Objects representing battle NPCs.
- ///
- BattleNpc = 0x02,
-
- ///
- /// Objects representing event NPCs.
- ///
- EventNpc = 0x03,
-
- ///
- /// Objects representing treasures.
- ///
- Treasure = 0x04,
-
- ///
- /// Objects representing aetherytes.
- ///
- Aetheryte = 0x05,
-
- ///
- /// Objects representing gathering points.
- ///
- GatheringPoint = 0x06,
-
- ///
- /// Objects representing event objects.
- ///
- EventObj = 0x07,
-
- ///
- /// Objects representing mounts.
- ///
- MountType = 0x08,
-
- ///
- /// Objects representing minions.
- ///
- Companion = 0x09, // Minion
-
- ///
- /// Objects representing retainers.
- ///
- Retainer = 0x0A,
- Area = 0x0B,
-
- ///
- /// Objects representing housing objects.
- ///
- Housing = 0x0C,
- Cutscene = 0x0D,
- CardStand = 0x0E
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Position3.cs b/Dalamud/Game/ClientState/Actors/Position3.cs
deleted file mode 100644
index 381d1a8de..000000000
--- a/Dalamud/Game/ClientState/Actors/Position3.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.ClientState.Actors {
- [StructLayout(LayoutKind.Sequential)]
- public struct Position3 {
- public float X;
- public float Z;
- public float Y;
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Resolvers/ClassJob.cs b/Dalamud/Game/ClientState/Actors/Resolvers/ClassJob.cs
deleted file mode 100644
index 82e4b1c42..000000000
--- a/Dalamud/Game/ClientState/Actors/Resolvers/ClassJob.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Actors.Resolvers
-{
- ///
- /// This object represents a class or job.
- ///
- public class ClassJob {
- ///
- /// ID of the ClassJob.
- ///
- public readonly int Id;
-
- ///
- /// Name of the ClassJob.
- ///
- public string Name => (string) XivApi.GetClassJob(this.Id).GetAwaiter().GetResult()["Name"];
-
- ///
- /// Set up the ClassJob resolver with the provided ID.
- ///
- /// The ID of the world.
- public ClassJob(byte id) {
- this.Id = id;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Resolvers/World.cs b/Dalamud/Game/ClientState/Actors/Resolvers/World.cs
deleted file mode 100644
index 53d23cdec..000000000
--- a/Dalamud/Game/ClientState/Actors/Resolvers/World.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Actors.Resolvers
-{
- ///
- /// This object represents a world a character can reside on.
- ///
- public class World {
- ///
- /// ID of the world.
- ///
- public readonly int Id;
-
- ///
- /// Name of the world.
- ///
- public string Name => (string) XivApi.GetWorld(this.Id).GetAwaiter().GetResult()["Name"];
-
- ///
- /// Set up the world resolver with the provided ID.
- ///
- /// The ID of the world.
- public World(byte id) {
- this.Id = id;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/Actor.cs b/Dalamud/Game/ClientState/Actors/Types/Actor.cs
deleted file mode 100644
index ae327211f..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/Actor.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-namespace Dalamud.Game.ClientState.Actors.Types {
- ///
- /// This class represents a basic FFXIV actor.
- ///
- public class Actor {
- ///
- /// The memory representation of the base actor.
- ///
- protected Structs.Actor actorStruct;
-
- ///
- /// Initialize a representation of a basic FFXIV actor.
- ///
- /// The memory representation of the base actor.
- public Actor(Structs.Actor actorStruct) {
- this.actorStruct = actorStruct;
- }
-
- ///
- /// Position of this .
- ///
- public Position3 Position => this.actorStruct.Position;
-
- ///
- /// Displayname of this Actor.
- ///
- public string Name => this.actorStruct.Name;
-
- ///
- /// Actor ID of this .
- ///
- public int ActorId => this.actorStruct.ActorId;
-
- ///
- /// Entity kind of this actor. See the ObjectKind enum for
- /// possible values.
- ///
- public ObjectKind ObjectKind => this.actorStruct.ObjectKind;
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/Chara.cs b/Dalamud/Game/ClientState/Actors/Types/Chara.cs
deleted file mode 100644
index 60ca0549c..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/Chara.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Dalamud.Game.ClientState.Actors.Resolvers;
-
-namespace Dalamud.Game.ClientState.Actors.Types {
- ///
- /// This class represents the base for non-static entities.
- ///
- public class Chara : Actor {
- ///
- /// Set up a new Chara with the provided memory representation.
- ///
- /// The memory representation of the base actor.
- public Chara(Structs.Actor actorStruct) : base(actorStruct) { }
-
- ///
- /// The level of this Chara.
- ///
- public byte Level => this.actorStruct.Level;
-
- ///
- /// The ClassJob of this Chara.
- ///
- public ClassJob ClassJob => new ClassJob(this.actorStruct.ClassJob);
-
- ///
- /// The current HP of this Chara.
- ///
- public int CurrentHp => this.actorStruct.CurrentHp;
-
- ///
- /// The maximum HP of this Chara.
- ///
- public int MaxHp => this.actorStruct.MaxHp;
-
- ///
- /// The current MP of this Chara.
- ///
- public int CurrentMp => this.actorStruct.CurrentMp;
-
- ///
- /// The maximum MP of this Chara.
- ///
- public int MaxMp => this.actorStruct.MaxMp;
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
deleted file mode 100644
index ea8bf9fcc..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
- ///
- /// This class represents a battle NPC.
- ///
- public class BattleNpc : Npc {
- ///
- /// Set up a new BattleNpc with the provided memory representation.
- ///
- /// The memory representation of the base actor.
- public BattleNpc(Structs.Actor actorStruct) : base(actorStruct) { }
-
- ///
- /// The BattleNpc of this BattleNpc.
- ///
- public BattleNpcSubKind BattleNpcKind => (BattleNpcSubKind) this.actorStruct.SubKind;
-
- ///
- /// The ID of this BattleNpc's owner.
- ///
- public int OwnerId => this.actorStruct.OwnerId;
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpcSubKind.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpcSubKind.cs
deleted file mode 100644
index f274a0af1..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpcSubKind.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
- ///
- /// Enum describing possible BattleNpc kinds.
- ///
- public enum BattleNpcSubKind : byte {
- ///
- /// Invalid BattleNpc.
- ///
- None = 0,
-
- ///
- /// BattleNpc representing a Pet.
- ///
- Pet = 2,
-
- ///
- /// BattleNpc representing a standard enemy.
- ///
- Enemy = 5
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
deleted file mode 100644
index ef0ce3b7c..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
- ///
- /// This class represents a NPC.
- ///
- public class Npc : Chara {
- ///
- /// Set up a new NPC with the provided memory representation.
- ///
- /// The memory representation of the base actor.
- public Npc(Structs.Actor actorStruct) : base(actorStruct) { }
-
- ///
- /// The data ID of the NPC linking to their respective game data.
- ///
- public int DataId => this.actorStruct.DataId;
- }
-}
diff --git a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs b/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
deleted file mode 100644
index ed09601de..000000000
--- a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using Dalamud.Game.ClientState.Actors.Resolvers;
-
-namespace Dalamud.Game.ClientState.Actors.Types {
- ///
- /// This class represents a player character.
- ///
- public class PlayerCharacter : Chara {
- ///
- /// Set up a new player character with the provided memory representation.
- ///
- /// The memory representation of the base actor.
- public PlayerCharacter(Structs.Actor actorStruct) : base(actorStruct) { }
-
- ///
- /// The current world of the character.
- ///
- public World CurrentWorld => new World(this.actorStruct.CurrentWorld);
-
- ///
- /// The home world of the character.
- ///
- public World HomeWorld => new World(this.actorStruct.HomeWorld);
- }
-}
diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs
deleted file mode 100644
index ade048517..000000000
--- a/Dalamud/Game/ClientState/ClientState.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.ClientState.Actors;
-using Dalamud.Game.ClientState.Actors.Types;
-using Dalamud.Game.Internal;
-using Serilog;
-
-namespace Dalamud.Game.ClientState
-{
- ///
- /// This class represents the state of the game client at the time of access.
- ///
- public class ClientState : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
-
- private ClientStateAddressResolver Address { get; }
-
- public readonly ClientLanguage ClientLanguage;
-
- ///
- /// The table of all present actors.
- ///
- public readonly ActorTable Actors;
-
- ///
- /// The local player character, if one is present.
- ///
- //public PlayerCharacter LocalPlayer { get; private set; }
- public PlayerCharacter LocalPlayer {
- get {
- var actor = this.Actors[0];
-
- if (actor is PlayerCharacter pc)
- return pc;
-
- return null;
- }
- }
- //public PlayerCharacter LocalPlayer => null;
-
- ///
- /// The content ID of the local character.
- ///
- public ulong LocalContentId => (ulong) Marshal.ReadInt64(Address.LocalContentId);
-
- ///
- /// The class facilitating Job Gauge data access
- ///
- public JobGauges JobGauges;
-
- ///
- /// Set up client state access.
- ///
- /// Dalamud instance
- /// /// StartInfo of the current Dalamud launch
- /// Sig scanner
- /// Game process module
- public ClientState(Dalamud dalamud, DalamudStartInfo startInfo, SigScanner scanner, ProcessModule targetModule) {
- Address = new ClientStateAddressResolver();
- Address.Setup(scanner);
-
- Log.Verbose("===== C L I E N T S T A T E =====");
-
- this.ClientLanguage = startInfo.Language;
-
- this.Actors = new ActorTable(Address);
-
- this.JobGauges = new JobGauges(Address);
-
- dalamud.Framework.OnUpdateEvent += FrameworkOnOnUpdateEvent;
- }
-
- private void FrameworkOnOnUpdateEvent(Framework framework) {
- //LocalPlayer = (PlayerCharacter) this.Actors[0];
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs b/Dalamud/Game/ClientState/ClientStateAddressResolver.cs
deleted file mode 100644
index ff2dae4f3..000000000
--- a/Dalamud/Game/ClientState/ClientStateAddressResolver.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.Internal;
-
-namespace Dalamud.Game.ClientState
-{
- public sealed class ClientStateAddressResolver : BaseAddressResolver {
- public IntPtr ActorTable { get; private set; }
- public IntPtr LocalContentId { get; private set; }
- public IntPtr JobGaugeData { get; set; }
-
- protected override void Setup64Bit(SigScanner sig) {
- ActorTable = sig.Module.BaseAddress + 0x1C62218;
- LocalContentId = sig.Module.BaseAddress + 0x1C2E000;
- JobGaugeData = sig.Module.BaseAddress + 0x1C5E4A0;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/JobGauge.cs b/Dalamud/Game/ClientState/JobGauge.cs
deleted file mode 100644
index 916921af7..000000000
--- a/Dalamud/Game/ClientState/JobGauge.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Runtime.InteropServices;
-using Serilog;
-
-namespace Dalamud.Game.ClientState {
- public class JobGauges {
- private ClientStateAddressResolver Address { get; }
-
- public JobGauges(ClientStateAddressResolver addressResolver) {
- Address = addressResolver;
-
- Log.Verbose("JobGaugeData address {JobGaugeData}", Address.ActorTable);
- }
-
- // Should only be called with the gauge types in
- // ClientState.Structs.JobGauge
- public T Get() {
- return Marshal.PtrToStructure(Address.JobGaugeData);
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/Actor.cs b/Dalamud/Game/ClientState/Structs/Actor.cs
deleted file mode 100644
index f06f19c3d..000000000
--- a/Dalamud/Game/ClientState/Structs/Actor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.ClientState.Actors;
-
-namespace Dalamud.Game.ClientState.Structs
-{
- ///
- /// Native memory representation of a FFXIV actor.
- ///
- [StructLayout(LayoutKind.Explicit)]
- public struct Actor {
- [FieldOffset(0x30)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)] public string Name;
- [FieldOffset(116)] public int ActorId;
- [FieldOffset(128)] public int DataId;
- [FieldOffset(132)] public int OwnerId;
- [FieldOffset(140)] public ObjectKind ObjectKind;
- [FieldOffset(141)] public byte SubKind;
- [FieldOffset(160)] public Position3 Position;
- [FieldOffset(6276)] public byte CurrentWorld;
- [FieldOffset(6278)] public byte HomeWorld;
- [FieldOffset(6328)] public int CurrentHp;
- [FieldOffset(6332)] public int MaxHp;
- [FieldOffset(6336)] public int CurrentMp;
- [FieldOffset(6340)] public int MaxMp;
- [FieldOffset(6358)] public byte ClassJob;
- [FieldOffset(6360)] public byte Level;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/ASTGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/ASTGauge.cs
deleted file mode 100644
index e6eca6548..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/ASTGauge.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct ASTGauge {
- [FieldOffset(4)] private CardType Card;
- [FieldOffset(5)] private unsafe fixed byte Seals[3];
-
- public CardType DrawnCard() {
- return Card;
- }
-
- public unsafe bool ContainsSeal(SealType seal) {
- if (Seals[0] == (byte)seal) return true;
- if (Seals[1] == (byte)seal) return true;
- if (Seals[2] == (byte)seal) return true;
- return false;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/BLMGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/BLMGauge.cs
deleted file mode 100644
index 8bbb74610..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/BLMGauge.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct BLMGauge {
- [FieldOffset(0)] public short TimeUntilNextPolyglot; //eno timer (ms)
- [FieldOffset(2)] public short ElementTimeRemaining; //ui/af timer
- [FieldOffset(4)] private byte ElementStance; //ui/af
- [FieldOffset(5)] public byte NumUmbralHearts; //number of umbral hearts
- [FieldOffset(6)] public byte NumPolyglotStacks; //number of polyglot stacks
- [FieldOffset(7)] private byte EnoState; //eno active?
-
- public bool InUmbralIce() {
- return ElementStance > 4;
- }
-
- public bool InAstralFire() {
- return ElementStance > 0 && ElementStance < 4;
- }
-
- public bool IsEnoActive() {
- return EnoState > 0;
- }
-
- }
-
-
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
deleted file mode 100644
index 11eb1f5ad..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct BRDGauge {
- [FieldOffset(0)] public short SongTimer;
- [FieldOffset(2)] public byte NumSongStacks;
- [FieldOffset(4)] public CurrentSong ActiveSong;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/DNCGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/DNCGauge.cs
deleted file mode 100644
index b77e6f0e4..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/DNCGauge.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public unsafe struct DNCGauge {
- [FieldOffset(0)] public byte NumFeathers;
- [FieldOffset(1)] public byte Esprit;
- [FieldOffset(2)] private fixed byte StepOrder[4];
- [FieldOffset(6)] public byte NumCompleteSteps;
-
- public bool IsDancing() {
- return StepOrder[0] != 0;
- }
-
- public ulong NextStep() {
- return (ulong)(15999 + StepOrder[NumCompleteSteps] - 1);
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/DRGGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/DRGGauge.cs
deleted file mode 100644
index fa71eb541..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/DRGGauge.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct DRGGauge {
- [FieldOffset(0)] public short BOTDTimer;
- [FieldOffset(2)] public BOTDState BOTDState;
- [FieldOffset(3)] public byte EyeCount;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/DRKGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/DRKGauge.cs
deleted file mode 100644
index 5c711cf57..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/DRKGauge.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
- [StructLayout(LayoutKind.Explicit)]
- public struct DRKGauge {
- [FieldOffset(0)] public byte Blood;
- [FieldOffset(2)] public short DarksideTimeRemaining;
- [FieldOffset(4)] private byte DarkArtsState;
- [FieldOffset(6)] public short ShadowTimeRemaining;
-
- public bool HasDarkArts() {
- return DarkArtsState > 0;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/GNBGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/GNBGauge.cs
deleted file mode 100644
index 969adda1d..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/GNBGauge.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct GNBGauge {
- [FieldOffset(0)] public byte NumAmmo;
- [FieldOffset(2)] public short MaxTimerDuration;
- [FieldOffset(4)] public byte AmmoComboStepNumber;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/JobEnums.cs b/Dalamud/Game/ClientState/Structs/JobGauge/JobEnums.cs
deleted file mode 100644
index 69762e295..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/JobEnums.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
- public enum SealType : byte {
- NONE = 0,
- SUN,
- MOON,
- CELESTIAL
- }
-
- public enum CardType : byte {
- NONE = 0,
- BALANCE,
- BOLE,
- ARROW,
- SPEAR,
- EWER,
- SPIRE,
- LORD = 0x70,
- LADY = 0x80
- }
-
- public enum SummonPet : byte {
- NONE = 0,
- IFRIT = 3,
- TITAN,
- GARUDA
- }
-
- public enum PetGlam : byte {
- NONE = 0,
- EMERALD,
- TOPAZ,
- RUBY
- }
-
- [Flags]
- public enum Sen : byte {
- NONE = 0,
- SETSU = 1 << 0,
- GETSU = 1 << 1,
- KA = 1 << 2
- }
-
- public enum BOTDState : byte {
- NONE = 0,
- BOTD,
- LOTD
- }
-
- public enum CurrentSong : byte {
- MAGE = 5,
- ARMY = 0xA,
- WANDERER = 0xF
- }
-
- public enum DismissedFairy : byte {
- EOS = 6,
- SELENE
- }
-
- public enum Mudras : byte {
- TEN = 1,
- CHI = 2,
- JIN = 3
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/MCHGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/MCHGauge.cs
deleted file mode 100644
index e606cb751..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/MCHGauge.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct MCHGauge{
-
- [FieldOffset(0)] public short OverheatTimeRemaining;
- [FieldOffset(2)] public short RobotTimeRemaining;
- [FieldOffset(4)] public byte Heat;
- [FieldOffset(5)] public byte Battery;
- [FieldOffset(6)] public byte LastRobotBatteryPower;
- [FieldOffset(7)] private byte TimerActive;
-
- public bool IsOverheated() {
- return (TimerActive & 1) != 0;
- }
- public bool IsRobotActive() {
- return (TimerActive & 2) != 0;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/MNKGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/MNKGauge.cs
deleted file mode 100644
index 0d40ee780..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/MNKGauge.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct MNKGauge {
- [FieldOffset(0)] public byte GLTimer;
- [FieldOffset(2)] public byte NumGLStacks;
- [FieldOffset(3)] public byte NumChakra;
- [FieldOffset(4)] private byte GLTimerFreezeState;
-
- public bool IsGLTimerFroze() {
- return GLTimerFreezeState > 0;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/NINGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/NINGauge.cs
deleted file mode 100644
index 672e27b81..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/NINGauge.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct NINGauge {
- [FieldOffset(0)] public int HutonTimeLeft;
- [FieldOffset(4)] public byte TCJMudrasUsed; //some sort of mask
- [FieldOffset(5)] public byte Ninki;
- [FieldOffset(6)] public byte NumHutonManualCasts; //wtf
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/PLDGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/PLDGauge.cs
deleted file mode 100644
index 30b7f65e3..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/PLDGauge.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct PLDGauge {
- [FieldOffset(0)] public byte GaugeAmount;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/RDMGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/RDMGauge.cs
deleted file mode 100644
index b0a2fa0c6..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/RDMGauge.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct RDMGauge {
- [FieldOffset(0)] public byte WhiteGauge;
- [FieldOffset(1)] public byte BlackGauge;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/SAMGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/SAMGauge.cs
deleted file mode 100644
index 6c10ba477..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/SAMGauge.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct SAMGauge {
-
- [FieldOffset(3)] public byte Kenki;
- [FieldOffset(4)] public Sen Sen;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/SCHGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/SCHGauge.cs
deleted file mode 100644
index 5d742ee0e..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/SCHGauge.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct SCHGauge {
- [FieldOffset(2)] public byte NumAetherflowStacks;
- [FieldOffset(3)] public byte FairyGaugeAmount;
- [FieldOffset(4)] public short SeraphTimer;
- [FieldOffset(6)] public DismissedFairy DismissedFairy;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/SMNGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/SMNGauge.cs
deleted file mode 100644
index 1742f4d97..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/SMNGauge.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct SMNGauge {
-
- //Unfinished
- [FieldOffset(0)] public short TimerRemaining;
- [FieldOffset(2)] public SummonPet ReturnSummon;
- [FieldOffset(3)] public PetGlam ReturnSummonGlam;
- [FieldOffset(4)] public byte NumStacks;
-
- public bool IsPhoenixReady() {
- return (NumStacks & 0x10) > 0;
- }
-
- public bool IsBahamutReady() {
- return (NumStacks & 8) > 0;
- }
-
- public bool HasAetherflowStacks() {
- return (NumStacks & 3) > 0;
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/WARGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/WARGauge.cs
deleted file mode 100644
index ed1ecf364..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/WARGauge.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct WARGauge {
- [FieldOffset(0)] public byte BeastGaugeAmount;
- }
-}
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/WHMGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/WHMGauge.cs
deleted file mode 100644
index a5ad15906..000000000
--- a/Dalamud/Game/ClientState/Structs/JobGauge/WHMGauge.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.ClientState.Structs.JobGauge {
-
- [StructLayout(LayoutKind.Explicit)]
- public struct WHMGauge {
- [FieldOffset(2)] public short LilyTimer; //Counts to 30k = 30s
- [FieldOffset(4)] public byte NumLilies;
- [FieldOffset(5)] public byte NumBloodLily;
- }
-}
diff --git a/Dalamud/Game/Command/CommandInfo.cs b/Dalamud/Game/Command/CommandInfo.cs
deleted file mode 100644
index 3905a843c..000000000
--- a/Dalamud/Game/Command/CommandInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Dalamud.Game.Command {
- ///
- /// This class describes a registered command.
- ///
- public sealed class CommandInfo {
- ///
- /// The function to be executed when the command is dispatched.
- ///
- /// The command itself.
- /// The arguments supplied to the command, ready for parsing.
- public delegate void HandlerDelegate(string command, string arguments);
-
- ///
- /// A which will be called when the command is dispatched.
- ///
- public HandlerDelegate Handler { get; }
-
- ///
- /// The help message for this command.
- ///
- public string HelpMessage { get; set; } = string.Empty;
-
- ///
- /// If this command should be shown in the help output.
- ///
- public bool ShowInHelp { get; set; } = true;
-
- ///
- /// Create a new CommandInfo with the provided handler.
- ///
- ///
- public CommandInfo(HandlerDelegate handler) {
- Handler = handler;
- }
- }
-}
diff --git a/Dalamud/Game/Command/CommandManager.cs b/Dalamud/Game/Command/CommandManager.cs
deleted file mode 100644
index aad85dfec..000000000
--- a/Dalamud/Game/Command/CommandManager.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Text.RegularExpressions;
-using Dalamud.Game.Chat;
-using Dalamud.Game.Internal.Libc;
-using Serilog;
-
-namespace Dalamud.Game.Command {
- ///
- /// This class manages registered in-game slash commands.
- ///
- public sealed class CommandManager {
- private readonly Dalamud dalamud;
-
- private readonly Dictionary commandMap = new Dictionary();
-
- ///
- /// Read-only list of all registered commands.
- ///
- public ReadOnlyDictionary Commands =>
- new ReadOnlyDictionary(this.commandMap);
-
- private readonly Regex commandRegexEn =
- new Regex(@"^The command (?.+) does not exist\.$", RegexOptions.Compiled);
-
- private readonly Regex commandRegexJp = new Regex(@"^そのコマンドはありません。: (?.+)$", RegexOptions.Compiled);
-
- private readonly Regex commandRegexDe =
- new Regex(@"^„(?.+)“ existiert nicht als Textkommando\.$", RegexOptions.Compiled);
-
- private readonly Regex commandRegexFr =
- new Regex(@"^La commande texte “(?.+)” n'existe pas\.$",
- RegexOptions.Compiled);
-
- private readonly Regex currentLangCommandRegex;
-
-
- public CommandManager(Dalamud dalamud, ClientLanguage language) {
- this.dalamud = dalamud;
-
- switch (language) {
- case ClientLanguage.Japanese:
- this.currentLangCommandRegex = this.commandRegexJp;
- break;
- case ClientLanguage.English:
- this.currentLangCommandRegex = this.commandRegexEn;
- break;
- case ClientLanguage.German:
- this.currentLangCommandRegex = this.commandRegexDe;
- break;
- case ClientLanguage.French:
- this.currentLangCommandRegex = this.commandRegexFr;
- break;
- }
-
- dalamud.Framework.Gui.Chat.OnChatMessageRaw += OnChatMessage;
- }
-
- private void OnChatMessage(XivChatType type, uint senderId, ref StdString sender,
- ref StdString message, ref bool isHandled) {
- if (type == XivChatType.GatheringSystemMessage && senderId == 0) {
- var cmdMatch = this.currentLangCommandRegex.Match(message.Value).Groups["command"];
- if (cmdMatch.Success) {
- // Yes, it's a chat command.
- var command = cmdMatch.Value;
- if (ProcessCommand(command)) isHandled = true;
- }
- }
- }
-
- private bool ProcessCommand(string content) {
- string command;
- string argument;
-
- var speratorPosition = content.IndexOf(' ');
- if (speratorPosition == -1 || speratorPosition + 1 >= content.Length) {
- // If no space was found or ends with the space. Process them as a no argument
- command = content;
- argument = string.Empty;
- } else {
- // e.g.)
- // /testcommand arg1
- // => Total of 17 chars
- // => command: 0-12 (12 chars)
- // => argument: 13-17 (4 chars)
- // => content.IndexOf(' ') == 12
- command = content.Substring(0, speratorPosition);
-
- var argStart = speratorPosition + 1;
- argument = content.Substring(argStart, content.Length - argStart);
- }
-
- if (!this.commandMap.TryGetValue(command, out var handler)) // Commad was not found.
- return false;
-
- DispatchCommand(command, argument, handler);
- return true;
- }
-
- ///
- /// Dispatch the handling of a command.
- ///
- /// The command to dispatch.
- /// The provided arguments.
- /// A object describing this command.
- public void DispatchCommand(string command, string argument, CommandInfo info) {
- try {
- info.Handler(command, argument);
- } catch (Exception ex) {
- 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.
- ///
- /// The command to register.
- /// A object describing the command.
- /// If adding was successful.
- public bool AddHandler(string command, CommandInfo info) {
- if (info == null) throw new ArgumentNullException(nameof(info), "Command handler is null.");
-
- try {
- this.commandMap.Add(command, info);
- return true;
- } catch (ArgumentException) {
- Log.Error("Command {CommandName} is already registered.", command);
- return false;
- }
- }
-
- ///
- /// Remove a command from the command handlers.
- ///
- /// The command to remove.
- /// If the removal was successful.
- public bool RemoveHandler(string command) {
- return this.commandMap.Remove(command);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/AntiDebug.cs b/Dalamud/Game/Internal/AntiDebug.cs
deleted file mode 100644
index 6ce25488b..000000000
--- a/Dalamud/Game/Internal/AntiDebug.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Hooking;
-using EasyHook;
-using Serilog;
-
-namespace Dalamud.Game.Internal
-{
- class AntiDebug : IDisposable
- {
- [UnmanagedFunctionPointer(CallingConvention.Winapi)]
- private delegate bool IsDebuggerPresentDelegate();
-
- private Hook debuggerPresentHook;
-
- public AntiDebug() {
- this.debuggerPresentHook = new Hook(LocalHook.GetProcAddress("Kernel32", "IsDebuggerPresent"),
- new IsDebuggerPresentDelegate(IsDebuggerPresentDetour));
-
- Log.Verbose("IsDebuggerPresent address {IsDebuggerPresent}", this.debuggerPresentHook.Address);
- }
-
- public void Enable() {
- this.debuggerPresentHook.Enable();
- }
-
- public void Dispose() {
- this.debuggerPresentHook.Disable();
- }
-
- private bool IsDebuggerPresentDetour() {
- return false;
- }
- }
-}
diff --git a/Dalamud/Game/Internal/BaseAddressResolver.cs b/Dalamud/Game/Internal/BaseAddressResolver.cs
deleted file mode 100644
index 8cbb83be5..000000000
--- a/Dalamud/Game/Internal/BaseAddressResolver.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.Internal {
- public abstract class BaseAddressResolver {
- protected bool IsResolved { get; set; }
-
- public void Setup(SigScanner scanner) {
- // Because C# don't allow to call virtual function while in ctor
- // we have to do this shit :\
-
- if (IsResolved) {
- return;
- }
-
- if (scanner.Is32BitProcess) {
- Setup32Bit(scanner);
- } else {
- Setup64Bit(scanner);
- }
- SetupInternal(scanner);
-
- IsResolved = true;
- }
-
- protected virtual void Setup32Bit(SigScanner scanner) {
- throw new NotSupportedException("32 bit version is not supported.");
- }
-
- protected virtual void Setup64Bit(SigScanner sig) {
- throw new NotSupportedException("64 bit version is not supported.");
- }
-
- protected virtual void SetupInternal(SigScanner scanner) {
- // Do nothing
- }
-
- protected T GetVirtualFunction(IntPtr address, int vtableOffset, int count) where T : class {
- // Get vtable
- var vtable = Marshal.ReadIntPtr(address, vtableOffset);
-
- // Get an address to the function
- var functionAddress = Marshal.ReadIntPtr(vtable, IntPtr.Size * count);
-
- return Marshal.GetDelegateForFunctionPointer(functionAddress);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs b/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs
deleted file mode 100644
index ad2e003f6..000000000
--- a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Internal.DXGI {
- public interface ISwapChainAddressResolver {
- IntPtr Present { get; set; }
- }
-}
diff --git a/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs
deleted file mode 100644
index 37c28197e..000000000
--- a/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Serilog;
-
-namespace Dalamud.Game.Internal.DXGI
-{
- public sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver
- {
- public IntPtr Present { get; set; }
- //public IntPtr ResizeBuffers { get; private set; }
-
- protected override void Setup64Bit(SigScanner sig)
- {
- var module = Process.GetCurrentProcess().Modules.Cast().First(m => m.ModuleName == "dxgi.dll");
-
- Log.Debug($"Found DXGI: {module.BaseAddress.ToInt64():X}");
-
- var scanner = new SigScanner(module);
-
- // This(code after the function head - offset of it) was picked to avoid running into issues with other hooks being installed into this function.
- Present = scanner.ScanModule("41 8B F0 8B FA 89 54 24 ?? 48 8B D9 48 89 4D ?? C6 44 24 ?? 00") - 0x37;
-
-
- // seems unnecessary for now, but we may need to handle it
- //ResizeBuffers = scanner.ScanModule("48 8B C4 55 41 54 41 55 41 56 41 57 48 8D 68 ?? 48 81 EC C0 00 00 00");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
deleted file mode 100644
index a9981b8ed..000000000
--- a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using SharpDX.Direct3D;
-using SharpDX.Direct3D11;
-using SharpDX.DXGI;
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using SharpDX.Windows;
-using Device = SharpDX.Direct3D11.Device;
-
-namespace Dalamud.Game.Internal.DXGI
-{
- /*
- * This method of getting the SwapChain Addresses is currently not used.
- * If the normal AddressResolver(SigScanner) fails, we should use it as a fallback.(Linux?)
- */
- public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver
- {
- private const int DxgiSwapchainMethodCount = 18;
- private const int D3D11DeviceMethodCount = 43;
-
- private static SwapChainDescription CreateSwapChainDescription(IntPtr renderForm) {
- return new SwapChainDescription {
- BufferCount = 1,
- Flags = SwapChainFlags.None,
- IsWindowed = true,
- ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), Format.R8G8B8A8_UNorm),
- OutputHandle = renderForm,
- SampleDescription = new SampleDescription(1, 0),
- SwapEffect = SwapEffect.Discard,
- Usage = Usage.RenderTargetOutput
- };
- }
-
- private IntPtr[] GetVTblAddresses(IntPtr pointer, int numberOfMethods)
- {
- return GetVTblAddresses(pointer, 0, numberOfMethods);
- }
-
- private IntPtr[] GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
- {
- List vtblAddresses = new List();
- IntPtr vTable = Marshal.ReadIntPtr(pointer);
- for (int i = startIndex; i < startIndex + numberOfMethods; i++)
- vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
-
- return vtblAddresses.ToArray();
- }
-
- private List d3d11VTblAddresses = null;
- private List dxgiSwapChainVTblAddresses = null;
-
- #region Internal device resources
-
- private Device device;
- private SwapChain swapChain;
- private RenderForm renderForm;
- #endregion
-
- #region Addresses
-
- public IntPtr Present { get; set; }
-
- #endregion
-
- protected override void Setup64Bit(SigScanner sig) {
- if (this.d3d11VTblAddresses == null) {
- this.d3d11VTblAddresses = new List();
- this.dxgiSwapChainVTblAddresses = new List();
-
- #region Get Device and SwapChain method addresses
-
- // Create temporary device + swapchain and determine method addresses
- this.renderForm = new RenderForm();
- Device.CreateWithSwapChain(
- DriverType.Hardware,
- DeviceCreationFlags.BgraSupport,
- CreateSwapChainDescription(this.renderForm.Handle),
- out this.device,
- out this.swapChain
- );
-
- if (this.device != null && this.swapChain != null) {
- this.d3d11VTblAddresses.AddRange(
- GetVTblAddresses(this.device.NativePointer, D3D11DeviceMethodCount));
- this.dxgiSwapChainVTblAddresses.AddRange(
- GetVTblAddresses(this.swapChain.NativePointer, DxgiSwapchainMethodCount));
- }
-
- this.device?.Dispose();
- this.swapChain?.Dispose();
-
- #endregion
- }
-
- Present = this.dxgiSwapChainVTblAddresses[8];
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Framework.cs b/Dalamud/Game/Internal/Framework.cs
deleted file mode 100644
index 31ede43cc..000000000
--- a/Dalamud/Game/Internal/Framework.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using Dalamud.Game.Internal.Gui;
-using Dalamud.Game.Internal.Libc;
-using Dalamud.Game.Internal.Network;
-using Dalamud.Hooking;
-using Serilog;
-using Dalamud.Game.Internal.File;
-
-namespace Dalamud.Game.Internal {
- ///
- /// This class represents the Framework of the native game client and grants access to various subsystems.
- ///
- public sealed class Framework : IDisposable {
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate bool OnUpdateDetour(IntPtr framework);
-
- public delegate void OnUpdateDelegate(Framework framework);
-
- public event OnUpdateDelegate OnUpdateEvent;
-
- private Hook updateHook;
-
-
- ///
- /// A raw pointer to the instance of Client::Framework
- ///
- private FrameworkAddressResolver Address { get; }
-
-#region Subsystems
-
- ///
- /// The GUI subsystem, used to access e.g. chat.
- ///
- public GameGui Gui { get; private set; }
-
- ///
- /// The Network subsystem, used to access network data.
- ///
- public GameNetwork Network { get; private set; }
-
- //public ResourceManager Resource { get; private set; }
-
- public LibcFunction Libc { get; private set; }
-
- private AntiDebug antiDebug;
-
-#endregion
-
- public Framework(SigScanner scanner, Dalamud dalamud) {
- Address = new FrameworkAddressResolver();
- Address.Setup(scanner);
-
- Log.Verbose("Framework address {FrameworkAddress}", Address.BaseAddress);
- if (Address.BaseAddress == IntPtr.Zero) {
- throw new InvalidOperationException("Framework is not initalized yet.");
- }
-
- // Hook virtual functions
- HookVTable();
-
- // Initialize subsystems
- Libc = new LibcFunction(scanner);
-
- Gui = new GameGui(Address.GuiManager, scanner, dalamud);
-
- Network = new GameNetwork(dalamud, scanner);
-
- //Resource = new ResourceManager(dalamud, scanner);
-
- this.antiDebug = new AntiDebug();
- }
-
- private void HookVTable() {
- var vtable = Marshal.ReadIntPtr(Address.BaseAddress);
- // Virtual function layout:
- // .rdata:00000001411F1FE0 dq offset Xiv__Framework___dtor
- // .rdata:00000001411F1FE8 dq offset Xiv__Framework__init
- // .rdata:00000001411F1FF0 dq offset sub_1400936E0
- // .rdata:00000001411F1FF8 dq offset sub_1400939E0
- // .rdata:00000001411F2000 dq offset Xiv__Framework__update
-
- var pUpdate = Marshal.ReadIntPtr(vtable, IntPtr.Size * 4);
- this.updateHook = new Hook(pUpdate, new OnUpdateDetour(HandleFrameworkUpdate), this);
- }
-
- public void Enable() {
- this.antiDebug.Enable();
- Gui.Enable();
- Network.Enable();
- //Resource.Enable();
-
- this.updateHook.Enable();
- }
-
- public void Dispose() {
- this.antiDebug.Dispose();
- Gui.Dispose();
- Network.Dispose();
- //Resource.Dispose();
-
- this.updateHook.Dispose();
- }
-
- private bool HandleFrameworkUpdate(IntPtr framework) {
- try {
- Gui.Chat.UpdateQueue(this);
- Network.UpdateQueue(this);
- } catch (Exception ex) {
- Log.Error(ex, "Exception while handling Framework::Update hook.");
- }
-
- try {
- OnUpdateEvent?.Invoke(this);
- } catch (Exception ex) {
- Log.Error(ex, "Exception while dispatching Framework::Update event.");
- }
-
- return this.updateHook.Original(framework);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/FrameworkAddressResolver.cs b/Dalamud/Game/Internal/FrameworkAddressResolver.cs
deleted file mode 100644
index 6d6b11263..000000000
--- a/Dalamud/Game/Internal/FrameworkAddressResolver.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.Internal {
- public sealed class FrameworkAddressResolver : BaseAddressResolver {
- public IntPtr BaseAddress { get; private set; }
-
- public IntPtr GuiManager { get; private set; }
-
- public IntPtr ScriptManager { get; private set; }
-
-
- protected override void Setup64Bit(SigScanner sig) {
- SetupFramework(sig);
-
- // Xiv__Framework__GetGuiManager+8 000 mov rax, [rcx+2C00h]
- // Xiv__Framework__GetGuiManager+F 000 retn
- GuiManager = Marshal.ReadIntPtr(BaseAddress, 0x2C08);
-
- // Called from Framework::Init
- ScriptManager = BaseAddress + 0x2C68; // note that no deref here
- }
-
- private void SetupFramework(SigScanner scanner) {
- // Dissasembly of part of the .dtor
- // 00007FF701AD665A | 48 C7 05 ?? ?? ?? ?? 00 00 00 00 | MOV QWORD PTR DS:[g_mainFramework],0
- // 00007FF701AD6665 | E8 ?? ?? ?? ?? | CALL ffxiv_dx11.7FF701E27130
- // 00007FF701AD666A | 48 8D ?? ?? ?? 00 00 | LEA RCX,QWORD PTR DS:[RBX + 2C38]
- // 00007FF701AD6671 | E8 ?? ?? ?? ?? | CALL ffxiv_dx11.7FF701E2A7D0
- // 00007FF701AD6676 | 48 8D ?? ?? ?? ?? ?? | LEA RAX,QWORD PTR DS:[7FF702C31F80
- var fwDtor = scanner.ScanText("48C705????????00000000 E8???????? 488D??????0000 E8???????? 488D");
- var fwOffset = Marshal.ReadInt32(fwDtor + 3);
- var pFramework = scanner.ResolveRelativeAddress(fwDtor + 11, fwOffset);
-
- // Framework does not change once initialized in startup so don't bother to deref again and again.
- BaseAddress = Marshal.ReadIntPtr(pFramework);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/ChatGui.cs b/Dalamud/Game/Internal/Gui/ChatGui.cs
deleted file mode 100644
index c9eb128c9..000000000
--- a/Dalamud/Game/Internal/Gui/ChatGui.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-using Dalamud.Game.Chat;
-using Dalamud.Game.Chat.SeStringHandling;
-using Dalamud.Game.Internal.Libc;
-using Dalamud.Hooking;
-using Discord.Rest;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Gui {
- public sealed class ChatGui : IDisposable {
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr PrintMessageDelegate(IntPtr manager, XivChatType chatType, IntPtr senderName,
- IntPtr message,
- uint senderId, IntPtr parameter);
-
- public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message,
- ref bool isHandled);
-
- public delegate void OnMessageRawDelegate(XivChatType type, uint senderId, ref StdString sender, ref StdString message,
- ref bool isHandled);
-
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void PopulateItemLinkDelegate(IntPtr linkObjectPtr, IntPtr itemInfoPtr);
-
- private readonly Queue chatQueue = new Queue();
-
- private readonly Hook printMessageHook;
-
- public event OnMessageDelegate OnChatMessage;
- [Obsolete("Please use OnChatMessage instead. For modifications, it will take precedence.")]
- public event OnMessageRawDelegate OnChatMessageRaw;
-
- private readonly Hook populateItemLinkHook;
-
- public int LastLinkedItemId { get; private set; }
- public byte LastLinkedItemFlags { get; private set; }
-
- private ChatGuiAddressResolver Address { get; }
-
- private IntPtr baseAddress = IntPtr.Zero;
-
- private readonly Dalamud dalamud;
-
- public ChatGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud) {
- this.dalamud = dalamud;
-
- Address = new ChatGuiAddressResolver(baseAddress);
- Address.Setup(scanner);
-
- Log.Verbose("Chat manager address {ChatManager}", Address.BaseAddress);
-
- this.printMessageHook =
- new Hook(Address.PrintMessage, new PrintMessageDelegate(HandlePrintMessageDetour),
- this);
- this.populateItemLinkHook =
- new Hook(Address.PopulateItemLinkObject,
- new PopulateItemLinkDelegate(HandlePopulateItemLinkDetour),
- this);
- }
-
- public void Enable() {
- this.printMessageHook.Enable();
- this.populateItemLinkHook.Enable();
- }
-
- public void Dispose() {
- this.printMessageHook.Dispose();
- this.populateItemLinkHook.Dispose();
- }
-
- private void HandlePopulateItemLinkDetour(IntPtr linkObjectPtr, IntPtr itemInfoPtr) {
- try {
- this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
-
- LastLinkedItemId = Marshal.ReadInt32(itemInfoPtr, 8);
- LastLinkedItemFlags = Marshal.ReadByte(itemInfoPtr, 0x14);
-
- Log.Debug($"HandlePopulateItemLinkDetour {linkObjectPtr} {itemInfoPtr} - linked:{LastLinkedItemId}");
- } catch (Exception ex) {
- Log.Error(ex, "Exception onPopulateItemLink hook.");
- this.populateItemLinkHook.Original(linkObjectPtr, itemInfoPtr);
- }
- }
-
- private IntPtr HandlePrintMessageDetour(IntPtr manager, XivChatType chattype, IntPtr pSenderName, IntPtr pMessage,
- uint senderid, IntPtr parameter) {
- var retVal = IntPtr.Zero;
-
- try {
- var sender = StdString.ReadFromPointer(pSenderName);
- var message = StdString.ReadFromPointer(pMessage);
-
- var parsedSender = SeString.Parse(sender.RawData);
- var parsedMessage = SeString.Parse(message.RawData);
-
- //Log.Debug($"HandlePrintMessageDetour {manager} - [{chattype}] [{BitConverter.ToString(message.RawData).Replace("-", " ")}] {message.Value} from {senderName.Value}");
-
- var originalMessageData = (byte[]) message.RawData.Clone();
- var oldEdited = parsedMessage.Encode();
-
- // Call events
- var isHandled = false;
- OnChatMessage?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
- OnChatMessageRaw?.Invoke(chattype, senderid, ref sender, ref message, ref isHandled);
-
- var newEdited = parsedMessage.Encode();
-
- if (!FastByteArrayCompare(oldEdited, newEdited)) {
- Log.Verbose("SeString was edited, taking precedence over StdString edit.");
- message.RawData = newEdited;
- }
- Log.Debug($"\nOLD: {BitConverter.ToString(originalMessageData)}\nNEW: {BitConverter.ToString(newEdited)}");
-
- var messagePtr = pMessage;
- OwnedStdString allocatedString = null;
-
- if (!FastByteArrayCompare(originalMessageData, message.RawData)) {
- allocatedString = this.dalamud.Framework.Libc.NewString(message.RawData);
- Log.Debug(
- $"HandlePrintMessageDetour String modified: {originalMessageData}({messagePtr}) -> {message}({allocatedString.Address})");
- messagePtr = allocatedString.Address;
- }
-
- // Print the original chat if it's handled.
- if (!isHandled)
- retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter);
-
- if (this.baseAddress == IntPtr.Zero)
- this.baseAddress = manager;
-
- allocatedString?.Dispose();
- } catch (Exception ex) {
- Log.Error(ex, "Exception on OnChatMessage hook.");
- retVal = this.printMessageHook.Original(manager, chattype, pSenderName, pMessage, senderid, parameter);
- }
-
- return retVal;
- }
-
- // Copyright (c) 2008-2013 Hafthor Stefansson
- // Distributed under the MIT/X11 software license
- // Ref: http://www.opensource.org/licenses/mit-license.php.
- // https://stackoverflow.com/a/8808245
- static unsafe bool FastByteArrayCompare(byte[] a1, byte[] a2)
- {
- if (a1 == a2) return true;
- if (a1 == null || a2 == null || a1.Length != a2.Length)
- return false;
- fixed (byte* p1 = a1, p2 = a2)
- {
- byte* x1 = p1, x2 = p2;
- int l = a1.Length;
- for (int i = 0; i < l / 8; i++, x1 += 8, x2 += 8)
- if (*((long*)x1) != *((long*)x2)) return false;
- if ((l & 4) != 0) { if (*((int*)x1) != *((int*)x2)) return false; x1 += 4; x2 += 4; }
- if ((l & 2) != 0) { if (*((short*)x1) != *((short*)x2)) return false; x1 += 2; x2 += 2; }
- if ((l & 1) != 0) if (*((byte*)x1) != *((byte*)x2)) return false;
- return true;
- }
- }
-
- ///
- /// Queue a chat message. While method is named as PrintChat, it only add a entry to the queue,
- /// later to be processed when UpdateQueue() is called.
- ///
- /// A message to send.
- public void PrintChat(XivChatEntry chat) {
- this.chatQueue.Enqueue(chat);
- }
-
- public void Print(string message) {
- PrintChat(new XivChatEntry {
- MessageBytes = Encoding.UTF8.GetBytes(message)
- });
- }
-
- public void PrintError(string message) {
- PrintChat(new XivChatEntry {
- MessageBytes = Encoding.UTF8.GetBytes(message),
- Type = XivChatType.Urgent
- });
- }
-
- ///
- /// Process a chat queue.
- ///
- public void UpdateQueue(Framework framework) {
- while (this.chatQueue.Count > 0) {
- var chat = this.chatQueue.Dequeue();
-
- var sender = chat.Name ?? "";
- var message = chat.MessageBytes ?? new byte[0];
-
- if (this.baseAddress != IntPtr.Zero)
- using (var senderVec = framework.Libc.NewString(Encoding.UTF8.GetBytes(sender)))
- using (var messageVec = framework.Libc.NewString(message))
- {
- Log.Verbose($"String allocated to {messageVec.Address.ToInt64():X}");
- this.printMessageHook.Original(this.baseAddress, chat.Type, senderVec.Address,
- messageVec.Address, chat.SenderId, chat.Parameters);
- }
- }
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs
deleted file mode 100644
index bc4d7b0f9..000000000
--- a/Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Internal.Gui {
- public sealed class ChatGuiAddressResolver : BaseAddressResolver {
- public IntPtr BaseAddress { get; }
-
- public IntPtr PrintMessage { get; private set; }
- public IntPtr PopulateItemLinkObject { get; private set; }
-
- public ChatGuiAddressResolver(IntPtr baseAddres) {
- BaseAddress = baseAddres;
- }
-
-
- /*
- --- for reference: 4.57 ---
-
-.text:00000001405CD210 ; __int64 __fastcall Xiv::Gui::ChatGui::PrintMessage(__int64 handler, unsigned __int16 chatType, __int64 senderName, __int64 message, int senderActorId, char isLocal)
-.text:00000001405CD210 Xiv__Gui__ChatGui__PrintMessage proc near
-.text:00000001405CD210 ; CODE XREF: sub_1401419F0+201↑p
-.text:00000001405CD210 ; sub_140141D10+220↑p ...
-.text:00000001405CD210
-.text:00000001405CD210 var_220 = qword ptr -220h
-.text:00000001405CD210 var_218 = byte ptr -218h
-.text:00000001405CD210 var_210 = word ptr -210h
-.text:00000001405CD210 var_208 = byte ptr -208h
-.text:00000001405CD210 var_200 = word ptr -200h
-.text:00000001405CD210 var_1FC = dword ptr -1FCh
-.text:00000001405CD210 var_1F8 = qword ptr -1F8h
-.text:00000001405CD210 var_1F0 = qword ptr -1F0h
-.text:00000001405CD210 var_1E8 = qword ptr -1E8h
-.text:00000001405CD210 var_1E0 = dword ptr -1E0h
-.text:00000001405CD210 var_1DC = word ptr -1DCh
-.text:00000001405CD210 var_1DA = word ptr -1DAh
-.text:00000001405CD210 var_1D8 = qword ptr -1D8h
-.text:00000001405CD210 var_1D0 = byte ptr -1D0h
-.text:00000001405CD210 var_1C8 = qword ptr -1C8h
-.text:00000001405CD210 var_1B0 = dword ptr -1B0h
-.text:00000001405CD210 var_1AC = dword ptr -1ACh
-.text:00000001405CD210 var_1A8 = dword ptr -1A8h
-.text:00000001405CD210 var_1A4 = dword ptr -1A4h
-.text:00000001405CD210 var_1A0 = dword ptr -1A0h
-.text:00000001405CD210 var_160 = dword ptr -160h
-.text:00000001405CD210 var_15C = dword ptr -15Ch
-.text:00000001405CD210 var_140 = dword ptr -140h
-.text:00000001405CD210 var_138 = dword ptr -138h
-.text:00000001405CD210 var_130 = byte ptr -130h
-.text:00000001405CD210 var_C0 = byte ptr -0C0h
-.text:00000001405CD210 var_50 = qword ptr -50h
-.text:00000001405CD210 var_38 = qword ptr -38h
-.text:00000001405CD210 var_30 = qword ptr -30h
-.text:00000001405CD210 var_28 = qword ptr -28h
-.text:00000001405CD210 var_20 = qword ptr -20h
-.text:00000001405CD210 senderActorId = dword ptr 30h
-.text:00000001405CD210 isLocal = byte ptr 38h
-.text:00000001405CD210
-.text:00000001405CD210 ; __unwind { // __GSHandlerCheck
-.text:00000001405CD210 push rbp
-.text:00000001405CD212 push rdi
-.text:00000001405CD213 push r14
-.text:00000001405CD215 push r15
-.text:00000001405CD217 lea rbp, [rsp-128h]
-.text:00000001405CD21F sub rsp, 228h
-.text:00000001405CD226 mov rax, cs:__security_cookie
-.text:00000001405CD22D xor rax, rsp
-.text:00000001405CD230 mov [rbp+140h+var_50], rax
-.text:00000001405CD237 xor r10b, r10b
-.text:00000001405CD23A mov [rsp+240h+var_1F8], rcx
-.text:00000001405CD23F xor eax, eax
-.text:00000001405CD241 mov r11, r9
-.text:00000001405CD244 mov r14, r8
-.text:00000001405CD247 mov r9d, eax
-.text:00000001405CD24A movzx r15d, dx
-.text:00000001405CD24E lea r8, [rcx+0C10h]
-.text:00000001405CD255 mov rdi, rcx
- */
-
- protected override void Setup64Bit(SigScanner sig) {
- //PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24D8FEFFFF 4881EC28020000 488B05???????? 4833C4 488985F0000000 4532D2 48894C2448"); LAST PART FOR 5.1???
- PrintMessage =
- sig.ScanText(
- "4055 53 56 4154 4157 48 8d ac 24 ?? ?? ?? ?? 48 81 ec 20 02 00 00 48 8b 05"
- );
- //PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24E8FEFFFF 4881EC18020000 488B05???????? 4833C4 488985E0000000 4532D2 48894C2438"); old
-
- //PrintMessage = sig.ScanText("40 55 57 41 56 41 57 48 8D AC 24 D8 FE FF FF 48 81 EC 28 02 00 00 48 8B 05 63 47 4A 01 48 33 C4 48 89 85 F0 00 00 00 45 32 D2 48 89 4C 24 48 33");
-
- //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
- 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 ?? ?? ?? FF 8B C8 EB 1D 0F B6 42 14 8B 4A");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Internal/Gui/GameGui.cs
deleted file mode 100644
index 370341300..000000000
--- a/Dalamud/Game/Internal/Gui/GameGui.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using Dalamud.Game.Chat;
-using Dalamud.Hooking;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Gui {
- public sealed class GameGui : IDisposable {
- private GameGuiAddressResolver Address { get; }
-
- public ChatGui Chat { get; private set; }
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr SetGlobalBgmDelegate(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6);
-
- private readonly Hook setGlobalBgmHook;
-
- public GameGui(IntPtr baseAddress, SigScanner scanner, Dalamud dalamud) {
- Address = new GameGuiAddressResolver(baseAddress);
- Address.Setup(scanner);
-
- Log.Verbose("===== G A M E G U I =====");
-
- Log.Verbose("GameGuiManager address {Address}", Address.BaseAddress);
- Log.Verbose("SetGlobalBgm address {Address}", Address.SetGlobalBgm);
-
- Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
-
- this.setGlobalBgmHook =
- new Hook(Address.SetGlobalBgm,
- new SetGlobalBgmDelegate(HandleSetGlobalBgmDetour),
- this);
- }
-
- private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
- var retVal = this.setGlobalBgmHook.Original(bgmKey, a2, a3, a4, a5, a6);
-
- Log.Verbose("SetGlobalBgm: {0} {1} {2} {3} {4} {5} -> {6}", bgmKey, a2, a3, a4, a5, a6, retVal);
-
- return retVal;
- }
-
- public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
-
- public void Enable() {
- Chat.Enable();
- this.setGlobalBgmHook.Enable();
- }
-
- public void Dispose() {
- Chat.Dispose();
- this.setGlobalBgmHook.Dispose();
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
deleted file mode 100644
index c0127e8d4..000000000
--- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Gui {
- public sealed class GameGuiAddressResolver : BaseAddressResolver {
- public IntPtr BaseAddress { get; private set; }
-
- public IntPtr ChatManager { get; private set; }
-
- public IntPtr SetGlobalBgm { get; private set; }
-
- public GameGuiAddressResolver(IntPtr baseAddress) {
- BaseAddress = baseAddress;
- }
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetChatManagerDelegate(IntPtr guiManager);
-
- protected override void SetupInternal(SigScanner scanner) {
- // Xiv__UiManager__GetChatManager 000 lea rax, [rcx+13E0h]
- // Xiv__UiManager__GetChatManager+7 000 retn
- ChatManager = BaseAddress + 0x13E0;
- }
-
- protected override void Setup64Bit(SigScanner sig) {
- //SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58 41 83 7A ?? ?? 76 51 4D 8B 92 ?? ?? ?? ?? 0F B6 44 24 ?? 49 81 C2 ?? ?? ?? ?? 66 41 89 4A ?? 33 C9 41 88 52 30 41 89 4A 14 66 41 89 4A ?? 41 88 42 12 49 89 4A 38 41 89 4A 40 49 89 4A 48 41 38 4A 30 74 14 8B 44 24 28 41 89 42 40 45 89 42 38");
- SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/TargetManager.cs b/Dalamud/Game/Internal/Gui/TargetManager.cs
deleted file mode 100644
index 202684581..000000000
--- a/Dalamud/Game/Internal/Gui/TargetManager.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using Dalamud.Game.ClientState;
-using Dalamud.Game.ClientState.Actors.Types;
-using Dalamud.Game.ClientState.Structs.JobGauge;
-using Dalamud.Hooking;
-using Serilog;
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.Internal.Gui {
- public class TargetManager {
- public delegate IntPtr GetTargetDelegate(IntPtr manager);
-
- private Hook getTargetHook;
-
- private TargetManagerAddressResolver Address;
-
- public unsafe TargetManager(Dalamud dalamud, SigScanner scanner) {
- this.Address = new TargetManagerAddressResolver();
- this.Address.Setup(scanner);
-
- Log.Verbose("===== T A R G E T M A N A G E R =====");
- Log.Verbose("GetTarget address {GetTarget}", Address.GetTarget);
-
- this.getTargetHook = new Hook(this.Address.GetTarget, new GetTargetDelegate(GetTargetDetour), this);
- }
-
- public void Enable() {
- this.getTargetHook.Enable();
- }
-
- public void Dispose() {
- this.getTargetHook.Dispose();
- }
-
- private IntPtr GetTargetDetour(IntPtr manager)
- {
- try {
- var res = this.getTargetHook.Original(manager);
-
- var test = Marshal.ReadInt32(res);
-
- Log.Debug($"GetTargetDetour {manager.ToInt64():X} -> RET: {res:X}");
-
- return res;
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception GetTargetDetour hook.");
- return this.getTargetHook.Original(manager);
- }
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/TargetManagerAddressResolver.cs b/Dalamud/Game/Internal/Gui/TargetManagerAddressResolver.cs
deleted file mode 100644
index 137742bc0..000000000
--- a/Dalamud/Game/Internal/Gui/TargetManagerAddressResolver.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Internal.Gui {
- class TargetManagerAddressResolver : BaseAddressResolver {
- public IntPtr GetTarget { get; private set; }
-
- protected override void Setup64Bit(SigScanner sig) {
- this.GetTarget = sig.ScanText("40 57 48 83 EC 40 48 8B F9 48 8B 49 08 48 8B 01 FF 50 40 66 83 B8 CA 81 00 00 00 74 33 48 8B 4F 08 48 8B 01 FF 50 40 66 83 B8 CA 81 00 00 04 74");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Libc/LibcFunction.cs b/Dalamud/Game/Internal/Libc/LibcFunction.cs
deleted file mode 100644
index 9ea4dc6a8..000000000
--- a/Dalamud/Game/Internal/Libc/LibcFunction.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Libc {
- public sealed class LibcFunction {
- // TODO: prolly callconv is not okay in x86
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr StdStringFromCStringDelegate(IntPtr pStdString, [MarshalAs(UnmanagedType.LPArray)]byte[] content, IntPtr size);
-
- // TODO: prolly callconv is not okay in x86
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr StdStringDeallocateDelegate(IntPtr address);
-
- private LibcFunctionAddressResolver Address { get; }
-
- private readonly StdStringFromCStringDelegate stdStringCtorCString;
- private readonly StdStringDeallocateDelegate stdStringDeallocate;
-
- public LibcFunction(SigScanner scanner) {
- Address = new LibcFunctionAddressResolver();
- Address.Setup(scanner);
-
- this.stdStringCtorCString = Marshal.GetDelegateForFunctionPointer(Address.StdStringFromCstring);
- this.stdStringDeallocate = Marshal.GetDelegateForFunctionPointer(Address.StdStringDeallocate);
- }
-
- public OwnedStdString NewString(byte[] content) {
- // While 0x70 bytes in the memory should be enough in DX11 version,
- // I don't trust my analysis so we're just going to allocate almost two times more than that.
- var pString = Marshal.AllocHGlobal(256);
-
- // Initialize a string
- var npos = new IntPtr(0xFFFFFFFF); // assumed to be -1 (0xFFFFFFFF in x86, 0xFFFFFFFF_FFFFFFFF in amd64)
- var pReallocString = this.stdStringCtorCString(pString, content, npos);
-
- //Log.Verbose("Prev: {Prev} Now: {Now}", pString, pReallocString);
-
- return new OwnedStdString(pReallocString, DeallocateStdString);
- }
-
- private void DeallocateStdString(IntPtr address) {
- this.stdStringDeallocate(address);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs b/Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs
deleted file mode 100644
index aeaefa595..000000000
--- a/Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Security.Policy;
-
-namespace Dalamud.Game.Internal.Libc {
- public sealed class LibcFunctionAddressResolver : BaseAddressResolver {
- private delegate IntPtr StringFromCString();
-
- public IntPtr StdStringFromCstring { get; private set; }
- public IntPtr StdStringDeallocate { get; private set; }
-
- protected override void Setup64Bit(SigScanner sig) {
- StdStringFromCstring = sig.ScanText("48895C2408 4889742410 57 4883EC20 488D4122 66C741200101 488901 498BD8");
- StdStringDeallocate = sig.ScanText("80792100 7512 488B5108 41B833000000 488B09 E9??????00 C3");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Libc/OwnedStdString.cs b/Dalamud/Game/Internal/Libc/OwnedStdString.cs
deleted file mode 100644
index ea68d8f91..000000000
--- a/Dalamud/Game/Internal/Libc/OwnedStdString.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Libc {
- public sealed class OwnedStdString : IDisposable {
- internal delegate void DeallocatorDelegate(IntPtr address);
-
- // ala. the drop flag
- private bool isDisposed;
-
- private readonly DeallocatorDelegate dealloc;
-
- public IntPtr Address { get; private set; }
-
- ///
- /// Construct a wrapper around std::string
- ///
- ///
- /// Violating any of these might cause an undefined hehaviour.
- /// 1. This function takes the ownership of the address.
- /// 2. A memory pointed by address argument is assumed to be allocated by Marshal.AllocHGlobal thus will try to call Marshal.FreeHGlobal on the address.
- /// 3. std::string object pointed by address must be initialized before calling this function.
- ///
- ///
- /// A deallocator function.
- ///
- internal OwnedStdString(IntPtr address, DeallocatorDelegate dealloc) {
- Address = address;
- this.dealloc = dealloc;
- }
-
- ~OwnedStdString() {
- ReleaseUnmanagedResources();
- }
-
- private void ReleaseUnmanagedResources() {
- if (Address == IntPtr.Zero) {
- // Something got seriously fucked.
- throw new AccessViolationException();
- }
-
- // Deallocate inner string first
- this.dealloc(Address);
-
- // Free the heap
- Marshal.FreeHGlobal(Address);
-
- // Better safe (running on a nullptr) than sorry. (running on a dangling pointer)
- Address = IntPtr.Zero;
- }
-
- public void Dispose() {
- // No double free plz, kthx.
- if (this.isDisposed) {
- return;
- }
- this.isDisposed = true;
-
- ReleaseUnmanagedResources();
- GC.SuppressFinalize(this);
- }
-
- public StdString Read() {
- return StdString.ReadFromPointer(Address);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Libc/StdString.cs b/Dalamud/Game/Internal/Libc/StdString.cs
deleted file mode 100644
index c91b26690..000000000
--- a/Dalamud/Game/Internal/Libc/StdString.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using Newtonsoft.Json.Linq;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Libc {
- ///
- /// Interation with std::string
- ///
- public class StdString {
- public static StdString ReadFromPointer(IntPtr cstring) {
- unsafe {
- if (cstring == IntPtr.Zero) {
- throw new ArgumentNullException(nameof(cstring));
- }
-
- var innerAddress = Marshal.ReadIntPtr(cstring);
- if (innerAddress == IntPtr.Zero) {
- throw new NullReferenceException("Inner reference to the cstring is null.");
- }
-
- var count = 0;
-
- // Count the number of chars. String is assumed to be zero-terminated.
- while (Marshal.ReadByte(innerAddress + count) != 0) {
- count += 1;
- }
-
- // raw copy, as UTF8 string conversion is lossy
- var rawData = new byte[count];
- Marshal.Copy(innerAddress, rawData, 0, count);
-
- return new StdString {
- RawData = rawData,
- Value = Encoding.UTF8.GetString(rawData)
- };
- }
- }
-
- private StdString() { }
-
- public string Value { get; private set; }
-
- public byte[] RawData { get; set; }
- }
-}
diff --git a/Dalamud/Game/Internal/Network/GameNetwork.cs b/Dalamud/Game/Internal/Network/GameNetwork.cs
deleted file mode 100644
index eb59ce2a5..000000000
--- a/Dalamud/Game/Internal/Network/GameNetwork.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Dalamud.Hooking;
-using Serilog;
-
-namespace Dalamud.Game.Internal.Network {
- public sealed class GameNetwork : IDisposable {
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate void ProcessZonePacketDelegate(IntPtr a, IntPtr b, IntPtr dataPtr);
-
- private readonly Hook processZonePacketHook;
-
- private GameNetworkAddressResolver Address { get; }
- private IntPtr baseAddress;
-
- public delegate void OnZonePacketDelegate(IntPtr dataPtr);
-
- public OnZonePacketDelegate OnZonePacket;
-
- private readonly Dalamud dalamud;
-
- private readonly Queue zoneInjectQueue = new Queue();
-
- public GameNetwork(Dalamud dalamud, SigScanner scanner) {
- this.dalamud = dalamud;
- Address = new GameNetworkAddressResolver();
- Address.Setup(scanner);
-
- Log.Verbose("===== G A M E N E T W O R K =====");
- Log.Verbose("ProcessZonePacket address {ProcessZonePacket}", Address.ProcessZonePacket);
-
- this.processZonePacketHook =
- new Hook(Address.ProcessZonePacket,
- new ProcessZonePacketDelegate(ProcessZonePacketDetour),
- this);
- }
-
- public void Enable() {
- this.processZonePacketHook.Enable();
- }
-
- public void Dispose() {
- this.processZonePacketHook.Dispose();
- }
-
- private void ProcessZonePacketDetour(IntPtr a, IntPtr b, IntPtr dataPtr) {
- this.baseAddress = a;
-
- // Call events
- this.OnZonePacket?.Invoke(dataPtr);
-
- try {
- this.processZonePacketHook.Original(a, b, dataPtr);
- } catch (Exception ex) {
- string header;
- try {
- var data = new byte[32];
- Marshal.Copy(dataPtr, data, 0, 32);
- header = BitConverter.ToString(data);
- } catch (Exception) {
- header = "failed";
- }
-
- Log.Error(ex, "Exception on ProcessZonePacket hook. Header: " + header);
-
- this.processZonePacketHook.Original(a, b, dataPtr);
- }
- }
-
-#if DEBUG
- public void InjectZoneProtoPacket(byte[] data) {
- this.zoneInjectQueue.Enqueue(data);
- }
-
- private void InjectActorControl(short cat, int param1) {
- var packetData = new byte[] {
- 0x14, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x17, 0x7C, 0xC5, 0x5D, 0x00, 0x00, 0x00, 0x00,
- 0x05, 0x00, 0x48, 0xB2, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x43, 0x7F, 0x00, 0x00
- };
-
- BitConverter.GetBytes((short) cat).CopyTo(packetData, 0x10);
-
- BitConverter.GetBytes((UInt32) param1).CopyTo(packetData, 0x14);
-
- InjectZoneProtoPacket(packetData);
- }
-#endif
-
- ///
- /// Process a chat queue.
- ///
- public void UpdateQueue(Framework framework)
- {
- while (this.zoneInjectQueue.Count > 0)
- {
- var packetData = this.zoneInjectQueue.Dequeue();
-
- var unmanagedPacketData = Marshal.AllocHGlobal(packetData.Length);
- Marshal.Copy(packetData, 0, unmanagedPacketData, packetData.Length);
-
- if (this.baseAddress != IntPtr.Zero) {
- this.processZonePacketHook.Original(this.baseAddress, IntPtr.Zero, unmanagedPacketData);
- }
-
- Marshal.FreeHGlobal(unmanagedPacketData);
- }
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs b/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs
deleted file mode 100644
index 09ad99ebb..000000000
--- a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Internal.Network {
- public sealed class GameNetworkAddressResolver : BaseAddressResolver {
- public IntPtr ProcessZonePacket { get; private set; }
-
- protected override void Setup64Bit(SigScanner sig) {
- //ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05");
- //ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 73 FF 0F B7 57 02 8D 42 ?? 3D ?? ?? 00 00 0F 87 60 01 00 00 4C 8D 05");
- ProcessZonePacket = sig.ScanText("48 89 74 24 ?? 57 48 83 EC 50 8B FA 49 8B F0");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Resource/ResourceManager.cs b/Dalamud/Game/Internal/Resource/ResourceManager.cs
deleted file mode 100644
index b12e1b8a6..000000000
--- a/Dalamud/Game/Internal/Resource/ResourceManager.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Game.Internal.Libc;
-using Dalamud.Hooking;
-using Serilog;
-
-namespace Dalamud.Game.Internal.File
-{
- public class ResourceManager {
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetResourceAsyncDelegate(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6, byte a7);
- private readonly Hook getResourceAsyncHook;
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetResourceSyncDelegate(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6);
- private readonly Hook getResourceSyncHook;
-
- private ResourceManagerAddressResolver Address { get; }
- private readonly Dalamud dalamud;
-
- class ResourceHandleHookInfo {
- public string Path { get; set; }
- public Stream DetourFile { get; set; }
- }
-
- private Dictionary resourceHookMap = new Dictionary();
-
- public ResourceManager(Dalamud dalamud, SigScanner scanner) {
- this.dalamud = dalamud;
- Address = new ResourceManagerAddressResolver();
- Address.Setup(scanner);
-
- Log.Verbose("===== R E S O U R C E M A N A G E R =====");
- Log.Verbose("GetResourceAsync address {GetResourceAsync}", Address.GetResourceAsync);
- Log.Verbose("GetResourceSync address {GetResourceSync}", Address.GetResourceSync);
-
- this.getResourceAsyncHook =
- new Hook(Address.GetResourceAsync,
- new GetResourceAsyncDelegate(GetResourceAsyncDetour),
- this);
-
- this.getResourceSyncHook =
- new Hook(Address.GetResourceSync,
- new GetResourceSyncDelegate(GetResourceSyncDetour),
- this);
-
- }
-
- public void Enable() {
- this.getResourceAsyncHook.Enable();
- this.getResourceSyncHook.Enable();
- }
-
- public void Dispose() {
- this.getResourceAsyncHook.Dispose();
- this.getResourceSyncHook.Dispose();
- }
-
- private IntPtr GetResourceAsyncDetour(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6, byte a7) {
-
- try {
- var path = Marshal.PtrToStringAnsi(a5);
-
- var resourceHandle = this.getResourceAsyncHook.Original(manager, a2, a3, a4, IntPtr.Zero, a6, a7);
- //var resourceHandle = IntPtr.Zero;
-
- Log.Verbose("GetResourceAsync CALL - this:{0} a2:{1} a3:{2} a4:{3} a5:{4} a6:{5} a7:{6} => RET:{7}", manager, a2, a3, a4, a5, a6, a7, resourceHandle);
-
- Log.Verbose($"->{path}");
-
- HandleGetResourceHookAcquire(resourceHandle, path);
-
- return resourceHandle;
- } catch (Exception ex) {
- Log.Error(ex, "Exception on ReadResourceAsync hook.");
-
- return this.getResourceAsyncHook.Original(manager, a2, a3, a4, a5, a6, a7);
- }
- }
-
- private void DumpMem(IntPtr address, int len = 512) {
- if (address == IntPtr.Zero)
- return;
-
- var data = new byte[len];
- Marshal.Copy(address, data, 0, len);
-
- Log.Verbose($"MEMDMP at {address.ToInt64():X} for {len:X}\n{Util.ByteArrayToHex(data)}");
- }
-
- private IntPtr GetResourceSyncDetour(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6) {
-
- try {
- var resourceHandle = this.getResourceSyncHook.Original(manager, a2, a3, a4, a5, a6);
-
- Log.Verbose("GetResourceSync CALL - this:{0} a2:{1} a3:{2} a4:{3} a5:{4} a6:{5} => RET:{6}", manager, a2, a3, a4, a5, a6, resourceHandle);
-
- var path = Marshal.PtrToStringAnsi(a5);
-
- Log.Verbose($"->{path}");
-
- HandleGetResourceHookAcquire(resourceHandle, path);
-
- return resourceHandle;
- } catch (Exception ex) {
- Log.Error(ex, "Exception on ReadResourceSync hook.");
-
- return this.getResourceSyncHook.Original(manager, a2, a3, a4, a5, a6);
- }
- }
-
- private void HandleGetResourceHookAcquire(IntPtr handlePtr, string path) {
- if (FilePathHasInvalidChars(path))
- return;
-
- if (this.resourceHookMap.ContainsKey(handlePtr)) {
- Log.Verbose($"-> Handle {handlePtr.ToInt64():X}({path}) was cached!");
- return;
- }
-
- var hookInfo = new ResourceHandleHookInfo {
- Path = path
- };
-
- var hookPath = Path.Combine(this.dalamud.StartInfo.WorkingDirectory, "ResourceHook", path);
-
- if (System.IO.File.Exists(hookPath)) {
- hookInfo.DetourFile = new FileStream(hookPath, FileMode.Open);
- Log.Verbose("-> Added resource hook detour at {0}", hookPath);
- }
-
- this.resourceHookMap.Add(handlePtr, hookInfo);
- }
-
- public static bool FilePathHasInvalidChars(string path)
- {
-
- return (!string.IsNullOrEmpty(path) && path.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs b/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs
deleted file mode 100644
index 2be49b4ac..000000000
--- a/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game.Internal.File
-{
- class ResourceManagerAddressResolver : BaseAddressResolver
- {
- public IntPtr GetResourceAsync { get; private set; }
- public IntPtr GetResourceSync { get; private set; }
-
- protected override void Setup64Bit(SigScanner sig) {
- GetResourceAsync = sig.ScanText("48 89 5C 24 08 48 89 54 24 10 57 48 83 EC 20 B8 03 00 00 00 48 8B F9 86 82 A1 00 00 00 48 8B 5C 24 38 B8 01 00 00 00 87 83 90 00 00 00 85 C0 74");
- GetResourceSync = sig.ScanText("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 30 48 8B F9 49 8B E9 48 83 C1 30 4D 8B F0 4C 8B EA FF 15 CE F6");
- //ReadResourceSync = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05");
- }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardItemRequest.cs b/Dalamud/Game/Network/MarketBoardItemRequest.cs
deleted file mode 100644
index 7ec9afe90..000000000
--- a/Dalamud/Game/Network/MarketBoardItemRequest.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Collections.Generic;
-using Dalamud.Game.Network.Structures;
-
-namespace Dalamud.Game.Network {
- internal class MarketBoardItemRequest {
- public uint CatalogId { get; set; }
- public byte AmountToArrive { get; set; }
-
- public List Listings { get; set; }
- public List History { get; set; }
-
- public int ListingsRequestId { get; set; } = -1;
-
- public bool IsDone => Listings.Count == AmountToArrive && History.Count != 0;
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs b/Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs
deleted file mode 100644
index cd675d865..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/IMarketBoardUploader.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Dalamud.Game.Network.Structures;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders {
- internal interface IMarketBoardUploader {
- void Upload(MarketBoardItemRequest itemRequest);
- void UploadTax(MarketTaxRates taxRates);
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs
deleted file mode 100644
index c3b5a4146..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryEntry.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
- internal class UniversalisHistoryEntry {
- [JsonProperty("hq")]
- public bool Hq { get; set; }
-
- [JsonProperty("pricePerUnit")]
- public uint PricePerUnit { get; set; }
-
- [JsonProperty("quantity")]
- public uint Quantity { get; set; }
-
- [JsonProperty("buyerName")]
- public string BuyerName { get; set; }
-
- [JsonProperty("onMannequin")]
- public bool OnMannequin { get; set; }
-
- [JsonProperty("sellerID")]
- public ulong SellerId { get; set; }
-
- [JsonProperty("buyerID")]
- public ulong BuyerId { get; set; }
-
- [JsonProperty("timestamp")]
- public long Timestamp { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs
deleted file mode 100644
index 51bcbacb8..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisHistoryUploadRequest.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
- internal class UniversalisHistoryUploadRequest {
- [JsonProperty("worldID")]
- public int WorldId { get; set; }
-
- [JsonProperty("itemID")]
- public uint ItemId { get; set; }
-
- [JsonProperty("entries")]
- public List Entries { get; set; }
-
- [JsonProperty("uploaderID")]
- public ulong UploaderId { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs
deleted file mode 100644
index 336e6773c..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsEntry.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
- internal class UniversalisItemListingsEntry {
- [JsonProperty("listingID")]
- public ulong ListingId { get; set; }
-
- [JsonProperty("hq")]
- public bool Hq { get; set; }
-
- [JsonProperty("pricePerUnit")]
- public uint PricePerUnit { get; set; }
-
- [JsonProperty("quantity")]
- public uint Quantity { get; set; }
-
- [JsonProperty("retainerName")]
- public string RetainerName { get; set; }
-
- [JsonProperty("retainerID")]
- public ulong RetainerId { get; set; }
-
- [JsonProperty("creatorName")]
- public string CreatorName { get; set; }
-
- [JsonProperty("onMannequin")]
- public bool OnMannequin { get; set; }
-
- [JsonProperty("sellerID")]
- public ulong SellerId { get; set; }
-
- [JsonProperty("creatorID")]
- public ulong CreatorId { get; set; }
-
- [JsonProperty("stainID")]
- public int StainId { get; set; }
-
- [JsonProperty("retainerCity")]
- public int RetainerCity { get; set; }
-
- [JsonProperty("lastReviewTime")]
- public long LastReviewTime { get; set; }
-
- [JsonProperty("materia")]
- public List Materia { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs
deleted file mode 100644
index e07525f13..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemListingsUploadRequest.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
- internal class UniversalisItemListingsUploadRequest {
- [JsonProperty("worldID")]
- public int WorldId { get; set; }
-
- [JsonProperty("itemID")]
- public uint ItemId { get; set; }
-
- [JsonProperty("listings")]
- public List Listings { get; set; }
-
- [JsonProperty("uploaderID")]
- public ulong UploaderId { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs
deleted file mode 100644
index 93742b84b..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisItemMateria.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis {
- internal class UniversalisItemMateria {
- [JsonProperty("slotID")]
- public int SlotId { get; set; }
-
- [JsonProperty("materiaID")]
- public int MateriaId { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
deleted file mode 100644
index 83c657b14..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisMarketBoardUploader.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using Dalamud.Game.Network.MarketBoardUploaders;
-using Dalamud.Game.Network.MarketBoardUploaders.Universalis;
-using Dalamud.Game.Network.Structures;
-using Newtonsoft.Json;
-using Serilog;
-
-namespace Dalamud.Game.Network.Universalis.MarketBoardUploaders {
- internal class UniversalisMarketBoardUploader : IMarketBoardUploader {
- private const string ApiBase = "https://universalis.app";
-
- //private const string ApiBase = "https://127.0.0.1:443";
- private const string ApiKey = "GGD6RdSfGyRiHM5WDnAo0Nj9Nv7aC5NDhMj3BebT";
-
- private readonly Dalamud dalamud;
-
- public UniversalisMarketBoardUploader(Dalamud dalamud) {
- this.dalamud = dalamud;
- }
-
- public void Upload(MarketBoardItemRequest request) {
- using (var client = new WebClient()) {
- client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
-
- Log.Verbose("Starting Universalis upload.");
- var uploader = this.dalamud.ClientState.LocalContentId;
-
- var listingsRequestObject = new UniversalisItemListingsUploadRequest();
- listingsRequestObject.WorldId = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Id;
- listingsRequestObject.UploaderId = uploader;
- listingsRequestObject.ItemId = request.CatalogId;
-
- listingsRequestObject.Listings = new List();
- foreach (var marketBoardItemListing in request.Listings) {
- var universalisListing = new UniversalisItemListingsEntry {
- Hq = marketBoardItemListing.IsHq,
- SellerId = marketBoardItemListing.RetainerOwnerId,
- RetainerName = marketBoardItemListing.RetainerName,
- RetainerId = marketBoardItemListing.RetainerId,
- CreatorId = marketBoardItemListing.ArtisanId,
- CreatorName = marketBoardItemListing.PlayerName,
- OnMannequin = marketBoardItemListing.OnMannequin,
- LastReviewTime = ((DateTimeOffset) marketBoardItemListing.LastReviewTime).ToUnixTimeSeconds(),
- PricePerUnit = marketBoardItemListing.PricePerUnit,
- Quantity = marketBoardItemListing.ItemQuantity,
- RetainerCity = marketBoardItemListing.RetainerCityId
- };
-
- universalisListing.Materia = new List();
- foreach (var itemMateria in marketBoardItemListing.Materia)
- universalisListing.Materia.Add(new UniversalisItemMateria {
- MateriaId = itemMateria.MateriaId,
- SlotId = itemMateria.Index
- });
-
- listingsRequestObject.Listings.Add(universalisListing);
- }
-
- var upload = JsonConvert.SerializeObject(listingsRequestObject);
- client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", upload);
- Log.Verbose(upload);
-
- var historyRequestObject = new UniversalisHistoryUploadRequest();
- historyRequestObject.WorldId = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Id;
- historyRequestObject.UploaderId = uploader;
- historyRequestObject.ItemId = request.CatalogId;
-
- historyRequestObject.Entries = new List();
- foreach (var marketBoardHistoryListing in request.History)
- historyRequestObject.Entries.Add(new UniversalisHistoryEntry {
- BuyerName = marketBoardHistoryListing.BuyerName,
- Hq = marketBoardHistoryListing.IsHq,
- OnMannequin = marketBoardHistoryListing.OnMannequin,
- PricePerUnit = marketBoardHistoryListing.SalePrice,
- Quantity = marketBoardHistoryListing.Quantity,
- Timestamp = ((DateTimeOffset) marketBoardHistoryListing.PurchaseTime).ToUnixTimeSeconds()
- });
-
- client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
-
- var historyUpload = JsonConvert.SerializeObject(historyRequestObject);
- client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
- Log.Verbose(historyUpload);
-
- Log.Verbose("Universalis data upload for item#{0} completed.", request.CatalogId);
- }
- }
-
- public void UploadTax(MarketTaxRates taxRates) {
- using (var client = new WebClient())
- {
- var taxRatesRequest = new UniversalisTaxUploadRequest();
- taxRatesRequest.WorldId = this.dalamud.ClientState.LocalPlayer.CurrentWorld.Id;
- taxRatesRequest.UploaderId = this.dalamud.ClientState.LocalContentId;
-
- taxRatesRequest.TaxData = new UniversalisTaxData {
- LimsaLominsa = taxRates.LimsaLominsaTax,
- Gridania = taxRates.GridaniaTax,
- Uldah = taxRates.UldahTax,
- Ishgard = taxRates.IshgardTax,
- Kugane = taxRates.KuganeTax,
- Crystarium = taxRates.CrystariumTax
- };
-
- client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
-
- var historyUpload = JsonConvert.SerializeObject(taxRatesRequest);
- client.UploadString(ApiBase + $"/upload/{ApiKey}", "POST", historyUpload);
- Log.Verbose(historyUpload);
-
- Log.Verbose("Universalis tax upload completed.");
- }
- }
- }
-}
diff --git a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs b/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs
deleted file mode 100644
index 0e142c17c..000000000
--- a/Dalamud/Game/Network/MarketBoardUploaders/Universalis/UniversalisTaxUploadRequest.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Newtonsoft.Json;
-
-namespace Dalamud.Game.Network.MarketBoardUploaders.Universalis
-{
- class UniversalisTaxUploadRequest
- {
- [JsonProperty("uploaderID")]
- public ulong UploaderId { get; set; }
-
- [JsonProperty("worldID")]
- public int WorldId { get; set; }
-
- [JsonProperty("marketTaxRates")]
- public UniversalisTaxData TaxData { get; set; }
- }
-
- class UniversalisTaxData {
- [JsonProperty("limsaLominsa")]
- public uint LimsaLominsa { get; set; }
-
- [JsonProperty("gridania")]
- public uint Gridania { get; set; }
-
- [JsonProperty("uldah")]
- public uint Uldah { get; set; }
-
- [JsonProperty("ishgard")]
- public uint Ishgard { get; set; }
-
- [JsonProperty("kugane")]
- public uint Kugane { get; set; }
-
- [JsonProperty("crystarium")]
- public uint Crystarium { get; set; }
- }
-}
diff --git a/Dalamud/Game/Network/NetworkHandlers.cs b/Dalamud/Game/Network/NetworkHandlers.cs
deleted file mode 100644
index b5b073075..000000000
--- a/Dalamud/Game/Network/NetworkHandlers.cs
+++ /dev/null
@@ -1,246 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using Dalamud.Data.TransientSheet;
-using Dalamud.Game.Network.MarketBoardUploaders;
-using Dalamud.Game.Network.Structures;
-using Dalamud.Game.Network.Universalis.MarketBoardUploaders;
-using Lumina.Excel;
-using Newtonsoft.Json.Linq;
-using Serilog;
-
-namespace Dalamud.Game.Network {
- public class NetworkHandlers {
- private readonly Dalamud dalamud;
-
- private readonly List marketBoardRequests = new List();
-
- private readonly bool optOutMbUploads;
- private readonly IMarketBoardUploader uploader;
-
- private byte[] lastPreferredRole;
-
- public delegate Task CfPop(ContentFinderCondition cfc);
- public event CfPop ProcessCfPop;
-
- public NetworkHandlers(Dalamud dalamud, bool optOutMbUploads) {
- this.dalamud = dalamud;
- this.optOutMbUploads = optOutMbUploads;
-
- this.uploader = new UniversalisMarketBoardUploader(dalamud);
-
- dalamud.Framework.Network.OnZonePacket += OnZonePacket;
-
- }
-
- private void OnZonePacket(IntPtr dataPtr) {
- if (!this.dalamud.Data.IsDataReady)
- return;
-
- var opCode = (ushort) Marshal.ReadInt16(dataPtr, 2);
-
- if (opCode == this.dalamud.Data.ServerOpCodes["CfNotifyPop"]) {
- var data = new byte[64];
- Marshal.Copy(dataPtr, data, 0, 64);
-
- var notifyType = data[16];
- var contentFinderConditionId = BitConverter.ToUInt16(data, 36);
-
- if (notifyType != 3 || contentFinderConditionId == 0)
- return;
-
- var contentFinderCondition = this.dalamud.Data.GetExcelSheet().GetRow(contentFinderConditionId);
-
- if (contentFinderCondition == null)
- {
- Log.Error("CFC key {0} not in lumina data.", contentFinderConditionId);
- return;
- }
-
- Task.Run(async () => {
- this.dalamud.Framework.Gui.Chat.Print($"Duty pop: " + contentFinderCondition.Name);
-
- await this.ProcessCfPop?.Invoke(contentFinderCondition);
-
- });
-
- return;
- }
-
- if (opCode == this.dalamud.Data.ServerOpCodes["CfPreferredRole"]) {
- if (this.dalamud.Configuration.PreferredRoleReminders == null)
- return;
-
- var data = new byte[64];
- Marshal.Copy(dataPtr, data, 0, 32);
-
- if (this.lastPreferredRole == null) {
- this.lastPreferredRole = data;
- return;
- }
-
- Task.Run(async () => {
- for (var rouletteIndex = 1; rouletteIndex < 11; rouletteIndex++) {
- var currentRoleKey = data[16 + rouletteIndex];
- var prevRoleKey = this.lastPreferredRole[16 + rouletteIndex];
-
- Log.Verbose("CfPreferredRole: {0} - {1} => {2}", rouletteIndex, prevRoleKey, currentRoleKey);
-
- if (currentRoleKey != prevRoleKey) {
- var rouletteName = rouletteIndex switch {
- 1 => "Duty Roulette: Leveling",
- 2 => "Duty Roulette: Level 50/60/70 Dungeons",
- 3 => "Duty Roulette: Main Scenario",
- 4 => "Duty Roulette: Guildhests",
- 5 => "Duty Roulette: Expert",
- 6 => "Duty Roulette: Trials",
- 8 => "Duty Roulette: Mentor",
- 9 => "Duty Roulette: Alliance Raids",
- 10 => "Duty Roulette: Normal Raids",
- _ => "Unknown ContentRoulette"
- };
-
- var prevRoleName = RoleKeyToPreferredRole(prevRoleKey);
- var currentRoleName = RoleKeyToPreferredRole(currentRoleKey);
-
- if (!this.dalamud.Configuration.PreferredRoleReminders.TryGetValue(rouletteIndex, out var roleToCheck))
- return;
-
- if (roleToCheck == DalamudConfiguration.PreferredRole.All || currentRoleName != roleToCheck)
- return;
-
- this.dalamud.Framework.Gui.Chat.Print($"Roulette bonus for {rouletteName} changed: {prevRoleName} => {currentRoleName}");
-
- if (this.dalamud.BotManager.IsConnected)
- await this.dalamud.BotManager.ProcessCfPreferredRoleChange(rouletteName, prevRoleName.ToString(), currentRoleName.ToString());
- }
- }
-
- this.lastPreferredRole = data;
- });
- return;
- }
-
- if (!this.optOutMbUploads) {
- if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardItemRequestStart"]) {
- var catalogId = (uint) Marshal.ReadInt32(dataPtr + 0x10);
- var amount = Marshal.ReadByte(dataPtr + 0x1B);
-
- this.marketBoardRequests.Add(new MarketBoardItemRequest {
- CatalogId = catalogId,
- AmountToArrive = amount,
- Listings = new List(),
- History = new List()
- });
-
- Log.Verbose($"NEW MB REQUEST START: item#{catalogId} amount#{amount}");
- return;
- }
-
- if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardOfferings"]) {
- var listing = MarketBoardCurrentOfferings.Read(dataPtr + 0x10);
-
- var request =
- this.marketBoardRequests.LastOrDefault(
- r => r.CatalogId == listing.ItemListings[0].CatalogId && !r.IsDone);
-
- if (request == null) {
- Log.Error(
- $"Market Board data arrived without a corresponding request: item#{listing.ItemListings[0].CatalogId}");
- return;
- }
-
- if (request.Listings.Count + listing.ItemListings.Count > request.AmountToArrive) {
- Log.Error(
- $"Too many Market Board listings received for request: {request.Listings.Count + listing.ItemListings.Count} > {request.AmountToArrive} item#{listing.ItemListings[0].CatalogId}");
- return;
- }
-
- if (request.ListingsRequestId != -1 && request.ListingsRequestId != listing.RequestId) {
- Log.Error(
- $"Non-matching RequestIds for Market Board data request: {request.ListingsRequestId}, {listing.RequestId}");
- return;
- }
-
- if (request.ListingsRequestId == -1 && request.Listings.Count > 0) {
- Log.Error(
- $"Market Board data request sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
- return;
- }
-
- if (request.ListingsRequestId == -1) {
- request.ListingsRequestId = listing.RequestId;
- Log.Verbose($"First Market Board packet in sequence: {listing.RequestId}");
- }
-
- request.Listings.AddRange(listing.ItemListings);
-
- Log.Verbose("Added {0} ItemListings to request#{1}, now {2}/{3}, item#{4}",
- listing.ItemListings.Count, request.ListingsRequestId, request.Listings.Count,
- request.AmountToArrive, request.CatalogId);
-
- if (request.IsDone) {
- Log.Verbose("Market Board request finished, starting upload: request#{0} item#{1} amount#{2}",
- request.ListingsRequestId, request.CatalogId, request.AmountToArrive);
- try {
- Task.Run(() => this.uploader.Upload(request));
- } catch (Exception ex) {
- Log.Error(ex, "Market Board data upload failed.");
- }
- }
-
- return;
- }
-
- if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardHistory"]) {
- var listing = MarketBoardHistory.Read(dataPtr + 0x10);
-
- var request = this.marketBoardRequests.LastOrDefault(r => r.CatalogId == listing.CatalogId);
-
- if (request == null) {
- Log.Error(
- $"Market Board data arrived without a corresponding request: item#{listing.CatalogId}");
- return;
- }
-
- if (request.ListingsRequestId != -1) {
- Log.Error(
- $"Market Board data history sequence break: {request.ListingsRequestId}, {request.Listings.Count}");
- return;
- }
-
- request.History.AddRange(listing.HistoryListings);
-
- Log.Verbose("Added history for item#{0}", listing.CatalogId);
- }
-
- if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"])
- {
- var taxes = MarketTaxRates.Read(dataPtr + 0x10);
-
- Log.Verbose("MarketTaxRates: limsa#{0} grid#{1} uldah#{2} ish#{3} kugane#{4} cr#{5}",
- taxes.LimsaLominsaTax, taxes.GridaniaTax, taxes.UldahTax, taxes.IshgardTax, taxes.KuganeTax, taxes.CrystariumTax);
- try
- {
- Task.Run(() => this.uploader.UploadTax(taxes));
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Market Board data upload failed.");
- }
- }
- }
- }
-
- private DalamudConfiguration.PreferredRole RoleKeyToPreferredRole(int key) => key switch
- {
- 1 => DalamudConfiguration.PreferredRole.Tank,
- 2 => DalamudConfiguration.PreferredRole.Dps,
- 3 => DalamudConfiguration.PreferredRole.Dps,
- 4 => DalamudConfiguration.PreferredRole.Healer,
- _ => DalamudConfiguration.PreferredRole.None
- };
- }
-}
diff --git a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs b/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs
deleted file mode 100644
index 7d9f72cc8..000000000
--- a/Dalamud/Game/Network/Structures/MarketBoardCurrentOfferings.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Dalamud.Game.Network.Structures
-{
- public class MarketBoardCurrentOfferings
- {
- public List ItemListings;
-
- public int ListingIndexEnd;
- public int ListingIndexStart;
- public int RequestId;
-
- public static unsafe MarketBoardCurrentOfferings Read(IntPtr dataPtr)
- {
- var output = new MarketBoardCurrentOfferings();
-
- using (var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544))
- {
- using (var reader = new BinaryReader(stream))
- {
- output.ItemListings = new List();
-
- for (var i = 0; i < 10; i++)
- {
- var listingEntry = new MarketBoardItemListing();
-
- listingEntry.ListingId = reader.ReadUInt64();
- listingEntry.RetainerId = reader.ReadUInt64();
- listingEntry.RetainerOwnerId = reader.ReadUInt64();
- listingEntry.ArtisanId = reader.ReadUInt64();
- listingEntry.PricePerUnit = reader.ReadUInt32();
- listingEntry.TotalTax = reader.ReadUInt32();
- listingEntry.ItemQuantity = reader.ReadUInt32();
- listingEntry.CatalogId = reader.ReadUInt32();
- listingEntry.LastReviewTime = DateTimeOffset.UtcNow.AddSeconds(-reader.ReadUInt16()).DateTime;
-
- reader.ReadUInt16(); // container
- reader.ReadUInt32(); // slot
- reader.ReadUInt16(); // durability
- reader.ReadUInt16(); // spiritbond
-
- listingEntry.Materia = new List();
-
- for (var materiaIndex = 0; materiaIndex < 5; materiaIndex++)
- {
- var materiaVal = reader.ReadUInt16();
-
- var materiaEntry = new MarketBoardItemListing.ItemMateria();
- materiaEntry.MateriaId = (materiaVal & 0xFF0) >> 4;
- materiaEntry.Index = materiaVal & 0xF;
-
- if (materiaEntry.MateriaId != 0)
- listingEntry.Materia.Add(materiaEntry);
- }
-
- reader.ReadUInt16();
- reader.ReadUInt32();
-
- listingEntry.RetainerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
- listingEntry.PlayerName = Encoding.UTF8.GetString(reader.ReadBytes(32)).TrimEnd('\u0000');
- listingEntry.IsHq = reader.ReadBoolean();
- listingEntry.MateriaCount = reader.ReadByte();
- listingEntry.OnMannequin = reader.ReadBoolean();
- listingEntry.RetainerCityId = reader.ReadByte();
- listingEntry.StainId = reader.ReadUInt16();
-
- reader.ReadUInt16();
- reader.ReadUInt32();
-
- if (listingEntry.CatalogId != 0)
- output.ItemListings.Add(listingEntry);
- }
-
- output.ListingIndexEnd = reader.ReadByte();
- output.ListingIndexStart = reader.ReadByte();
- output.RequestId = reader.ReadUInt16();
- }
- }
-
- return output;
- }
-
- public class MarketBoardItemListing
- {
- public ulong ArtisanId;
- public uint CatalogId;
- public bool IsHq;
- public uint ItemQuantity;
- public DateTime LastReviewTime;
- public ulong ListingId;
-
- public List Materia;
- public int MateriaCount;
- public bool OnMannequin;
- public string PlayerName;
- public uint PricePerUnit;
- public int RetainerCityId;
- public ulong RetainerId;
-
- public string RetainerName;
- public ulong RetainerOwnerId;
- public int StainId;
- public uint TotalTax;
-
- public class ItemMateria
- {
- public int Index;
- public int MateriaId;
- }
- }
- }
-}
diff --git a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs b/Dalamud/Game/Network/Structures/MarketBoardHistory.cs
deleted file mode 100644
index c96b4a0e0..000000000
--- a/Dalamud/Game/Network/Structures/MarketBoardHistory.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace Dalamud.Game.Network.Structures {
- public class MarketBoardHistory {
- public uint CatalogId;
- public uint CatalogId2;
-
- public List HistoryListings;
-
- public static unsafe MarketBoardHistory Read(IntPtr dataPtr) {
- var output = new MarketBoardHistory();
-
- using (var stream = new UnmanagedMemoryStream((byte*) dataPtr.ToPointer(), 1544)) {
- using (var reader = new BinaryReader(stream)) {
- output.CatalogId = reader.ReadUInt32();
- output.CatalogId2 = reader.ReadUInt32();
-
- output.HistoryListings = new List();
-
- for (var i = 0; i < 10; i++) {
- var listingEntry = new MarketBoardHistoryListing();
-
- listingEntry.SalePrice = reader.ReadUInt32();
- listingEntry.PurchaseTime = DateTimeOffset.FromUnixTimeSeconds(reader.ReadUInt32()).UtcDateTime;
- listingEntry.Quantity = reader.ReadUInt32();
- listingEntry.IsHq = reader.ReadBoolean();
-
- reader.ReadBoolean();
-
- listingEntry.OnMannequin = reader.ReadBoolean();
- listingEntry.BuyerName = Encoding.UTF8.GetString(reader.ReadBytes(33)).TrimEnd('\u0000');
- listingEntry.CatalogId = reader.ReadUInt32();
-
- if (listingEntry.CatalogId != 0)
- output.HistoryListings.Add(listingEntry);
- }
- }
- }
-
- return output;
- }
-
- public class MarketBoardHistoryListing {
- public string BuyerName;
-
- public uint CatalogId;
- public bool IsHq;
- public bool OnMannequin;
- public DateTime PurchaseTime;
- public uint Quantity;
- public uint SalePrice;
- }
- }
-}
diff --git a/Dalamud/Game/Network/Structures/MarketTaxRate.cs b/Dalamud/Game/Network/Structures/MarketTaxRate.cs
deleted file mode 100644
index b0ce2772c..000000000
--- a/Dalamud/Game/Network/Structures/MarketTaxRate.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using System.Text;
-
-namespace Dalamud.Game.Network.Structures
-{
- public class MarketTaxRates
- {
- public uint LimsaLominsaTax;
- public uint GridaniaTax;
- public uint UldahTax;
- public uint IshgardTax;
- public uint KuganeTax;
- public uint CrystariumTax;
-
-
- public static unsafe MarketTaxRates Read(IntPtr dataPtr)
- {
- var output = new MarketTaxRates();
-
- using (var stream = new UnmanagedMemoryStream((byte*)dataPtr.ToPointer(), 1544))
- {
- using (var reader = new BinaryReader(stream))
- {
- stream.Position += 8;
-
- output.LimsaLominsaTax = reader.ReadUInt32();
- output.GridaniaTax = reader.ReadUInt32();
- output.UldahTax = reader.ReadUInt32();
- output.IshgardTax = reader.ReadUInt32();
- output.KuganeTax = reader.ReadUInt32();
- output.CrystariumTax = reader.ReadUInt32();
- }
- }
-
- return output;
- }
- }
-}
diff --git a/Dalamud/Game/Network/WinSockHandlers.cs b/Dalamud/Game/Network/WinSockHandlers.cs
deleted file mode 100644
index f2d9d9706..000000000
--- a/Dalamud/Game/Network/WinSockHandlers.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using Dalamud.Hooking;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Sockets;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Game
-{
- internal sealed class WinSockHandlers : IDisposable
- {
- [UnmanagedFunctionPointer(CallingConvention.Winapi)]
- private delegate IntPtr SocketDelegate(int af, int type, int protocol);
- private Hook ws2SocketHook;
-
- [DllImport("ws2_32.dll", CallingConvention = CallingConvention.Winapi)]
- private static extern int setsockopt(IntPtr socket, SocketOptionLevel level, SocketOptionName optName, ref IntPtr optVal, int optLen);
-
- public WinSockHandlers() {
- this.ws2SocketHook = Hook.FromSymbol("ws2_32.dll", "socket", new SocketDelegate(OnSocket));
- this.ws2SocketHook.Enable();
- }
-
- private IntPtr OnSocket(int af, int type, int protocol)
- {
- var socket = this.ws2SocketHook.Original(af, type, protocol);
-
- // IPPROTO_TCP
- if (type == 1)
- {
- // INVALID_SOCKET
- if (socket != new IntPtr(-1))
- {
- // In case you're not aware of it: (albeit you should)
- // https://linux.die.net/man/7/tcp
- // https://assets.extrahop.com/whitepapers/TCP-Optimization-Guide-by-ExtraHop.pdf
- var value = new IntPtr(1);
- setsockopt(socket, SocketOptionLevel.Tcp, SocketOptionName.NoDelay, ref value, 4);
-
- // Enable tcp_quickack option. This option is undocumented in MSDN but it is supported in Windows 7 and onwards.
- value = new IntPtr(1);
- setsockopt(socket, SocketOptionLevel.Tcp, (SocketOptionName)12, ref value, 4);
- }
- }
-
- return socket;
- }
-
- public void Dispose() {
- ws2SocketHook.Dispose();
- }
- }
-}
diff --git a/Dalamud/Game/SigScanner.cs b/Dalamud/Game/SigScanner.cs
deleted file mode 100644
index 1d4fc7df8..000000000
--- a/Dalamud/Game/SigScanner.cs
+++ /dev/null
@@ -1,251 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Serilog;
-
-namespace Dalamud.Game {
- ///
- /// A SigScanner facilitates searching for memory signatures in a given ProcessModule.
- ///
- public sealed class SigScanner : IDisposable {
- ///
- /// Set up the SigScanner.
- ///
- /// The ProcessModule to be used for scanning
- /// Whether or not to copy the module upon initialization for search operations to use, as to not get disturbed by possible hooks.
- public SigScanner(ProcessModule module, bool doCopy = false) {
- Module = module;
- Is32BitProcess = !Environment.Is64BitProcess;
- IsCopy = doCopy;
-
- // Limit the search space to .text section.
- SetupSearchSpace(module);
-
- if (IsCopy)
- SetupCopiedSegments();
-
- Log.Verbose("Module base: {Address}", TextSectionBase);
- Log.Verbose("Module size: {Size}", TextSectionSize);
- }
-
- ///
- /// If the search on this module is performed on a copy.
- ///
- public bool IsCopy { get; private set; }
-
- ///
- /// If the ProcessModule is 32-bit.
- ///
- public bool Is32BitProcess { get; }
-
- ///
- /// The base address of the search area. When copied, this will be the address of the copy.
- ///
- public IntPtr SearchBase => IsCopy ? this.moduleCopyPtr : Module.BaseAddress;
-
- ///
- /// The base address of the .text section search area.
- ///
- public IntPtr TextSectionBase => new IntPtr(SearchBase.ToInt64() + TextSectionOffset);
- ///
- /// The offset of the .text section from the base of the module.
- ///
- public long TextSectionOffset { get; private set; }
- ///
- /// The size of the text section.
- ///
- public int TextSectionSize { get; private set; }
-
- ///
- /// The base address of the .data section search area.
- ///
- public IntPtr DataSectionBase => new IntPtr(SearchBase.ToInt64() + DataSectionOffset);
- ///
- /// The offset of the .data section from the base of the module.
- ///
- public long DataSectionOffset { get; private set; }
- ///
- /// The size of the .data section.
- ///
- public int DataSectionSize { get; private set; }
-
- ///
- /// The ProcessModule on which the search is performed.
- ///
- public ProcessModule Module { get; }
-
- private IntPtr TextSectionTop => TextSectionBase + TextSectionSize;
-
- private void SetupSearchSpace(ProcessModule module) {
- var baseAddress = module.BaseAddress;
-
- // We don't want to read all of IMAGE_DOS_HEADER or IMAGE_NT_HEADER stuff so we cheat here.
- var ntNewOffset = Marshal.ReadInt32(baseAddress, 0x3C);
- var ntHeader = baseAddress + ntNewOffset;
-
- // IMAGE_NT_HEADER
- var fileHeader = ntHeader + 4;
- var numSections = Marshal.ReadInt16(ntHeader, 6);
-
- // IMAGE_OPTIONAL_HEADER
- var optionalHeader = fileHeader + 20;
-
- IntPtr sectionHeader;
- if (Is32BitProcess) // IMAGE_OPTIONAL_HEADER32
- sectionHeader = optionalHeader + 224;
- else // IMAGE_OPTIONAL_HEADER64
- sectionHeader = optionalHeader + 240;
-
- // IMAGE_SECTION_HEADER
- var sectionCursor = sectionHeader;
- for (var i = 0; i < numSections; i++) {
- var sectionName = Marshal.ReadInt64(sectionCursor);
-
- // .text
- switch (sectionName) {
- case 0x747865742E: // .text
- TextSectionOffset = Marshal.ReadInt32(sectionCursor, 12);
- TextSectionSize = Marshal.ReadInt32(sectionCursor, 8);
- break;
- case 0x617461642E: // .data
- DataSectionOffset = Marshal.ReadInt32(sectionCursor, 12);
- DataSectionSize = Marshal.ReadInt32(sectionCursor, 8);
- break;
- }
-
- sectionCursor += 40;
- }
- }
-
- private IntPtr moduleCopyPtr;
- private long moduleCopyOffset;
-
- private unsafe void SetupCopiedSegments() {
- Log.Verbose("module copy START");
- // .text
- this.moduleCopyPtr = Marshal.AllocHGlobal(Module.ModuleMemorySize);
- Log.Verbose($"Alloc: {this.moduleCopyPtr.ToInt64():x}");
- Buffer.MemoryCopy(Module.BaseAddress.ToPointer(), this.moduleCopyPtr.ToPointer(), Module.ModuleMemorySize,
- Module.ModuleMemorySize);
-
- this.moduleCopyOffset = this.moduleCopyPtr.ToInt64() - Module.BaseAddress.ToInt64();
-
- Log.Verbose("copy OK!");
- }
-
- ///
- /// Free the memory of the copied module search area on object disposal, if applicable.
- ///
- public void Dispose() {
- Marshal.FreeHGlobal(this.moduleCopyPtr);
- }
-
- ///
- /// Scan for a byte signature in the .text section.
- ///
- /// The signature.
- /// The real offset of the found signature.
- public IntPtr ScanText(string signature) {
- var mBase = IsCopy ? this.moduleCopyPtr : TextSectionBase;
-
- var scanRet = Scan(mBase, TextSectionSize, signature);
-
- if (IsCopy)
- scanRet = new IntPtr(scanRet.ToInt64() - this.moduleCopyOffset);
-
- return scanRet;
- }
-
- ///
- /// Scan for a byte signature in the .data section.
- ///
- /// The signature.
- /// The real offset of the found signature.
- public IntPtr ScanData(string signature) {
- var scanRet = Scan(DataSectionBase, DataSectionSize, signature);
-
- if (IsCopy)
- scanRet = new IntPtr(scanRet.ToInt64() - this.moduleCopyOffset);
-
- return scanRet;
- }
-
- ///
- /// Scan for a byte signature in the whole module search area.
- ///
- /// The signature.
- /// The real offset of the found signature.
- public IntPtr ScanModule(string signature) {
- var scanRet = Scan(SearchBase, Module.ModuleMemorySize, signature);
-
- if (IsCopy)
- scanRet = new IntPtr(scanRet.ToInt64() - this.moduleCopyOffset);
-
- return scanRet;
- }
-
- public IntPtr Scan(IntPtr baseAddress, int size, string signature) {
- var needle = SigToNeedle(signature);
-
- unsafe {
- var pCursor = (byte*) baseAddress.ToPointer();
- var pTop = (byte*) (baseAddress + size - needle.Length);
- while (pCursor < pTop) {
- if (IsMatch(pCursor, needle)) return (IntPtr) pCursor;
-
- // Advance an offset
- pCursor += 1;
- }
- }
-
- throw new KeyNotFoundException($"Can't find a signature of {signature}");
- }
-
- public IntPtr ResolveRelativeAddress(IntPtr nextInstAddr, int relOffset) {
- if (Is32BitProcess) throw new NotSupportedException("32 bit is not supported.");
-
- return nextInstAddr + relOffset;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private unsafe bool IsMatch(byte* pCursor, byte?[] needle) {
- for (var i = 0; i < needle.Length; i++) {
- var expected = needle[i];
- if (expected == null) continue;
-
- var actual = *(pCursor + i);
- if (expected != actual) return false;
- }
-
- return true;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private byte?[] SigToNeedle(string signature) {
- // Strip all whitespaces
- signature = signature.Replace(" ", "");
-
- if (signature.Length % 2 != 0)
- throw new ArgumentException("Signature without whitespaces must be divisible by two.",
- nameof(signature));
-
- var needleLength = signature.Length / 2;
- var needle = new byte?[needleLength];
-
- for (var i = 0; i < needleLength; i++) {
- var hexString = signature.Substring(i * 2, 2);
- if (hexString == "??" || hexString == "**") {
- needle[i] = null;
- continue;
- }
-
- needle[i] = byte.Parse(hexString, NumberStyles.AllowHexSpecifier);
- }
-
- return needle;
- }
- }
-}
diff --git a/Dalamud/Hooking/Hook.cs b/Dalamud/Hooking/Hook.cs
deleted file mode 100644
index c6311a79d..000000000
--- a/Dalamud/Hooking/Hook.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using EasyHook;
-
-namespace Dalamud.Hooking {
- ///
- /// Manages a hook which can be used to intercept a call to native function.
- /// This class is basically a thin wrapper around the LocalHook type to provide helper functions.
- ///
- /// Delegate type to represents a function prototype. This must be the same prototype as original function do.
- public sealed class Hook : IDisposable where T : Delegate {
- private bool isDisposed;
-
- private readonly IntPtr address;
-
- private readonly T original;
-
- private readonly LocalHook hookInfo;
-
- ///
- /// A memory address of the target function.
- ///
- /// Hook is already disposed.
- public IntPtr Address {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get {
- CheckDisposed();
- return this.address;
- }
- }
-
- ///
- /// A delegate function that can be used to call the actual function as if function is not hooked yet.
- ///
- ///
- /// Hook is already disposed.
- public T Original {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get {
- CheckDisposed();
- return this.original;
- }
- }
-
-
- ///
- /// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function. Hook is not activated until Enable() method is called.
- ///
- /// A name of the module currently loaded in the memory. (e.g. ws2_32.dll)
- /// A name of the exported function name (e.g. send)
- /// Callback function. Delegate must have a same original function prototype.
- /// A callback object which can be accessed within the detour.
- ///
- public static Hook FromSymbol(string moduleName, string exportName, Delegate detour, object callbackParam = null) {
- // Get a function address from the symbol name.
- var address = LocalHook.GetProcAddress(moduleName, exportName);
-
- return new Hook(address, detour, callbackParam);
- }
-
- ///
- /// Createss a hook. Hook is not activated until Enable() method is called.
- ///
- /// A memory address to install a hook.
- /// Callback function. Delegate must have a same original function prototype.
- /// A callback object which can be accessed within the detour.
- public Hook(IntPtr address, Delegate detour, object callbackParam = null) {
- this.hookInfo = LocalHook.Create(address, detour, callbackParam); // Installs a hook here
- this.address = address;
- this.original = Marshal.GetDelegateForFunctionPointer(this.hookInfo.HookBypassAddress);
- }
-
- ///
- /// Remove a hook from the current process.
- ///
- public void Dispose() {
- if (this.isDisposed) {
- return;
- }
-
- this.hookInfo.Dispose();
-
- this.isDisposed = true;
- }
-
- ///
- /// Starts intercepting a call to the function.
- ///
- public void Enable() {
- CheckDisposed();
-
- this.hookInfo.ThreadACL.SetExclusiveACL(null);
- }
-
- ///
- /// Stops intercepting a call to the function.
- ///
- public void Disable() {
- CheckDisposed();
-
- this.hookInfo.ThreadACL.SetInclusiveACL(null);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void CheckDisposed() {
- if (this.isDisposed) {
- throw new ObjectDisposedException("Hook is already disposed.");
- }
- }
- }
-}
diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs
deleted file mode 100644
index 6290cbb40..000000000
--- a/Dalamud/Interface/DalamudDataWindow.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Data;
-using ImGuiNET;
-using Newtonsoft.Json;
-
-namespace Dalamud.Interface
-{
- class DalamudDataWindow {
- private DataManager dataMgr;
-
- private bool wasReady;
- private string serverOpString;
- private string cfcString = "N/A";
-
- private int currentKind;
-
- public DalamudDataWindow(DataManager dataMgr) {
- this.dataMgr = dataMgr;
-
- Load();
- }
-
- private void Load() {
- if (this.dataMgr.IsDataReady)
- {
- this.serverOpString = JsonConvert.SerializeObject(this.dataMgr.ServerOpCodes, Formatting.Indented);
- this.wasReady = true;
- }
- }
-
- public bool Draw()
- {
- ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.Always);
-
- var isOpen = true;
-
- if (!ImGui.Begin("Dalamud Data", ref isOpen, ImGuiWindowFlags.NoCollapse))
- {
- ImGui.End();
- return false;
- }
-
- // Main window
- if (ImGui.Button("Force Reload"))
- Load();
- ImGui.SameLine();
- var copy = ImGui.Button("Copy all");
- ImGui.SameLine();
- ImGui.Combo("Data kind", ref currentKind, new[] {"ServerOpCode", "ContentFinderCondition"}, 2);
-
- ImGui.BeginChild("scrolling", new Vector2(0, 0), false, ImGuiWindowFlags.HorizontalScrollbar);
-
- if (copy)
- ImGui.LogToClipboard();
-
- ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
-
- if (this.wasReady) {
- switch (currentKind) {
- case 0: ImGui.TextUnformatted(this.serverOpString);
- break;
- case 1: ImGui.TextUnformatted(this.cfcString);
- break;
- }
- } else {
- ImGui.TextUnformatted("Data not ready.");
- }
-
- ImGui.PopStyleVar();
-
- ImGui.EndChild();
- ImGui.End();
-
- return isOpen;
- }
- }
-}
diff --git a/Dalamud/Interface/DalamudLogWindow.cs b/Dalamud/Interface/DalamudLogWindow.cs
deleted file mode 100644
index 5d49c961a..000000000
--- a/Dalamud/Interface/DalamudLogWindow.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-using System.Threading.Tasks;
-using ImGuiNET;
-
-namespace Dalamud.Interface
-{
- class DalamudLogWindow : IDisposable {
- private bool autoScroll = true;
- private string logText = string.Empty;
-
- public DalamudLogWindow() {
- SerilogEventSink.Instance.OnLogLine += Serilog_OnLogLine;
- }
-
- public void Dispose() {
- SerilogEventSink.Instance.OnLogLine -= Serilog_OnLogLine;
- }
-
- private void Serilog_OnLogLine(object sender, string e)
- {
- AddLog(e + "\n");
- }
-
- public void Clear() {
- this.logText = string.Empty;
- }
-
- public void AddLog(string line) {
- this.logText += line;
- }
-
- public bool Draw() {
- ImGui.SetNextWindowSize(new Vector2(500, 400), ImGuiCond.FirstUseEver);
-
- var isOpen = true;
-
- if (!ImGui.Begin("Dalamud LOG", ref isOpen, ImGuiWindowFlags.NoCollapse))
- {
- ImGui.End();
- return false;
- }
-
- // Options menu
- if (ImGui.BeginPopup("Options"))
- {
- ImGui.Checkbox("Auto-scroll", ref this.autoScroll);
- ImGui.EndPopup();
- }
-
- // Main window
- if (ImGui.Button("Options"))
- ImGui.OpenPopup("Options");
- ImGui.SameLine();
- var clear = ImGui.Button("Clear");
- ImGui.SameLine();
- var copy = ImGui.Button("Copy");
-
- ImGui.BeginChild("scrolling", new Vector2(0, 0), false, ImGuiWindowFlags.HorizontalScrollbar);
-
- if (clear)
- Clear();
- if (copy)
- ImGui.LogToClipboard();
-
- ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
-
- ImGui.TextUnformatted(this.logText);
-
- ImGui.PopStyleVar();
-
- if (this.autoScroll && ImGui.GetScrollY() >= ImGui.GetScrollMaxY())
- ImGui.SetScrollHereY(1.0f);
-
- ImGui.EndChild();
- ImGui.End();
-
- return isOpen;
- }
- }
-}
diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs
deleted file mode 100644
index 7c0c25bd7..000000000
--- a/Dalamud/Interface/InterfaceManager.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-using System;
-using System.IO;
-using System.Numerics;
-using System.Runtime.InteropServices;
-using Dalamud.Game;
-using Dalamud.Game.Internal.DXGI;
-using Dalamud.Hooking;
-using EasyHook;
-using ImGuiNET;
-using ImGuiScene;
-using Serilog;
-
-// general dev notes, here because it's easiest
-/*
- * - Hooking ResizeBuffers seemed to be unnecessary, though I'm not sure why. Left out for now since it seems to work without it.
- * - We may want to build our ImGui command list in a thread to keep it divorced from present. We'd still have to block in present to
- * synchronize on the list and render it, but ideally the overall delay we add to present would then be shorter. This may cause minor
- * timing issues with anything animated inside ImGui, but that is probably rare and may not even be noticeable.
- * - Our hook is too low level to really work well with debugging, as we only have access to the 'real' dx objects and not any
- * that have been hooked/wrapped by tools.
- * - Might eventually want to render to a separate target and composite, especially with reshade etc in the mix.
- */
-
-namespace Dalamud.Interface
-{
- public class InterfaceManager : IDisposable
- {
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr PresentDelegate(IntPtr swapChain, uint syncInterval, uint presentFlags);
-
- private readonly Hook presentHook;
-
- private readonly Hook setCursorHook;
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr SetCursorDelegate(IntPtr hCursor);
-
- private ISwapChainAddressResolver Address { get; }
-
- private Dalamud dalamud;
- private RawDX11Scene scene;
-
- ///
- /// This event gets called by a plugin UiBuilder when read
- ///
- public event RawDX11Scene.BuildUIDelegate OnDraw;
-
- public InterfaceManager(Dalamud dalamud, SigScanner scanner)
- {
- this.dalamud = dalamud;
-
- try {
- var sigResolver = new SwapChainSigResolver();
- sigResolver.Setup(scanner);
-
- Log.Verbose("Found SwapChain via signatures.");
-
- Address = sigResolver;
- } catch (Exception ex) {
- // The SigScanner method fails on wine/proton since DXGI is not a real DLL. We fall back to vtable to detect our Present function address.
- Log.Error(ex, "Could not get SwapChain address via sig method, falling back to vtable...");
-
- var vtableResolver = new SwapChainVtableResolver();
- vtableResolver.Setup(scanner);
-
- Log.Verbose("Found SwapChain via vtable.");
-
- Address = vtableResolver;
- }
-
- var setCursorAddr = LocalHook.GetProcAddress("user32.dll", "SetCursor");
-
- Log.Verbose("===== S W A P C H A I N =====");
- Log.Verbose("SetCursor address {SetCursor}", setCursorAddr);
- Log.Verbose("Present address {Present}", Address.Present);
-
- this.setCursorHook = new Hook(setCursorAddr, new SetCursorDelegate(SetCursorDetour), this);
-
- this.presentHook =
- new Hook(Address.Present,
- new PresentDelegate(PresentDetour),
- this);
- }
-
- public void Enable()
- {
- this.setCursorHook.Enable();
- this.presentHook.Enable();
- }
-
- private void Disable()
- {
- this.setCursorHook.Disable();
- this.presentHook.Disable();
- }
-
- public void Dispose()
- {
- // HACK: this is usually called on a separate thread from PresentDetour (likely on a dedicated render thread)
- // and if we aren't already disabled, disposing of the scene and hook can frequently crash due to the hook
- // being disposed of in this thread while it is actively in use in the render thread.
- // This is a terrible way to prevent issues, but should basically always work to ensure that all outstanding
- // calls to PresentDetour have finished (and Disable means no new ones will start), before we try to cleanup
- // So... not great, but much better than constantly crashing on unload
- this.Disable();
- System.Threading.Thread.Sleep(100);
-
- this.scene.Dispose();
- this.presentHook.Dispose();
- }
-
- public TextureWrap LoadImage(string filePath)
- {
- try
- {
- return this.scene?.LoadImage(filePath) ?? null;
- }
- catch (Exception ex)
- {
- Log.Error(ex, $"Failed to load image from {filePath}");
- }
- return null;
- }
-
- public TextureWrap LoadImage(byte[] imageData)
- {
- try
- {
- return this.scene?.LoadImage(imageData) ?? null;
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Failed to load image from memory");
- }
- return null;
- }
-
- private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
- {
- if (this.scene == null)
- {
- this.scene = new RawDX11Scene(swapChain);
- this.scene.ImGuiIniPath = Path.Combine(Path.GetDirectoryName(this.dalamud.StartInfo.ConfigurationPath), "dalamudUI.ini");
- this.scene.OnBuildUI += Display;
-
- var fontPathJp = Path.Combine(Path.GetDirectoryName(typeof(InterfaceManager).Assembly.Location), "UIRes", "NotoSansCJKjp-Medium.otf");
- ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathJp, 17.0f, null, ImGui.GetIO().Fonts.GetGlyphRangesJapanese());
-
- ImGui.GetIO().Fonts.Build();
-
- ImGui.GetStyle().GrabRounding = 3f;
- ImGui.GetStyle().FrameRounding = 4f;
- ImGui.GetStyle().WindowRounding = 4f;
- ImGui.GetStyle().WindowBorderSize = 0f;
- ImGui.GetStyle().WindowMenuButtonPosition = ImGuiDir.Right;
- ImGui.GetStyle().ScrollbarSize = 16f;
-
- ImGui.GetStyle().Colors[(int) ImGuiCol.WindowBg] = new Vector4(0.06f, 0.06f, 0.06f, 0.87f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.FrameBg] = new Vector4(0.29f, 0.29f, 0.29f, 0.54f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.FrameBgHovered] = new Vector4(0.54f, 0.54f, 0.54f, 0.40f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.FrameBgActive] = new Vector4(0.64f, 0.64f, 0.64f, 0.67f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.TitleBgActive] = new Vector4(0.29f, 0.29f, 0.29f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.CheckMark] = new Vector4(0.86f, 0.86f, 0.86f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.SliderGrab] = new Vector4(0.54f, 0.54f, 0.54f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.SliderGrabActive] = new Vector4(0.67f, 0.67f, 0.67f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.Button] = new Vector4(0.71f, 0.71f, 0.71f, 0.40f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.ButtonHovered] = new Vector4(0.47f, 0.47f, 0.47f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.ButtonActive] = new Vector4(0.74f, 0.74f, 0.74f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.Header] = new Vector4(0.59f, 0.59f, 0.59f, 0.31f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.HeaderHovered] = new Vector4(0.50f, 0.50f, 0.50f, 0.80f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.HeaderActive] = new Vector4(0.60f, 0.60f, 0.60f, 1.00f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.ResizeGrip] = new Vector4(0.79f, 0.79f, 0.79f, 0.25f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.ResizeGripHovered] = new Vector4(0.78f, 0.78f, 0.78f, 0.67f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.ResizeGripActive] = new Vector4(0.88f, 0.88f, 0.88f, 0.95f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.Tab] = new Vector4(0.23f, 0.23f, 0.23f, 0.86f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.TabHovered] = new Vector4(0.71f, 0.71f, 0.71f, 0.80f);
- ImGui.GetStyle().Colors[(int) ImGuiCol.TabActive] = new Vector4(0.36f, 0.36f, 0.36f, 1.00f);
- }
-
- this.scene.Render();
-
- return this.presentHook.Original(swapChain, syncInterval, presentFlags);
- }
-
- // can't access imgui IO before first present call
- private bool lastWantCapture = false;
-
- private IntPtr SetCursorDetour(IntPtr hCursor) {
- if (this.lastWantCapture == true && (!scene?.IsImGuiCursor(hCursor) ?? false))
- return IntPtr.Zero;
-
- return this.setCursorHook.Original(hCursor);
- }
-
- private void Display()
- {
- // this is more or less part of what reshade/etc do to avoid having to manually
- // set the cursor inside the ui
- // This will just tell ImGui to draw its own software cursor instead of using the hardware cursor
- // The scene internally will handle hiding and showing the hardware (game) cursor
- // If the player has the game software cursor enabled, we can't really do anything about that and
- // they will see both cursors.
- // Doing this here because it's somewhat application-specific behavior
- //ImGui.GetIO().MouseDrawCursor = ImGui.GetIO().WantCaptureMouse;
- this.lastWantCapture = ImGui.GetIO().WantCaptureMouse;
-
- OnDraw?.Invoke();
- }
- }
-}
diff --git a/Dalamud/Interface/SerilogEventSink.cs b/Dalamud/Interface/SerilogEventSink.cs
deleted file mode 100644
index 3e0f7d2d2..000000000
--- a/Dalamud/Interface/SerilogEventSink.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Serilog;
-using Serilog.Configuration;
-using Serilog.Core;
-using Serilog.Events;
-
-namespace Dalamud.Interface
-{
- public class SerilogEventSink : ILogEventSink
- {
- private readonly IFormatProvider _formatProvider;
-
- public static SerilogEventSink Instance;
-
- public event EventHandler OnLogLine;
-
- public SerilogEventSink(IFormatProvider formatProvider)
- {
- _formatProvider = formatProvider;
-
- Instance = this;
- }
-
- public void Emit(LogEvent logEvent)
- {
- var message = $"[{DateTimeOffset.Now.ToString()}][{logEvent.Level}] {logEvent.RenderMessage(_formatProvider)}";
-
- if (logEvent.Exception != null)
- message += "\n" + logEvent.Exception;
-
- OnLogLine?.Invoke(this, message);
- }
- }
-
- public static class MySinkExtensions
- {
- public static LoggerConfiguration EventSink(
- this LoggerSinkConfiguration loggerConfiguration,
- IFormatProvider formatProvider = null)
- {
- return loggerConfiguration.Sink(new SerilogEventSink(formatProvider));
- }
- }
-}
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
deleted file mode 100644
index 0e689236d..000000000
--- a/Dalamud/Interface/UiBuilder.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using ImGuiNET;
-using ImGuiScene;
-
-namespace Dalamud.Interface
-{
- ///
- /// This class represents the Dalamud UI that is drawn on top of the game.
- /// It can be used to draw custom windows and overlays.
- ///
- public class UiBuilder : IDisposable {
- private readonly string namespaceName;
-
- ///
- /// The delegate that gets called when Dalamud is ready to draw your windows or overlays.
- /// When it is called, you can use static ImGui calls.
- ///
- public event RawDX11Scene.BuildUIDelegate OnBuildUi;
-
- private readonly InterfaceManager interfaceManager;
-
- ///
- /// Create a new UiBuilder and register it. You do not have to call this manually.
- ///
- /// The interface manager to register on.
- /// The plugin namespace.
- public UiBuilder(InterfaceManager interfaceManager, string namespaceName) {
- this.namespaceName = namespaceName;
-
- this.interfaceManager = interfaceManager;
- this.interfaceManager.OnDraw += OnDraw;
- }
-
- ///
- /// Unregister the UiBuilder. Do not call this in plugin code.
- ///
- public void Dispose() {
- this.interfaceManager.OnDraw -= OnDraw;
- }
-
- ///
- /// Loads an image from the specified file.
- ///
- /// The full filepath to the image.
- /// A object wrapping the created image. Use inside ImGui.Image()
- public TextureWrap LoadImage(string filePath) =>
- this.interfaceManager.LoadImage(filePath);
-
- ///
- /// Loads an image from a byte stream, such as a png downloaded into memory.
- ///
- /// A byte array containing the raw image data.
- /// A object wrapping the created image. Use inside ImGui.Image()
- public TextureWrap LoadImage(byte[] imageData) =>
- this.interfaceManager.LoadImage(imageData);
-
- private void OnDraw() {
- ImGui.PushID(this.namespaceName);
- OnBuildUi?.Invoke();
- ImGui.PopID();
- }
- }
-}
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
deleted file mode 100644
index d6d603346..000000000
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Configuration;
-using Dalamud.Data;
-using Dalamud.Game;
-using Dalamud.Game.ClientState;
-using Dalamud.Game.Command;
-using Dalamud.Game.Internal;
-using Dalamud.Game.Internal.Gui;
-using Dalamud.Interface;
-
-namespace Dalamud.Plugin
-{
- ///
- /// This class acts as an interface to various objects needed to interact with Dalamud and the game.
- ///
- public class DalamudPluginInterface : IDisposable {
- ///
- /// The CommandManager object that allows you to add and remove custom chat commands.
- ///
- public readonly CommandManager CommandManager;
-
- ///
- /// The ClientState object that allows you to access current client memory information like actors, territories, etc.
- ///
- public readonly ClientState ClientState;
-
- ///
- /// The Framework object that allows you to interact with the client.
- ///
- public readonly Framework Framework;
-
- ///
- /// A UiBuilder instance which allows you to draw UI into the game via ImGui draw calls.
- ///
- public readonly UiBuilder UiBuilder;
-
- ///
- /// A SigScanner instance targeting the main module of the FFXIV process.
- ///
- public readonly SigScanner TargetModuleScanner;
-
- ///
- /// A DataManager instance which allows you to access game data needed by the main dalamud features.
- ///
- public readonly DataManager Data;
-
- private readonly Dalamud dalamud;
- private readonly string pluginName;
-
- ///
- /// Set up the interface and populate all fields needed.
- ///
- ///
- public DalamudPluginInterface(Dalamud dalamud, string pluginName) {
- this.CommandManager = dalamud.CommandManager;
- this.Framework = dalamud.Framework;
- this.ClientState = dalamud.ClientState;
- this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, pluginName);
- this.TargetModuleScanner = dalamud.SigScanner;
- this.Data = dalamud.Data;
-
- this.dalamud = dalamud;
- this.pluginName = pluginName;
- }
-
- ///
- /// Unregister your plugin and dispose all references. You have to call this when your IDalamudPlugin is disposed.
- ///
- public void Dispose() {
- this.UiBuilder.Dispose();
- }
-
- ///
- /// Save a plugin configuration(inheriting IPluginConfiguration).
- ///
- /// The current configuration.
- public void SavePluginConfig(IPluginConfiguration currentConfig) {
- if (this.dalamud.Configuration.PluginConfigurations == null)
- this.dalamud.Configuration.PluginConfigurations = new Dictionary();
-
- if (this.dalamud.Configuration.PluginConfigurations.ContainsKey(this.pluginName)) {
- this.dalamud.Configuration.PluginConfigurations[this.pluginName] = currentConfig;
- return;
- }
-
- if (currentConfig == null)
- return;
-
- this.dalamud.Configuration.PluginConfigurations.Add(this.pluginName, currentConfig);
- this.dalamud.Configuration.Save(this.dalamud.StartInfo.ConfigurationPath);
- }
-
- ///
- /// Get a previously saved plugin configuration or null if none was saved before.
- ///
- /// A previously saved config or null if none was saved before.
- public IPluginConfiguration GetPluginConfig() {
- if (this.dalamud.Configuration.PluginConfigurations == null)
- this.dalamud.Configuration.PluginConfigurations = new Dictionary();
-
- if (!this.dalamud.Configuration.PluginConfigurations.ContainsKey(this.pluginName))
- return null;
-
- return this.dalamud.Configuration.PluginConfigurations[this.pluginName] as IPluginConfiguration;
- }
-
- #region Logging
-
- ///
- /// Log a templated message to the in-game debug log.
- ///
- /// The message template.
- /// Values to log.
- public void Log(string messageTemplate, params object[] values) {
- Serilog.Log.Information(messageTemplate, values);
- }
-
- ///
- /// Log a templated error message to the in-game debug log.
- ///
- /// The message template.
- /// Values to log.
- public void LogError(string messageTemplate, params object[] values)
- {
- Serilog.Log.Error(messageTemplate, values);
- }
-
- ///
- /// Log a templated error message to the in-game debug log.
- ///
- /// The exception that caused the error.
- /// The message template.
- /// Values to log.
- public void LogError(Exception exception, string messageTemplate, params object[] values)
- {
- Serilog.Log.Error(exception, messageTemplate, values);
- }
-
- #endregion
- }
-}
diff --git a/Dalamud/Plugin/Features/IHasConfigUi.cs b/Dalamud/Plugin/Features/IHasConfigUi.cs
deleted file mode 100644
index 53e64ea98..000000000
--- a/Dalamud/Plugin/Features/IHasConfigUi.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using Dalamud.Interface;
-
-namespace Dalamud.Plugin.Features
-{
- ///
- /// This interface represents a Dalamud plugin that has a configuration UI which can be triggered.
- ///
- public interface IHasConfigUi : IHasUi
- {
- ///
- /// An event handler that is fired when the plugin should show its configuration interface.
- ///
- EventHandler OpenConfigUi { get; }
- }
-}
diff --git a/Dalamud/Plugin/Features/IHasUi.cs b/Dalamud/Plugin/Features/IHasUi.cs
deleted file mode 100644
index afdb74df8..000000000
--- a/Dalamud/Plugin/Features/IHasUi.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Interface;
-
-namespace Dalamud.Plugin.Features
-{
- ///
- /// This interface represents a Dalamud plugin that has user interface which can be drawn.
- ///
- public interface IHasUi : IDalamudPlugin
- {
- ///
- /// A function that gets called when Dalamud is ready to draw your UI.
- ///
- /// An object you can use to e.g. load images.
- void Draw(UiBuilder uiBuilder);
- }
-}
diff --git a/Dalamud/Plugin/IDalamudPlugin.cs b/Dalamud/Plugin/IDalamudPlugin.cs
deleted file mode 100644
index 2e1cb67a8..000000000
--- a/Dalamud/Plugin/IDalamudPlugin.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Plugin
-{
- ///
- /// This interface represents a basic Dalamud plugin. All plugins have to implement this interface.
- ///
- public interface IDalamudPlugin : IDisposable
- {
- ///
- /// The name of the plugin.
- ///
- string Name { get; }
-
- ///
- /// Initializes a Dalamud plugin.
- ///
- /// The needed to access various Dalamud objects.
- void Initialize(DalamudPluginInterface pluginInterface);
- }
-}
diff --git a/Dalamud/Plugin/PluginDefinition.cs b/Dalamud/Plugin/PluginDefinition.cs
deleted file mode 100644
index 29b373b75..000000000
--- a/Dalamud/Plugin/PluginDefinition.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dalamud.Plugin
-{
- public class PluginDefinition
- {
- public string Author { get; set; }
- public string Name { get; set; }
- public string InternalName { get; set; }
- public string AssemblyVersion { get; set; }
- public string Description { get; set; }
- }
-}
diff --git a/Dalamud/Plugin/PluginInstallerWindow.cs b/Dalamud/Plugin/PluginInstallerWindow.cs
deleted file mode 100644
index 6626239f7..000000000
--- a/Dalamud/Plugin/PluginInstallerWindow.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Numerics;
-using System.Text;
-using System.Threading.Tasks;
-using Dalamud.Plugin.Features;
-using ImGuiNET;
-using Newtonsoft.Json;
-using Serilog;
-
-namespace Dalamud.Plugin
-{
- class PluginInstallerWindow {
- private const string PluginRepoBaseUrl = "https://goaaats.github.io/DalamudPlugins/";
-
- private PluginManager manager;
- private string pluginDirectory;
- private ReadOnlyCollection pluginMaster;
- private bool errorModalDrawing = true;
- private bool errorModalOnNextFrame = false;
-
- private enum PluginInstallStatus {
- None,
- InProgress,
- Success,
- Fail
- }
-
- private PluginInstallStatus installStatus = PluginInstallStatus.None;
-
- private bool masterDownloadFailed = false;
-
- public PluginInstallerWindow(PluginManager manager, string pluginDirectory) {
- this.manager = manager;
- this.pluginDirectory = pluginDirectory;
- Task.Run(CachePluginMaster).ContinueWith(t => {
- this.masterDownloadFailed = this.masterDownloadFailed || t.IsFaulted;
- this.errorModalDrawing = this.masterDownloadFailed;
- this.errorModalOnNextFrame = this.masterDownloadFailed;
- });
- }
-
- private void CachePluginMaster() {
- try {
- using var client = new WebClient();
-
- var data = client.DownloadString(PluginRepoBaseUrl + "pluginmaster.json");
-
- this.pluginMaster = JsonConvert.DeserializeObject>(data);
- } catch {
- this.masterDownloadFailed = true;
- }
- }
-
- private void InstallPlugin(PluginDefinition definition) {
- try {
- var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory, definition.InternalName, definition.AssemblyVersion));
- var dllFile = new FileInfo(Path.Combine(outputDir.FullName, $"{definition.InternalName}.dll"));
- var disabledFile = new FileInfo(Path.Combine(outputDir.FullName, ".disabled"));
-
- if (dllFile.Exists) {
- if (disabledFile.Exists)
- disabledFile.Delete();
-
- this.manager.LoadPluginFromAssembly(dllFile);
- this.installStatus = PluginInstallStatus.Success;
- return;
- }
-
- if (outputDir.Exists)
- outputDir.Delete(true);
- outputDir.Create();
-
- var path = Path.GetTempFileName();
- Log.Information("Downloading plugin to {0}", path);
- using var client = new WebClient();
- client.DownloadFile(PluginRepoBaseUrl + $"/plugins/{definition.InternalName}/latest.zip", path);
-
- Log.Information("Extracting to {0}", outputDir);
-
- ZipFile.ExtractToDirectory(path, outputDir.FullName);
-
- this.installStatus = PluginInstallStatus.Success;
- this.manager.LoadPluginFromAssembly(dllFile);
- } catch (Exception e) {
- Log.Error(e, "Plugin download failed hard.");
- this.installStatus = PluginInstallStatus.Fail;
- }
- }
-
- public bool Draw() {
- var windowOpen = true;
-
- ImGui.SetNextWindowSize(new Vector2(750, 520));
-
- ImGui.Begin("Plugin Installer", ref windowOpen,
- ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoScrollbar);
-
- ImGui.Text("This window allows you install and remove in-game plugins.");
- ImGui.Text("They are made by third-party developers.");
- ImGui.Separator();
-
- ImGui.BeginChild("scrolling", new Vector2(0, 400), true, ImGuiWindowFlags.HorizontalScrollbar);
-
- ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(1, 3));
-
- if (this.pluginMaster == null) {
- ImGui.Text("Loading plugins...");
- } else if (this.masterDownloadFailed) {
- ImGui.Text("Download failed.");
- }
- else
- {
- foreach (var pluginDefinition in this.pluginMaster)
- {
- if (ImGui.CollapsingHeader(pluginDefinition.Name))
- {
- ImGui.Indent();
-
- ImGui.Text(pluginDefinition.Name);
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.5f, 0.5f, 0.5f, 1.0f), $" by {pluginDefinition.Author}");
-
- ImGui.Text(pluginDefinition.Description);
-
- var isInstalled = this.manager.Plugins.Where(x=> x.Definition != null).Any(
- x => x.Definition.InternalName == pluginDefinition.InternalName);
-
- if (!isInstalled) {
- if (this.installStatus == PluginInstallStatus.InProgress) {
- ImGui.Button($"Install in progress...");
- } else {
- if (ImGui.Button($"Install v{pluginDefinition.AssemblyVersion}"))
- {
- this.installStatus = PluginInstallStatus.InProgress;
-
- Task.Run(() => InstallPlugin(pluginDefinition)).ContinueWith(t => {
- this.installStatus = t.IsFaulted ? PluginInstallStatus.Fail : this.installStatus;
- this.errorModalDrawing = this.installStatus == PluginInstallStatus.Fail;
- this.errorModalOnNextFrame = this.installStatus == PluginInstallStatus.Fail;
- });
- }
- }
-
- } else {
- var installedPlugin = this.manager.Plugins.Where(x => x.Definition != null).First(
- x => x.Definition.InternalName == pluginDefinition.InternalName);
-
- if (ImGui.Button("Disable"))
- {
- this.manager.DisablePlugin(installedPlugin.Definition);
- }
-
- if (installedPlugin.Plugin is IHasConfigUi v2Plugin && v2Plugin.OpenConfigUi != null) {
- ImGui.SameLine();
-
- if (ImGui.Button("Open Configuration"))
- {
- v2Plugin.OpenConfigUi?.Invoke(null, null);
- }
- }
- }
-
- ImGui.Unindent();
- }
- }
- }
-
- ImGui.PopStyleVar();
-
- ImGui.EndChild();
-
- ImGui.Separator();
-
- if (ImGui.Button("Remove All"))
- {
-
- }
-
- ImGui.SameLine();
-
- if (ImGui.Button("Open Plugin folder"))
- {
-
- }
-
- ImGui.SameLine();
-
- if (ImGui.Button("Close"))
- {
- windowOpen = false;
- }
-
- if (ImGui.Button("test modal")) {
- this.installStatus = PluginInstallStatus.Fail;
- this.errorModalDrawing = true;
- this.errorModalOnNextFrame = true;
- }
-
- ImGui.Spacing();
-
- if (ImGui.BeginPopupModal("Installer failed", ref this.errorModalDrawing, ImGuiWindowFlags.AlwaysAutoResize))
- {
- ImGui.Text("The plugin installer ran into an issue.");
- ImGui.Text("Please restart the game and report this error on our discord.");
-
- ImGui.Spacing();
-
- if (ImGui.Button("OK", new Vector2(120, 40))) { ImGui.CloseCurrentPopup(); }
-
- ImGui.EndPopup();
- }
-
- if (this.errorModalOnNextFrame) {
- ImGui.OpenPopup("Installer failed");
- this.errorModalOnNextFrame = false;
- }
-
-
- ImGui.End();
-
- return windowOpen;
- }
- }
-}
diff --git a/Dalamud/Plugin/PluginManager.cs b/Dalamud/Plugin/PluginManager.cs
deleted file mode 100644
index 70db2506a..000000000
--- a/Dalamud/Plugin/PluginManager.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using Newtonsoft.Json;
-using Serilog;
-
-namespace Dalamud.Plugin
-{
- public class PluginManager {
- private readonly Dalamud dalamud;
- private readonly string pluginDirectory;
-
- private readonly Type interfaceType = typeof(IDalamudPlugin);
-
- public readonly List<(IDalamudPlugin Plugin, PluginDefinition Definition)> Plugins = new List<(IDalamudPlugin plugin, PluginDefinition def)>();
-
- public PluginManager(Dalamud dalamud, string pluginDirectory) {
- this.dalamud = dalamud;
- this.pluginDirectory = pluginDirectory;
- }
-
- public void UnloadPlugins() {
- if (this.Plugins == null)
- return;
-
- for (var i = 0; i < this.Plugins.Count; i++) {
- this.Plugins[i].Plugin.Dispose();
- }
-
- this.Plugins.Clear();
- }
-
- public void LoadPlugins() {
- LoadPluginsAt(new DirectoryInfo(this.pluginDirectory));
- }
-
- public void DisablePlugin(PluginDefinition definition) {
- var thisPlugin = this.Plugins.Where(x => x.Definition != null)
- .First(x => x.Definition.InternalName == definition.InternalName);
-
- var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory, definition.InternalName, definition.AssemblyVersion));
- File.Create(Path.Combine(outputDir.FullName, ".disabled"));
-
- thisPlugin.Plugin.Dispose();
-
- this.Plugins.Remove(thisPlugin);
- }
-
- public void LoadPluginFromAssembly(FileInfo dllFile) {
- Log.Information("Loading assembly at {0}", dllFile);
- var assemblyName = AssemblyName.GetAssemblyName(dllFile.FullName);
- var pluginAssembly = Assembly.Load(assemblyName);
-
- if (pluginAssembly != null)
- {
- Log.Information("Loading types for {0}", pluginAssembly.FullName);
- var types = pluginAssembly.GetTypes();
- foreach (var type in types)
- {
- if (type.IsInterface || type.IsAbstract)
- {
- continue;
- }
-
- if (type.GetInterface(interfaceType.FullName) != null)
- {
- var disabledFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, ".disabled"));
-
- if (disabledFile.Exists) {
- Log.Information("Plugin {0} is disabled.", dllFile.FullName);
- return;
- }
-
- var defJsonFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, $"{Path.GetFileNameWithoutExtension(dllFile.Name)}.json"));
-
- PluginDefinition pluginDef = null;
- if (defJsonFile.Exists)
- {
- Log.Information("Loading definition for plugin DLL {0}", dllFile.FullName);
-
- pluginDef =
- JsonConvert.DeserializeObject(
- File.ReadAllText(defJsonFile.FullName));
- }
- else
- {
- Log.Information("Plugin DLL {0} has no definition.", dllFile.FullName);
- return;
- }
-
- var plugin = (IDalamudPlugin)Activator.CreateInstance(type);
-
- var dalamudInterface = new DalamudPluginInterface(this.dalamud, type.Assembly.GetName().Name);
- plugin.Initialize(dalamudInterface);
- Log.Information("Loaded plugin: {0}", plugin.Name);
- this.Plugins.Add((plugin, pluginDef));
- }
- }
- }
- }
-
- private void LoadPluginsAt(DirectoryInfo folder) {
- if (folder.Exists)
- {
- Log.Information("Loading plugins at {0}", folder);
-
- var pluginDlls = folder.GetFiles("*.dll", SearchOption.AllDirectories);
-
- foreach (var dllFile in pluginDlls) {
- LoadPluginFromAssembly(dllFile);
- }
- }
- }
- }
-}
diff --git a/Dalamud/Resources/eye.png b/Dalamud/Resources/eye.png
deleted file mode 100644
index 5154d00df36e5f8dc772560cca1cd9914d020cd8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 50593
zcmbq*bySp3)UbspsnTsAAR(-@l(Y*-H`3DGNGdBJt?&buPH7ONTVi(&SaPLvDVJDk
zVaa`;^*!%7-~Znq91io$+_`gm?!7~dwx%j288g|HD_1DNFO_t!T)Dmh{H)))35;~$
z>_Nb<8xHcX2?&zV}6*f}V<9Xx;{(!Z^T6^7?@mTXQ5WZU!eu1S7T2LXJ1|@0d|=>hr(o
zSAl)sai_SULn~EFZdTWB2GY4o0@4P(cyZfFpZ22j*l4m%QhGhR^ElI|nrY#zO*Xv?
zO(3-X$#B`}oPgTKub+eyj>8Gu;ABp4vV9fnf50zJ@R$LW8gZcbFE8n1;=rhHDug(|
z>D2a1{@+{?^VR%+b2Dqawf}v3WhBY-?^8+T|34TNYgCJhtAvL}GUwn+B3u>g%0TrF
zF?ZiRC?`1cGjUJKdAj8kfK%XwgxyDqqj9z{st1Us7$
zVcc{p#cK=v0Z2t6mt$(5#
z@~9~eLofv9ml2N!QM}qB1rxNjE3leX(Ye6BOfF9Q51@~e_C^4*0v}-W;KWIqzk(nD
zP99JGhtV%lG;VLg_$3eHarq*l=5!&26D+_3(00`7H5WTecnoYMJ|D`eyjnpp2Nu=-
zTLjNRe>7H0ObG5b)w%FcPcFVmWP;P3rg$y5u8(}k)20|qxMeb@=s%=7#V4@mS|BjA
zSWf0oBF2vstgA@m)woL~Y!2N#qLdgPtc){F<}80e
@TzNXWe3!L}`
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