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