diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj
index ddc2e39ca..32c5c75c2 100644
--- a/Dalamud.Injector/Dalamud.Injector.csproj
+++ b/Dalamud.Injector/Dalamud.Injector.csproj
@@ -14,10 +14,10 @@
true
- 4.8.5.0
- 4.8.5.0
+ 4.8.8.0
+ 4.8.8.0
XIVLauncher addon injection
- 4.8.5.0
+ 4.8.8.0
diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs
index d25243c8e..ffd612034 100644
--- a/Dalamud.Injector/Program.cs
+++ b/Dalamud.Injector/Program.cs
@@ -13,6 +13,8 @@ using Newtonsoft.Json;
namespace Dalamud.Injector {
internal static class Program {
+ static private Process process = null;
+
private static void Main(string[] args) {
#if !DEBUG
AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs eventArgs)
@@ -25,9 +27,10 @@ namespace Dalamud.Injector {
};
#endif
- var pid = int.Parse(args[0]);
-
- Process process = null;
+ var pid = -1;
+ if (args.Length == 1) {
+ pid = int.Parse(args[0]);
+ }
switch (pid) {
case -1:
@@ -45,10 +48,12 @@ namespace Dalamud.Injector {
}
DalamudStartInfo startInfo;
- if (args.Length == 1) {
+ if (args.Length <= 1) {
startInfo = GetDefaultStartInfo();
Console.WriteLine("\nA Dalamud start info was not found in the program arguments. One has been generated for you.");
Console.WriteLine("\nCopy the following contents into the program arguments:");
+ Console.WriteLine();
+ Console.WriteLine(Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(startInfo))));
} else {
startInfo = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Convert.FromBase64String(args[1])));
}
@@ -80,6 +85,7 @@ namespace Dalamud.Injector {
}
private static DalamudStartInfo GetDefaultStartInfo() {
+ var ffxivDir = Path.GetDirectoryName(process.MainModule.FileName);
var startInfo = new DalamudStartInfo {
WorkingDirectory = null,
ConfigurationPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
@@ -89,7 +95,7 @@ namespace Dalamud.Injector {
DefaultPluginDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
@"\XIVLauncher\devPlugins",
- GameVersion = File.ReadAllText(@"C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn\game\ffxivgame.ver"),
+ GameVersion = File.ReadAllText(Path.Combine(ffxivDir, "ffxivgame.ver")),
Language = ClientLanguage.English
};
diff --git a/Dalamud/Configuration/DalamudConfiguration.cs b/Dalamud/Configuration/DalamudConfiguration.cs
index 6953ac76b..7a1671cc2 100644
--- a/Dalamud/Configuration/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/DalamudConfiguration.cs
@@ -27,14 +27,25 @@ namespace Dalamud
public Dictionary PreferredRoleReminders { get; set; }
+ public string LanguageOverride { get; set; }
+
public string LastVersion { get; set; }
+ [JsonIgnore]
+ public string ConfigPath;
+
public static DalamudConfiguration Load(string path) {
- return JsonConvert.DeserializeObject(File.ReadAllText(path));
+ var deserialized = JsonConvert.DeserializeObject(File.ReadAllText(path));
+ deserialized.ConfigPath = path;
+
+ return deserialized;
}
- public void Save(string path) {
- File.WriteAllText(path, JsonConvert.SerializeObject(this, Formatting.Indented));
+ ///
+ /// Save the configuration at the path it was loaded from.
+ ///
+ public void Save() {
+ File.WriteAllText(this.ConfigPath, JsonConvert.SerializeObject(this, Formatting.Indented));
}
}
}
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
index 08394abd6..f33c04873 100644
--- a/Dalamud/Dalamud.cs
+++ b/Dalamud/Dalamud.cs
@@ -22,7 +22,10 @@ using Dalamud.Game.Network;
using Dalamud.Interface;
using Dalamud.Plugin;
using ImGuiNET;
+using Newtonsoft.Json;
using Serilog;
+using Serilog.Core;
+using Serilog.Events;
namespace Dalamud {
public sealed class Dalamud : IDisposable {
@@ -36,13 +39,13 @@ namespace Dalamud {
public readonly Framework Framework;
- public readonly CommandManager CommandManager;
+ public CommandManager CommandManager { get; private set; }
- public readonly ChatHandlers ChatHandlers;
+ public ChatHandlers ChatHandlers { get; private set; }
- public readonly NetworkHandlers NetworkHandlers;
+ public NetworkHandlers NetworkHandlers { get; private set; }
- public readonly DiscordBotManager BotManager;
+ public DiscordBotManager BotManager { get; private set; }
public PluginManager PluginManager { get; private set; }
public PluginRepository PluginRepository { get; private set; }
@@ -50,31 +53,29 @@ namespace Dalamud {
public readonly ClientState ClientState;
public readonly DalamudStartInfo StartInfo;
+ private readonly LoggingLevelSwitch loggingLevelSwitch;
public readonly DalamudConfiguration Configuration;
private readonly WinSockHandlers WinSock2;
- public readonly InterfaceManager InterfaceManager;
+ public InterfaceManager InterfaceManager { get; private set; }
- public readonly DataManager Data;
-
- private AntiDebug antiDebug;
+ public DataManager Data { get; private set; }
private Localization localizationMgr;
+ public bool IsReady { get; private set; }
private readonly string assemblyVersion = Assembly.GetAssembly(typeof(ChatHandlers)).GetName().Version.ToString();
- public Dalamud(DalamudStartInfo info) {
+ public Dalamud(DalamudStartInfo info, LoggingLevelSwitch loggingLevelSwitch) {
this.StartInfo = info;
-
- this.localizationMgr = new Localization(this.StartInfo.WorkingDirectory);
- this.localizationMgr.SetupWithUiCulture();
+ this.loggingLevelSwitch = loggingLevelSwitch;
this.Configuration = DalamudConfiguration.Load(info.ConfigurationPath);
-
+
this.baseDirectory = info.WorkingDirectory;
this.unloadSignal = new ManualResetEvent(false);
@@ -86,50 +87,61 @@ namespace Dalamud {
// 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.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig);
-
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.");
- }
+ AssetManager.EnsureAssets(this.baseDirectory).ContinueWith(async task => {
+ this.localizationMgr = new Localization(this.StartInfo.WorkingDirectory);
+ if (!string.IsNullOrEmpty(this.Configuration.LanguageOverride)) {
+ this.localizationMgr.SetupWithLangCode(this.Configuration.LanguageOverride);
+ } else {
+ this.localizationMgr.SetupWithUiCulture();
+ }
+
+ try {
+ this.InterfaceManager = new InterfaceManager(this, this.SigScanner);
+ this.InterfaceManager.OnDraw += BuildDalamudUi;
+
+ this.InterfaceManager.Enable();
+ } catch (Exception e) {
+ Log.Information(e, "Could not init interface.");
+ }
+
+ this.Data = new DataManager(this.StartInfo.Language);
+ await this.Data.Initialize(this.baseDirectory);
+
+ this.NetworkHandlers = new NetworkHandlers(this, this.Configuration.OptOutMbCollection);
+
+ // Initialize managers. Basically handlers for the logic
+ this.CommandManager = new CommandManager(this, info.Language);
+ SetupCommands();
+
+ this.ChatHandlers = new ChatHandlers(this);
+
+ // Discord Bot Manager
+ this.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig);
+ this.BotManager.Start();
+
+ try
+ {
+ this.PluginManager = new PluginManager(this, this.StartInfo.PluginDirectory, this.StartInfo.DefaultPluginDirectory);
+ this.PluginManager.LoadPlugins();
+
+ this.PluginRepository = new PluginRepository(PluginManager, this.StartInfo.PluginDirectory, this.StartInfo.GameVersion);
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Plugin load failed.");
+ }
+
+ IsReady = true;
+ });
}
public void Start() {
- try {
- this.InterfaceManager?.Enable();
- } catch (Exception e) {
- Log.Information("Could not enable interface.");
- }
-
this.Framework.Enable();
this.ClientState.Enable();
-
- this.BotManager.Start();
-
- try {
- this.PluginManager = new PluginManager(this, this.StartInfo.PluginDirectory, this.StartInfo.DefaultPluginDirectory);
- this.PluginManager.LoadPlugins();
-
- PluginRepository = new PluginRepository(PluginManager, this.StartInfo.PluginDirectory, this.StartInfo.GameVersion);
- } catch (Exception ex) {
- Log.Error(ex, "Plugin load failed.");
- }
}
public void Unload() {
@@ -145,7 +157,7 @@ namespace Dalamud {
// due to rendering happening on another thread, where a plugin might receive
// a render call after it has been disposed, which can crash if it attempts to
// use any resources that it freed in its own Dispose method
- this.InterfaceManager.Dispose();
+ this.InterfaceManager?.Dispose();
try
{
@@ -166,8 +178,6 @@ namespace Dalamud {
this.WinSock2.Dispose();
this.SigScanner.Dispose();
-
- this.antiDebug?.Dispose();
}
#region Interface
@@ -180,8 +190,6 @@ namespace Dalamud {
private bool isImguiDrawDevMenu = false;
#endif
- private bool isAntiDebugEnabled = false;
-
private bool isImguiDrawLogWindow = false;
private bool isImguiDrawDataWindow = false;
private bool isImguiDrawPluginWindow = false;
@@ -207,6 +215,18 @@ namespace Dalamud {
this.logWindow = new DalamudLogWindow();
this.isImguiDrawLogWindow = true;
}
+ if (ImGui.BeginMenu("Set log level..."))
+ {
+ foreach (var logLevel in Enum.GetValues(typeof(LogEventLevel)).Cast()) {
+ if (ImGui.MenuItem(logLevel + "##logLevelSwitch", "", this.loggingLevelSwitch.MinimumLevel == logLevel))
+ {
+ this.loggingLevelSwitch.MinimumLevel = logLevel;
+ }
+ }
+
+ ImGui.EndMenu();
+ }
+ ImGui.Separator();
if (ImGui.MenuItem("Open Data window"))
{
this.dataWindow = new DalamudDataWindow(this);
@@ -220,15 +240,8 @@ namespace Dalamud {
this.isImguiDrawCreditsWindow = true;
}
ImGui.MenuItem("Draw ImGui demo", "", ref this.isImguiDrawDemoWindow);
- ImGui.Separator();
- if (ImGui.MenuItem("Enable AntiDebug", "", ref this.isAntiDebugEnabled)) {
- if (this.isAntiDebugEnabled) {
- this.antiDebug = new AntiDebug();
- this.antiDebug.Enable();
- } else {
- this.antiDebug?.Dispose();
- }
- }
+ if (ImGui.MenuItem("Dump ImGui info"))
+ OnDebugImInfoCommand(null, null);
ImGui.Separator();
if (ImGui.MenuItem("Unload Dalamud"))
{
@@ -395,7 +408,7 @@ namespace Dalamud {
CommandManager.AddHandler("/xlitem", new CommandInfo(OnItemLinkCommand)
{
- HelpMessage = Loc.Localize("DalamudItemLinkHelp", "Link an item by name. Usage: /xlitem - . For matching an item exactly, use /xlitem +
- ")
+ HelpMessage = Loc.Localize("DalamudItemLinkHelp", "Open a window you can use to link any specific item to chat.")
});
#if DEBUG
@@ -424,6 +437,17 @@ namespace Dalamud {
this.CommandManager.AddHandler("/xlcredits", new CommandInfo(OnOpenCreditsCommand) {
HelpMessage = Loc.Localize("DalamudCreditsHelp", "Opens the credits for dalamud.")
});
+
+ this.CommandManager.AddHandler("/xllanguage", new CommandInfo(OnSetLanguageCommand)
+ {
+ HelpMessage = Loc.Localize("DalamudLanguageHelp", "Set the language for the in-game addon and plugins that support it.")
+ });
+
+ this.CommandManager.AddHandler("/imdebug", new CommandInfo(OnDebugImInfoCommand)
+ {
+ HelpMessage = "ImGui DEBUG",
+ ShowInHelp = false
+ });
}
private void OnUnloadCommand(string command, string arguments) {
@@ -476,7 +500,7 @@ namespace Dalamud {
this.Configuration.BadWords.Add(arguments);
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
+ this.Configuration.Save();
Framework.Gui.Chat.Print(string.Format(Loc.Localize("DalamudMuted", "Muted \"{0}\"."), arguments));
}
@@ -490,7 +514,7 @@ namespace Dalamud {
return;
}
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
+ this.Configuration.Save();
foreach (var word in this.Configuration.BadWords) Framework.Gui.Chat.Print($"\"{word}\"");
}
@@ -501,7 +525,7 @@ namespace Dalamud {
this.Configuration.BadWords.RemoveAll(x => x == arguments);
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
+ this.Configuration.Save();
Framework.Gui.Chat.Print(string.Format(Loc.Localize("DalamudUnmuted", "Unmuted \"{0}\"."), arguments));
}
@@ -534,7 +558,7 @@ namespace Dalamud {
private bool isImguiDrawItemSearchWindow;
private void OnItemLinkCommand(string command, string arguments) {
- this.itemSearchCommandWindow = new ItemSearchWindow(this.Data, new UiBuilder(this.InterfaceManager, "ItemSearcher"));
+ this.itemSearchCommandWindow = new ItemSearchWindow(this.Data, new UiBuilder(this.InterfaceManager, "ItemSearcher"), false);
this.itemSearchCommandWindow.OnItemChosen += (sender, item) => {
var hexData = new byte[] {
0x02, 0x13, 0x06, 0xFE, 0xFF, 0xF3, 0xF3, 0xF3, 0x03, 0x02, 0x27, 0x07, 0x03, 0xF2, 0x3A, 0x2F,
@@ -597,7 +621,7 @@ namespace Dalamud {
Framework.Gui.Chat.Print($"Set bonus notifications for {argParts[0]}({rouletteIndex}) to {role}");
Framework.Gui.Chat.Print(string.Format(Loc.Localize("DalamudBonusSet", "Set bonus notifications for {0}({1}) to {2}"), argParts[0], rouletteIndex, role));
- this.Configuration.Save(this.StartInfo.ConfigurationPath);
+ this.Configuration.Save();
return;
@@ -610,6 +634,28 @@ namespace Dalamud {
this.isImguiDrawDevMenu = true;
}
+ private void OnDebugImInfoCommand(string command, string arguments) {
+ var io = this.InterfaceManager.LastImGuiIoPtr;
+ var info = $"WantCaptureKeyboard: {io.WantCaptureKeyboard}\n";
+ info += $"WantCaptureMouse: {io.WantCaptureMouse}\n";
+ info += $"WantSetMousePos: {io.WantSetMousePos}\n";
+ info += $"WantTextInput: {io.WantTextInput}\n";
+ info += $"WantSaveIniSettings: {io.WantSaveIniSettings}\n";
+ info += $"BackendFlags: {(int) io.BackendFlags}\n";
+ info += $"DeltaTime: {io.DeltaTime}\n";
+ info += $"DisplaySize: {io.DisplaySize.X} {io.DisplaySize.Y}\n";
+ info += $"Framerate: {io.Framerate}\n";
+ info += $"MetricsActiveWindows: {io.MetricsActiveWindows}\n";
+ info += $"MetricsRenderWindows: {io.MetricsRenderWindows}\n";
+ info += $"MousePos: {io.MousePos.X} {io.MousePos.Y}\n";
+ info += $"MouseClicked: {io.MouseClicked}\n";
+ info += $"MouseDown: {io.MouseDown}\n";
+ info += $"NavActive: {io.NavActive}\n";
+ info += $"NavVisible: {io.NavVisible}\n";
+
+ Log.Information(info);
+ }
+
private void OnOpenInstallerCommand(string command, string arguments) {
this.pluginWindow = new PluginInstallerWindow(this.PluginManager, PluginRepository, this.StartInfo.GameVersion);
this.isImguiDrawPluginWindow = true;
@@ -624,6 +670,19 @@ namespace Dalamud {
this.isImguiDrawCreditsWindow = true;
}
+ private void OnSetLanguageCommand(string command, string arguments)
+ {
+ if (Localization.ApplicableLangCodes.Contains(arguments.ToLower())) {
+ this.localizationMgr.SetupWithLangCode(arguments.ToLower());
+ this.Configuration.LanguageOverride = arguments.ToLower();
+ } else {
+ this.localizationMgr.SetupWithUiCulture();
+ this.Configuration.LanguageOverride = null;
+ }
+
+ this.Configuration.Save();
+ }
+
private int RouletteSlugToKey(string slug) => slug.ToLower() switch {
"leveling" => 1,
"506070" => 2,
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index fa74f15ef..e35fe6dcf 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -14,9 +14,9 @@
true
- 4.8.5.0
- 4.8.5.0
- 4.8.5.0
+ 4.8.8.0
+ 4.8.8.0
+ 4.8.8.0
@@ -79,26 +79,5 @@
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index edc46ac23..f90f5ea22 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -22,8 +22,6 @@ 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; }
///
@@ -53,20 +51,14 @@ namespace Dalamud.Data
this.language = language;
}
- public async Task Initialize()
+ public async Task Initialize(string baseDir)
{
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"));
+ JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(baseDir, "UIRes", "serveropcode.json")));
this.ServerOpCodes = new ReadOnlyDictionary(opCodeDict);
Log.Verbose("Loaded {0} ServerOpCodes.", opCodeDict.Count);
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 4d5bc571d..3e09596cc 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -6,6 +6,7 @@ using Dalamud.Interface;
using EasyHook;
using Serilog;
using Serilog.Core;
+using Serilog.Events;
namespace Dalamud {
public sealed class EntryPoint : IEntryPoint {
@@ -15,7 +16,8 @@ namespace Dalamud {
public void Run(RemoteHooking.IContext ctx, DalamudStartInfo info) {
// Setup logger
- Log.Logger = NewLogger(info.WorkingDirectory);
+ var (logger, levelSwitch) = NewLogger(info.WorkingDirectory);
+ Log.Logger = logger;
try {
Log.Information("Initializing a session..");
@@ -28,7 +30,7 @@ namespace Dalamud {
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
- using var dalamud = new Dalamud(info);
+ using var dalamud = new Dalamud(info, levelSwitch);
Log.Information("Starting a session..");
// Run session
@@ -44,18 +46,24 @@ namespace Dalamud {
}
}
- private Logger NewLogger(string baseDirectory) {
+ private (Logger logger, LoggingLevelSwitch levelSwitch) NewLogger(string baseDirectory) {
var logPath = Path.Combine(baseDirectory, "dalamud.txt");
- return new LoggerConfiguration()
+ var levelSwitch = new LoggingLevelSwitch();
+
+#if DEBUG
+ levelSwitch.MinimumLevel = LogEventLevel.Verbose;
+#else
+ levelSwitch.MinimumLevel = LogEventLevel.Information;
+#endif
+
+ var newLogger = new LoggerConfiguration()
.WriteTo.Async(a => a.File(logPath))
.WriteTo.EventSink()
-#if DEBUG
- .MinimumLevel.Verbose()
-#else
- .MinimumLevel.Information()
-#endif
+ .MinimumLevel.ControlledBy(levelSwitch)
.CreateLogger();
+
+ return (newLogger, levelSwitch);
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs arg) {
diff --git a/Dalamud/Game/Chat/SeIconChar.cs b/Dalamud/Game/Chat/SeIconChar.cs
new file mode 100644
index 000000000..401238689
--- /dev/null
+++ b/Dalamud/Game/Chat/SeIconChar.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Dalamud.Game.Chat
+{
+ ///
+ /// Special unicode characters with game-related symbols that work both in-game and in any dalamud window.
+ ///
+ public enum SeIconChar {
+ BotanistSprout = 0xE034,
+ ItemLevel = 0xE033,
+ AutoTranslateOpen = 0xE040,
+ AutoTranslateClose = 0xE041,
+ HighQuality = 0xE03C,
+ Clock = 0xE031,
+ Gil = 0xE049,
+ Hyadelyn = 0xE048,
+
+ MouseNoClick = 0xE050,
+ MouseLeftClick = 0xE051,
+ MouseRightClick = 0xE052,
+ MouseBothClick = 0xE053,
+ MouseWheel = 0xE054,
+ Mouse1 = 0xE055,
+ Mouse2 = 0xE056,
+ Mouse3 = 0xE057,
+ Mouse4 = 0xE058,
+ Mouse5 = 0xE059,
+
+ LevelEn = 0xE06A,
+ LevelDe = 0xE06B,
+ LevelFr = 0xE06C,
+
+ Experience = 0xE0BC,
+ ExperienceFilled = 0xE0BD,
+
+ TimeAm = 0xE06D,
+ TimePm = 0xE06E,
+
+ ArrowRight = 0xE06F,
+ ArrowDown = 0xE035,
+
+ Number0 = 0xE060,
+ Number1 = 0xE061,
+ Number2 = 0xE062,
+ Number3 = 0xE063,
+ Number4 = 0xE064,
+ Number5 = 0xE065,
+ Number6 = 0xE066,
+ Number7 = 0xE067,
+ Number8 = 0xE068,
+ Number9 = 0xE069,
+
+ BoxedNumber0 = 0xE08F,
+ BoxedNumber1 = 0xE090,
+ BoxedNumber2 = 0xE091,
+ BoxedNumber3 = 0xE092,
+ BoxedNumber4 = 0xE093,
+ BoxedNumber5 = 0xE094,
+ BoxedNumber6 = 0xE095,
+ BoxedNumber7 = 0xE096,
+ BoxedNumber8 = 0xE097,
+ BoxedNumber9 = 0xE098,
+ BoxedNumber10 = 0xE099,
+ BoxedNumber11 = 0xE09A,
+ BoxedNumber12 = 0xE09B,
+ BoxedNumber13 = 0xE09C,
+ BoxedNumber14 = 0xE09D,
+ BoxedNumber15 = 0xE09E,
+ BoxedNumber16 = 0xE09F,
+ BoxedNumber17 = 0xE0A0,
+ BoxedNumber18 = 0xE0A1,
+ BoxedNumber19 = 0xE0A2,
+ BoxedNumber20 = 0xE0A3,
+ BoxedNumber21 = 0xE0A4,
+ BoxedNumber22 = 0xE0A5,
+ BoxedNumber23 = 0xE0A6,
+ BoxedNumber24 = 0xE0A7,
+ BoxedNumber25 = 0xE0A8,
+ BoxedNumber26 = 0xE0A9,
+ BoxedNumber27 = 0xE0AA,
+ BoxedNumber28 = 0xE0AB,
+ BoxedNumber29 = 0xE0AC,
+ BoxedNumber30 = 0xE0AD,
+ BoxedNumber31 = 0xE0AE,
+
+ BoxedPlus = 0xE0AF,
+ BoxedQuestionMark = 0xE070,
+ BoxedStar = 0xE0C0,
+
+ BoxedRoman1 = 0xE0C1,
+ BoxedRoman2 = 0xE0C2,
+ BoxedRoman3 = 0xE0C3,
+ BoxedRoman4 = 0xE0C4,
+ BoxedRoman5 = 0xE0C5,
+ BoxedRoman6 = 0xE0C6,
+
+ BoxedLetterA = 0xE071,
+ BoxedLetterB = 0xE072,
+ BoxedLetterC = 0xE073,
+ BoxedLetterD = 0xE074,
+ BoxedLetterE = 0xE075,
+ BoxedLetterF = 0xE076,
+ BoxedLetterG = 0xE077,
+ BoxedLetterH = 0xE078,
+ BoxedLetterI = 0xE079,
+ BoxedLetterJ = 0xE07A,
+ BoxedLetterK = 0xE07B,
+ BoxedLetterL = 0xE07C,
+ BoxedLetterM = 0xE07D,
+ BoxedLetterN = 0xE07E,
+ BoxedLetterO = 0xE07F,
+ BoxedLetterP = 0xE080,
+ BoxedLetterQ = 0xE081,
+ BoxedLetterR = 0xE082,
+ BoxedLetterS = 0xE083,
+ BoxedLetterT = 0xE084,
+ BoxedLetterU = 0xE085,
+ BoxedLetterV = 0xE086,
+ BoxedLetterW = 0xE087,
+ BoxedLetterX = 0xE088,
+ BoxedLetterY = 0xE089,
+ BoxedLetterZ = 0xE08A,
+
+ Circle = 0xE04A,
+ Square = 0xE04B,
+ Cross = 0xE04C,
+ Triangle = 0xE04D,
+ Hexagon = 0xE042,
+ Prohibited = 0xE043,
+
+
+ Dice = 0xE03E,
+ Debuff = 0xE05B,
+ Buff = 0xE05C,
+ CrossWorld = 0xE05D,
+
+ EurekaLevel = 0xE03A,
+
+ LinkMarker = 0xE0BB,
+
+ Glamoured = 0xE03B,
+ GlamouredDyed = 0xE04E,
+
+ QuestSync = 0xE0BE,
+ QuestRepeatable = 0xE0BF,
+
+ ImeHiragana = 0xE020,
+ ImeKatakana = 0xE021,
+ ImeAlphanumeric = 0xE022,
+ ImeKatakanaHalfWidth = 0xE023,
+ ImeAlphanumericHalfWidth = 0xE024,
+
+ Instance1 = 0xE0B1,
+ Instance2 = 0xE0B2,
+ Instance3 = 0xE0B3,
+ Instance4 = 0xE0B4,
+ Instance5 = 0xE0B5,
+ Instance6 = 0xE0B6,
+ Instance7 = 0xE0B7,
+ Instance8 = 0xE0B8,
+ Instance9 = 0xE0B9,
+ InstanceMerged = 0xE0BA,
+
+ LocalTimeEn = 0xE0D0,
+ ServerTimeEn = 0xE0D1,
+ EorzeaTimeEn = 0xE0D2,
+ LocalTimeDe = 0xE0D3,
+ ServerTimeDe = 0xE0D4,
+ EorzeaTimeDe = 0xE0D5,
+ LocalTimeFr = 0xE0D6,
+ ServerTimeFr = 0xE0D7,
+ EorzeaTimeFr = 0xE0D8,
+ LocalTimeJa = 0xE0D9,
+ ServerTimeJa = 0xE0DA,
+ EorzeaTimeJa = 0xE0DB,
+ }
+}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payload.cs b/Dalamud/Game/Chat/SeStringHandling/Payload.cs
index 25b4531de..716ad0eed 100644
--- a/Dalamud/Game/Chat/SeStringHandling/Payload.cs
+++ b/Dalamud/Game/Chat/SeStringHandling/Payload.cs
@@ -5,6 +5,13 @@ using System.Linq;
using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Serilog;
+// TODOs:
+// - refactor integer handling now that we have multiple packed types
+// - common construction/property design for subclasses
+// - lumina DI
+// - design for handling raw values vs resolved values, both for input and output
+// - wrapper class(es) for handling of composite links in chat (item, map etc) and formatting operations
+
namespace Dalamud.Game.Chat.SeStringHandling
{
///
@@ -148,6 +155,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
Int16 = 0xF2,
Int16Packed = 0xF4, // seen in map links, seemingly 2 8-bit values packed into 2 bytes with only one marker
Int24Special = 0xF6, // unsure how different form Int24 - used for hq items that add 1 million, also used for normal 24-bit values in map links
+ Int24Packed = 0xFC, // used in map links- sometimes short+byte, sometimes... not??
Int24 = 0xFA,
Int32 = 0xFE
}
@@ -189,6 +197,8 @@ namespace Dalamud.Game.Chat.SeStringHandling
case IntegerType.Int24Special:
// Fallthrough - same logic
+ case IntegerType.Int24Packed:
+ // fallthrough again
case IntegerType.Int24:
{
var v = 0;
@@ -267,6 +277,7 @@ namespace Dalamud.Game.Chat.SeStringHandling
var type = bytes.Length switch
{
4 => IntegerType.Int32,
+ 3 => IntegerType.Int24Packed,
2 => IntegerType.Int16Packed,
_ => throw new NotSupportedException()
};
@@ -276,17 +287,32 @@ namespace Dalamud.Game.Chat.SeStringHandling
protected (uint, uint) GetPackedIntegers(BinaryReader input)
{
+ // HACK - this was already a hack, but the addition of Int24Packed made it even worse
+ // All of this should be redone/removed at some point
+
+ var marker = (IntegerType)input.ReadByte();
+ input.BaseStream.Position--;
+
var value = GetInteger(input);
- if (value > 0xFFFF)
+
+ if (marker == IntegerType.Int24Packed)
{
- return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF));
+ return ((uint)((value & 0xFFFF00) >> 8), (uint)(value & 0xFF));
}
- else if (value > 0xFF)
+ // this used to be the catchall before Int24Packed; leave it for now to ensure we handle all encodings
+ else // if (marker == IntegerType.Int16Packed || marker == IntegerType.Int32)
{
- return ((uint)((value & 0xFF00) >> 8), (uint)(value & 0xFF));
+ if (value > 0xFFFF)
+ {
+ return ((uint)((value & 0xFFFF0000) >> 16), (uint)(value & 0xFFFF));
+ }
+ else if (value > 0xFF)
+ {
+ return ((uint)((value & 0xFF00) >> 8), (uint)(value & 0xFF));
+ }
}
- // unsure if there are other cases, like "odd" pairings of 2+1 bytes etc
+ // unsure if there are other cases
throw new NotSupportedException();
}
diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs
index 6115adab2..f422133d8 100644
--- a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs
+++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs
@@ -65,15 +65,34 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads
//}
}
+ public override string ToString()
+ {
+ return $"{Type} - TerritoryTypeId: {TerritoryTypeId}, MapId: {MapId}, RawX: {RawX}, RawY: {RawY}";
+ }
+
protected override void ProcessChunkImpl(BinaryReader reader, long endOfStream)
{
- (TerritoryTypeId, MapId) = GetPackedIntegers(reader);
- RawX = (uint)GetInteger(reader);
- RawY = (uint)GetInteger(reader);
- // the Z coordinate is never in this chunk, just the text (if applicable)
+ // for debugging for now
+ var oldPos = reader.BaseStream.Position;
+ var bytes = reader.ReadBytes((int)(endOfStream - reader.BaseStream.Position));
+ reader.BaseStream.Position = oldPos;
- // seems to always be FF 01
- reader.ReadBytes(2);
+ try
+ {
+ (TerritoryTypeId, MapId) = GetPackedIntegers(reader);
+ RawX = (uint)GetInteger(reader);
+ RawY = (uint)GetInteger(reader);
+ // the Z coordinate is never in this chunk, just the text (if applicable)
+
+ // seems to always be FF 01
+ reader.ReadBytes(2);
+ }
+ catch (NotSupportedException)
+ {
+ Serilog.Log.Information($"Unsupported map bytes {BitConverter.ToString(bytes).Replace("-", " ")}");
+ // we still want to break here for now, or we'd just throw again later
+ throw;
+ }
}
#region ugliness
diff --git a/Dalamud/Game/ChatHandlers.cs b/Dalamud/Game/ChatHandlers.cs
index 739e1d40e..3c2d59474 100644
--- a/Dalamud/Game/ChatHandlers.cs
+++ b/Dalamud/Game/ChatHandlers.cs
@@ -119,7 +119,7 @@ namespace Dalamud.Game {
});
this.dalamud.Configuration.LastVersion = assemblyVersion;
- this.dalamud.Configuration.Save(this.dalamud.StartInfo.ConfigurationPath);
+ this.dalamud.Configuration.Save();
}
try {
diff --git a/Dalamud/Game/ClientState/Actors/ActorTable.cs b/Dalamud/Game/ClientState/Actors/ActorTable.cs
index e11374fb9..760a4e492 100644
--- a/Dalamud/Game/ClientState/Actors/ActorTable.cs
+++ b/Dalamud/Game/ClientState/Actors/ActorTable.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types;
@@ -11,9 +12,10 @@ namespace Dalamud.Game.ClientState.Actors {
///
/// This collection represents the currently spawned FFXIV actors.
///
- public class ActorTable : ICollection, IDisposable {
+ public class ActorTable : IReadOnlyCollection, ICollection, IDisposable {
#region temporary imports for crash workaround
+
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
@@ -21,6 +23,7 @@ namespace Dalamud.Game.ClientState.Actors {
IntPtr lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);
+
#endregion
private ClientStateAddressResolver Address { get; }
@@ -42,7 +45,8 @@ namespace Dalamud.Game.ClientState.Actors {
Address = addressResolver;
this.dalamud = dalamud;
- this.someActorTableAccessHook = new Hook(Address.SomeActorTableAccess, new SomeActorTableAccessDelegate(SomeActorTableAccessDetour), this);
+ this.someActorTableAccessHook = new Hook(
+ Address.SomeActorTableAccess, new SomeActorTableAccessDelegate(SomeActorTableAccessDetour), this);
Log.Verbose("Actor table address {ActorTable}", Address.ViewportActorTable);
}
@@ -74,15 +78,14 @@ namespace Dalamud.Game.ClientState.Actors {
if (!this.isReady)
return null;
- if (this.someActorTableAccessHook != null)
- {
+ if (this.someActorTableAccessHook != null) {
this.someActorTableAccessHook.Dispose();
this.someActorTableAccessHook = null;
}
if (index >= Length)
return null;
-
+
var tblIndex = this.realActorTablePtr + 8 + index * 8;
var offset = Marshal.ReadIntPtr(tblIndex);
@@ -94,9 +97,8 @@ namespace Dalamud.Game.ClientState.Actors {
// FIXME: hack workaround for trying to access the player on logout, after the main object has been deleted
var sz = Marshal.SizeOf(typeof(Structs.Actor));
- var actorMem = Marshal.AllocHGlobal(sz); // we arguably could just reuse this
- if (!ReadProcessMemory(Process.GetCurrentProcess().Handle, offset, actorMem, sz, out _))
- {
+ var actorMem = Marshal.AllocHGlobal(sz); // we arguably could just reuse this
+ if (!ReadProcessMemory(Process.GetCurrentProcess().Handle, offset, actorMem, sz, out _)) {
Log.Debug("ActorTable - ReadProcessMemory failed: likely player deletion during logout");
return null;
}
@@ -106,17 +108,16 @@ namespace Dalamud.Game.ClientState.Actors {
//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, this.dalamud);
- case ObjectKind.BattleNpc: return new BattleNpc(actorStruct, this.dalamud);
- default: return new Actor(actorStruct, this.dalamud);
+
+ switch (actorStruct.ObjectKind) {
+ case ObjectKind.Player: return new PlayerCharacter(offset, actorStruct, this.dalamud);
+ case ObjectKind.BattleNpc: return new BattleNpc(offset, actorStruct, this.dalamud);
+ default: return new Actor(offset, actorStruct, this.dalamud);
}
}
}
- private class ActorTableEnumerator : IEnumerator {
+ private class ActorTableEnumerator : IEnumerator {
private readonly ActorTable table;
private int currentIndex;
@@ -134,18 +135,29 @@ namespace Dalamud.Game.ClientState.Actors {
this.currentIndex = 0;
}
- public object Current => this.table[this.currentIndex];
+ public Actor Current => this.table[this.currentIndex];
+
+ object IEnumerator.Current => Current;
+
+ // Required by IEnumerator even though we have nothing we want to dispose here.
+ public void Dispose() {}
}
- public IEnumerator GetEnumerator() {
+ public IEnumerator GetEnumerator() {
return new ActorTableEnumerator(this);
}
+ IEnumerator IEnumerable.GetEnumerator() {
+ return GetEnumerator();
+ }
+
///
/// The amount of currently spawned actors.
///
public int Length => !this.isReady ? 0 : Marshal.ReadInt32(this.realActorTablePtr);
+ int IReadOnlyCollection.Count => Length;
+
int ICollection.Count => Length;
bool ICollection.IsSynchronized => false;
diff --git a/Dalamud/Game/ClientState/Actors/Types/Actor.cs b/Dalamud/Game/ClientState/Actors/Types/Actor.cs
index fd9a06584..275a5cd39 100644
--- a/Dalamud/Game/ClientState/Actors/Types/Actor.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/Actor.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Dalamud.Game.ClientState.Actors.Types {
///
/// This class represents a basic FFXIV actor.
@@ -10,14 +12,21 @@ namespace Dalamud.Game.ClientState.Actors.Types {
protected Dalamud dalamud;
+ ///
+ /// The address of this actor in memory.
+ ///
+ public readonly IntPtr Address;
+
///
/// Initialize a representation of a basic FFXIV actor.
///
/// The memory representation of the base actor.
/// A dalamud reference needed to access game data in Resolvers.
- public Actor(Structs.Actor actorStruct, Dalamud dalamud) {
+ /// The address of this actor in memory.
+ public Actor(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud) {
this.actorStruct = actorStruct;
this.dalamud = dalamud;
+ this.Address = address;
}
///
diff --git a/Dalamud/Game/ClientState/Actors/Types/Chara.cs b/Dalamud/Game/ClientState/Actors/Types/Chara.cs
index 4c01753db..45471e719 100644
--- a/Dalamud/Game/ClientState/Actors/Types/Chara.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/Chara.cs
@@ -1,3 +1,4 @@
+using System;
using Dalamud.Game.ClientState.Actors.Resolvers;
namespace Dalamud.Game.ClientState.Actors.Types {
@@ -10,7 +11,8 @@ namespace Dalamud.Game.ClientState.Actors.Types {
///
/// The memory representation of the base actor.
/// A dalamud reference needed to access game data in Resolvers.
- protected Chara(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
+ /// The address of this actor in memory.
+ protected Chara(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud) : base(address, actorStruct, dalamud) { }
///
/// The level of this Chara.
diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
index d316cb730..b4be1321e 100644
--- a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/BattleNpc.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
///
/// This class represents a battle NPC.
@@ -8,7 +10,8 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
///
/// The memory representation of the base actor.
/// A dalamud reference needed to access game data in Resolvers.
- public BattleNpc(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
+ /// The address of this actor in memory.
+ public BattleNpc(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud) : base(address, actorStruct, dalamud) { }
///
/// The BattleNpc of this BattleNpc.
diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
index 2bd31b1e5..99cb9e739 100644
--- a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/Npc.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
///
/// This class represents a NPC.
@@ -8,11 +10,17 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer {
///
/// The memory representation of the base actor.
/// A dalamud reference needed to access game data in Resolvers.
- protected Npc(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
+ /// The address of this actor in memory.
+ protected Npc(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud) : base(address, actorStruct, dalamud) { }
///
/// The data ID of the NPC linking to their respective game data.
///
public int DataId => this.actorStruct.DataId;
+
+ ///
+ /// The name ID of the NPC linking to their respective game data.
+ ///
+ public int NameId => this.actorStruct.NameId;
}
}
diff --git a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs b/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
index 818c828a7..366794513 100644
--- a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
@@ -1,3 +1,4 @@
+using System;
using Dalamud.Game.ClientState.Actors.Resolvers;
using SharpDX.Text;
@@ -11,7 +12,8 @@ namespace Dalamud.Game.ClientState.Actors.Types {
///
/// The memory representation of the base actor.
/// A dalamud reference needed to access game data in Resolvers.
- public PlayerCharacter(Structs.Actor actorStruct, Dalamud dalamud) : base(actorStruct, dalamud) { }
+ /// The address of this actor in memory.
+ public PlayerCharacter(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud) : base(address, actorStruct, dalamud) { }
///
/// The current world of the character.
diff --git a/Dalamud/Game/ClientState/Structs/Actor.cs b/Dalamud/Game/ClientState/Structs/Actor.cs
index cf82da97c..68090891b 100644
--- a/Dalamud/Game/ClientState/Structs/Actor.cs
+++ b/Dalamud/Game/ClientState/Structs/Actor.cs
@@ -24,10 +24,10 @@ namespace Dalamud.Game.ClientState.Structs
[FieldOffset(145)] public byte PlayerTargetStatus; // This is some kind of enum
[FieldOffset(146)] public byte YalmDistanceFromPlayer2; // and the other is z distance
[FieldOffset(160)] public Position3 Position;
-
+ [FieldOffset(0x17F8)] public int TargetActorId;
// This field can't be correctly aligned, so we have to cut it manually.
[FieldOffset(0x17d0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public byte[] CompanyTag;
- [FieldOffset(0x17F8)] public int TargetActorId;
+ [FieldOffset(0x1868)] public int NameId;
[FieldOffset(0x1884)] public byte CurrentWorld;
[FieldOffset(0x1886)] public byte HomeWorld;
[FieldOffset(6328)] public int CurrentHp;
diff --git a/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs b/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
index 11eb1f5ad..b181d57a0 100644
--- a/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
+++ b/Dalamud/Game/ClientState/Structs/JobGauge/BRDGauge.cs
@@ -11,6 +11,7 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge {
public struct BRDGauge {
[FieldOffset(0)] public short SongTimer;
[FieldOffset(2)] public byte NumSongStacks;
+ [FieldOffset(3)] public byte SoulVoiceValue;
[FieldOffset(4)] public CurrentSong ActiveSong;
}
}
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
index 8cbb83be5..6c465b931 100644
--- a/Dalamud/Game/Internal/BaseAddressResolver.cs
+++ b/Dalamud/Game/Internal/BaseAddressResolver.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Runtime.InteropServices;
namespace Dalamud.Game.Internal {
@@ -35,7 +35,7 @@ namespace Dalamud.Game.Internal {
// Do nothing
}
- protected T GetVirtualFunction(IntPtr address, int vtableOffset, int count) where T : class {
+ public T GetVirtualFunction(IntPtr address, int vtableOffset, int count) where T : class {
// Get vtable
var vtable = Marshal.ReadIntPtr(address, vtableOffset);
diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Internal/Gui/GameGui.cs
index 86de67e7a..89f64eb2e 100644
--- a/Dalamud/Game/Internal/Gui/GameGui.cs
+++ b/Dalamud/Game/Internal/Gui/GameGui.cs
@@ -1,6 +1,6 @@
using System;
using System.Runtime.InteropServices;
-using Dalamud.Game.Chat;
+using Dalamud.Game.Chat.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Serilog;
@@ -22,6 +22,18 @@ namespace Dalamud.Game.Internal.Gui {
private delegate IntPtr HandleItemOutDelegate(IntPtr hoverState, IntPtr a2, IntPtr a3, ulong a4);
private readonly Hook handleItemOutHook;
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate IntPtr GetUIObjectDelegate();
+ private readonly GetUIObjectDelegate getUIObject;
+
+ [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
+ private delegate IntPtr GetUIMapObjectDelegate(IntPtr UIObject);
+ private GetUIMapObjectDelegate getUIMapObject;
+
+ [UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
+ private delegate bool OpenMapWithFlagDelegate(IntPtr UIMapObject, string flag);
+ private OpenMapWithFlagDelegate openMapWithFlag;
+
///
/// The item ID that is currently hovered by the player. 0 when no item is hovered.
/// If > 1.000.000, subtract 1.000.000 and treat it as HQ
@@ -43,6 +55,7 @@ namespace Dalamud.Game.Internal.Gui {
Log.Verbose("SetGlobalBgm address {Address}", Address.SetGlobalBgm);
Log.Verbose("HandleItemHover address {Address}", Address.HandleItemHover);
Log.Verbose("HandleItemOut address {Address}", Address.HandleItemOut);
+ Log.Verbose("GetUIObject address {Address}", Address.GetUIObject);
Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
@@ -59,6 +72,8 @@ namespace Dalamud.Game.Internal.Gui {
new Hook(Address.HandleItemOut,
new HandleItemOutDelegate(HandleItemOutDetour),
this);
+
+ this.getUIObject = Marshal.GetDelegateForFunctionPointer(Address.GetUIObject);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@@ -111,6 +126,39 @@ namespace Dalamud.Game.Internal.Gui {
return retVal;
}
+ public bool OpenMapWithMapLink(MapLinkPayload mapLink)
+ {
+ var uiObjectPtr = getUIObject();
+
+ if (uiObjectPtr.Equals(IntPtr.Zero))
+ {
+ Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
+ return false;
+ }
+
+ getUIMapObject =
+ Address.GetVirtualFunction(uiObjectPtr, 0, 8);
+
+
+ var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr);
+
+ if (uiMapObjectPtr.Equals(IntPtr.Zero))
+ {
+ Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
+ return false;
+ }
+
+ openMapWithFlag =
+ Address.GetVirtualFunction(uiMapObjectPtr, 0, 63);
+
+ var mapLinkString =
+ $"m:{mapLink.TerritoryTypeId},{mapLink.MapId},{unchecked((int)mapLink.RawX)},{unchecked((int)mapLink.RawY)}";
+
+ Log.Debug($"OpenMapWithMapLink: Opening Map Link: {mapLinkString}");
+
+ return this.openMapWithFlag(uiMapObjectPtr, mapLinkString);
+ }
+
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() {
diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
index 8fbda8a5a..5142d0d41 100644
--- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
+++ b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
@@ -11,6 +11,7 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr SetGlobalBgm { get; private set; }
public IntPtr HandleItemHover { get; set; }
public IntPtr HandleItemOut { get; set; }
+ public IntPtr GetUIObject { get; private set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
@@ -29,6 +30,7 @@ namespace Dalamud.Game.Internal.Gui {
SetGlobalBgm = sig.ScanText("4C 8B 15 ?? ?? ?? ?? 4D 85 D2 74 58");
HandleItemHover = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 5C 24 ?? 48 89 AE ?? ?? ?? ??");
HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
+ GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
}
}
}
diff --git a/Dalamud/Interface/AssetManager.cs b/Dalamud/Interface/AssetManager.cs
new file mode 100644
index 000000000..a6e19bec8
--- /dev/null
+++ b/Dalamud/Interface/AssetManager.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Serilog;
+
+namespace Dalamud.Interface
+{
+ class AssetManager {
+ private const string AssetStoreUrl = "https://goatcorp.github.io/DalamudAssets/";
+
+ private static readonly Dictionary AssetDictionary = new Dictionary {
+ {AssetStoreUrl + "UIRes/serveropcode.json", "UIRes/serveropcode.json" },
+ {AssetStoreUrl + "UIRes/NotoSansCJKjp-Medium.otf", "UIRes/NotoSansCJKjp-Medium.otf" },
+ {AssetStoreUrl + "UIRes/logo.png", "UIRes/logo.png" },
+ {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_de.json", "UIRes/loc/dalamud/dalamud_de.json" },
+ {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_es.json", "UIRes/loc/dalamud/dalamud_es.json" },
+ {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_fr.json", "UIRes/loc/dalamud/dalamud_fr.json" },
+ {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_it.json", "UIRes/loc/dalamud/dalamud_it.json" },
+ {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_ja.json", "UIRes/loc/dalamud/dalamud_ja.json" },
+ {"https://img.finalfantasyxiv.com/lds/pc/global/fonts/FFXIV_Lodestone_SSF.ttf", "UIRes/gamesym.ttf" }
+ };
+
+ public static async Task EnsureAssets(string baseDir) {
+ using var client = new HttpClient();
+
+ var assetVerRemote = await client.GetStringAsync(AssetStoreUrl + "version");
+
+ var assetVerPath = Path.Combine(baseDir, "assetver");
+ var assetVerLocal = "0";
+ if (File.Exists(assetVerPath))
+ assetVerLocal = File.ReadAllText(assetVerPath);
+
+ var forceRedownload = assetVerLocal != assetVerRemote;
+ if (forceRedownload)
+ Log.Information("Assets need redownload");
+
+ Log.Verbose("Starting asset download");
+
+ foreach (var entry in AssetDictionary) {
+ var filePath = Path.Combine(baseDir, entry.Value);
+
+ Directory.CreateDirectory(Path.GetDirectoryName(filePath));
+
+ if (!File.Exists(filePath) || forceRedownload) {
+ Log.Verbose("Downloading {0} to {1}...", entry.Key, entry.Value);
+ try {
+ File.WriteAllBytes(filePath, await client.GetByteArrayAsync(entry.Key));
+ } catch (Exception ex) {
+ // If another game is running, we don't want to just fail in here
+ Log.Error(ex, "Could not download asset.");
+ }
+
+ }
+ }
+
+ try {
+ File.WriteAllText(assetVerPath, assetVerRemote);
+ } catch (Exception ex) {
+ Log.Error(ex, "Could not write asset version.");
+ }
+ }
+
+ }
+}
diff --git a/Dalamud/Interface/DalamudCreditsWindow.cs b/Dalamud/Interface/DalamudCreditsWindow.cs
index 0db5052a5..b2a3fbd2a 100644
--- a/Dalamud/Interface/DalamudCreditsWindow.cs
+++ b/Dalamud/Interface/DalamudCreditsWindow.cs
@@ -22,6 +22,7 @@ attick
Aida-Enna
perchbird
Wintermute
+fmauNeko
diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs
index b98b4e242..078713ac6 100644
--- a/Dalamud/Interface/DalamudDataWindow.cs
+++ b/Dalamud/Interface/DalamudDataWindow.cs
@@ -1,4 +1,5 @@
using System.Numerics;
+using Dalamud.Game.Chat;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
using ImGuiNET;
@@ -45,8 +46,8 @@ namespace Dalamud.Interface
ImGui.SameLine();
var copy = ImGui.Button("Copy all");
ImGui.SameLine();
- ImGui.Combo("Data kind", ref this.currentKind, new[] {"ServerOpCode", "ContentFinderCondition", "State"},
- 3);
+ ImGui.Combo("Data kind", ref this.currentKind, new[] {"ServerOpCode", "ContentFinderCondition", "State", "Font Test"},
+ 4);
ImGui.BeginChild("scrolling", new Vector2(0, 0), false, ImGuiWindowFlags.HorizontalScrollbar);
@@ -81,16 +82,16 @@ namespace Dalamud.Interface
stateString += $"HomeWorldName: {this.dalamud.ClientState.LocalPlayer.HomeWorld.GameData.Name}\n";
stateString += $"LocalCID: {this.dalamud.ClientState.LocalContentId:X}\n";
stateString += $"LastLinkedItem: {this.dalamud.Framework.Gui.Chat.LastLinkedItemId.ToString()}\n";
- stateString += $"TerritoryType: {this.dalamud.ClientState.TerritoryType}\n";
+ stateString += $"TerritoryType: {this.dalamud.ClientState.TerritoryType}\n\n";
for (var i = 0; i < this.dalamud.ClientState.Actors.Length; i++) {
var actor = this.dalamud.ClientState.Actors[i];
stateString +=
- $" -> {i} - {actor.Name} - {actor.Position.X} {actor.Position.Y} {actor.Position.Z}\n";
+ $"{actor.Address.ToInt64():X}:{actor.ActorId:X}[{i}] - {actor.ObjectKind} - {actor.Name} - {actor.Position.X} {actor.Position.Y} {actor.Position.Z}\n";
if (actor is Npc npc)
- stateString += $" DataId: {npc.DataId}\n";
+ stateString += $" DataId: {npc.DataId} NameId:{npc.NameId}\n";
if (actor is Chara chara)
stateString +=
@@ -105,6 +106,14 @@ namespace Dalamud.Interface
ImGui.TextUnformatted(stateString);
}
break;
+ case 3:
+ var specialChars = string.Empty;
+ for (var i = 0xE020; i <= 0xE0DB; i++) {
+ specialChars += $"0x{i:X} - {(SeIconChar) i} - {(char) i}\n";
+ }
+
+ ImGui.TextUnformatted(specialChars);
+ break;
}
else
ImGui.TextUnformatted("Data not ready.");
diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs
index 1a7959989..3d66d24d8 100644
--- a/Dalamud/Interface/InterfaceManager.cs
+++ b/Dalamud/Interface/InterfaceManager.cs
@@ -52,6 +52,8 @@ namespace Dalamud.Interface
private delegate void InstallRTSSHook();
private string rtssPath;
+ public ImGuiIOPtr LastImGuiIoPtr;
+
///
/// This event gets called by a plugin UiBuilder when read
///
@@ -198,7 +200,7 @@ namespace Dalamud.Interface
return null;
}
- private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
+ private unsafe IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
{
if (this.scene == null)
{
@@ -207,11 +209,31 @@ namespace Dalamud.Interface
this.scene.OnBuildUI += Display;
this.scene.OnNewInputFrame += OnNewInputFrame;
+ ImFontConfigPtr fontConfig = ImGuiNative.ImFontConfig_ImFontConfig();
+ fontConfig.MergeMode = true;
+ fontConfig.PixelSnapH = true;
+
var fontPathJp = Path.Combine(this.dalamud.StartInfo.WorkingDirectory, "UIRes", "NotoSansCJKjp-Medium.otf");
ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathJp, 17.0f, null, ImGui.GetIO().Fonts.GetGlyphRangesJapanese());
+ var fontPathGame = Path.Combine(this.dalamud.StartInfo.WorkingDirectory, "UIRes", "gamesym.ttf");
+ Log.Verbose(fontPathGame);
+
+ var rangeHandle = GCHandle.Alloc(new ushort[]
+ {
+ 0xE020,
+ 0xE0DB,
+ 0
+ }, GCHandleType.Pinned);
+
+
+ ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathGame, 17.0f, fontConfig, rangeHandle.AddrOfPinnedObject());
+
ImGui.GetIO().Fonts.Build();
+ fontConfig.Destroy();
+ rangeHandle.Free();
+
ImGui.GetStyle().GrabRounding = 3f;
ImGui.GetStyle().FrameRounding = 4f;
ImGui.GetStyle().WindowRounding = 4f;
@@ -297,7 +319,8 @@ namespace Dalamud.Interface
// 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;
+ this.LastImGuiIoPtr = ImGui.GetIO();
+ this.lastWantCapture = this.LastImGuiIoPtr.WantCaptureMouse;
OnDraw?.Invoke();
}
diff --git a/Dalamud/Interface/ItemSearchWindow.cs b/Dalamud/Interface/ItemSearchWindow.cs
index 15da2b609..1261b0e97 100644
--- a/Dalamud/Interface/ItemSearchWindow.cs
+++ b/Dalamud/Interface/ItemSearchWindow.cs
@@ -24,6 +24,7 @@ namespace Dalamud.Interface
{
private readonly DataManager data;
private readonly UiBuilder builder;
+ private readonly bool closeOnChoose;
private string lastSearchText = string.Empty;
private string searchText = string.Empty;
@@ -40,14 +41,16 @@ namespace Dalamud.Interface
public event EventHandler- OnItemChosen;
- public ItemSearchWindow(DataManager data, UiBuilder builder) {
+ public ItemSearchWindow(DataManager data, UiBuilder builder, bool closeOnChoose = true) {
this.data = data;
this.builder = builder;
+ this.closeOnChoose = closeOnChoose;
while (!data.IsDataReady)
Thread.Sleep(1);
- this.luminaItems = this.data.GetExcelSheet
- ().GetRows();
+
+ Task.Run(() => this.data.GetExcelSheet
- ().GetRows()).ContinueWith(t => this.luminaItems = t.Result);
}
public bool Draw() {
@@ -95,56 +98,69 @@ namespace Dalamud.Interface
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
- if (!string.IsNullOrEmpty(this.searchText) || this.currentKind != 0) {
- if (this.lastSearchText != this.searchText || this.lastKind != this.currentKind) {
- this.lastSearchText = this.searchText;
- this.lastKind = this.currentKind;
+ if (this.luminaItems != null) {
+ if (!string.IsNullOrEmpty(this.searchText) || this.currentKind != 0)
+ {
+ if (this.lastSearchText != this.searchText || this.lastKind != this.currentKind)
+ {
+ this.lastSearchText = this.searchText;
+ this.lastKind = this.currentKind;
- this.searchCancelTokenSource?.Cancel();
+ this.searchCancelTokenSource?.Cancel();
- this.searchCancelTokenSource = new CancellationTokenSource();
+ this.searchCancelTokenSource = new CancellationTokenSource();
- var asyncEnum = this.luminaItems.ToAsyncEnumerable();
+ var asyncEnum = this.luminaItems.ToAsyncEnumerable();
- if (!string.IsNullOrEmpty(this.searchText)) {
- Log.Debug("Searching for " + this.searchText);
- asyncEnum = asyncEnum.Where(
- x => (x.Name.ToLower().Contains(this.searchText.ToLower()) ||
- int.TryParse(this.searchText, out var parsedId) &&
- parsedId == x.RowId));
+ if (!string.IsNullOrEmpty(this.searchText))
+ {
+ Log.Debug("Searching for " + this.searchText);
+ asyncEnum = asyncEnum.Where(
+ x => (x.Name.ToLower().Contains(this.searchText.ToLower()) ||
+ int.TryParse(this.searchText, out var parsedId) &&
+ parsedId == x.RowId));
+ }
+
+ if (this.currentKind != 0)
+ {
+ Log.Debug("Searching for C" + this.currentKind);
+ asyncEnum = asyncEnum.Where(x => x.ItemSearchCategory == this.currentKind);
+ }
+
+ this.selectedItemIndex = -1;
+ this.selectedItemTex?.Dispose();
+ this.selectedItemTex = null;
+
+ this.searchTask = asyncEnum.ToListAsync(this.searchCancelTokenSource.Token);
}
- if (this.currentKind != 0) {
- Log.Debug("Searching for C" + this.currentKind);
- asyncEnum = asyncEnum.Where(x => x.ItemSearchCategory == this.currentKind);
+ if (this.searchTask.IsCompletedSuccessfully)
+ {
+ for (var i = 0; i < this.searchTask.Result.Count; i++)
+ {
+ if (ImGui.Selectable(this.searchTask.Result[i].Name, this.selectedItemIndex == i))
+ {
+ this.selectedItemIndex = i;
+
+ var iconTex = this.data.GetIcon(this.searchTask.Result[i].Icon);
+ this.selectedItemTex?.Dispose();
+ this.selectedItemTex =
+ this.builder.LoadImageRaw(iconTex.GetRgbaImageData(), iconTex.Header.Width,
+ iconTex.Header.Height, 4);
+ }
+ }
}
+ }
+ else
+ {
+ ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectHint", "Type to start searching..."));
this.selectedItemIndex = -1;
this.selectedItemTex?.Dispose();
this.selectedItemTex = null;
-
- this.searchTask = asyncEnum.ToListAsync(this.searchCancelTokenSource.Token);
- }
-
- if (this.searchTask.IsCompletedSuccessfully) {
- for (var i = 0; i < this.searchTask.Result.Count; i++) {
- if (ImGui.Selectable(this.searchTask.Result[i].Name, this.selectedItemIndex == i)) {
- this.selectedItemIndex = i;
-
- var iconTex = this.data.GetIcon(this.searchTask.Result[i].Icon);
- this.selectedItemTex?.Dispose();
- this.selectedItemTex =
- this.builder.LoadImageRaw(iconTex.GetRgbaImageData(), iconTex.Header.Width,
- iconTex.Header.Height, 4);
- }
- }
}
} else {
- ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectHint", "Type to start searching..."));
-
- this.selectedItemIndex = -1;
- this.selectedItemTex?.Dispose();
- this.selectedItemTex = null;
+ ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectLoading", "Loading item list..."));
}
ImGui.PopStyleVar();
@@ -153,8 +169,20 @@ namespace Dalamud.Interface
if (ImGui.Button(Loc.Localize("Choose", "Choose"))) {
OnItemChosen?.Invoke(this, this.searchTask.Result[this.selectedItemIndex]);
- this.selectedItemTex?.Dispose();
- isOpen = false;
+
+ if (this.closeOnChoose) {
+ this.selectedItemTex?.Dispose();
+ isOpen = false;
+ }
+ }
+
+ if (!this.closeOnChoose) {
+ ImGui.SameLine();
+ if (ImGui.Button(Loc.Localize("Close", "Close")))
+ {
+ this.selectedItemTex?.Dispose();
+ isOpen = false;
+ }
}
ImGui.End();
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index c58364f42..31468e302 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -95,7 +95,7 @@ namespace Dalamud.Interface
try {
OnBuildUi?.Invoke();
} catch (Exception ex) {
- Log.Error("[{0}] UiBuilder OnBuildUi caught exception");
+ Log.Error(ex, "[{0}] UiBuilder OnBuildUi caught exception", this.namespaceName);
OnBuildUi = null;
OnOpenConfigUi = null;
diff --git a/Dalamud/Localization.cs b/Dalamud/Localization.cs
index ea791f548..b4a856aeb 100644
--- a/Dalamud/Localization.cs
+++ b/Dalamud/Localization.cs
@@ -39,6 +39,11 @@ namespace Dalamud
}
public void SetupWithLangCode(string langCode) {
+ if (langCode.ToLower() == "en") {
+ Loc.SetupWithFallbacks();
+ return;
+ }
+
Loc.Setup(File.ReadAllText(Path.Combine(this.workingDirectory, "UIRes", "loc", "dalamud", $"dalamud_{langCode}.json")));
}
}
diff --git a/Dalamud/Plugin/PluginRepository.cs b/Dalamud/Plugin/PluginRepository.cs
index af8ff3326..97a80d567 100644
--- a/Dalamud/Plugin/PluginRepository.cs
+++ b/Dalamud/Plugin/PluginRepository.cs
@@ -14,7 +14,7 @@ namespace Dalamud.Plugin
{
public class PluginRepository
{
- private const string PluginRepoBaseUrl = "https://goaaats.github.io/DalamudPlugins/";
+ private const string PluginRepoBaseUrl = "https://goatcorp.github.io/DalamudPlugins/";
private PluginManager manager;
private string pluginDirectory;
diff --git a/Dalamud/UIRes/77240429-37533100-6bab-11ea-9ad6-69c99e0bc4f9.png b/Dalamud/UIRes/77240429-37533100-6bab-11ea-9ad6-69c99e0bc4f9.png
deleted file mode 100644
index 143b1f8b1..000000000
Binary files a/Dalamud/UIRes/77240429-37533100-6bab-11ea-9ad6-69c99e0bc4f9.png and /dev/null differ
diff --git a/Dalamud/UIRes/NotoSansCJKjp-Medium.otf b/Dalamud/UIRes/NotoSansCJKjp-Medium.otf
deleted file mode 100644
index ba41937ae..000000000
Binary files a/Dalamud/UIRes/NotoSansCJKjp-Medium.otf and /dev/null differ
diff --git a/Dalamud/UIRes/loc/dalamud/dalamud_de.json b/Dalamud/UIRes/loc/dalamud/dalamud_de.json
deleted file mode 100644
index d64d4594b..000000000
--- a/Dalamud/UIRes/loc/dalamud/dalamud_de.json
+++ /dev/null
@@ -1,194 +0,0 @@
-{
- "DalamudUnloadHelp": {
- "message": "Entläd das XIVLauncher In-Game-Addon.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPluginReloadHelp": {
- "message": "Läd alle Plugins neu.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPrintChatHelp": {
- "message": "Gibt eine Nachricht im Chat aus.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdInfoHelp": {
- "message": "Zeigt eine Liste aller verfügbaren Textkommandos an.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteHelp": {
- "message": "Gib ein Wort oder einen Satz ein, der nicht im Chat auftauchen soll. Nutzung: /xlmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteListHelp": {
- "message": "Listet stummgeschaltete Worte oder Sätze auf.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudUnmuteHelp": {
- "message": "Löscht ein Wort oder einen Satz von der Liste der stummgeschalteten Worte. Nutzung: /xlunmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudLastLinkHelp": {
- "message": "Öffnet den zuletzt im Chat geposteten Link in deinem Browser.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBotJoinHelp": {
- "message": "Füge den XIVLauncher Discord-Bot zu einem deiner Server hinzu.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBgmSetHelp": {
- "message": "Setzt die Hintergrundmusik im Spiel. Nutzung: /xlbgmset ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudItemLinkHelp": {
- "message": "Verlinkt den angegebenen Gegenstand. Nutzung: /xlitem
- . Um den exakten Namen anzugeben, nutze /xlitem +
- ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBonusHelp": {
- "message": "Sende eine Benachrichtigung, wenn ein Zufallsinhalt einen Bonus für die Rolle hast, die du angibst. Nutzung: /xlbonus ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudDevMenuHelp": {
- "message": "Öffne das dev-Menü DEBUG",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudInstallerHelp": {
- "message": "Öffnet den Plugin-Installer",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCreditsHelp": {
- "message": "Öffnet die Liste der Mitwirkenden",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdHelpAvailable": {
- "message": "Verfügbare Kommandos:",
- "description": "Dalamud.OnHelpCommand"
- },
- "DalamudMuted": {
- "message": "\"{0}\" stummgeschaltet.",
- "description": "Dalamud.OnBadWordsAddCommand"
- },
- "DalamudNoneMuted": {
- "message": "Keine stummgeschalteten Wörte oder Sätze.",
- "description": "Dalamud.OnBadWordsListCommand"
- },
- "DalamudUnmuted": {
- "message": "\"{0}\" freigegeben.",
- "description": "Dalamud.OnBadWordsRemoveCommand"
- },
- "DalamudNoLastLink": {
- "message": "Keinen Link gefunden...",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudOpeningLink": {
- "message": "{0} wird geöffnet",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudBotNotSetup": {
- "message": "Der XIVLauncher Discord-Bot wurde nicht korrekt eingestellt. Bitte prüfe die Einstellungen und unser FAQ.",
- "description": "Dalamud.OnBotJoinCommand"
- },
- "DalamudChannelNotSetup": {
- "message": "Du hast keinen Discord-Kanal für diese Notifikationen eingestellt - du wirst sie also nur im Chat erhalten.\nUm einen Kanal einzustellen, nutze bitte die XIVLauncher-Einstellungen.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusSet": {
- "message": "Bonus-Notifikationen für {0}({1}) auf {2} gesetzt",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudInvalidArguments": {
- "message": "Parameter nicht erkannt.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusPossibleValues": {
- "message": "Mögliche Werte für Zufallsinhalte: leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nMögliche Werte für Rollen: tank, dps, healer, all, none/reset",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudItemNotFound": {
- "message": "Gegenstand konnte nicht gefunden werden.",
- "description": "<b__0>d.MoveNext"
- },
- "InstallerHeader": {
- "message": "Plugin-Installer",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerHint": {
- "message": "Dieses Fenster erlaubt es dir, Plugins zu installieren.\nSie werden von Drittanbietern entwickelt.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerLoading": {
- "message": "Plugins werden geladen...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDownloadFailed": {
- "message": "Download fehlgeschlagen.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInstalled": {
- "message": " (installiert)",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInProgress": {
- "message": "Wird installiert...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDisable": {
- "message": "Deaktivieren",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerOpenConfig": {
- "message": "Einstellungen öffnen",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdating": {
- "message": "Wird aktualisiert...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdateComplete": {
- "message": "{0} Plugins aktualisiert!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerNoUpdates": {
- "message": "Keine Aktualisierungen gefunden!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdatePlugins": {
- "message": "Plugins aktualisieren",
- "description": "PluginInstallerWindow.Draw"
- },
- "Close": {
- "message": "Schließen",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerError": {
- "message": "Installation fehlgeschlagen",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerErrorHint": {
- "message": "Der Plugin-Installer konnte die Operation nicht erfolgreich beenden.\nBitte starte das Spiel neu und melde diesen Fehler auf unserem Discord-Server.",
- "description": "PluginInstallerWindow.Draw"
- },
- "OK": {
- "message": "OK",
- "description": "PluginInstallerWindow.Draw"
- },
- "DalamudWelcome": {
- "message": "XIVLauncher In-Game-Addon v{0} geladen.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginLoaded": {
- "message": " 》 {0} v{1} geladen.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudUpdated": {
- "message": "Das In-Game-Addon wurde aktualisiert oder neu installiert. Bitte prüfe unseren Discord-Server für weitere Informationen!",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateRequired": {
- "message": "Eines oder mehrere deiner Plugins müssen aktualisiert werden. Bitte nutze das /xlplugins-Kommando, um sie zu aktualisieren.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateCheckFail": {
- "message": "Konnte nicht auf Plugin-Aktualisierungen prüfen.",
- "description": "ChatHandlers.OnChatMessage"
- }
-}
\ No newline at end of file
diff --git a/Dalamud/UIRes/loc/dalamud/dalamud_es.json b/Dalamud/UIRes/loc/dalamud/dalamud_es.json
deleted file mode 100644
index e8aceb20b..000000000
--- a/Dalamud/UIRes/loc/dalamud/dalamud_es.json
+++ /dev/null
@@ -1,194 +0,0 @@
-{
- "DalamudUnloadHelp": {
- "message": "Decarga el extra In-Game de XIVLauncher.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPluginReloadHelp": {
- "message": "Recarga todos de los plugins.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPrintChatHelp": {
- "message": "Publica al chat.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdInfoHelp": {
- "message": "Muestre la lista de los comandos disponibles.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteHelp": {
- "message": "Bloquea una palabra u oración que aperecer en el chat. Uso: /xlmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteListHelp": {
- "message": "Enumera las palabras u oraciónes qué están bloqueadas.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudUnmuteHelp": {
- "message": "Desbloquea una palabra u oración. Uso: /xlunmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudLastLinkHelp": {
- "message": "Abre el enlace anterior en su navegador por defecto.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBotJoinHelp": {
- "message": "Agrega el bot Discord de XIVLauncher que ha configurado a su servidor.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBgmSetHelp": {
- "message": "Configura la música ambiental del juego. Uso: /xlbgmset ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudItemLinkHelp": {
- "message": "Enlaza un artículo por nombre. Uso: /xlitem . Para emperejando un artículo exactamente, utiliza /xlitem +",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBonusHelp": {
- "message": "Notifícase cuando una ruleta tenga un extra que usted especifica. Ejecútalo sin parametres para más información. Uso: /xlbonus ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudDevMenuHelp": {
- "message": "Dibuja el menú dev DEBUG",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudInstallerHelp": {
- "message": "Abre el instalador de plugins",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCreditsHelp": {
- "message": "Abra los méritos de Dalamud.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdHelpAvailable": {
- "message": "Comandos disponibles:",
- "description": "Dalamud.OnHelpCommand"
- },
- "DalamudMuted": {
- "message": "Ha bloqueado \"{0}\".",
- "description": "Dalamud.OnBadWordsAddCommand"
- },
- "DalamudNoneMuted": {
- "message": "No hay palabras u oraciónes qué están bloqueadas.",
- "description": "Dalamud.OnBadWordsListCommand"
- },
- "DalamudUnmuted": {
- "message": "Ha desbloqueado \"{0}\".",
- "description": "Dalamud.OnBadWordsRemoveCommand"
- },
- "DalamudNoLastLink": {
- "message": "No hay un enlace anterior...",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudOpeningLink": {
- "message": "Está abriendo {0}",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudBotNotSetup": {
- "message": "El bot Discord de XIVLauncher no configuría corecto o no pudo conectar a Discord. Por favor revisa los ajustes y el FAQ.",
- "description": "Dalamud.OnBotJoinCommand"
- },
- "DalamudChannelNotSetup": {
- "message": "No configuría un canal Discord para estos notificaciónes - solo recibirá en el chat. Para que lo configura, por favor utiliza los ajustes de XIVLauncher en el juego.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusSet": {
- "message": "Configura notificaciónes bonus para {0}({1}) a {2}",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudInvalidArguments": {
- "message": "Hay argumentes que no reconocido.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusPossibleValues": {
- "message": "Valores posibles para ruleta: leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nValores posibles para rol: tank, dps, healer, all, none/reset",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudItemNotFound": {
- "message": "No pudo encuentra el artículo.",
- "description": "<b__0>d.MoveNext"
- },
- "InstallerHeader": {
- "message": "Instalador de Plugins",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerHint": {
- "message": "Esta ventana permite que instalar y elimnar los plugins en el juego.\nFueron hechos por desarrolladores terceros.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerLoading": {
- "message": "Está cargando los plugins...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDownloadFailed": {
- "message": "La descarga falló.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInstalled": {
- "message": " (instalado)",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInProgress": {
- "message": "Instalación en curso...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDisable": {
- "message": "Desactiva",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerOpenConfig": {
- "message": "Abre Configuración",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdating": {
- "message": "Actualizando...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdateComplete": {
- "message": "¡{0} plugins han actualizado!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerNoUpdates": {
- "message": "¡No hay actualizaciónes!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdatePlugins": {
- "message": "Actualiza plugins",
- "description": "PluginInstallerWindow.Draw"
- },
- "Close": {
- "message": "Cierra",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerError": {
- "message": "El instalador falló",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerErrorHint": {
- "message": "El instalador de plugins corrió a una problema, o el plugin está incompatible.\nPor favor reinicia el juego y informa el error en neustro Discord.",
- "description": "PluginInstallerWindow.Draw"
- },
- "OK": {
- "message": "OK",
- "description": "PluginInstallerWindow.Draw"
- },
- "DalamudWelcome": {
- "message": "El extra In-Game v{0} de XIVLauncher ha cargado.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginLoaded": {
- "message": " 》 {0} v{1} ha cargado.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudUpdated": {
- "message": "¡El extra In-Game había actualizado o reinstalado con éxito! Por favor comproba el Discord para un changelog completo.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateRequired": {
- "message": "Uno o más de sus plugins deben habar actualizado. ¡Por favor utiliza el comando /xlplugins para los actualizan!",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateCheckFail": {
- "message": "No pudo buscar para actualizaciónes de los plugins.",
- "description": "ChatHandlers.OnChatMessage"
- }
-}
\ No newline at end of file
diff --git a/Dalamud/UIRes/loc/dalamud/dalamud_fr.json b/Dalamud/UIRes/loc/dalamud/dalamud_fr.json
deleted file mode 100644
index 9bba4cc16..000000000
--- a/Dalamud/UIRes/loc/dalamud/dalamud_fr.json
+++ /dev/null
@@ -1,194 +0,0 @@
-{
- "DalamudUnloadHelp": {
- "message": "Désactive l'addon in-game de XIVLauncher.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPluginReloadHelp": {
- "message": "Recharge tous les plugins.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPrintChatHelp": {
- "message": "Afficher dans le chat.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdInfoHelp": {
- "message": "Montre la liste des commandes disponibles.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteHelp": {
- "message": "Met en sourdine un mot ou une phrase dans le chat. Utilisation : /xlmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteListHelp": {
- "message": "Liste les mots ou phrases en sourdine.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudUnmuteHelp": {
- "message": "Ré-affiche un mot ou une phrase. Utilisation : /xlunmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudLastLinkHelp": {
- "message": "Ouvre le dernier lien affiché dans le chat dans votre navigateur par défaut.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBotJoinHelp": {
- "message": "Ajoute le bot discord XIVLauncher que vous avez configuré à votre serveur.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBgmSetHelp": {
- "message": "Définit la musique de fond. Utilisation : /xlbgmset ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudItemLinkHelp": {
- "message": "Envoie le lien d'un objet grâce à son nom. Utilisation : /xlitem . Pour trouver un objet précis, utilisez /xlitem +",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBonusHelp": {
- "message": "Informe lorsque une mission aléatoire possède le bonus spécifié. Exécuter sans paramètres pour plus d'infos. Utilisation : /xlbonus ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudDevMenuHelp": {
- "message": "Fait sortir le menu dev DEBUG",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudInstallerHelp": {
- "message": "Ouvrir l’installateur de plugins",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCreditsHelp": {
- "message": "Ouvre la liste des participants.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdHelpAvailable": {
- "message": "Commandes disponibles :",
- "description": "Dalamud.OnHelpCommand"
- },
- "DalamudMuted": {
- "message": "\"{0}\" est mis en sourdine.",
- "description": "Dalamud.OnBadWordsAddCommand"
- },
- "DalamudNoneMuted": {
- "message": "Pas de mots ou phrases en sourdine.",
- "description": "Dalamud.OnBadWordsListCommand"
- },
- "DalamudUnmuted": {
- "message": "\"{0}\" est de nouveau visible.",
- "description": "Dalamud.OnBadWordsRemoveCommand"
- },
- "DalamudNoLastLink": {
- "message": "Il n'y a pas de lien...",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudOpeningLink": {
- "message": "Ouverture de {0}",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudBotNotSetup": {
- "message": "Le bot discord XIVLauncher n'a pas été configuré correctement ou ne peut pas se connecter à discord. Veuillez vérifier les paramètres et la FAQ.",
- "description": "Dalamud.OnBotJoinCommand"
- },
- "DalamudChannelNotSetup": {
- "message": "Vous n'avez pas configuré de canal discord pour ces notifications - vous les recevrez uniquement dans le chat. Pour ce faire, veuillez utiliser les paramètres \"In-game\" dans XIVLauncher.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusSet": {
- "message": "Définit les notifications de bonus pour {0}({1}) à {2}",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudInvalidArguments": {
- "message": "Arguments non-reconnus.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusPossibleValues": {
- "message": "Valeurs possibles pour mission aléatoire : leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nValeurs possibles pour rôle : tank, dps, healer, all, none/reset",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudItemNotFound": {
- "message": "L'objet n'a pas pu être trouvé.",
- "description": "<b__0>d.MoveNext"
- },
- "InstallerHeader": {
- "message": "Installateur de Plugin",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerHint": {
- "message": "Cette fenêtre vous autorise à installer ou retirer des plugins en jeu.\nIls sont créés par des développeurs tiers.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerLoading": {
- "message": "Chargement des plugins...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDownloadFailed": {
- "message": "Le téléchargement a échoué.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInstalled": {
- "message": " (installé)",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInProgress": {
- "message": "Installation en cours...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDisable": {
- "message": "Désactiver",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerOpenConfig": {
- "message": "Ouvrir la configuration",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdating": {
- "message": "Mise à jour...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdateComplete": {
- "message": "{0} plugin(s) mis à jour !",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerNoUpdates": {
- "message": "Pas de mise à jour trouvée !",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdatePlugins": {
- "message": "Mettre à jour les plugins",
- "description": "PluginInstallerWindow.Draw"
- },
- "Close": {
- "message": "Fermer",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerError": {
- "message": "Échec de l'installation",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerErrorHint": {
- "message": "L'installateur de plugins a rencontré un problème ou le plugin est incompatible.\nVeuillez redémarrer le jeu et rapporter cette erreur sur notre discord.",
- "description": "PluginInstallerWindow.Draw"
- },
- "OK": {
- "message": "OK",
- "description": "PluginInstallerWindow.Draw"
- },
- "DalamudWelcome": {
- "message": "Addon en jeu XIVLauncher v{0} chargé.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginLoaded": {
- "message": " 》 {0} v{1} chargé.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudUpdated": {
- "message": "L'addon en jeu à été mis à jour ou réinstallé avec succès ! Veuillez consulter le discord pour plus d'informations.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateRequired": {
- "message": "Un ou plusieurs plugins ne sont plus à jour. Veuillez utiliser la commande en jeu /xlplugins pour les mettre à jour !",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateCheckFail": {
- "message": "Impossible de vérifier les mises à jour des plugins.",
- "description": "ChatHandlers.OnChatMessage"
- }
-}
\ No newline at end of file
diff --git a/Dalamud/UIRes/loc/dalamud/dalamud_it.json b/Dalamud/UIRes/loc/dalamud/dalamud_it.json
deleted file mode 100644
index 8ed844ff0..000000000
--- a/Dalamud/UIRes/loc/dalamud/dalamud_it.json
+++ /dev/null
@@ -1,194 +0,0 @@
-{
- "DalamudUnloadHelp": {
- "message": "Disattiva l'addon in gioco di XIVLauncher.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPluginReloadHelp": {
- "message": "Ricarica tutti i plugin.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPrintChatHelp": {
- "message": "Stampa in chat.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdInfoHelp": {
- "message": "Mostra lista dei comandi disponibili.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteHelp": {
- "message": "Proibisci a una parola o a una frase di apparire in chat. Uso: /xlmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteListHelp": {
- "message": "Elenca parole e frasi proibite.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudUnmuteHelp": {
- "message": "Permetti a una parola o a una frase di apparire in chat. Uso: /xlunmute ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudLastLinkHelp": {
- "message": "Apri il link piú recente della chat nel tuo browser predefinito.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBotJoinHelp": {
- "message": "Aggiungi al tuo server il bot Discord di XIVLauncher che hai impostato.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBgmSetHelp": {
- "message": "Imposta la musica di sottofondo del gioco. Uso: /xlbgmset ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudItemLinkHelp": {
- "message": "Linka un oggetto per nome. Uso: /xlitem . Per abbinare un oggetto specifico, usa /xlitem +",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBonusHelp": {
- "message": "Notificami quando una roulette contiene un bonus specifico. Esegui senza parametri aggiuntivi per maggiori informazioni. Uso: /xlbonus ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudDevMenuHelp": {
- "message": "Mostra menu sviluppatore DEBUG",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudInstallerHelp": {
- "message": "Apri l'installatore dei plugin",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCreditsHelp": {
- "message": "Apri i titoli di coda per dalamud.",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdHelpAvailable": {
- "message": "Comandi disponibili:",
- "description": "Dalamud.OnHelpCommand"
- },
- "DalamudMuted": {
- "message": "Silenziato \"{0}\".",
- "description": "Dalamud.OnBadWordsAddCommand"
- },
- "DalamudNoneMuted": {
- "message": "Nessuna parola o frase proibita.",
- "description": "Dalamud.OnBadWordsListCommand"
- },
- "DalamudUnmuted": {
- "message": "Riattivato \"{0}\".",
- "description": "Dalamud.OnBadWordsRemoveCommand"
- },
- "DalamudNoLastLink": {
- "message": "Nessun link recente...",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudOpeningLink": {
- "message": "Aprendo {0}",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudBotNotSetup": {
- "message": "Il bot Discord di XIVLauncher non è stato impostato correttamente o non ha potuto connettersi a Discord. Per favore controlla le impostazioni e le FAQ.",
- "description": "Dalamud.OnBotJoinCommand"
- },
- "DalamudChannelNotSetup": {
- "message": "Non hai impostato un canale Discord per queste notifiche - Per fare ció, utilizza le impostazioni di gioco di XIVLauncher. Al momento, riceverai le notifiche solo nella chat.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusSet": {
- "message": "Impostate notifiche bonus per {0}({1} a {2})",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudInvalidArguments": {
- "message": "Argomenti non risconosciuti.",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusPossibleValues": {
- "message": "Possibili valori per la roulette: leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nPossibili valori per i ruoli: tank, dps, healer, all, none/reset",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudItemNotFound": {
- "message": "Oggetto non trovato.",
- "description": "<b__0>d.MoveNext"
- },
- "InstallerHeader": {
- "message": "Installatore Plugin",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerHint": {
- "message": "Questa finestra ti permette di installare e rimuovere i plugin di gioco.\nSono sviluppati da terze parti.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerLoading": {
- "message": "Caricamento plugins...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDownloadFailed": {
- "message": "Download fallito.",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInstalled": {
- "message": " (installato)",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInProgress": {
- "message": "Installazione in corso...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDisable": {
- "message": "Disabilita",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerOpenConfig": {
- "message": "Apri configurazione",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdating": {
- "message": "Aggiornamento...",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdateComplete": {
- "message": "{0} plugins aggiornati!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerNoUpdates": {
- "message": "Nessun aggiornamento trovato!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdatePlugins": {
- "message": "Aggiorna plugins",
- "description": "PluginInstallerWindow.Draw"
- },
- "Close": {
- "message": "Chiudi",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerError": {
- "message": "Installazione fallita",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerErrorHint": {
- "message": "L'installatore ha riscontrato dei problemi o il plugin é incompatibile.\nRiavvia il gioco e segnalaci questo errore sul nostro Discord.",
- "description": "PluginInstallerWindow.Draw"
- },
- "OK": {
- "message": "OK",
- "description": "PluginInstallerWindow.Draw"
- },
- "DalamudWelcome": {
- "message": "XIVLauncher addon in gioco v{0} caricato.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginLoaded": {
- "message": " 》 {0} v{1} caricato.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudUpdated": {
- "message": "L'addon in gioco è stato aggiornato o reinstallato con successo! Controlla su Discord per un changelog completo.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateRequired": {
- "message": "Uno o piú dei tuoi plugins necessita un aggiornamento. Usa il comando /xlplugins in gioco per aggiornarli!",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateCheckFail": {
- "message": "Non è stato possibile controllare gli aggiornamenti dei plugin.",
- "description": "ChatHandlers.OnChatMessage"
- }
-}
\ No newline at end of file
diff --git a/Dalamud/UIRes/loc/dalamud/dalamud_ja.json b/Dalamud/UIRes/loc/dalamud/dalamud_ja.json
deleted file mode 100644
index c4f81d2bf..000000000
--- a/Dalamud/UIRes/loc/dalamud/dalamud_ja.json
+++ /dev/null
@@ -1,194 +0,0 @@
-{
- "DalamudUnloadHelp": {
- "message": "XIVLauncher In-Game アドオンをアンロードします。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPluginReloadHelp": {
- "message": "全てのプラグインをリロードします。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudPrintChatHelp": {
- "message": "チャットに出力する。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdInfoHelp": {
- "message": "利用可能なコマンド一覧を表示します。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteHelp": {
- "message": "チャットに表示される単語や文章をミュートします。 利用法: /xlmute <単語 または、文章>",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudMuteListHelp": {
- "message": "ミュートされた単語または文章の一覧を表示します。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudUnmuteHelp": {
- "message": "単語または文章のミュートを解除します。利用法: /xlunmute <単語 または、文章>",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudLastLinkHelp": {
- "message": "デフォルトブラウザで直前に投稿したリンクを開きます。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBotJoinHelp": {
- "message": "設定した XIVLauncher の Discord ボットを自分のサーバーへ追加します。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBgmSetHelp": {
- "message": "ゲームBGMを設定します。利用法: /xlbgmset ",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudItemLinkHelp": {
- "message": "アイテムを名前でリンクします。使用法: /xlitem <アイテム名> アイテム名を完全一致したい場合: /xlitem +<アイテム名>",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudBonusHelp": {
- "message": "ルーレットに指定したボーナスがある場合に通知します。詳細はパラメータなしで実行してください。使用法: /xlbonus <ルーレット名> <ロール名>",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudDevMenuHelp": {
- "message": "DEBUG 開発メニューを表示します。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudInstallerHelp": {
- "message": "プラグインインストーラを開きます",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCreditsHelp": {
- "message": "Dalamud のクレジットを開きます。",
- "description": "Dalamud.SetupCommands"
- },
- "DalamudCmdHelpAvailable": {
- "message": "利用可能なコマンド:",
- "description": "Dalamud.OnHelpCommand"
- },
- "DalamudMuted": {
- "message": "\"{0}\" をミュートしました。",
- "description": "Dalamud.OnBadWordsAddCommand"
- },
- "DalamudNoneMuted": {
- "message": "ミュートされている単語または、文章はありません。",
- "description": "Dalamud.OnBadWordsListCommand"
- },
- "DalamudUnmuted": {
- "message": "\"{0}\" のミュートを解除しました。",
- "description": "Dalamud.OnBadWordsRemoveCommand"
- },
- "DalamudNoLastLink": {
- "message": "直前のリンクがありません……",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudOpeningLink": {
- "message": "{0} を開いています。",
- "description": "Dalamud.OnLastLinkCommand"
- },
- "DalamudBotNotSetup": {
- "message": "XIVLauncher の Discordボットが正しく設定されていないか、Discord に接続できませんでした。設定やFAQをご確認ください。",
- "description": "Dalamud.OnBotJoinCommand"
- },
- "DalamudChannelNotSetup": {
- "message": "通知用の Discord チャンネルを設定していません (チャットでのみ受信できます)。Discord で通知を受け取るには、XIVLauncher の In-Game 設定をしてください。",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusSet": {
- "message": "{0}({1}) のボーナス通知を {2} に設定します",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudInvalidArguments": {
- "message": "認識できないパラメータです。",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudBonusPossibleValues": {
- "message": "ルーレットの可能な入力:leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nロールの可能な入力:tank, dps, healer, all, none/reset",
- "description": "Dalamud.OnRouletteBonusNotifyCommand"
- },
- "DalamudItemNotFound": {
- "message": "アイテムを見つけられませんでした。",
- "description": "<b__0>d.MoveNext"
- },
- "InstallerHeader": {
- "message": "プラグインインストーラ",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerHint": {
- "message": "このウィンドウでは、In-Game プラグインのインストールと削除を行うことができます。\nこれらはサードパーティの開発者によって作られたものです。",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerLoading": {
- "message": "プラグインをロード中……",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDownloadFailed": {
- "message": "ダウンロードが失敗しました。",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInstalled": {
- "message": " (導入済み)",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerInProgress": {
- "message": "インストール中……",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerDisable": {
- "message": "無効化",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerOpenConfig": {
- "message": "設定を開く",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdating": {
- "message": "アップデートしています……",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdateComplete": {
- "message": "{0} のプラグインが更新されました!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerNoUpdates": {
- "message": "アップデートが見つかりませんでした!",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerUpdatePlugins": {
- "message": "プラグインをアップデートする",
- "description": "PluginInstallerWindow.Draw"
- },
- "Close": {
- "message": "閉じる",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerError": {
- "message": "インストールが失敗しました",
- "description": "PluginInstallerWindow.Draw"
- },
- "InstallerErrorHint": {
- "message": "プラグインのインストーラに問題が発生したか、プラグインとの互換性がありません。\nゲームを再起動して、このエラーを私たちのディスコードで報告してください。",
- "description": "PluginInstallerWindow.Draw"
- },
- "OK": {
- "message": "OK",
- "description": "PluginInstallerWindow.Draw"
- },
- "DalamudWelcome": {
- "message": "XIVLauncher In-Game アドオン v{0} がロードされました.",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginLoaded": {
- "message": " 》 {0} v{1} がロードされました。",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudUpdated": {
- "message": "In-Game アドオンの更新または、再インストールに成功しました。詳細な変更履歴はDiscordで確認してください。",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateRequired": {
- "message": "いくつかのプラグインで更新が必要です。/xlplugins コマンドを使用して、プラグインを更新してください。",
- "description": "ChatHandlers.OnChatMessage"
- },
- "DalamudPluginUpdateCheckFail": {
- "message": "プラグインの更新を確認できませんでした。",
- "description": "ChatHandlers.OnChatMessage"
- }
-}
\ No newline at end of file
diff --git a/Dalamud/UIRes/logo.png b/Dalamud/UIRes/logo.png
deleted file mode 100644
index 5b118df26..000000000
Binary files a/Dalamud/UIRes/logo.png and /dev/null differ
diff --git a/README.md b/README.md
index 47c86fc5f..af3fb4aa9 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,11 @@
Dalamud is a plugin development framework for FINAL FANTASY XIV that provides access to game data and native interoperability with the game itself to add functionality and quality-of-life.
-It is meant to be used in conjunction with [FFXIVQuickLauncher](https://github.com/goaaats/FFXIVQuickLauncher).
+It is meant to be used in conjunction with [FFXIVQuickLauncher](https://github.com/goatcorp/FFXIVQuickLauncher).
## Plugin development
Dalamud features a growing API for in-game plugin development with game data and chat access and overlays.
-Please see the [API documentation](https://goaaats.github.io/Dalamud/api/index.html) for more details.
+Please see the [API documentation](https://goatcorp.github.io/Dalamud/api/index.html) for more details.
If you need any support regarding the API or usage of Dalamud, please [join our discord server](https://discord.gg/3NMcUV5).
diff --git a/lib/ImGuiScene b/lib/ImGuiScene
index b096e5b2e..aaa037938 160000
--- a/lib/ImGuiScene
+++ b/lib/ImGuiScene
@@ -1 +1 @@
-Subproject commit b096e5b2e9826525394a0c00b987aad1f2c4eccb
+Subproject commit aaa037938d6fe835a15542a3451d12108e3f83b6