diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj index d41829c9c..efd3d98d3 100644 --- a/Dalamud.Injector/Dalamud.Injector.csproj +++ b/Dalamud.Injector/Dalamud.Injector.csproj @@ -14,10 +14,10 @@ true - 5.1.0.4 - 5.1.0.4 + 5.1.0.5 + 5.1.0.5 XIVLauncher addon injection - 5.1.0.4 + 5.1.0.5 diff --git a/Dalamud/Configuration/DalamudConfiguration.cs b/Dalamud/Configuration/DalamudConfiguration.cs index 87041e80b..c90ffbed6 100644 --- a/Dalamud/Configuration/DalamudConfiguration.cs +++ b/Dalamud/Configuration/DalamudConfiguration.cs @@ -18,17 +18,6 @@ namespace Dalamud public List BadWords { get; set; } - public enum PreferredRole - { - None, - All, - Tank, - Dps, - Healer - } - - public Dictionary PreferredRoleReminders { get; set; } - public bool DutyFinderTaskbarFlash { get; set; } = true; public bool DutyFinderChatMessage { get; set; } = true; diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 97fdc94a7..9e0150237 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Net; +using System.Numerics; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -179,7 +180,7 @@ namespace Dalamud { public void Start() { #if DEBUG - ReplaceExceptionHandler(); + //ReplaceExceptionHandler(); #endif } @@ -249,6 +250,31 @@ namespace Dalamud { private void BuildDalamudUi() { + if (!this.isImguiDrawDevMenu && !ClientState.Condition.Any()) + { + ImGui.PushStyleColor(ImGuiCol.Button, new Vector4(0, 0, 0, 0)); + ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0, 0, 0, 0)); + ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0, 0, 0, 0)); + ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0, 0, 0, 1)); + ImGui.PushStyleColor(ImGuiCol.TextSelectedBg, new Vector4(0, 0, 0, 1)); + ImGui.PushStyleColor(ImGuiCol.Border, new Vector4(0, 0, 0, 1)); + ImGui.PushStyleColor(ImGuiCol.BorderShadow, new Vector4(0, 0, 0, 1)); + ImGui.PushStyleColor(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 1)); + + ImGui.SetNextWindowPos(new Vector2(0, 0), ImGuiCond.Always); + ImGui.SetNextWindowBgAlpha(1); + + if (ImGui.Begin("DevMenu Opener", ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoSavedSettings)) + { + if (ImGui.Button("###devMenuOpener", new Vector2(40, 25))) + this.isImguiDrawDevMenu = true; + + ImGui.End(); + } + + ImGui.PopStyleColor(5); + } + if (this.isImguiDrawDevMenu) { if (ImGui.BeginMainMenuBar()) @@ -515,10 +541,6 @@ namespace Dalamud { }); #endif - CommandManager.AddHandler("/xlbonus", new CommandInfo(OnRouletteBonusNotifyCommand) { - HelpMessage = Loc.Localize("DalamudBonusHelp", "Notify when a roulette has a bonus you specified. Run without parameters for more info. Usage: /xlbonus ") - }); - CommandManager.AddHandler("/xldev", new CommandInfo(OnDebugDrawDevMenu) { HelpMessage = Loc.Localize("DalamudDevMenuHelp", "Draw dev menu DEBUG"), ShowInHelp = false @@ -669,46 +691,6 @@ namespace Dalamud { } #endif - private void OnRouletteBonusNotifyCommand(string command, string arguments) - { - if (this.Configuration.DiscordFeatureConfig.CfPreferredRoleChannel == null) - Framework.Gui.Chat.PrintError(Loc.Localize("DalamudChannelNotSetup", "You have not set up a discord channel for these notifications - you will only receive them in chat. To do this, please use the XIVLauncher in-game settings.")); - - if (string.IsNullOrEmpty(arguments)) - goto InvalidArgs; - - var argParts = arguments.Split(); - if (argParts.Length < 2) - goto InvalidArgs; - - - if (this.Configuration.PreferredRoleReminders == null) - this.Configuration.PreferredRoleReminders = new Dictionary(); - - var rouletteIndex = RouletteSlugToKey(argParts[0]); - - if (rouletteIndex == 0) - goto InvalidArgs; - - if (!Enum.TryParse(argParts[1].First().ToString().ToUpper() + argParts[1].ToLower().Substring(1), out DalamudConfiguration.PreferredRole role)) - goto InvalidArgs; - - if (this.Configuration.PreferredRoleReminders.ContainsKey(rouletteIndex)) - this.Configuration.PreferredRoleReminders[rouletteIndex] = role; - else - this.Configuration.PreferredRoleReminders.Add(rouletteIndex, role); - - this.Framework.Gui.Chat.Print($"Set bonus notifications for {argParts[0]}({rouletteIndex}) to {role}"); - this.Framework.Gui.Chat.Print(string.Format(Loc.Localize("DalamudBonusSet", "Set bonus notifications for {0}({1}) to {2}"), argParts[0], rouletteIndex, role)); - this.Configuration.Save(); - - return; - - InvalidArgs: - this.Framework.Gui.Chat.PrintError(Loc.Localize("DalamudInvalidArguments", "Unrecognized arguments.")); - this.Framework.Gui.Chat.Print(Loc.Localize("DalamudBonusPossibleValues", "Possible values for roulette: leveling, 506070, msq, guildhests, expert, trials, mentor, alliance, normal\nPossible values for role: tank, dps, healer, all, none/reset")); - } - private void OnDebugDrawDevMenu(string command, string arguments) { this.isImguiDrawDevMenu = !this.isImguiDrawDevMenu; } @@ -789,27 +771,5 @@ namespace Dalamud { } }); } - - private int RouletteSlugToKey(string slug) => slug.ToLower() switch { - "leveling" => 1, - "506070" => 2, - "msq" => 3, - "guildhests" => 4, - "expert" => 5, - "trials" => 6, - "mentor" => 8, - "alliance" => 9, - "normal" => 10, - _ => 0 - }; - - private DalamudConfiguration.PreferredRole RoleNameToPreferredRole(string name) => name.ToLower() switch - { - "Tank" => DalamudConfiguration.PreferredRole.Tank, - "Healer" => DalamudConfiguration.PreferredRole.Healer, - "Dps" => DalamudConfiguration.PreferredRole.Dps, - "All" => DalamudConfiguration.PreferredRole.All, - _ => DalamudConfiguration.PreferredRole.None - }; } } diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 771febdb7..d9fa11cb2 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -15,9 +15,9 @@ true - 5.1.0.4 - 5.1.0.4 - 5.1.0.4 + 5.1.0.5 + 5.1.0.5 + 5.1.0.5 diff --git a/Dalamud/Game/Chat/SeStringHandling/Payload.cs b/Dalamud/Game/Chat/SeStringHandling/Payload.cs index 89f6c8bd4..8a37e3138 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payload.cs @@ -51,7 +51,7 @@ namespace Dalamud.Game.Chat.SeStringHandling /// /// The Lumina instance to use for any necessary data lookups. /// - protected DataManager DataResolver; + public DataManager DataResolver; // private for now, since subclasses shouldn't interact with this // To force-invalidate it, Dirty can be set to true diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs index c01ed0ee2..98c7ff6b8 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/AutoTranslatePayload.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using Dalamud.Data; using Dalamud.Data.TransientSheet; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -34,7 +35,10 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + [JsonProperty] private uint group; + + [JsonProperty] private uint key; internal AutoTranslatePayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs index 265b8d088..6815e6d0d 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/ItemPayload.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using Dalamud.Data; using Lumina.Excel.GeneratedSheets; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -22,6 +23,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public Item Item { get @@ -57,8 +59,10 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Whether or not this item link is for a high-quality version of the item. /// + [JsonProperty] public bool IsHQ { get; private set; } = false; + [JsonProperty] private uint itemId; internal ItemPayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs index 768d95716..ce547691d 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; using Dalamud.Data; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -20,6 +21,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public Map Map { get @@ -36,6 +38,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public TerritoryType TerritoryType { get @@ -70,6 +73,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The readable y-coordinate position for this map link. This value is approximate and unrounded. /// + [JsonIgnore] public float YCoord { get @@ -82,6 +86,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// The printable map coordinates for this link. This value tries to match the in-game printable text as closely as possible /// but is an approximation and may be slightly off for some positions. /// + [JsonIgnore] public string CoordinateString { get @@ -102,6 +107,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The region name for this map link. This corresponds to the upper zone name found in the actual in-game map UI. eg, "La Noscea" /// + [JsonIgnore] public string PlaceNameRegion { get @@ -115,6 +121,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The place name for this map link. This corresponds to the lower zone name found in the actual in-game map UI. eg, "Limsa Lominsa Upper Decks" /// + [JsonIgnore] public string PlaceName { get @@ -129,7 +136,10 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// public string DataString => $"m:{TerritoryType.RowId},{Map.RowId},{RawX},{RawY}"; + [JsonProperty] private uint territoryTypeId; + + [JsonProperty] private uint mapId; // there is no Z; it's purely in the text payload where applicable diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs index 64ddcb374..1cfe9bfa8 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/PlayerPayload.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using Dalamud.Data; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -14,10 +15,12 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads { public override PayloadType Type => PayloadType.Player; + [JsonProperty] private string playerName; /// /// The player's displayed name. This does not contain the server name. /// + [JsonIgnore] public string PlayerName { get { return this.playerName; } @@ -35,6 +38,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public World World { get @@ -48,8 +52,10 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// A text representation of this player link matching how it might appear in-game. /// The world name will always be present. /// + [JsonIgnore] public string DisplayedName => $"{PlayerName}{(char)SeIconChar.CrossWorld}{World.Name}"; + [JsonProperty] private uint serverId; internal PlayerPayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs index 301bde07e..a2438d32a 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/RawPayload.cs @@ -1,3 +1,4 @@ +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; @@ -20,6 +21,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads public override PayloadType Type => PayloadType.Unknown; + [JsonProperty] private byte[] data; // this is a bit different from the underlying data // We need to store just the chunk data for decode to behave nicely, but when reading data out @@ -28,6 +30,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// The entire payload byte sequence for this payload. /// The returned data is a clone and modifications will not be persisted. /// + [JsonIgnore] public byte[] Data { get @@ -38,8 +41,10 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + [JsonProperty] private byte chunkType; + [JsonConstructor] internal RawPayload(byte chunkType) { this.chunkType = chunkType; diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs index a82438fc0..11e90c3e3 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/StatusPayload.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; using Dalamud.Data; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -20,6 +21,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public Status Status { get @@ -29,6 +31,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + [JsonProperty] private uint statusId; internal StatusPayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs index be2f5c13e..6c5ec22cc 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/TextPayload.cs @@ -1,3 +1,4 @@ +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; @@ -13,11 +14,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads public override PayloadType Type => PayloadType.RawText; // allow modifying the text of existing payloads on the fly + [JsonProperty] private string text; /// /// The text contained in this payload. /// This may contain SE's special unicode characters. /// + [JsonIgnore] public string Text { get { return this.text; } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs index 2fede7f94..d25c0e033 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIForegroundPayload.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; using Dalamud.Data; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -31,6 +32,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public UIColor UIColor { get @@ -43,6 +45,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The color key used as a lookup in the UIColor table for this foreground color. /// + [JsonIgnore] public ushort ColorKey { get { return this.colorKey; } @@ -57,6 +60,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The Red/Green/Blue values for this foreground color, encoded as a typical hex color. /// + [JsonIgnore] public uint RGB { get @@ -65,6 +69,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + [JsonProperty] private ushort colorKey; internal UIForegroundPayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs index d82d249f3..655e3c01e 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/UIGlowPayload.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; using Dalamud.Data; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling.Payloads { @@ -31,6 +32,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// Value is evaluated lazily and cached. /// + [JsonIgnore] public UIColor UIColor { get @@ -43,6 +45,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The color key used as a lookup in the UIColor table for this glow color. /// + [JsonIgnore] public ushort ColorKey { get { return this.colorKey; } @@ -57,6 +60,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads /// /// The Red/Green/Blue values for this glow color, encoded as a typical hex color. /// + [JsonIgnore] public uint RGB { get @@ -65,6 +69,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads } } + [JsonProperty] private ushort colorKey; internal UIGlowPayload() { } diff --git a/Dalamud/Game/Chat/SeStringHandling/SeString.cs b/Dalamud/Game/Chat/SeStringHandling/SeString.cs index a7c954fab..847e296e9 100644 --- a/Dalamud/Game/Chat/SeStringHandling/SeString.cs +++ b/Dalamud/Game/Chat/SeStringHandling/SeString.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using Dalamud.Data; using Dalamud.Game.Chat.SeStringHandling.Payloads; +using Newtonsoft.Json; namespace Dalamud.Game.Chat.SeStringHandling { @@ -38,6 +40,7 @@ namespace Dalamud.Game.Chat.SeStringHandling /// Creates a new SeString from an ordered list of payloads. /// /// The Payload objects to make up this string. + [JsonConstructor] public SeString(List payloads) { Payloads = payloads; @@ -100,5 +103,42 @@ namespace Dalamud.Game.Chat.SeStringHandling return messageBytes.ToArray(); } + + /// + /// Serializes the SeString to json + /// + /// An json representation of this object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings() + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + TypeNameHandling = TypeNameHandling.Auto + }); + } + + /// + /// Creates a SeString from a json. (For testing - not recommended for production use.) + /// + /// A serialized SeString produced by ToJson() + /// An initialized instance of DataManager for Lumina queries. + /// A SeString initialized with values from the json + public static SeString FromJson(string json, DataManager dataManager) + { + var s = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + TypeNameHandling = TypeNameHandling.Auto, + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + + foreach(var payload in s.Payloads) + { + payload.DataResolver = dataManager; + } + + return s; + } } } diff --git a/Dalamud/Game/ClientState/Actors/ActorTable.cs b/Dalamud/Game/ClientState/Actors/ActorTable.cs index 9dd372ea1..048259ada 100644 --- a/Dalamud/Game/ClientState/Actors/ActorTable.cs +++ b/Dalamud/Game/ClientState/Actors/ActorTable.cs @@ -92,6 +92,7 @@ namespace Dalamud.Game.ClientState.Actors { return actorStruct.ObjectKind switch { ObjectKind.Player => new PlayerCharacter(offset, actorStruct, this.dalamud), ObjectKind.BattleNpc => new BattleNpc(offset, actorStruct, this.dalamud), + ObjectKind.EventObj => new EventObj(offset, actorStruct, this.dalamud), _ => new Actor(offset, actorStruct, this.dalamud) }; } diff --git a/Dalamud/Game/ClientState/Actors/Types/NonPlayer/EventObj.cs b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/EventObj.cs new file mode 100644 index 000000000..265e80151 --- /dev/null +++ b/Dalamud/Game/ClientState/Actors/Types/NonPlayer/EventObj.cs @@ -0,0 +1,21 @@ +using System; + +namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer { + /// + /// This class represents an EventObj. + /// + public class EventObj : Actor { + /// + /// Set up a new EventObj with the provided memory representation. + /// + /// The memory representation of the base actor. + /// A dalamud reference needed to access game data in Resolvers. + /// The address of this actor in memory. + public EventObj(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; + } +} diff --git a/Dalamud/Game/Network/NetworkHandlers.cs b/Dalamud/Game/Network/NetworkHandlers.cs index 5cc8b9adc..60fd6c574 100644 --- a/Dalamud/Game/Network/NetworkHandlers.cs +++ b/Dalamud/Game/Network/NetworkHandlers.cs @@ -22,8 +22,6 @@ namespace Dalamud.Game.Network { private readonly bool optOutMbUploads; private readonly IMarketBoardUploader uploader; - private byte[] lastPreferredRole; - public delegate Task CfPop(ContentFinderCondition cfc); public event CfPop ProcessCfPop; @@ -90,60 +88,6 @@ namespace Dalamud.Game.Network { return; } - if (opCode == this.dalamud.Data.ServerOpCodes["CfPreferredRole"]) { - if (this.dalamud.Configuration.PreferredRoleReminders == null) - return; - - var data = new byte[64]; - Marshal.Copy(dataPtr, data, 0, 32); - - if (this.lastPreferredRole == null) { - this.lastPreferredRole = data; - return; - } - - Task.Run(async () => { - for (var rouletteIndex = 1; rouletteIndex < 11; rouletteIndex++) { - var currentRoleKey = data[rouletteIndex]; - var prevRoleKey = this.lastPreferredRole[rouletteIndex]; - - Log.Verbose("CfPreferredRole: {0} - {1} => {2}", rouletteIndex, prevRoleKey, currentRoleKey); - - if (currentRoleKey != prevRoleKey) { - var rouletteName = rouletteIndex switch { - 1 => "Duty Roulette: Leveling", - 2 => "Duty Roulette: Level 50/60/70 Dungeons", - 3 => "Duty Roulette: Main Scenario", - 4 => "Duty Roulette: Guildhests", - 5 => "Duty Roulette: Expert", - 6 => "Duty Roulette: Trials", - 8 => "Duty Roulette: Mentor", - 9 => "Duty Roulette: Alliance Raids", - 10 => "Duty Roulette: Normal Raids", - _ => "Unknown ContentRoulette" - }; - - var prevRoleName = RoleKeyToPreferredRole(prevRoleKey); - var currentRoleName = RoleKeyToPreferredRole(currentRoleKey); - - if (!this.dalamud.Configuration.PreferredRoleReminders.TryGetValue(rouletteIndex, out var roleToCheck)) - return; - - if (roleToCheck == DalamudConfiguration.PreferredRole.All || currentRoleName != roleToCheck) - return; - - this.dalamud.Framework.Gui.Chat.Print($"Roulette bonus for {rouletteName} changed: {prevRoleName} => {currentRoleName}"); - - if (this.dalamud.BotManager.IsConnected) - await this.dalamud.BotManager.ProcessCfPreferredRoleChange(rouletteName, prevRoleName.ToString(), currentRoleName.ToString()); - } - } - - this.lastPreferredRole = data; - }); - return; - } - if (!this.optOutMbUploads) { if (opCode == this.dalamud.Data.ServerOpCodes["MarketBoardItemRequestStart"]) { var catalogId = (uint) Marshal.ReadInt32(dataPtr); @@ -235,6 +179,19 @@ namespace Dalamud.Game.Network { request.History.AddRange(listing.HistoryListings); Log.Verbose("Added history for item#{0}", listing.CatalogId); + + if (request.AmountToArrive == 0) { + Log.Verbose("Request had 0 amount, uploading now"); + + try + { + Task.Run(() => this.uploader.Upload(request)); + } + catch (Exception ex) + { + Log.Error(ex, "Market Board data upload failed."); + } + } } if (opCode == this.dalamud.Data.ServerOpCodes["MarketTaxRates"]) @@ -254,14 +211,5 @@ namespace Dalamud.Game.Network { } } } - - private DalamudConfiguration.PreferredRole RoleKeyToPreferredRole(int key) => key switch - { - 1 => DalamudConfiguration.PreferredRole.Tank, - 2 => DalamudConfiguration.PreferredRole.Dps, - 3 => DalamudConfiguration.PreferredRole.Dps, - 4 => DalamudConfiguration.PreferredRole.Healer, - _ => DalamudConfiguration.PreferredRole.None - }; } } diff --git a/Dalamud/Interface/AssetManager.cs b/Dalamud/Interface/AssetManager.cs index e45ad1015..a5e31fc79 100644 --- a/Dalamud/Interface/AssetManager.cs +++ b/Dalamud/Interface/AssetManager.cs @@ -24,6 +24,9 @@ namespace Dalamud.Interface {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" }, + {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_ko.json", "UIRes/loc/dalamud/dalamud_ko.json" }, + {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_no.json", "UIRes/loc/dalamud/dalamud_no.json" }, + {AssetStoreUrl + "UIRes/loc/dalamud/dalamud_ru.json", "UIRes/loc/dalamud/dalamud_ru.json" }, {"https://img.finalfantasyxiv.com/lds/pc/global/fonts/FFXIV_Lodestone_SSF.ttf", "UIRes/gamesym.ttf" } }; diff --git a/Dalamud/Interface/DalamudChangelogWindow.cs b/Dalamud/Interface/DalamudChangelogWindow.cs index 6d87f8a1a..bfa19f516 100644 --- a/Dalamud/Interface/DalamudChangelogWindow.cs +++ b/Dalamud/Interface/DalamudChangelogWindow.cs @@ -11,13 +11,13 @@ namespace Dalamud.Interface { private readonly Dalamud dalamud; private string assemblyVersion = Util.AssemblyVersion; - private const bool WarrantsChangelog = false; + private const bool WarrantsChangelog = true; private const string ChangeLog = - @"* All plugin windows now hide together with the in-game UI when you toggle it. -You can change this behaviour with /xlsettings under the ""Look&Feel"" tab. -* The ""Item hovering"" feature, which was previously broken due to patch 5.3 is now working again. -* Added some extra infos about the state of the addon to the log, so we can help you better in case you encounter crashes. -* Added this changelog window."; + @"* The /xlbonus command was removed - it has been remade as the ""Adventurer in Need"" plugin by Caraxi and is way better now. Please check it out! +* Plugin UI is now also hidden when in GPose or in a cutscene. You can disable this in the /xlsettings window. +* Universalis will now be updated when a shown item has no listings. +* Updated the localization files +* Added Norwegian, Korean and Russian localization - thanks a lot to all of our translators, especially Ridge, Hibiya and xDarkOne! If you wish to join the effort, please check our #translations channel."; public DalamudChangelogWindow(Dalamud dalamud) { this.dalamud = dalamud; diff --git a/Dalamud/Interface/DalamudCreditsWindow.cs b/Dalamud/Interface/DalamudCreditsWindow.cs index 568665f5c..f99af3154 100644 --- a/Dalamud/Interface/DalamudCreditsWindow.cs +++ b/Dalamud/Interface/DalamudCreditsWindow.cs @@ -34,13 +34,29 @@ Pohky Localization by: -Truci -fmauNeko -Roy -karashiiro +Airiel +Akira +area402 +Ridge +availuzje +CBMaca +Delaene +fang2hou Miu +fmauNeko qtBxi -N30n014 +JasonLucas +karashiiro +hibiya +sayumizumi +N30N014 +Neocrow +OhagiYamada +xDarkOne +Truci +Roy +xenris +Xorus diff --git a/Dalamud/Interface/DalamudSettingsWindow.cs b/Dalamud/Interface/DalamudSettingsWindow.cs index 8876295af..dd13888ae 100644 --- a/Dalamud/Interface/DalamudSettingsWindow.cs +++ b/Dalamud/Interface/DalamudSettingsWindow.cs @@ -99,8 +99,8 @@ namespace Dalamud.Interface ImGui.Dummy(new Vector2(10f, 10f)); - ImGui.Checkbox(Loc.Localize("DalamudSettingToggleUiHide", "Hide plugin UI when the game UI is hidden"), ref this.doToggleUiHide); - ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleUiHideHint", "Check this box to hide any open windows by plugins when toggling the game overlay.")); + ImGui.Checkbox(Loc.Localize("DalamudSettingToggleUiHide", "Hide plugin UI when the game UI is hidden and during cutscenes and gpose"), ref this.doToggleUiHide); + ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleUiHideHint", "Check this box to hide any open windows by plugins when toggling the game overlay, or upon entering gpose or a cutscene.")); ImGui.EndTabItem(); } diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index e4a311ec4..4d24cd8b8 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Numerics; using System.Runtime.InteropServices; using System.Text; +using System.Threading; using CheapLoc; using Dalamud.Game; using Dalamud.Game.Internal.DXGI; @@ -207,9 +208,13 @@ namespace Dalamud.Interface // Sets up a deferred invocation of font rebuilding, before the next render frame public void RebuildFonts() { + Log.Verbose("[FONT] RebuildFonts() called"); + // don't invoke this multiple times per frame, in case multiple plugins call it if (!this.isRebuildingFonts) { + Log.Verbose("[FONT] RebuildFonts() trigger"); + this.isRebuildingFonts = true; this.scene.OnNewRenderFrame += RebuildFontsInternal; } @@ -300,10 +305,18 @@ namespace Dalamud.Interface }, GCHandleType.Pinned); IconFont = ImGui.GetIO().Fonts.AddFontFromFileTTF(fontPathIcon, 17.0f, null, iconRangeHandle.AddrOfPinnedObject()); + Log.Verbose("[FONT] Invoke OnBuildFonts"); this.OnBuildFonts?.Invoke(); + Log.Verbose("[FONT] OnBuildFonts OK!"); + + for (var i = 0; i < ImGui.GetIO().Fonts.Fonts.Size; i++) { + Log.Verbose("{0} - {1}", i, ImGui.GetIO().Fonts.Fonts[i].GetDebugName()); + } ImGui.GetIO().Fonts.Build(); + Log.Verbose("[FONT] Fonts built!"); + fontConfig.Destroy(); japaneseRangeHandle.Free(); gameRangeHandle.Free(); @@ -313,11 +326,15 @@ namespace Dalamud.Interface // This is intended to only be called as a handler attached to scene.OnNewRenderFrame private void RebuildFontsInternal() { + Log.Verbose("[FONT] RebuildFontsInternal() called"); SetupFonts(); + Log.Verbose("[FONT] RebuildFontsInternal() detaching"); this.scene.OnNewRenderFrame -= RebuildFontsInternal; this.scene.InvalidateFonts(); + Log.Verbose("[FONT] Font Rebuild OK!"); + this.isRebuildingFonts = false; } diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs index 10c213bd6..b94474483 100644 --- a/Dalamud/Interface/UiBuilder.cs +++ b/Dalamud/Interface/UiBuilder.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Dalamud.Game.ClientState; using Dalamud.Game.Internal.Gui; using ImGuiNET; using ImGuiScene; @@ -38,9 +39,12 @@ namespace Dalamud.Interface /// public bool DisableAutomaticUiHide { get; set; } = false; - private readonly InterfaceManager interfaceManager; - private readonly GameGui gameGui; - private readonly DalamudConfiguration config; + private bool CutsceneOrGposeActive => this.dalamud.ClientState != null && this.dalamud.ClientState.Condition[ConditionFlag.OccupiedInCutSceneEvent] || + this.dalamud.ClientState.Condition[ConditionFlag.WatchingCutscene] || + this.dalamud.ClientState.Condition[ConditionFlag.WatchingCutscene78]; + + private Dalamud dalamud; + #if DEBUG internal static bool DoStats { get; set; } = true; #else @@ -56,13 +60,11 @@ namespace Dalamud.Interface /// /// The interface manager to register on. /// The plugin namespace. - internal UiBuilder(InterfaceManager interfaceManager, GameGui gameGui, DalamudConfiguration config, string namespaceName) { + internal UiBuilder(Dalamud dalamud, string namespaceName) { this.namespaceName = namespaceName; - this.interfaceManager = interfaceManager; - this.gameGui = gameGui; - this.config = config; - this.interfaceManager.OnDraw += OnDraw; + this.dalamud = dalamud; + this.dalamud.InterfaceManager.OnDraw += OnDraw; this.stopwatch = new System.Diagnostics.Stopwatch(); } @@ -70,7 +72,7 @@ namespace Dalamud.Interface /// Unregister the UiBuilder. Do not call this in plugin code. /// public void Dispose() { - this.interfaceManager.OnDraw -= OnDraw; + this.dalamud.InterfaceManager.OnDraw -= OnDraw; } /// @@ -79,7 +81,7 @@ namespace Dalamud.Interface /// The full filepath to the image. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImage(string filePath) => - this.interfaceManager.LoadImage(filePath); + this.dalamud.InterfaceManager.LoadImage(filePath); /// /// Loads an image from a byte stream, such as a png downloaded into memory. @@ -87,7 +89,7 @@ namespace Dalamud.Interface /// A byte array containing the raw image data. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImage(byte[] imageData) => - this.interfaceManager.LoadImage(imageData); + this.dalamud.InterfaceManager.LoadImage(imageData); /// /// Loads an image from raw unformatted pixel data, with no type or header information. To load formatted data, use . @@ -98,7 +100,7 @@ namespace Dalamud.Interface /// The number of channels (bytes per pixel) of the image contained in . This should usually be 4. /// A object wrapping the created image. Use inside ImGui.Image() public TextureWrap LoadImageRaw(byte[] imageData, int width, int height, int numChannels) => - this.interfaceManager.LoadImageRaw(imageData, width, height, numChannels); + this.dalamud.InterfaceManager.LoadImageRaw(imageData, width, height, numChannels); /// /// An event that is called any time ImGui fonts need to be rebuilt.
@@ -109,8 +111,8 @@ namespace Dalamud.Interface ///
public Action OnBuildFonts { - get { return this.interfaceManager.OnBuildFonts; } - set { this.interfaceManager.OnBuildFonts = value; } + get { return this.dalamud.InterfaceManager.OnBuildFonts; } + set { this.dalamud.InterfaceManager.OnBuildFonts = value; } } /// @@ -118,8 +120,11 @@ namespace Dalamud.Interface /// This will invoke any handlers and ensure that any loaded fonts are /// ready to be used on the next UI frame. /// - public void RebuildFonts() => - this.interfaceManager.RebuildFonts(); + public void RebuildFonts() + { + Log.Verbose("[FONT] {0} plugin is initiating FONT REBUILD", this.namespaceName); + this.dalamud.InterfaceManager.RebuildFonts(); + } /// /// Event that is fired when the plugin should open its configuration interface. @@ -130,7 +135,7 @@ namespace Dalamud.Interface private void OnDraw() { - if (this.gameGui.GameUiHidden && this.config.ToggleUiHide && !DisableAutomaticUiHide) + if ((this.dalamud.Framework.Gui.GameUiHidden || CutsceneOrGposeActive) && this.dalamud.Configuration.ToggleUiHide && !DisableAutomaticUiHide) return; ImGui.PushID(this.namespaceName); diff --git a/Dalamud/Localization.cs b/Dalamud/Localization.cs index b4a856aeb..838b45e13 100644 --- a/Dalamud/Localization.cs +++ b/Dalamud/Localization.cs @@ -13,7 +13,7 @@ namespace Dalamud class Localization { private readonly string workingDirectory; - public static readonly string[] ApplicableLangCodes = { "de", "ja", "fr", "it", "es" }; + public static readonly string[] ApplicableLangCodes = { "de", "ja", "fr", "it", "es", "ko", "no", "ru" }; public Localization(string workingDirectory) { this.workingDirectory = workingDirectory; diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs index 6f39c2d2b..73346299c 100644 --- a/Dalamud/Plugin/DalamudPluginInterface.cs +++ b/Dalamud/Plugin/DalamudPluginInterface.cs @@ -75,7 +75,7 @@ namespace Dalamud.Plugin this.CommandManager = dalamud.CommandManager; this.Framework = dalamud.Framework; this.ClientState = dalamud.ClientState; - this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, dalamud.Framework.Gui, dalamud.Configuration, pluginName); + this.UiBuilder = new UiBuilder(dalamud, pluginName); this.TargetModuleScanner = dalamud.SigScanner; this.Data = dalamud.Data; this.SeStringManager = dalamud.SeStringManager; diff --git a/Dalamud/Plugin/PluginInstallerWindow.cs b/Dalamud/Plugin/PluginInstallerWindow.cs index e7d67f7e4..30068b3fc 100644 --- a/Dalamud/Plugin/PluginInstallerWindow.cs +++ b/Dalamud/Plugin/PluginInstallerWindow.cs @@ -57,7 +57,8 @@ namespace Dalamud.Plugin ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoScrollbar); ImGui.Text(Loc.Localize("InstallerHint", "This window allows you install and remove in-game plugins.\nThey are made by third-party developers.")); - ImGui.SameLine(); + ImGui.SameLine(ImGui.GetWindowWidth() - 250); + ImGui.SetNextItemWidth(240); ImGui.InputTextWithHint("###XPlPluginInstaller_Search", Loc.Localize("InstallerSearch", "Search"), ref this.searchText, 100); ImGui.Separator();