diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index 65ec356a7..9be9d59cd 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -33,16 +33,23 @@
"GitHubActions",
"GitLab",
"Jenkins",
+ "Rider",
"SpaceAutomation",
"TeamCity",
"Terminal",
- "TravisCI"
+ "TravisCI",
+ "VisualStudio",
+ "VSCode"
]
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
+ "Partition": {
+ "type": "string",
+ "description": "Partition to use on CI"
+ },
"Plan": {
"type": "boolean",
"description": "Shows the execution plan (HTML)"
diff --git a/Dalamud/ClientLanguageExtensions.cs b/Dalamud/ClientLanguageExtensions.cs
new file mode 100644
index 000000000..dccefb93f
--- /dev/null
+++ b/Dalamud/ClientLanguageExtensions.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Dalamud
+{
+ ///
+ /// Extension methods for the class.
+ ///
+ public static class ClientLanguageExtensions
+ {
+ ///
+ /// Converts a Dalamud ClientLanguage to the corresponding Lumina variant.
+ ///
+ /// Langauge to convert.
+ /// Converted langauge.
+ public static Lumina.Data.Language ToLumina(this ClientLanguage language)
+ {
+ return language switch
+ {
+ ClientLanguage.Japanese => Lumina.Data.Language.Japanese,
+ ClientLanguage.English => Lumina.Data.Language.English,
+ ClientLanguage.German => Lumina.Data.Language.German,
+ ClientLanguage.French => Lumina.Data.Language.French,
+ _ => throw new ArgumentOutOfRangeException(nameof(language)),
+ };
+ }
+ }
+}
diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index 4eb6e3b03..33933d98f 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -92,6 +92,13 @@ namespace Dalamud.Configuration.Internal
///
public Dictionary DevPluginSettings { get; set; } = new();
+ ///
+ /// Gets or sets a list of additional locations that dev plugins should be loaded from. This can
+ /// be either a DLL or folder, but should be the absolute path, or a path relative to the currently
+ /// injected Dalamud instance.
+ ///
+ public List DevPluginLoadLocations { get; set; } = new();
+
///
/// Gets or sets the global UI scale.
///
diff --git a/Dalamud/Configuration/Internal/DevPluginLocationSettings.cs b/Dalamud/Configuration/Internal/DevPluginLocationSettings.cs
new file mode 100644
index 000000000..995fb1a23
--- /dev/null
+++ b/Dalamud/Configuration/Internal/DevPluginLocationSettings.cs
@@ -0,0 +1,24 @@
+namespace Dalamud.Configuration
+{
+ ///
+ /// Additional locations to load dev plugins from.
+ ///
+ internal sealed class DevPluginLocationSettings
+ {
+ ///
+ /// Gets or sets the dev pluign path.
+ ///
+ public string Path { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the third party repo is enabled.
+ ///
+ public bool IsEnabled { get; set; }
+
+ ///
+ /// Clone this object.
+ ///
+ /// A shallow copy of this object.
+ public DevPluginLocationSettings Clone() => this.MemberwiseClone() as DevPluginLocationSettings;
+ }
+}
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
index e9357c4a6..be4278ec5 100644
--- a/Dalamud/Dalamud.cs
+++ b/Dalamud/Dalamud.cs
@@ -7,11 +7,9 @@ using System.Threading;
using Dalamud.Configuration.Internal;
using Dalamud.Data;
using Dalamud.Game;
-using Dalamud.Game.Addon;
using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Dalamud.Game.Internal;
-using Dalamud.Game.Network;
using Dalamud.Game.Network.Internal;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Hooking.Internal;
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index ebdf24c57..093c8bb1a 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -5,9 +5,8 @@ using System.Diagnostics;
using System.IO;
using System.Threading;
-using Dalamud.Data.LuminaExtensions;
-using Dalamud.Interface;
using Dalamud.Interface.Internal;
+using Dalamud.Utility;
using ImGuiScene;
using JetBrains.Annotations;
using Lumina;
@@ -96,15 +95,7 @@ namespace Dalamud.Data
/// The , giving access to game rows.
public ExcelSheet GetExcelSheet(ClientLanguage language) where T : ExcelRow
{
- var lang = language switch
- {
- ClientLanguage.Japanese => Lumina.Data.Language.Japanese,
- ClientLanguage.English => Lumina.Data.Language.English,
- ClientLanguage.German => Lumina.Data.Language.German,
- ClientLanguage.French => Lumina.Data.Language.French,
- _ => throw new ArgumentOutOfRangeException(nameof(language), $"Unknown Language: {language}"),
- };
- return this.Excel.GetSheet(lang);
+ return this.Excel.GetSheet(language.ToLumina());
}
///
@@ -146,18 +137,30 @@ namespace Dalamud.Data
///
/// The icon ID.
/// The containing the icon.
- public TexFile GetIcon(int iconId)
+ public TexFile GetIcon(uint iconId)
{
return this.GetIcon(this.Language, iconId);
}
+ ///
+ /// Get a containing the icon with the given ID, of the given quality.
+ ///
+ /// A value indicating whether the icon should be HQ.
+ /// The icon ID.
+ /// The containing the icon.
+ public TexFile GetIcon(bool isHq, uint iconId)
+ {
+ var type = isHq ? "hq/" : string.Empty;
+ return this.GetIcon(type, iconId);
+ }
+
///
/// Get a containing the icon with the given ID, of the given language.
///
/// The requested language.
/// The icon ID.
/// The containing the icon.
- public TexFile GetIcon(ClientLanguage iconLanguage, int iconId)
+ public TexFile GetIcon(ClientLanguage iconLanguage, uint iconId)
{
var type = iconLanguage switch
{
@@ -177,7 +180,7 @@ namespace Dalamud.Data
/// The type of the icon (e.g. 'hq' to get the HQ variant of an item icon).
/// The icon ID.
/// The containing the icon.
- public TexFile GetIcon(string type, int iconId)
+ public TexFile GetIcon(string type, uint iconId)
{
type ??= string.Empty;
if (type.Length > 0 && !type.EndsWith("/"))
@@ -186,7 +189,8 @@ namespace Dalamud.Data
var filePath = string.Format(IconFileFormat, iconId / 1000, type, iconId);
var file = this.GetFile(filePath);
- if (file != default(TexFile) || type.Length <= 0) return file;
+ if (type == string.Empty || file != default)
+ return file;
// Couldn't get specific type, try for generic version.
filePath = string.Format(IconFileFormat, iconId / 1000, string.Empty, iconId);
@@ -194,6 +198,14 @@ namespace Dalamud.Data
return file;
}
+ ///
+ /// Get a containing the HQ icon with the given ID.
+ ///
+ /// The icon ID.
+ /// The containing the icon.
+ public TexFile GetHqIcon(uint iconId)
+ => this.GetIcon(true, iconId);
+
///
/// Get the passed as a drawable ImGui TextureWrap.
///
@@ -210,13 +222,30 @@ namespace Dalamud.Data
public TextureWrap GetImGuiTexture(string path)
=> this.GetImGuiTexture(this.GetFile(path));
+ ///
+ /// Get a containing the icon with the given ID.
+ ///
+ /// The icon ID.
+ /// The containing the icon.
+ public TextureWrap GetImGuiTextureIcon(uint iconId)
+ => this.GetImGuiTexture(this.GetIcon(iconId));
+
+ ///
+ /// Get a containing the icon with the given ID, of the given quality.
+ ///
+ /// A value indicating whether the icon should be HQ.
+ /// The icon ID.
+ /// The containing the icon.
+ public TextureWrap GetImGuiTextureIcon(bool isHq, uint iconId)
+ => this.GetImGuiTexture(this.GetIcon(isHq, iconId));
+
///
/// Get a containing the icon with the given ID, of the given language.
///
/// The requested language.
/// The icon ID.
/// The containing the icon.
- public TextureWrap GetImGuiTextureIcon(ClientLanguage iconLanguage, int iconId)
+ public TextureWrap GetImGuiTextureIcon(ClientLanguage iconLanguage, uint iconId)
=> this.GetImGuiTexture(this.GetIcon(iconLanguage, iconId));
///
@@ -225,9 +254,17 @@ namespace Dalamud.Data
/// The type of the icon (e.g. 'hq' to get the HQ variant of an item icon).
/// The icon ID.
/// The containing the icon.
- public TextureWrap GetImGuiTextureIcon(string type, int iconId)
+ public TextureWrap GetImGuiTextureIcon(string type, uint iconId)
=> this.GetImGuiTexture(this.GetIcon(type, iconId));
+ ///
+ /// Get a containing the HQ icon with the given ID.
+ ///
+ /// The icon ID.
+ /// The containing the icon.
+ public TextureWrap GetImGuiTextureHqIcon(uint iconId)
+ => this.GetImGuiTexture(this.GetHqIcon(iconId));
+
#endregion
///
@@ -263,21 +300,12 @@ namespace Dalamud.Data
var luminaOptions = new LuminaOptions
{
CacheFileResources = true,
-
#if DEBUG
PanicOnSheetChecksumMismatch = true,
#else
PanicOnSheetChecksumMismatch = false,
#endif
-
- DefaultExcelLanguage = this.Language switch
- {
- ClientLanguage.Japanese => Lumina.Data.Language.Japanese,
- ClientLanguage.English => Lumina.Data.Language.English,
- ClientLanguage.German => Lumina.Data.Language.German,
- ClientLanguage.French => Lumina.Data.Language.French,
- _ => throw new ArgumentOutOfRangeException(nameof(this.Language), $"Unknown Language: {this.Language}"),
- },
+ DefaultExcelLanguage = this.Language.ToLumina(),
};
var processModule = Process.GetCurrentProcess().MainModule;
diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs
index 378f841fd..6ce1cdc4b 100644
--- a/Dalamud/EntryPoint.cs
+++ b/Dalamud/EntryPoint.cs
@@ -142,7 +142,7 @@ namespace Dalamud
var oldFile = new FileInfo(oldPath);
if (!oldFile.Exists)
- oldFile.Create();
+ oldFile.Create().Close();
using var reader = new BinaryReader(logFile.Open(FileMode.Open, FileAccess.Read));
using var writer = new BinaryWriter(oldFile.Open(FileMode.Append, FileAccess.Write));
diff --git a/Dalamud/Game/Internal/BaseAddressResolver.cs b/Dalamud/Game/BaseAddressResolver.cs
similarity index 94%
rename from Dalamud/Game/Internal/BaseAddressResolver.cs
rename to Dalamud/Game/BaseAddressResolver.cs
index 287bacaaa..b1873b0d7 100644
--- a/Dalamud/Game/Internal/BaseAddressResolver.cs
+++ b/Dalamud/Game/BaseAddressResolver.cs
@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
-namespace Dalamud.Game.Internal
+namespace Dalamud.Game
{
///
/// Base memory address resolver.
@@ -11,9 +11,9 @@ namespace Dalamud.Game.Internal
public abstract class BaseAddressResolver
{
///
- /// A list of memory addresses that were found, to list in /xldata.
+ /// Gets a list of memory addresses that were found, to list in /xldata.
///
- public static Dictionary> DebugScannedValues = new();
+ public static Dictionary> DebugScannedValues { get; } = new();
///
/// Gets or sets a value indicating whether the resolver has successfully run or .
diff --git a/Dalamud/Game/ClientState/Actors/Types/Chara.cs b/Dalamud/Game/ClientState/Actors/Types/Chara.cs
index 792ca17c0..5c8dca228 100644
--- a/Dalamud/Game/ClientState/Actors/Types/Chara.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/Chara.cs
@@ -65,7 +65,7 @@ namespace Dalamud.Game.ClientState.Actors.Types
///
/// Gets the ClassJob of this Chara.
///
- public ClassJobResolver ClassJob => new(*(byte*)(this.Address + ActorOffsets.ClassJob), this.Dalamud);
+ public ExcelResolver ClassJob => new(*(byte*)(this.Address + ActorOffsets.ClassJob), this.Dalamud);
///
/// Gets the level of this Chara.
diff --git a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs b/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
index a1ebe1ab0..e04c36d32 100644
--- a/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
+++ b/Dalamud/Game/ClientState/Actors/Types/PlayerCharacter.cs
@@ -23,14 +23,14 @@ namespace Dalamud.Game.ClientState.Actors.Types
}
///
- /// Gets the current world of the character.
+ /// Gets the current world of the character.
///
- public WorldResolver CurrentWorld => new(*(ushort*)(this.Address + ActorOffsets.CurrentWorld), this.Dalamud);
+ public ExcelResolver CurrentWorld => new(*(ushort*)(this.Address + ActorOffsets.CurrentWorld), this.Dalamud);
///
- /// Gets the home world of the character.
+ /// Gets the home world of the character.
///
- public WorldResolver HomeWorld => new(*(ushort*)(this.Address + ActorOffsets.HomeWorld), this.Dalamud);
+ public ExcelResolver HomeWorld => new(*(ushort*)(this.Address + ActorOffsets.HomeWorld), this.Dalamud);
///
/// Gets the Free Company tag of this player.
diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs
index b9e40ccd7..0df4c1f69 100644
--- a/Dalamud/Game/ClientState/ClientState.cs
+++ b/Dalamud/Game/ClientState/ClientState.cs
@@ -1,14 +1,16 @@
using System;
using System.ComponentModel;
+using System.Linq;
using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors;
using Dalamud.Game.ClientState.Actors.Types;
+using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Fates;
-using Dalamud.Game.Internal;
+using Dalamud.Game.ClientState.GamePad;
+using Dalamud.Game.ClientState.Keys;
using Dalamud.Hooking;
using JetBrains.Annotations;
-using Lumina.Excel.GeneratedSheets;
using Serilog;
namespace Dalamud.Game.ClientState
@@ -93,7 +95,7 @@ namespace Dalamud.Game.ClientState
///
/// Event that gets fired when a duty is ready.
///
- public event EventHandler CfPop;
+ public event EventHandler CfPop;
///
/// Gets the table of all present actors.
@@ -194,7 +196,7 @@ namespace Dalamud.Game.ClientState
return this.setupTerritoryTypeHook.Original(manager, terriType);
}
- private void NetworkHandlersOnCfPop(object sender, ContentFinderCondition e)
+ private void NetworkHandlersOnCfPop(object sender, Lumina.Excel.GeneratedSheets.ContentFinderCondition e)
{
this.CfPop?.Invoke(this, e);
}
diff --git a/Dalamud/Game/ClientState/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs
similarity index 94%
rename from Dalamud/Game/ClientState/Condition.cs
rename to Dalamud/Game/ClientState/Conditions/Condition.cs
index b416c4df4..5a4322532 100644
--- a/Dalamud/Game/ClientState/Condition.cs
+++ b/Dalamud/Game/ClientState/Conditions/Condition.cs
@@ -1,6 +1,6 @@
using System;
-namespace Dalamud.Game.ClientState
+namespace Dalamud.Game.ClientState.Conditions
{
///
/// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc.
@@ -37,7 +37,7 @@ namespace Dalamud.Game.ClientState
{
var idx = (int)flag;
- if (idx > MaxConditionEntries || idx < 0)
+ if (idx < 0 || idx >= MaxConditionEntries)
return false;
return *(bool*)(this.ConditionArrayBase + idx);
diff --git a/Dalamud/Game/ClientState/ConditionFlag.cs b/Dalamud/Game/ClientState/Conditions/ConditionFlag.cs
similarity index 99%
rename from Dalamud/Game/ClientState/ConditionFlag.cs
rename to Dalamud/Game/ClientState/Conditions/ConditionFlag.cs
index dc3d72d61..75c295ed0 100644
--- a/Dalamud/Game/ClientState/ConditionFlag.cs
+++ b/Dalamud/Game/ClientState/Conditions/ConditionFlag.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.ClientState
+namespace Dalamud.Game.ClientState.Conditions
{
///
/// Possible state flags (or conditions as they're called internally) that can be set on the local client.
diff --git a/Dalamud/Game/ClientState/Fates/Types/Fate.cs b/Dalamud/Game/ClientState/Fates/Fate.cs
similarity index 75%
rename from Dalamud/Game/ClientState/Fates/Types/Fate.cs
rename to Dalamud/Game/ClientState/Fates/Fate.cs
index a42e3f925..2b284b6a5 100644
--- a/Dalamud/Game/ClientState/Fates/Types/Fate.cs
+++ b/Dalamud/Game/ClientState/Fates/Fate.cs
@@ -1,17 +1,19 @@
using System;
+using System.Numerics;
using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Memory;
-using FFXIVClientStructs.FFXIV.Client.System.String;
-namespace Dalamud.Game.ClientState.Fates.Types
+namespace Dalamud.Game.ClientState.Fates
{
///
/// This class represents an FFXIV Fate.
///
public unsafe partial class Fate : IEquatable
{
+ private Dalamud dalamud;
+
///
/// Initializes a new instance of the class.
///
@@ -20,7 +22,7 @@ namespace Dalamud.Game.ClientState.Fates.Types
internal Fate(IntPtr address, Dalamud dalamud)
{
this.Address = address;
- this.Dalamud = dalamud;
+ this.dalamud = dalamud;
}
///
@@ -28,10 +30,7 @@ namespace Dalamud.Game.ClientState.Fates.Types
///
public IntPtr Address { get; }
- ///
- /// Gets Dalamud itself.
- ///
- private protected Dalamud Dalamud { get; }
+ private FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext*)this.Address;
public static bool operator ==(Fate fate1, Fate fate2)
{
@@ -53,7 +52,7 @@ namespace Dalamud.Game.ClientState.Fates.Types
if (fate == null)
return false;
- if (fate.Dalamud.ClientState.LocalContentId == 0)
+ if (fate.dalamud.ClientState.LocalContentId == 0)
return false;
return true;
@@ -83,22 +82,22 @@ namespace Dalamud.Game.ClientState.Fates.Types
///
/// Gets the Fate ID of this .
///
- public ushort FateId => *(ushort*)(this.Address + FateOffsets.FateId);
+ public ushort FateId => this.Struct->FateId;
///
/// Gets game data linked to this Fate.
///
- public Lumina.Excel.GeneratedSheets.Fate GameData => this.Dalamud.Data.GetExcelSheet().GetRow(this.FateId);
+ public Lumina.Excel.GeneratedSheets.Fate GameData => this.dalamud.Data.GetExcelSheet().GetRow(this.FateId);
///
/// Gets the time this started.
///
- public int StartTimeEpoch => *(int*)(this.Address + FateOffsets.StartTimeEpoch);
+ public int StartTimeEpoch => this.Struct->StartTimeEpoch;
///
/// Gets how long this will run.
///
- public short Duration => *(short*)(this.Address + FateOffsets.Duration);
+ public short Duration => this.Struct->Duration;
///
/// Gets the remaining time in seconds for this .
@@ -108,31 +107,31 @@ namespace Dalamud.Game.ClientState.Fates.Types
///
/// Gets the displayname of this .
///
- public SeString Name => MemoryHelper.ReadSeString((Utf8String*)(this.Address + FateOffsets.Name));
+ public SeString Name => MemoryHelper.ReadSeString(&this.Struct->Name);
///
/// Gets the state of this (Running, Ended, Failed, Preparation, WaitingForEnd).
///
- public FateState State => *(FateState*)(this.Address + FateOffsets.State);
+ public FateState State => (FateState)this.Struct->State;
///
/// Gets the progress amount of this .
///
- public byte Progress => *(byte*)(this.Address + FateOffsets.Progress);
+ public byte Progress => this.Struct->Progress;
///
/// Gets the level of this .
///
- public byte Level => *(byte*)(this.Address + FateOffsets.Level);
+ public byte Level => this.Struct->Level;
///
/// Gets the position of this .
///
- public Position3 Position => *(Position3*)(this.Address + FateOffsets.Position);
+ public Vector3 Position => new(this.Struct->X, this.Struct->Y, this.Struct->Z);
///
/// Gets the territory this is located in.
///
- public TerritoryTypeResolver TerritoryType => new(*(ushort*)(this.Address + FateOffsets.Territory), this.Dalamud);
+ public ExcelResolver TerritoryType => new(this.Struct->TerritoryID, this.dalamud);
}
}
diff --git a/Dalamud/Game/ClientState/Fates/Types/FateState.cs b/Dalamud/Game/ClientState/Fates/FateState.cs
similarity index 93%
rename from Dalamud/Game/ClientState/Fates/Types/FateState.cs
rename to Dalamud/Game/ClientState/Fates/FateState.cs
index 94eb00717..c7a789231 100644
--- a/Dalamud/Game/ClientState/Fates/Types/FateState.cs
+++ b/Dalamud/Game/ClientState/Fates/FateState.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.ClientState.Fates.Types
+namespace Dalamud.Game.ClientState.Fates
{
///
/// This represents the state of a single Fate.
diff --git a/Dalamud/Game/ClientState/Fates/FateTable.cs b/Dalamud/Game/ClientState/Fates/FateTable.cs
index 07158820e..cd6e58ada 100644
--- a/Dalamud/Game/ClientState/Fates/FateTable.cs
+++ b/Dalamud/Game/ClientState/Fates/FateTable.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
-using Dalamud.Game.ClientState.Fates.Types;
using JetBrains.Annotations;
using Serilog;
@@ -13,11 +12,6 @@ namespace Dalamud.Game.ClientState.Fates
///
public sealed partial class FateTable
{
- // If the pointer at this offset is 0, do not scan the table
- private const int CheckPtrOffset = 0x80;
- private const int FirstPtrOffset = 0x90;
- private const int LastPtrOffset = 0x98;
-
private readonly Dalamud dalamud;
private readonly ClientStateAddressResolver address;
@@ -45,12 +39,13 @@ namespace Dalamud.Game.ClientState.Fates
if (fateTable == IntPtr.Zero)
return 0;
- var check = *(long*)(fateTable + CheckPtrOffset);
+ // Sonar used this to check if the table was safe to read
+ var check = Struct->Unk80.ToInt64();
if (check == 0)
return 0;
- var start = *(long*)(fateTable + FirstPtrOffset);
- var end = *(long*)(fateTable + LastPtrOffset);
+ var start = Struct->FirstFatePtr.ToInt64();
+ var end = Struct->LastFatePtr.ToInt64();
if (start == 0 || end == 0)
return 0;
@@ -58,7 +53,10 @@ namespace Dalamud.Game.ClientState.Fates
}
}
- private unsafe IntPtr FateTableAddress
+ ///
+ /// Gets the address of the Fate table.
+ ///
+ internal unsafe IntPtr FateTableAddress
{
get
{
@@ -69,6 +67,8 @@ namespace Dalamud.Game.ClientState.Fates
}
}
+ private unsafe FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager*)this.FateTableAddress;
+
///
/// Get an actor at the specified spawn index.
///
@@ -80,22 +80,6 @@ namespace Dalamud.Game.ClientState.Fates
get
{
var address = this.GetFateAddress(index);
- return this[address];
- }
- }
-
- ///
- /// Get a Fate at the specified address.
- ///
- /// The Fate address.
- /// A at the specified address.
- public Fate this[IntPtr address]
- {
- get
- {
- if (address == IntPtr.Zero)
- return null;
-
return this.CreateFateReference(address);
}
}
@@ -114,7 +98,7 @@ namespace Dalamud.Game.ClientState.Fates
if (fateTable == IntPtr.Zero)
return IntPtr.Zero;
- var firstFate = *(IntPtr*)(fateTable + FirstPtrOffset);
+ var firstFate = this.Struct->FirstFatePtr;
return *(IntPtr*)(firstFate + (8 * index));
}
@@ -139,20 +123,11 @@ namespace Dalamud.Game.ClientState.Fates
///
/// This collection represents the currently available Fate events.
///
- public sealed partial class FateTable : IReadOnlyCollection, ICollection
+ public sealed partial class FateTable : IReadOnlyCollection
{
///
int IReadOnlyCollection.Count => this.Length;
- ///
- int ICollection.Count => this.Length;
-
- ///
- bool ICollection.IsSynchronized => false;
-
- ///
- object ICollection.SyncRoot => this;
-
///
public IEnumerator GetEnumerator()
{
@@ -164,15 +139,5 @@ namespace Dalamud.Game.ClientState.Fates
///
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
-
- ///
- void ICollection.CopyTo(Array array, int index)
- {
- for (var i = 0; i < this.Length; i++)
- {
- array.SetValue(this[i], index);
- index++;
- }
- }
}
}
diff --git a/Dalamud/Game/ClientState/Fates/Types/FateOffsets.cs b/Dalamud/Game/ClientState/Fates/Types/FateOffsets.cs
deleted file mode 100644
index 73bc7a702..000000000
--- a/Dalamud/Game/ClientState/Fates/Types/FateOffsets.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace Dalamud.Game.ClientState.Fates.Types
-{
- ///
- /// Memory offsets for the type.
- ///
- [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.")]
- public static class FateOffsets
- {
- public const int FateId = 0x18;
- public const int StartTimeEpoch = 0x20;
- public const int Duration = 0x28;
- public const int Name = 0xC0;
- public const int State = 0x3AC;
- public const int Progress = 0x3B8;
- public const int Level = 0x3F9;
- public const int Position = 0x450;
- public const int Territory = 0x74E;
- }
-}
diff --git a/Dalamud/Game/ClientState/GamepadButtons.cs b/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs
similarity index 97%
rename from Dalamud/Game/ClientState/GamepadButtons.cs
rename to Dalamud/Game/ClientState/GamePad/GamepadButtons.cs
index 80a745d53..7813803c8 100644
--- a/Dalamud/Game/ClientState/GamepadButtons.cs
+++ b/Dalamud/Game/ClientState/GamePad/GamepadButtons.cs
@@ -1,6 +1,6 @@
-using System;
+using System;
-namespace Dalamud.Game.ClientState
+namespace Dalamud.Game.ClientState.GamePad
{
///
/// Bitmask of the Button ushort used by the game.
diff --git a/Dalamud/Game/ClientState/Structs/GamepadInput.cs b/Dalamud/Game/ClientState/GamePad/GamepadInput.cs
similarity index 98%
rename from Dalamud/Game/ClientState/Structs/GamepadInput.cs
rename to Dalamud/Game/ClientState/GamePad/GamepadInput.cs
index df80b0ef4..d6d46a0cc 100644
--- a/Dalamud/Game/ClientState/Structs/GamepadInput.cs
+++ b/Dalamud/Game/ClientState/GamePad/GamepadInput.cs
@@ -1,6 +1,6 @@
using System.Runtime.InteropServices;
-namespace Dalamud.Game.ClientState.Structs
+namespace Dalamud.Game.ClientState.GamePad
{
///
/// Struct which gets populated by polling the gamepads.
diff --git a/Dalamud/Game/ClientState/GamepadState.cs b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
similarity index 97%
rename from Dalamud/Game/ClientState/GamepadState.cs
rename to Dalamud/Game/ClientState/GamePad/GamepadState.cs
index 2d84fdb83..8759673b2 100644
--- a/Dalamud/Game/ClientState/GamepadState.cs
+++ b/Dalamud/Game/ClientState/GamePad/GamepadState.cs
@@ -1,11 +1,10 @@
using System;
-using Dalamud.Game.ClientState.Structs;
using Dalamud.Hooking;
using ImGuiNET;
using Serilog;
-namespace Dalamud.Game.ClientState
+namespace Dalamud.Game.ClientState.GamePad
{
///
/// Exposes the game gamepad state to dalamud.
@@ -24,7 +23,7 @@ namespace Dalamud.Game.ClientState
private int rightStickY;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// Resolver knowing the pointer to the GamepadPoll function.
public GamepadState(ClientStateAddressResolver resolver)
@@ -43,12 +42,10 @@ namespace Dalamud.Game.ClientState
private delegate int ControllerPoll(IntPtr controllerInput);
-#if DEBUG
///
/// Gets the pointer to the current instance of the GamepadInput struct.
///
- public IntPtr GamepadInput { get; private set; }
-#endif
+ public IntPtr GamepadInputAddress { get; private set; }
///
/// Gets the state of the left analogue stick in the left direction between 0 (not tilted) and 1 (max tilt).
@@ -189,9 +186,7 @@ namespace Dalamud.Game.ClientState
var original = this.gamepadPoll.Original(gamepadInput);
try
{
-#if DEBUG
- this.GamepadInput = gamepadInput;
-#endif
+ this.GamepadInputAddress = gamepadInput;
var input = (GamepadInput*)gamepadInput;
this.leftStickX = input->LeftStickX;
this.leftStickY = input->LeftStickY;
diff --git a/Dalamud/Game/ClientState/KeyState.cs b/Dalamud/Game/ClientState/Keys/KeyState.cs
similarity index 87%
rename from Dalamud/Game/ClientState/KeyState.cs
rename to Dalamud/Game/ClientState/Keys/KeyState.cs
index e17d2cf50..b9d21ef2e 100644
--- a/Dalamud/Game/ClientState/KeyState.cs
+++ b/Dalamud/Game/ClientState/Keys/KeyState.cs
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using Serilog;
-namespace Dalamud.Game.ClientState
+namespace Dalamud.Game.ClientState.Keys
{
///
/// Wrapper around the game keystate buffer, which contains the pressed state for all keyboard keys, indexed by virtual vkCode.
@@ -52,6 +52,13 @@ namespace Dalamud.Game.ClientState
}
}
+ ///
+ /// Get or set the keypressed state for a given VirtualKey enum.
+ ///
+ /// The virtual key to change.
+ /// Whether the specified key is currently pressed.
+ public bool this[VirtualKey vk] => this[(int)vk];
+
///
/// Clears the pressed state for all keys.
///
diff --git a/Dalamud/Game/ClientState/Keys/VirtualKey.cs b/Dalamud/Game/ClientState/Keys/VirtualKey.cs
new file mode 100644
index 000000000..ab9436822
--- /dev/null
+++ b/Dalamud/Game/ClientState/Keys/VirtualKey.cs
@@ -0,0 +1,1044 @@
+namespace Dalamud.Game.ClientState.Keys
+{
+ ///
+ /// Virtual-key codes.
+ ///
+ ///
+ /// Defined in winuser.h from Windows SDK v6.1.
+ ///
+ public enum VirtualKey : ushort
+ {
+ ///
+ /// This is an addendum to use on functions in which you have to pass a zero value to represent no key code.
+ ///
+ NO_KEY = 0,
+
+ ///
+ /// Left mouse button.
+ ///
+ LBUTTON = 1,
+
+ ///
+ /// Right mouse button.
+ ///
+ RBUTTON = 2,
+
+ ///
+ /// Control-break processing.
+ ///
+ CANCEL = 3,
+
+ ///
+ /// Middle mouse button (three-button mouse).
+ ///
+ ///
+ /// NOT contiguous with L and R buttons.
+ ///
+ MBUTTON = 4,
+
+ ///
+ /// X1 mouse button.
+ ///
+ ///
+ /// NOT contiguous with L and R buttons.
+ ///
+ XBUTTON1 = 5,
+
+ ///
+ /// X2 mouse button.
+ ///
+ ///
+ /// NOT contiguous with L and R buttons.
+ ///
+ XBUTTON2 = 6,
+
+ ///
+ /// BACKSPACE key.
+ ///
+ BACK = 8,
+
+ ///
+ /// TAB key.
+ ///
+ TAB = 9,
+
+ ///
+ /// CLEAR key.
+ ///
+ CLEAR = 12,
+
+ ///
+ /// RETURN key.
+ ///
+ RETURN = 13,
+
+ ///
+ /// SHIFT key.
+ ///
+ SHIFT = 16,
+
+ ///
+ /// CONTROL key.
+ ///
+ CONTROL = 17,
+
+ ///
+ /// ALT key.
+ ///
+ MENU = 18,
+
+ ///
+ /// PAUSE key.
+ ///
+ PAUSE = 19,
+
+ ///
+ /// CAPS LOCK key.
+ ///
+ CAPITAL = 20,
+
+ ///
+ /// IME Kana mode.
+ ///
+ KANA = 21,
+
+ ///
+ /// IME Hanguel mode (maintained for compatibility; use User32.VirtualKey.HANGUL).
+ ///
+ HANGEUL = KANA,
+
+ ///
+ /// IME Hangul mode.
+ ///
+ HANGUL = KANA,
+
+ ///
+ /// IME Junja mode.
+ ///
+ JUNJA = 23,
+
+ ///
+ /// IME final mode.
+ ///
+ FINAL = 24,
+
+ ///
+ /// IME Hanja mode.
+ ///
+ HANJA = 25,
+
+ ///
+ /// IME Kanji mode.
+ ///
+ KANJI = HANJA,
+
+ ///
+ /// ESC key.
+ ///
+ ESCAPE = 27,
+
+ ///
+ /// IME convert.
+ ///
+ CONVERT = 28,
+
+ ///
+ /// IME nonconvert.
+ ///
+ NONCONVERT = 29,
+
+ ///
+ /// IME accept.
+ ///
+ ACCEPT = 30,
+
+ ///
+ /// IME mode change request.
+ ///
+ MODECHANGE = 31,
+
+ ///
+ /// SPACEBAR.
+ ///
+ SPACE = 32,
+
+ ///
+ /// PAGE UP key.
+ ///
+ PRIOR = 33,
+
+ ///
+ /// PAGE DOWN key.
+ ///
+ NEXT = 34,
+
+ ///
+ /// END key.
+ ///
+ END = 35,
+
+ ///
+ /// HOME key.
+ ///
+ HOME = 36,
+
+ ///
+ /// LEFT ARROW key.
+ ///
+ LEFT = 37,
+
+ ///
+ /// UP ARROW key.
+ ///
+ UP = 38,
+
+ ///
+ /// RIGHT ARROW key.
+ ///
+ RIGHT = 39,
+
+ ///
+ /// DOWN ARROW key.
+ ///
+ DOWN = 40,
+
+ ///
+ /// SELECT key.
+ ///
+ SELECT = 41,
+
+ ///
+ /// PRINT key.
+ ///
+ PRINT = 42,
+
+ ///
+ /// EXECUTE key.
+ ///
+ EXECUTE = 43,
+
+ ///
+ /// PRINT SCREEN key.
+ ///
+ SNAPSHOT = 44,
+
+ ///
+ /// INS key.
+ ///
+ INSERT = 45,
+
+ ///
+ /// DEL key.
+ ///
+ DELETE = 46,
+
+ ///
+ /// HELP key.
+ ///
+ HELP = 47,
+
+ ///
+ /// 0 key.
+ ///
+ KEY_0 = 48,
+
+ ///
+ /// 1 key.
+ ///
+ KEY_1 = 49,
+
+ ///
+ /// 2 key.
+ ///
+ KEY_2 = 50,
+
+ ///
+ /// 3 key.
+ ///
+ KEY_3 = 51,
+
+ ///
+ /// 4 key.
+ ///
+ KEY_4 = 52,
+
+ ///
+ /// 5 key.
+ ///
+ KEY_5 = 53,
+
+ ///
+ /// 6 key.
+ ///
+ KEY_6 = 54,
+
+ ///
+ /// 7 key.
+ ///
+ KEY_7 = 55,
+
+ ///
+ /// 8 key.
+ ///
+ KEY_8 = 56,
+
+ ///
+ /// 9 key.
+ ///
+ KEY_9 = 57,
+
+ ///
+ /// A key.
+ ///
+ A = 65,
+
+ ///
+ /// B key.
+ ///
+ B = 66,
+
+ ///
+ /// C key.
+ ///
+ C = 67,
+
+ ///
+ /// D key.
+ ///
+ D = 68,
+
+ ///
+ /// E key.
+ ///
+ E = 69,
+
+ ///
+ /// F key.
+ ///
+ F = 70,
+
+ ///
+ /// G key.
+ ///
+ G = 71,
+
+ ///
+ /// H key.
+ ///
+ H = 72,
+
+ ///
+ /// I key.
+ ///
+ I = 73,
+
+ ///
+ /// J key.
+ ///
+ J = 74,
+
+ ///
+ /// K key.
+ ///
+ K = 75,
+
+ ///
+ /// L key.
+ ///
+ L = 76,
+
+ ///
+ /// M key.
+ ///
+ M = 77,
+
+ ///
+ /// N key.
+ ///
+ N = 78,
+
+ ///
+ /// O key.
+ ///
+ O = 79,
+
+ ///
+ /// P key.
+ ///
+ P = 80,
+
+ ///
+ /// Q key.
+ ///
+ Q = 81,
+
+ ///
+ /// R key.
+ ///
+ R = 82,
+
+ ///
+ /// S key.
+ ///
+ S = 83,
+
+ ///
+ /// T key.
+ ///
+ T = 84,
+
+ ///
+ /// U key.
+ ///
+ U = 85,
+
+ ///
+ /// V key.
+ ///
+ V = 86,
+
+ ///
+ /// W key.
+ ///
+ W = 87,
+
+ ///
+ /// X key.
+ ///
+ X = 88,
+
+ ///
+ /// Y key.
+ ///
+ Y = 89,
+
+ ///
+ /// Z key.
+ ///
+ Z = 90,
+
+ ///
+ /// Left Windows key (Natural keyboard).
+ ///
+ LWIN = 91,
+
+ ///
+ /// Right Windows key (Natural keyboard).
+ ///
+ RWIN = 92,
+
+ ///
+ /// Applications key (Natural keyboard).
+ ///
+ APPS = 93,
+
+ ///
+ /// Computer Sleep key.
+ ///
+ SLEEP = 95,
+
+ ///
+ /// Numeric keypad 0 key.
+ ///
+ NUMPAD0 = 96,
+
+ ///
+ /// Numeric keypad 1 key.
+ ///
+ NUMPAD1 = 97,
+
+ ///
+ /// Numeric keypad 2 key.
+ ///
+ NUMPAD2 = 98,
+
+ ///
+ /// Numeric keypad 3 key.
+ ///
+ NUMPAD3 = 99,
+
+ ///
+ /// Numeric keypad 4 key.
+ ///
+ NUMPAD4 = 100,
+
+ ///
+ /// Numeric keypad 5 key.
+ ///
+ NUMPAD5 = 101,
+
+ ///
+ /// Numeric keypad 6 key.
+ ///
+ NUMPAD6 = 102,
+
+ ///
+ /// Numeric keypad 7 key.
+ ///
+ NUMPAD7 = 103,
+
+ ///
+ /// Numeric keypad 8 key.
+ ///
+ NUMPAD8 = 104,
+
+ ///
+ /// Numeric keypad 9 key.
+ ///
+ NUMPAD9 = 105,
+
+ ///
+ /// Multiply key.
+ ///
+ MULTIPLY = 106,
+
+ ///
+ /// Add key.
+ ///
+ ADD = 107,
+
+ ///
+ /// Separator key.
+ ///
+ SEPARATOR = 108,
+
+ ///
+ /// Subtract key.
+ ///
+ SUBTRACT = 109,
+
+ ///
+ /// Decimal key.
+ ///
+ DECIMAL = 110,
+
+ ///
+ /// Divide key.
+ ///
+ DIVIDE = 111,
+
+ ///
+ /// F1 Key.
+ ///
+ F1 = 112,
+
+ ///
+ /// F2 Key.
+ ///
+ F2 = 113,
+
+ ///
+ /// F3 Key.
+ ///
+ F3 = 114,
+
+ ///
+ /// F4 Key.
+ ///
+ F4 = 115,
+
+ ///
+ /// F5 Key.
+ ///
+ F5 = 116,
+
+ ///
+ /// F6 Key.
+ ///
+ F6 = 117,
+
+ ///
+ /// F7 Key.
+ ///
+ F7 = 118,
+
+ ///
+ /// F8 Key.
+ ///
+ F8 = 119,
+
+ ///
+ /// F9 Key.
+ ///
+ F9 = 120,
+
+ ///
+ /// F10 Key.
+ ///
+ F10 = 121,
+
+ ///
+ /// F11 Key.
+ ///
+ F11 = 122,
+
+ ///
+ /// F12 Key.
+ ///
+ F12 = 123,
+
+ ///
+ /// F13 Key.
+ ///
+ F13 = 124,
+
+ ///
+ /// F14 Key.
+ ///
+ F14 = 125,
+
+ ///
+ /// F15 Key.
+ ///
+ F15 = 126,
+
+ ///
+ /// F16 Key.
+ ///
+ F16 = 127,
+
+ ///
+ /// F17 Key.
+ ///
+ F17 = 128,
+
+ ///
+ /// F18 Key.
+ ///
+ F18 = 129,
+
+ ///
+ /// F19 Key.
+ ///
+ F19 = 130,
+
+ ///
+ /// F20 Key.
+ ///
+ F20 = 131,
+
+ ///
+ /// F21 Key.
+ ///
+ F21 = 132,
+
+ ///
+ /// F22 Key.
+ ///
+ F22 = 133,
+
+ ///
+ /// F23 Key.
+ ///
+ F23 = 134,
+
+ ///
+ /// F24 Key.
+ ///
+ F24 = 135,
+
+ ///
+ /// NUM LOCK key.
+ ///
+ NUMLOCK = 144,
+
+ ///
+ /// SCROLL LOCK key.
+ ///
+ SCROLL = 145,
+
+ ///
+ /// '=' key on numpad (NEC PC-9800 kbd definitions).
+ ///
+ OEM_NEC_EQUAL = 146,
+
+ ///
+ /// 'Dictionary' key (Fujitsu/OASYS kbd definitions).
+ ///
+ OEM_FJ_JISHO = OEM_NEC_EQUAL,
+
+ ///
+ /// 'Unregister word' key (Fujitsu/OASYS kbd definitions).
+ ///
+ OEM_FJ_MASSHOU = 147,
+
+ ///
+ /// 'Register word' key (Fujitsu/OASYS kbd definitions).
+ ///
+ OEM_FJ_TOUROKU = 148,
+
+ ///
+ /// 'Left OYAYUBI' key (Fujitsu/OASYS kbd definitions).
+ ///
+ OEM_FJ_LOYA = 149,
+
+ ///
+ /// 'Right OYAYUBI' key (Fujitsu/OASYS kbd definitions).
+ ///
+ OEM_FJ_ROYA = 150,
+
+ ///
+ /// Left SHIFT key.
+ ///
+ ///
+ /// Used only as parameters to User32.GetAsyncKeyState and User32.GetKeyState. No other API or message will distinguish left and right keys in this way.
+ ///
+ LSHIFT = 160,
+
+ ///
+ /// Right SHIFT key.
+ ///
+ RSHIFT = 161,
+
+ ///
+ /// Left CONTROL key.
+ ///
+ LCONTROL = 162,
+
+ ///
+ /// Right CONTROL key.
+ ///
+ RCONTROL = 163,
+
+ ///
+ /// Left MENU key.
+ ///
+ LMENU = 164,
+
+ ///
+ /// Right MENU key.
+ ///
+ RMENU = 165,
+
+ ///
+ /// Browser Back key.
+ ///
+ BROWSER_BACK = 166,
+
+ ///
+ /// Browser Forward key.
+ ///
+ BROWSER_FORWARD = 167,
+
+ ///
+ /// Browser Refresh key.
+ ///
+ BROWSER_REFRESH = 168,
+
+ ///
+ /// Browser Stop key.
+ ///
+ BROWSER_STOP = 169,
+
+ ///
+ /// Browser Search key.
+ ///
+ BROWSER_SEARCH = 170,
+
+ ///
+ /// Browser Favorites key.
+ ///
+ BROWSER_FAVORITES = 171,
+
+ ///
+ /// Browser Start and Home key.
+ ///
+ BROWSER_HOME = 172,
+
+ ///
+ /// Volume Mute key.
+ ///
+ VOLUME_MUTE = 173,
+
+ ///
+ /// Volume Down key.
+ ///
+ VOLUME_DOWN = 174,
+
+ ///
+ /// Volume Up key.
+ ///
+ VOLUME_UP = 175,
+
+ ///
+ /// Next Track key.
+ ///
+ MEDIA_NEXT_TRACK = 176,
+
+ ///
+ /// Previous Track key.
+ ///
+ MEDIA_PREV_TRACK = 177,
+
+ ///
+ /// Stop Media key.
+ ///
+ MEDIA_STOP = 178,
+
+ ///
+ /// Play/Pause Media key.
+ ///
+ MEDIA_PLAY_PAUSE = 179,
+
+ ///
+ /// Start Mail key.
+ ///
+ LAUNCH_MAIL = 180,
+
+ ///
+ /// Select Media key.
+ ///
+ LAUNCH_MEDIA_SELECT = 181,
+
+ ///
+ /// Start Application 1 key.
+ ///
+ LAUNCH_APP1 = 182,
+
+ ///
+ /// Start Application 2 key.
+ ///
+ LAUNCH_APP2 = 183,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the ';:' key.
+ ///
+ OEM_1 = 186,
+
+ ///
+ /// For any country/region, the '+' key.
+ ///
+ OEM_PLUS = 187,
+
+ ///
+ /// For any country/region, the ',' key.
+ ///
+ OEM_COMMA = 188,
+
+ ///
+ /// For any country/region, the '-' key.
+ ///
+ OEM_MINUS = 189,
+
+ ///
+ /// For any country/region, the '.' key.
+ ///
+ OEM_PERIOD = 190,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the '/?' key.
+ ///
+ OEM_2 = 191,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the '`~' key.
+ ///
+ OEM_3 = 192,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the '[{' key.
+ ///
+ OEM_4 = 219,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the '\|' key.
+ ///
+ OEM_5 = 220,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the ']}' key.
+ ///
+ OEM_6 = 221,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ ///
+ /// For the US standard keyboard, the 'single-quote/double-quote' (''"') key.
+ ///
+ OEM_7 = 222,
+
+ ///
+ /// Used for miscellaneous characters; it can vary by keyboard..
+ ///
+ OEM_8 = 223,
+
+ ///
+ /// OEM specific.
+ ///
+ ///
+ /// 'AX' key on Japanese AX kbd.
+ ///
+ OEM_AX = 225,
+
+ ///
+ /// Either the angle bracket ("<>") key or the backslash ("\|") key on the RT 102-key keyboard.
+ ///
+ OEM_102 = 226,
+
+ ///
+ /// OEM specific.
+ ///
+ ///
+ /// Help key on ICO.
+ ///
+ ICO_HELP = 227,
+
+ ///
+ /// OEM specific.
+ ///
+ ///
+ /// 00 key on ICO.
+ ///
+ ICO_00 = 228,
+
+ ///
+ /// IME PROCESS key.
+ ///
+ PROCESSKEY = 229,
+
+ ///
+ /// OEM specific.
+ ///
+ ///
+ /// Clear key on ICO.
+ ///
+ ICO_CLEAR = 230,
+
+ ///
+ /// Used to pass Unicode characters as if they were keystrokes. The PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods..
+ ///
+ ///
+ /// For more information, see Remark in User32.KEYBDINPUT, User32.SendInput, User32.WindowMessage.WM_KEYDOWN, and User32.WindowMessage.WM_KEYUP.
+ ///
+ PACKET = 231,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_RESET = 233,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_JUMP = 234,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_PA1 = 235,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_PA2 = 236,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_PA3 = 237,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_WSCTRL = 238,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_CUSEL = 239,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_ATTN = 240,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_FINISH = 241,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_COPY = 242,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_AUTO = 243,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_ENLW = 244,
+
+ ///
+ /// Nokia/Ericsson definition.
+ ///
+ OEM_BACKTAB = 245,
+
+ ///
+ /// Attn key.
+ ///
+ ATTN = 246,
+
+ ///
+ /// CrSel key.
+ ///
+ CRSEL = 247,
+
+ ///
+ /// ExSel key.
+ ///
+ EXSEL = 248,
+
+ ///
+ /// Erase EOF key.
+ ///
+ EREOF = 249,
+
+ ///
+ /// Play key.
+ ///
+ PLAY = 250,
+
+ ///
+ /// Zoom key.
+ ///
+ ZOOM = 251,
+
+ ///
+ /// Reserved constant by Windows headers definition.
+ ///
+ NONAME = 252,
+
+ ///
+ /// PA1 key.
+ ///
+ PA1 = 253,
+
+ ///
+ /// Clear key.
+ ///
+ OEM_CLEAR = 254,
+ }
+}
diff --git a/Dalamud/Game/ClientState/Resolvers/ClassJobResolver.cs b/Dalamud/Game/ClientState/Resolvers/ClassJobResolver.cs
deleted file mode 100644
index b9603838d..000000000
--- a/Dalamud/Game/ClientState/Resolvers/ClassJobResolver.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Dalamud.Game.ClientState.Resolvers
-{
- ///
- /// This object represents a class or job.
- ///
- public class ClassJobResolver : BaseResolver
- {
- ///
- /// Initializes a new instance of the class.
- /// Set up the ClassJob resolver with the provided ID.
- ///
- /// The ID of the classJob.
- /// The Dalamud instance.
- internal ClassJobResolver(ushort id, Dalamud dalamud)
- : base(id, dalamud)
- {
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Resolvers/BaseResolver{T}.cs b/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs
similarity index 75%
rename from Dalamud/Game/ClientState/Resolvers/BaseResolver{T}.cs
rename to Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs
index 2ded995d7..920f7b69e 100644
--- a/Dalamud/Game/ClientState/Resolvers/BaseResolver{T}.cs
+++ b/Dalamud/Game/ClientState/Resolvers/ExcelResolver{T}.cs
@@ -3,19 +3,19 @@ using Lumina.Excel;
namespace Dalamud.Game.ClientState.Resolvers
{
///
- /// This object represents a class or job.
+ /// This object resolves a rowID within an Excel sheet.
///
/// The type of Lumina sheet to resolve.
- public class BaseResolver where T : ExcelRow
+ public class ExcelResolver where T : ExcelRow
{
private readonly Dalamud dalamud;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The ID of the classJob.
/// The Dalamud instance.
- internal BaseResolver(uint id, Dalamud dalamud)
+ internal ExcelResolver(uint id, Dalamud dalamud)
{
this.dalamud = dalamud;
this.Id = id;
diff --git a/Dalamud/Game/ClientState/Resolvers/FateResolver.cs b/Dalamud/Game/ClientState/Resolvers/FateResolver.cs
deleted file mode 100644
index 15f2fce0d..000000000
--- a/Dalamud/Game/ClientState/Resolvers/FateResolver.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Dalamud.Game.ClientState.Resolvers
-{
- ///
- /// This object represents a Fate a character can participate in.
- ///
- public class FateResolver : BaseResolver
- {
- ///
- /// Initializes a new instance of the class.
- /// Set up the Fate resolver with the provided ID.
- ///
- /// The ID of the Fate.
- /// The Dalamud instance.
- internal FateResolver(ushort id, Dalamud dalamud)
- : base(id, dalamud)
- {
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Resolvers/TerritoryTypeResolver.cs b/Dalamud/Game/ClientState/Resolvers/TerritoryTypeResolver.cs
deleted file mode 100644
index 248bf94bb..000000000
--- a/Dalamud/Game/ClientState/Resolvers/TerritoryTypeResolver.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Dalamud.Game.ClientState.Resolvers
-{
- ///
- /// This object represents a territory a character can be in.
- ///
- public class TerritoryTypeResolver : BaseResolver
- {
- ///
- /// Initializes a new instance of the class.
- /// Set up the territory type resolver with the provided ID.
- ///
- /// The ID of the territory type.
- /// The Dalamud instance.
- internal TerritoryTypeResolver(ushort id, Dalamud dalamud)
- : base(id, dalamud)
- {
- }
- }
-}
diff --git a/Dalamud/Game/ClientState/Resolvers/WorldResolver.cs b/Dalamud/Game/ClientState/Resolvers/WorldResolver.cs
deleted file mode 100644
index 0d37e3549..000000000
--- a/Dalamud/Game/ClientState/Resolvers/WorldResolver.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Dalamud.Game.ClientState.Resolvers
-{
- ///
- /// This object represents a world a character can reside on.
- ///
- public class WorldResolver : BaseResolver
- {
- ///
- /// Initializes a new instance of the class.
- /// Set up the world resolver with the provided ID.
- ///
- /// The ID of the world.
- /// The Dalamud instance.
- internal WorldResolver(ushort id, Dalamud dalamud)
- : base(id, dalamud)
- {
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Framework.cs b/Dalamud/Game/Framework.cs
similarity index 98%
rename from Dalamud/Game/Internal/Framework.cs
rename to Dalamud/Game/Framework.cs
index abe3272e0..cd16fb829 100644
--- a/Dalamud/Game/Internal/Framework.cs
+++ b/Dalamud/Game/Framework.cs
@@ -5,13 +5,13 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
-using Dalamud.Game.Internal.Gui;
-using Dalamud.Game.Internal.Libc;
-using Dalamud.Game.Internal.Network;
+using Dalamud.Game.Gui;
+using Dalamud.Game.Libc;
+using Dalamud.Game.Network;
using Dalamud.Hooking;
using Serilog;
-namespace Dalamud.Game.Internal
+namespace Dalamud.Game
{
///
/// This class represents the Framework of the native game client and grants access to various subsystems.
@@ -90,7 +90,7 @@ namespace Dalamud.Game.Internal
///
/// Gets the stats history mapping.
///
- public static Dictionary> StatsHistory = new();
+ public static Dictionary> StatsHistory { get; } = new();
#region Subsystems
diff --git a/Dalamud/Game/Internal/FrameworkAddressResolver.cs b/Dalamud/Game/FrameworkAddressResolver.cs
similarity index 97%
rename from Dalamud/Game/Internal/FrameworkAddressResolver.cs
rename to Dalamud/Game/FrameworkAddressResolver.cs
index 1af2e9263..7bcae5045 100644
--- a/Dalamud/Game/Internal/FrameworkAddressResolver.cs
+++ b/Dalamud/Game/FrameworkAddressResolver.cs
@@ -1,7 +1,9 @@
using System;
using System.Runtime.InteropServices;
-namespace Dalamud.Game.Internal
+using Dalamud.Game.Internal;
+
+namespace Dalamud.Game
{
///
/// The address resolver for the class.
diff --git a/Dalamud/Game/GameVersion.cs b/Dalamud/Game/GameVersion.cs
index 8ef76eabe..a93e0bff2 100644
--- a/Dalamud/Game/GameVersion.cs
+++ b/Dalamud/Game/GameVersion.cs
@@ -209,6 +209,32 @@ namespace Dalamud.Game
return v2 <= v1;
}
+ public static GameVersion operator +(GameVersion v1, TimeSpan v2)
+ {
+ if (v1 == null)
+ throw new ArgumentNullException(nameof(v1));
+
+ if (v1.Year == -1 || v1.Month == -1 || v1.Day == -1)
+ return v1;
+
+ var date = new DateTime(v1.Year, v1.Month, v1.Day) + v2;
+
+ return new GameVersion(date.Year, date.Month, date.Day, v1.Major, v1.Minor);
+ }
+
+ public static GameVersion operator -(GameVersion v1, TimeSpan v2)
+ {
+ if (v1 == null)
+ throw new ArgumentNullException(nameof(v1));
+
+ if (v1.Year == -1 || v1.Month == -1 || v1.Day == -1)
+ return v1;
+
+ var date = new DateTime(v1.Year, v1.Month, v1.Day) - v2;
+
+ return new GameVersion(date.Year, date.Month, date.Day, v1.Major, v1.Minor);
+ }
+
///
/// Parse a version string. YYYY.MM.DD.majr.minr or "any".
///
diff --git a/Dalamud/Game/Internal/Gui/Addon/Addon.cs b/Dalamud/Game/Gui/Addons/Addon.cs
similarity index 56%
rename from Dalamud/Game/Internal/Gui/Addon/Addon.cs
rename to Dalamud/Game/Gui/Addons/Addon.cs
index 5a0c4ce98..207443b8b 100644
--- a/Dalamud/Game/Internal/Gui/Addon/Addon.cs
+++ b/Dalamud/Game/Gui/Addons/Addon.cs
@@ -1,66 +1,63 @@
using System;
-namespace Dalamud.Game.Internal.Gui.Addon
+using Dalamud.Memory;
+
+namespace Dalamud.Game.Gui.Addons
{
///
/// This class represents an in-game UI "Addon".
///
- public class Addon
+ public unsafe class Addon
{
- ///
- /// The address of the addon.
- ///
- public IntPtr Address;
-
- ///
- /// The addon interop data.
- ///
- protected Structs.Addon addonStruct;
-
///
/// Initializes a new instance of the class.
///
/// The address of the addon.
- /// The addon interop data.
- public Addon(IntPtr address, Structs.Addon addonStruct)
+ public Addon(IntPtr address)
{
this.Address = address;
- this.addonStruct = addonStruct;
}
+ ///
+ /// Gets the address of the addon.
+ ///
+ public IntPtr Address { get; }
+
///
/// Gets the name of the addon.
///
- public string Name => this.addonStruct.Name;
+ public string Name => MemoryHelper.ReadString((IntPtr)this.Struct->Name, 0x20);
///
/// Gets the X position of the addon on screen.
///
- public short X => this.addonStruct.X;
+ public short X => this.Struct->X;
///
/// Gets the Y position of the addon on screen.
///
- public short Y => this.addonStruct.Y;
+ public short Y => this.Struct->Y;
///
/// Gets the scale of the addon.
///
- public float Scale => this.addonStruct.Scale;
+ public float Scale => this.Struct->Scale;
///
/// Gets the width of the addon. This may include non-visible parts.
///
- public unsafe float Width => this.addonStruct.RootNode->Width * this.Scale;
+ public unsafe float Width => this.Struct->RootNode->Width * this.Scale;
///
/// Gets the height of the addon. This may include non-visible parts.
///
- public unsafe float Height => this.addonStruct.RootNode->Height * this.Scale;
+ public unsafe float Height => this.Struct->RootNode->Height * this.Scale;
///
/// Gets a value indicating whether the addon is visible.
///
- public bool Visible => (this.addonStruct.Flags & 0x20) == 0x20;
+ public bool Visible => this.Struct->IsVisible;
+
+ private FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase* Struct => (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)this.Address;
}
}
diff --git a/Dalamud/Game/Internal/Gui/ChatGui.cs b/Dalamud/Game/Gui/ChatGui.cs
similarity index 93%
rename from Dalamud/Game/Internal/Gui/ChatGui.cs
rename to Dalamud/Game/Gui/ChatGui.cs
index 09aa234eb..09f5d2a2a 100644
--- a/Dalamud/Game/Internal/Gui/ChatGui.cs
+++ b/Dalamud/Game/Gui/ChatGui.cs
@@ -2,16 +2,15 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Text;
-using Dalamud.Game.Internal.Libc;
+using Dalamud.Game.Libc;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Serilog;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// This class handles interacting with the native chat UI.
@@ -60,17 +59,6 @@ namespace Dalamud.Game.Internal.Gui
/// A value indicating whether the message was handled or should be propagated.
public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled);
- ///
- /// A delegate type used with the event.
- ///
- /// The type of chat.
- /// The sender ID.
- /// The sender name.
- /// The message sent.
- /// A value indicating whether the message was handled or should be propagated.
- [Obsolete("Please use OnMessageDelegate instead. For modifications, it will take precedence.")]
- public delegate void OnMessageRawDelegate(XivChatType type, uint senderId, ref StdString sender, ref StdString message, ref bool isHandled);
-
///
/// A delegate type used with the event.
///
@@ -113,12 +101,6 @@ namespace Dalamud.Game.Internal.Gui
///
public event OnMessageDelegate OnChatMessage;
- ///
- /// Event that will be fired when a chat message is sent by the game, containing raw, unparsed data.
- ///
- [Obsolete("Please use OnChatMessage instead. For modifications, it will take precedence.")]
- public event OnMessageRawDelegate OnChatMessageRaw;
-
///
/// Event that allows you to stop messages from appearing in chat by setting the isHandled parameter to true.
///
@@ -353,7 +335,7 @@ namespace Dalamud.Game.Internal.Gui
this.LastLinkedItemId = Marshal.ReadInt32(itemInfoPtr, 8);
this.LastLinkedItemFlags = Marshal.ReadByte(itemInfoPtr, 0x14);
- Log.Debug($"HandlePopulateItemLinkDetour {linkObjectPtr} {itemInfoPtr} - linked:{this.LastLinkedItemId}");
+ Log.Verbose($"HandlePopulateItemLinkDetour {linkObjectPtr} {itemInfoPtr} - linked:{this.LastLinkedItemId}");
}
catch (Exception ex)
{
@@ -388,7 +370,6 @@ namespace Dalamud.Game.Internal.Gui
if (!isHandled)
{
this.OnChatMessage?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
- this.OnChatMessageRaw?.Invoke(chattype, senderid, ref sender, ref message, ref isHandled);
}
var newEdited = parsedMessage.Encode();
diff --git a/Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs b/Dalamud/Game/Gui/ChatGuiAddressResolver.cs
similarity index 97%
rename from Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs
rename to Dalamud/Game/Gui/ChatGuiAddressResolver.cs
index 067558e12..07c154f1f 100644
--- a/Dalamud/Game/Internal/Gui/ChatGuiAddressResolver.cs
+++ b/Dalamud/Game/Gui/ChatGuiAddressResolver.cs
@@ -1,6 +1,8 @@
using System;
-namespace Dalamud.Game.Internal.Gui
+using Dalamud.Game.Internal;
+
+namespace Dalamud.Game.Gui
{
///
/// The address resolver for the class.
@@ -102,7 +104,7 @@ namespace Dalamud.Game.Internal.Gui
protected override void Setup64Bit(SigScanner sig)
{
// PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24D8FEFFFF 4881EC28020000 488B05???????? 4833C4 488985F0000000 4532D2 48894C2448"); LAST PART FOR 5.1???
- this.PrintMessage = sig.ScanText("4055 53 56 4154 4157 48 8d ac 24 ?? ?? ?? ?? 48 81 ec 20 02 00 00 48 8b 05");
+ this.PrintMessage = sig.ScanText("40 55 53 56 41 54 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC 20 02 00 00 48 8B 05");
// PrintMessage = sig.ScanText("4055 57 41 ?? 41 ?? 488DAC24E8FEFFFF 4881EC18020000 488B05???????? 4833C4 488985E0000000 4532D2 48894C2438"); old
// PrintMessage = sig.ScanText("40 55 57 41 56 41 57 48 8D AC 24 D8 FE FF FF 48 81 EC 28 02 00 00 48 8B 05 63 47 4A 01 48 33 C4 48 89 85 F0 00 00 00 45 32 D2 48 89 4C 24 48 33");
diff --git a/Dalamud/Game/Internal/Gui/FlyTextGui.cs b/Dalamud/Game/Gui/FlyTextGui.cs
similarity index 100%
rename from Dalamud/Game/Internal/Gui/FlyTextGui.cs
rename to Dalamud/Game/Gui/FlyTextGui.cs
diff --git a/Dalamud/Game/Internal/Gui/FlyTextGuiAddressResolver.cs b/Dalamud/Game/Gui/FlyTextGuiAddressResolver.cs
similarity index 100%
rename from Dalamud/Game/Internal/Gui/FlyTextGuiAddressResolver.cs
rename to Dalamud/Game/Gui/FlyTextGuiAddressResolver.cs
diff --git a/Dalamud/Game/Internal/Gui/FlyTextKind.cs b/Dalamud/Game/Gui/FlyTextKind.cs
similarity index 100%
rename from Dalamud/Game/Internal/Gui/FlyTextKind.cs
rename to Dalamud/Game/Gui/FlyTextKind.cs
diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs
similarity index 86%
rename from Dalamud/Game/Internal/Gui/GameGui.cs
rename to Dalamud/Game/Gui/GameGui.cs
index 005a15da9..c783d338f 100644
--- a/Dalamud/Game/Internal/Gui/GameGui.cs
+++ b/Dalamud/Game/Gui/GameGui.cs
@@ -1,25 +1,23 @@
using System;
+using System.Numerics;
using System.Runtime.InteropServices;
+using Dalamud.Game.Gui.Addons;
+using Dalamud.Game.Gui.PartyFinder;
+using Dalamud.Game.Internal.Gui;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Hooking;
using Dalamud.Interface;
+using Dalamud.Utility;
using Serilog;
-using SharpDX;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// A class handling many aspects of the in-game UI.
///
public sealed class GameGui : IDisposable
{
- ///
- /// The delegate of the native method that gets the Client::UI::UIModule address.
- ///
- /// The Client::UI::UIModule address.
- public readonly GetBaseUIObjectDelegate GetBaseUIObject;
-
private readonly Dalamud dalamud;
private readonly GameGuiAddressResolver address;
@@ -147,6 +145,12 @@ namespace Dalamud.Game.Internal.Gui
///
public event EventHandler OnUiHideToggled;
+ ///
+ /// Gets a callable delegate for the GetBaseUIObject game method.
+ ///
+ /// The Client::UI::UIModule address.
+ public GetBaseUIObjectDelegate GetBaseUIObject { get; }
+
///
/// Gets the instance.
///
@@ -233,13 +237,13 @@ namespace Dalamud.Game.Internal.Gui
/// Coordinates in the world.
/// Converted coordinates.
/// True if worldPos corresponds to a position in front of the camera.
- public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos)
+ public bool WorldToScreen(SharpDX.Vector3 worldPos, out SharpDX.Vector2 screenPos)
{
// Get base object with matrices
var matrixSingleton = this.getMatrixSingleton();
// Read current ViewProjectionMatrix plus game window size
- var viewProjectionMatrix = default(Matrix);
+ var viewProjectionMatrix = default(SharpDX.Matrix);
float width, height;
var windowPos = ImGuiHelpers.MainViewport.Pos;
@@ -254,9 +258,9 @@ namespace Dalamud.Game.Internal.Gui
height = *(rawMatrix + 1);
}
- Vector3.Transform(ref worldPos, ref viewProjectionMatrix, out Vector3 pCoords);
+ SharpDX.Vector3.Transform(ref worldPos, ref viewProjectionMatrix, out SharpDX.Vector3 pCoords);
- screenPos = new Vector2(pCoords.X / pCoords.Z, pCoords.Y / pCoords.Z);
+ screenPos = new SharpDX.Vector2(pCoords.X / pCoords.Z, pCoords.Y / pCoords.Z);
screenPos.X = (0.5f * width * (screenPos.X + 1f)) + windowPos.X;
screenPos.Y = (0.5f * height * (1f - screenPos.Y)) + windowPos.Y;
@@ -266,6 +270,39 @@ namespace Dalamud.Game.Internal.Gui
screenPos.Y > windowPos.Y && screenPos.Y < windowPos.Y + height;
}
+ ///
+ /// Converts in-world coordinates to screen coordinates (upper left corner origin).
+ ///
+ /// Coordinates in the world.
+ /// Converted coordinates.
+ /// True if worldPos corresponds to a position in front of the camera.
+ ///
+ /// This overload requires a conversion to SharpDX vectors, however the penalty should be negligible.
+ ///
+ public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos)
+ {
+ var result = this.WorldToScreen(worldPos.ToSharpDX(), out var sharpScreenPos);
+ screenPos = sharpScreenPos.ToSystem();
+ return result;
+ }
+
+ ///
+ /// Converts in-world coordinates to screen coordinates (upper left corner origin).
+ ///
+ /// Coordinates in the world.
+ /// Converted coordinates.
+ /// True if worldPos corresponds to a position in front of the camera.
+ ///
+ /// This overload requires a conversion to SharpDX vectors, however the penalty should be negligible.
+ ///
+ public bool WorldToScreen(Position3 worldPos, out Vector2 screenPos)
+ {
+ // This overload is necessary due to Positon3 implicit operators.
+ var result = this.WorldToScreen((SharpDX.Vector3)worldPos, out var sharpScreenPos);
+ screenPos = sharpScreenPos.ToSystem();
+ return result;
+ }
+
///
/// Converts screen coordinates to in-world coordinates via raycasting.
///
@@ -273,7 +310,7 @@ namespace Dalamud.Game.Internal.Gui
/// Converted coordinates.
/// How far to search for a collision.
/// True if successful. On false, worldPos's contents are undefined.
- public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f)
+ public bool ScreenToWorld(SharpDX.Vector2 screenPos, out SharpDX.Vector3 worldPos, float rayDistance = 100000.0f)
{
// The game is only visible in the main viewport, so if the cursor is outside
// of the game window, do not bother calculating anything
@@ -291,7 +328,7 @@ namespace Dalamud.Game.Internal.Gui
var matrixSingleton = this.getMatrixSingleton();
// Read current ViewProjectionMatrix plus game window size
- var viewProjectionMatrix = default(Matrix);
+ var viewProjectionMatrix = default(SharpDX.Matrix);
float width, height;
unsafe
{
@@ -306,18 +343,18 @@ namespace Dalamud.Game.Internal.Gui
viewProjectionMatrix.Invert();
- var localScreenPos = new Vector2(screenPos.X - windowPos.X, screenPos.Y - windowPos.Y);
- var screenPos3D = new Vector3
+ var localScreenPos = new SharpDX.Vector2(screenPos.X - windowPos.X, screenPos.Y - windowPos.Y);
+ var screenPos3D = new SharpDX.Vector3
{
X = (localScreenPos.X / width * 2.0f) - 1.0f,
Y = -((localScreenPos.Y / height * 2.0f) - 1.0f),
Z = 0,
};
- Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPos);
+ SharpDX.Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPos);
screenPos3D.Z = 1;
- Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPosOne);
+ SharpDX.Vector3.TransformCoordinate(ref screenPos3D, ref viewProjectionMatrix, out var camPosOne);
var clipPos = camPosOne - camPos;
clipPos.Normalize();
@@ -347,7 +384,7 @@ namespace Dalamud.Game.Internal.Gui
}
}
- worldPos = new Vector3
+ worldPos = new SharpDX.Vector3
{
X = worldPosArray[0],
Y = worldPosArray[1],
@@ -358,6 +395,23 @@ namespace Dalamud.Game.Internal.Gui
return isSuccess;
}
+ ///
+ /// Converts screen coordinates to in-world coordinates via raycasting.
+ ///
+ /// Screen coordinates.
+ /// Converted coordinates.
+ /// How far to search for a collision.
+ /// True if successful. On false, worldPos's contents are undefined.
+ ///
+ /// This overload requires a conversion to SharpDX vectors, however the penalty should be negligible.
+ ///
+ public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f)
+ {
+ var result = this.ScreenToWorld(screenPos.ToSharpDX(), out var sharpworldPos);
+ worldPos = sharpworldPos.ToSystem();
+ return result;
+ }
+
///
/// Gets a pointer to the game's UI module.
///
@@ -385,12 +439,14 @@ namespace Dalamud.Game.Internal.Gui
/// The addon name.
/// The index of the addon, starting at 1.
/// The native memory representation of the addon, if it exists.
- public Addon.Addon GetAddonByName(string name, int index)
+ public Addon GetAddonByName(string name, int index)
{
- var addonMem = this.GetUiObjectByName(name, index);
- if (addonMem == IntPtr.Zero) return null;
- var addonStruct = Marshal.PtrToStructure(addonMem);
- return new Addon.Addon(addonMem, addonStruct);
+ var address = this.GetUiObjectByName(name, index);
+
+ if (address == IntPtr.Zero)
+ return null;
+
+ return new Addon(address);
}
///
diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Gui/GameGuiAddressResolver.cs
similarity index 99%
rename from Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
rename to Dalamud/Game/Gui/GameGuiAddressResolver.cs
index 12c46faa4..b3e04d68d 100644
--- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
+++ b/Dalamud/Game/Gui/GameGuiAddressResolver.cs
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// The address resolver for the class.
diff --git a/Dalamud/Game/Internal/Gui/HoverActionKind.cs b/Dalamud/Game/Gui/HoverActionKind.cs
similarity index 96%
rename from Dalamud/Game/Internal/Gui/HoverActionKind.cs
rename to Dalamud/Game/Gui/HoverActionKind.cs
index f069cb614..217ea18fb 100644
--- a/Dalamud/Game/Internal/Gui/HoverActionKind.cs
+++ b/Dalamud/Game/Gui/HoverActionKind.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// ActionKinds used in AgentActionDetail.
diff --git a/Dalamud/Game/Internal/Gui/HoveredAction.cs b/Dalamud/Game/Gui/HoveredAction.cs
similarity index 94%
rename from Dalamud/Game/Internal/Gui/HoveredAction.cs
rename to Dalamud/Game/Gui/HoveredAction.cs
index ebc0dea15..1a7336610 100644
--- a/Dalamud/Game/Internal/Gui/HoveredAction.cs
+++ b/Dalamud/Game/Gui/HoveredAction.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// This class represents the hotbar action currently hovered over by the cursor.
diff --git a/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacket.cs b/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacket.cs
new file mode 100644
index 000000000..9f8834ecd
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacket.cs
@@ -0,0 +1,28 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
+
+namespace Dalamud.Game.Gui.PartyFinder.Internal
+{
+ ///
+ /// The structure of the PartyFinder packet.
+ ///
+ [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "Sequential struct marshaling.")]
+ [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "Sequential struct marshaling.")]
+ [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the field usage.")]
+ [StructLayout(LayoutKind.Sequential)]
+ internal readonly struct PartyFinderPacket
+ {
+ ///
+ /// Gets the size of this packet.
+ ///
+ internal static int PacketSize { get; } = Marshal.SizeOf();
+
+ internal readonly int BatchNumber;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ private readonly byte[] padding1;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ internal readonly PartyFinderPacketListing[] Listings;
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacketListing.cs b/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacketListing.cs
new file mode 100644
index 000000000..75f24c88c
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Internal/PartyFinderPacketListing.cs
@@ -0,0 +1,99 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace Dalamud.Game.Gui.PartyFinder.Internal
+{
+ ///
+ /// The structure of an individual listing within a packet.
+ ///
+ [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "Sequential struct marshaling.")]
+ [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the field usage.")]
+ [StructLayout(LayoutKind.Sequential)]
+ internal readonly struct PartyFinderPacketListing
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ private readonly byte[] header1;
+ internal readonly uint Id;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
+ private readonly byte[] header2;
+
+ internal readonly uint ContentIdLower;
+ private readonly ushort unknownShort1;
+ private readonly ushort unknownShort2;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
+ private readonly byte[] header3;
+
+ internal readonly byte Category;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ private readonly byte[] header4;
+
+ internal readonly ushort Duty;
+ internal readonly byte DutyType;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
+ private readonly byte[] header5;
+
+ internal readonly ushort World;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ private readonly byte[] header6;
+
+ internal readonly byte Objective;
+ internal readonly byte BeginnersWelcome;
+ internal readonly byte Conditions;
+ internal readonly byte DutyFinderSettings;
+ internal readonly byte LootRules;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ private readonly byte[] header7; // all zero in every pf I've examined
+
+ private readonly uint lastPatchHotfixTimestamp; // last time the servers were restarted?
+ internal readonly ushort SecondsRemaining;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
+ private readonly byte[] header8; // 00 00 01 00 00 00 in every pf I've examined
+
+ internal readonly ushort MinimumItemLevel;
+ internal readonly ushort HomeWorld;
+ internal readonly ushort CurrentWorld;
+
+ private readonly byte header9;
+
+ internal readonly byte NumSlots;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ private readonly byte[] header10;
+
+ internal readonly byte SearchArea;
+
+ private readonly byte header11;
+
+ internal readonly byte NumParties;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
+ private readonly byte[] header12; // 00 00 00 always. maybe numParties is a u32?
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ internal readonly uint[] Slots;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ internal readonly byte[] JobsPresent;
+
+ // Note that ByValTStr will not work here because the strings are UTF-8 and there's only a CharSet for UTF-16 in C#.
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ internal readonly byte[] Name;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 192)]
+ internal readonly byte[] Description;
+
+ internal bool IsNull()
+ {
+ // a valid party finder must have at least one slot set
+ return this.Slots.All(slot => slot == 0);
+ }
+ }
+}
diff --git a/Dalamud/Game/Internal/Gui/PartyFinderAddressResolver.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs
old mode 100755
new mode 100644
similarity index 82%
rename from Dalamud/Game/Internal/Gui/PartyFinderAddressResolver.cs
rename to Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs
index 3c0f80e34..75da83180
--- a/Dalamud/Game/Internal/Gui/PartyFinderAddressResolver.cs
+++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderAddressResolver.cs
@@ -1,11 +1,11 @@
using System;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui.PartyFinder
{
///
/// The address resolver for the class.
///
- internal class PartyFinderAddressResolver : BaseAddressResolver
+ public class PartyFinderAddressResolver : BaseAddressResolver
{
///
/// Gets the address of the native ReceiveListing method.
diff --git a/Dalamud/Game/Internal/Gui/PartyFinderGui.cs b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
old mode 100755
new mode 100644
similarity index 79%
rename from Dalamud/Game/Internal/Gui/PartyFinderGui.cs
rename to Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
index 24079cf4e..dcfd03c46
--- a/Dalamud/Game/Internal/Gui/PartyFinderGui.cs
+++ b/Dalamud/Game/Gui/PartyFinder/PartyFinderGui.cs
@@ -1,11 +1,12 @@
using System;
using System.Runtime.InteropServices;
-using Dalamud.Game.Internal.Gui.Structs;
+using Dalamud.Game.Gui.PartyFinder.Internal;
+using Dalamud.Game.Gui.PartyFinder.Types;
using Dalamud.Hooking;
using Serilog;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui.PartyFinder
{
///
/// This class handles interacting with the native PartyFinder window.
@@ -30,7 +31,7 @@ namespace Dalamud.Game.Internal.Gui
this.address = new PartyFinderAddressResolver();
this.address.Setup(scanner);
- this.memory = Marshal.AllocHGlobal(PartyFinder.PacketInfo.PacketSize);
+ this.memory = Marshal.AllocHGlobal(PartyFinderPacket.PacketSize);
this.receiveListingHook = new Hook(this.address.ReceiveListing, new ReceiveListingDelegate(this.HandleReceiveListingDetour));
}
@@ -87,7 +88,7 @@ namespace Dalamud.Game.Internal.Gui
{
var dataPtr = data + 0x10;
- var packet = Marshal.PtrToStructure(dataPtr);
+ var packet = Marshal.PtrToStructure(dataPtr);
// rewriting is an expensive operation, so only do it if necessary
var needToRewrite = false;
@@ -125,33 +126,8 @@ namespace Dalamud.Game.Internal.Gui
// copy our new memory over the game's
unsafe
{
- Buffer.MemoryCopy((void*)this.memory, (void*)dataPtr, PartyFinder.PacketInfo.PacketSize, PartyFinder.PacketInfo.PacketSize);
+ Buffer.MemoryCopy((void*)this.memory, (void*)dataPtr, PartyFinderPacket.PacketSize, PartyFinderPacket.PacketSize);
}
}
}
-
- ///
- /// This class represents additional arguments passed by the game.
- ///
- public class PartyFinderListingEventArgs
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The batch number.
- internal PartyFinderListingEventArgs(int batchNumber)
- {
- this.BatchNumber = batchNumber;
- }
-
- ///
- /// Gets the batch number.
- ///
- public int BatchNumber { get; }
-
- ///
- /// Gets or sets a value indicating whether the listing is visible.
- ///
- public bool Visible { get; set; } = true;
- }
}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderCategory.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderCategory.cs
new file mode 100644
index 000000000..d7ffe568b
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderCategory.cs
@@ -0,0 +1,48 @@
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Category flags for the class.
+ ///
+ public enum DutyFinderCategory
+ {
+ ///
+ /// The duty category.
+ ///
+ Duty = 0,
+
+ ///
+ /// The quest battle category.
+ ///
+ QuestBattles = 1 << 0,
+
+ ///
+ /// The fate category.
+ ///
+ Fates = 1 << 1,
+
+ ///
+ /// The treasure hunt category.
+ ///
+ TreasureHunt = 1 << 2,
+
+ ///
+ /// The hunt category.
+ ///
+ TheHunt = 1 << 3,
+
+ ///
+ /// The gathering forays category.
+ ///
+ GatheringForays = 1 << 4,
+
+ ///
+ /// The deep dungeons category.
+ ///
+ DeepDungeons = 1 << 5,
+
+ ///
+ /// The adventuring forays category.
+ ///
+ AdventuringForays = 1 << 6,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderConditionFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderConditionFlags.cs
new file mode 100644
index 000000000..2abd371ab
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderConditionFlags.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Condition flags for the class.
+ ///
+ [Flags]
+ public enum DutyFinderConditionFlags : uint
+ {
+ ///
+ /// No duty condition.
+ ///
+ None = 1,
+
+ ///
+ /// The duty complete condition.
+ ///
+ DutyComplete = 2,
+
+ ///
+ /// The duty incomplete condition.
+ ///
+ DutyIncomplete = 4,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderLootRuleFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderLootRuleFlags.cs
new file mode 100644
index 000000000..aa75807fd
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderLootRuleFlags.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Loot rule flags for the class.
+ ///
+ [Flags]
+ public enum DutyFinderLootRuleFlags : uint
+ {
+ ///
+ /// No loot rules.
+ ///
+ None = 0,
+
+ ///
+ /// The greed only rule.
+ ///
+ GreedOnly = 1,
+
+ ///
+ /// The lootmaster rule.
+ ///
+ Lootmaster = 2,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderObjectiveFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderObjectiveFlags.cs
new file mode 100644
index 000000000..40e34c1fc
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderObjectiveFlags.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Objective flags for the class.
+ ///
+ [Flags]
+ public enum DutyFinderObjectiveFlags : uint
+ {
+ ///
+ /// No objective.
+ ///
+ None = 0,
+
+ ///
+ /// The duty completion objective.
+ ///
+ DutyCompletion = 1,
+
+ ///
+ /// The practice objective.
+ ///
+ Practice = 2,
+
+ ///
+ /// The loot objective.
+ ///
+ Loot = 4,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSearchAreaFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSearchAreaFlags.cs
new file mode 100644
index 000000000..c9c238e48
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSearchAreaFlags.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Search area flags for the class.
+ ///
+ [Flags]
+ public enum DutyFinderSearchAreaFlags : uint
+ {
+ ///
+ /// Datacenter.
+ ///
+ DataCentre = 1 << 0,
+
+ ///
+ /// Private.
+ ///
+ Private = 1 << 1,
+
+ ///
+ /// Alliance raid.
+ ///
+ AllianceRaid = 1 << 2,
+
+ ///
+ /// World.
+ ///
+ World = 1 << 3,
+
+ ///
+ /// One player per job.
+ ///
+ OnePlayerPerJob = 1 << 5,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs
new file mode 100644
index 000000000..6dfe10c69
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyFinderSettingsFlags.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Duty finder settings flags for the class.
+ ///
+ [Flags]
+ public enum DutyFinderSettingsFlags : uint
+ {
+ ///
+ /// No duty finder settings.
+ ///
+ None = 0,
+
+ ///
+ /// The undersized party setting.
+ ///
+ UndersizedParty = 1 << 0,
+
+ ///
+ /// The minimum item level setting.
+ ///
+ MinimumItemLevel = 1 << 1,
+
+ ///
+ /// The silence echo setting.
+ ///
+ SilenceEcho = 1 << 2,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/DutyType.cs b/Dalamud/Game/Gui/PartyFinder/Types/DutyType.cs
new file mode 100644
index 000000000..3e3342938
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/DutyType.cs
@@ -0,0 +1,23 @@
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Duty type flags for the class.
+ ///
+ public enum DutyType
+ {
+ ///
+ /// No duty type.
+ ///
+ Other = 0,
+
+ ///
+ /// The roulette duty type.
+ ///
+ Roulette = 1 << 0,
+
+ ///
+ /// The normal duty type.
+ ///
+ Normal = 1 << 1,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs
new file mode 100644
index 000000000..98fa1b1fe
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/JobFlags.cs
@@ -0,0 +1,146 @@
+using System;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Job flags for the class.
+ ///
+ [Flags]
+ public enum JobFlags
+ {
+ ///
+ /// Gladiator (GLD).
+ ///
+ Gladiator = 1 << 1,
+
+ ///
+ /// Pugilist (PGL).
+ ///
+ Pugilist = 1 << 2,
+
+ ///
+ /// Marauder (MRD).
+ ///
+ Marauder = 1 << 3,
+
+ ///
+ /// Lancer (LNC).
+ ///
+ Lancer = 1 << 4,
+
+ ///
+ /// Archer (ARC).
+ ///
+ Archer = 1 << 5,
+
+ ///
+ /// Conjurer (CNJ).
+ ///
+ Conjurer = 1 << 6,
+
+ ///
+ /// Thaumaturge (THM).
+ ///
+ Thaumaturge = 1 << 7,
+
+ ///
+ /// Paladin (PLD).
+ ///
+ Paladin = 1 << 8,
+
+ ///
+ /// Monk (MNK).
+ ///
+ Monk = 1 << 9,
+
+ ///
+ /// Warrior (WAR).
+ ///
+ Warrior = 1 << 10,
+
+ ///
+ /// Dragoon (DRG).
+ ///
+ Dragoon = 1 << 11,
+
+ ///
+ /// Bard (BRD).
+ ///
+ Bard = 1 << 12,
+
+ ///
+ /// White mage (WHM).
+ ///
+ WhiteMage = 1 << 13,
+
+ ///
+ /// Black mage (BLM).
+ ///
+ BlackMage = 1 << 14,
+
+ ///
+ /// Arcanist (ACN).
+ ///
+ Arcanist = 1 << 15,
+
+ ///
+ /// Summoner (SMN).
+ ///
+ Summoner = 1 << 16,
+
+ ///
+ /// Scholar (SCH).
+ ///
+ Scholar = 1 << 17,
+
+ ///
+ /// Rogue (ROG).
+ ///
+ Rogue = 1 << 18,
+
+ ///
+ /// Ninja (NIN).
+ ///
+ Ninja = 1 << 19,
+
+ ///
+ /// Machinist (MCH).
+ ///
+ Machinist = 1 << 20,
+
+ ///
+ /// Dark Knight (DRK).
+ ///
+ DarkKnight = 1 << 21,
+
+ ///
+ /// Astrologian (AST).
+ ///
+ Astrologian = 1 << 22,
+
+ ///
+ /// Samurai (SAM).
+ ///
+ Samurai = 1 << 23,
+
+ ///
+ /// Red mage (RDM).
+ ///
+ RedMage = 1 << 24,
+
+ ///
+ /// Blue mage (BLM).
+ ///
+ BlueMage = 1 << 25,
+
+ ///
+ /// Gunbreaker (GNB).
+ ///
+ Gunbreaker = 1 << 26,
+
+ ///
+ /// Dancer (DNC).
+ ///
+ Dancer = 1 << 27,
+ }
+}
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs b/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs
new file mode 100644
index 000000000..b899dd62f
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/JobFlagsExtensions.cs
@@ -0,0 +1,27 @@
+using System;
+
+using Dalamud.Data;
+using Lumina.Excel.GeneratedSheets;
+
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// Extensions for the enum.
+ ///
+ public static class JobFlagsExtensions
+ {
+ ///
+ /// Get the actual ClassJob from the in-game sheets for this JobFlags.
+ ///
+ /// A JobFlags enum member.
+ /// A DataManager to get the ClassJob from.
+ /// A ClassJob if found or null if not.
+ public static ClassJob ClassJob(this JobFlags job, DataManager data)
+ {
+ var result = Math.Log2((double)job);
+ return result % 1 == 0
+ ? data.GetExcelSheet().GetRow((uint)result)
+ : null;
+ }
+ }
+}
diff --git a/Dalamud/Game/Internal/Gui/Structs/PartyFinderListing.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
similarity index 87%
rename from Dalamud/Game/Internal/Gui/Structs/PartyFinderListing.cs
rename to Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
index b533a9741..c75748942 100644
--- a/Dalamud/Game/Internal/Gui/Structs/PartyFinderListing.cs
+++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListing.cs
@@ -3,10 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using Dalamud.Data;
+using Dalamud.Game.Gui.PartyFinder.Internal;
using Dalamud.Game.Text.SeStringHandling;
using Lumina.Excel.GeneratedSheets;
-namespace Dalamud.Game.Internal.Gui.Structs
+namespace Dalamud.Game.Gui.PartyFinder.Types
{
///
/// A single listing in party finder.
@@ -31,7 +32,7 @@ namespace Dalamud.Game.Internal.Gui.Structs
/// The interop listing data.
/// The DataManager instance.
/// The SeStringManager instance.
- internal PartyFinderListing(PartyFinder.Listing listing, DataManager dataManager, SeStringManager seStringManager)
+ internal PartyFinderListing(PartyFinderPacketListing listing, DataManager dataManager, SeStringManager seStringManager)
{
this.objective = listing.Objective;
this.conditions = listing.Conditions;
@@ -48,7 +49,7 @@ namespace Dalamud.Game.Internal.Gui.Structs
this.World = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.World));
this.HomeWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.HomeWorld));
this.CurrentWorld = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.CurrentWorld));
- this.Category = (Category)listing.Category;
+ this.Category = (DutyFinderCategory)listing.Category;
this.RawDuty = listing.Duty;
this.Duty = new Lazy(() => dataManager.GetExcelSheet().GetRow(listing.Duty));
this.DutyType = (DutyType)listing.DutyType;
@@ -103,7 +104,7 @@ namespace Dalamud.Game.Internal.Gui.Structs
///
/// Gets the Party Finder category this listing is listed under.
///
- public Category Category { get; }
+ public DutyFinderCategory Category { get; }
///
/// Gets the row ID of the duty this listing is for. May be 0 for non-duty listings.
@@ -154,12 +155,12 @@ namespace Dalamud.Game.Internal.Gui.Structs
///
/// Gets the objective of this listing.
///
- public ObjectiveFlags Objective => (ObjectiveFlags)this.objective;
+ public DutyFinderObjectiveFlags Objective => (DutyFinderObjectiveFlags)this.objective;
///
/// Gets the conditions of this listing.
///
- public ConditionFlags Conditions => (ConditionFlags)this.conditions;
+ public DutyFinderConditionFlags Conditions => (DutyFinderConditionFlags)this.conditions;
///
/// Gets the Duty Finder settings that will be used for this listing.
@@ -169,13 +170,13 @@ namespace Dalamud.Game.Internal.Gui.Structs
///
/// Gets the loot rules that will be used for this listing.
///
- public LootRuleFlags LootRules => (LootRuleFlags)this.lootRules;
+ public DutyFinderLootRuleFlags LootRules => (DutyFinderLootRuleFlags)this.lootRules;
///
/// Gets where this listing is searching. Note that this is also used for denoting alliance raid listings and one
/// player per job.
///
- public SearchAreaFlags SearchArea => (SearchAreaFlags)this.searchArea;
+ public DutyFinderSearchAreaFlags SearchArea => (DutyFinderSearchAreaFlags)this.searchArea;
///
/// Gets a list of the class/job IDs that are currently present in the party.
@@ -194,14 +195,14 @@ namespace Dalamud.Game.Internal.Gui.Structs
///
/// The flag to check for.
/// A value indicating whether the flag is present.
- public bool this[ObjectiveFlags flag] => this.objective == 0 || (this.objective & (uint)flag) > 0;
+ public bool this[DutyFinderObjectiveFlags flag] => this.objective == 0 || (this.objective & (uint)flag) > 0;
///
/// Check if the given flag is present.
///
/// The flag to check for.
/// A value indicating whether the flag is present.
- public bool this[ConditionFlags flag] => this.conditions == 0 || (this.conditions & (uint)flag) > 0;
+ public bool this[DutyFinderConditionFlags flag] => this.conditions == 0 || (this.conditions & (uint)flag) > 0;
///
/// Check if the given flag is present.
@@ -215,14 +216,14 @@ namespace Dalamud.Game.Internal.Gui.Structs
///
/// The flag to check for.
/// A value indicating whether the flag is present.
- public bool this[LootRuleFlags flag] => this.lootRules == 0 || (this.lootRules & (uint)flag) > 0;
+ public bool this[DutyFinderLootRuleFlags flag] => this.lootRules == 0 || (this.lootRules & (uint)flag) > 0;
///
/// Check if the given flag is present.
///
/// The flag to check for.
/// A value indicating whether the flag is present.
- public bool this[SearchAreaFlags flag] => this.searchArea == 0 || (this.searchArea & (uint)flag) > 0;
+ public bool this[DutyFinderSearchAreaFlags flag] => this.searchArea == 0 || (this.searchArea & (uint)flag) > 0;
#endregion
diff --git a/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListingEventArgs.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListingEventArgs.cs
new file mode 100644
index 000000000..ff6bd607d
--- /dev/null
+++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderListingEventArgs.cs
@@ -0,0 +1,27 @@
+namespace Dalamud.Game.Gui.PartyFinder.Types
+{
+ ///
+ /// This class represents additional arguments passed by the game.
+ ///
+ public class PartyFinderListingEventArgs
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The batch number.
+ internal PartyFinderListingEventArgs(int batchNumber)
+ {
+ this.BatchNumber = batchNumber;
+ }
+
+ ///
+ /// Gets the batch number.
+ ///
+ public int BatchNumber { get; }
+
+ ///
+ /// Gets or sets a value indicating whether the listing is visible.
+ ///
+ public bool Visible { get; set; } = true;
+ }
+}
diff --git a/Dalamud/Game/Internal/Gui/Structs/PartyFinderSlot.cs b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs
similarity index 97%
rename from Dalamud/Game/Internal/Gui/Structs/PartyFinderSlot.cs
rename to Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs
index 02b549842..d740c0c0a 100644
--- a/Dalamud/Game/Internal/Gui/Structs/PartyFinderSlot.cs
+++ b/Dalamud/Game/Gui/PartyFinder/Types/PartyFinderSlot.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
-namespace Dalamud.Game.Internal.Gui.Structs
+namespace Dalamud.Game.Gui.PartyFinder.Types
{
///
/// A player slot in a Party Finder listing.
diff --git a/Dalamud/Game/Internal/Gui/Toast/QuestToastOptions.cs b/Dalamud/Game/Gui/Toast/QuestToastOptions.cs
old mode 100755
new mode 100644
similarity index 96%
rename from Dalamud/Game/Internal/Gui/Toast/QuestToastOptions.cs
rename to Dalamud/Game/Gui/Toast/QuestToastOptions.cs
index 34fa674e7..11f09a523
--- a/Dalamud/Game/Internal/Gui/Toast/QuestToastOptions.cs
+++ b/Dalamud/Game/Gui/Toast/QuestToastOptions.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui.Toast
+namespace Dalamud.Game.Gui.Toast
{
///
/// This class represents options that can be used with the class for the quest toast variant.
diff --git a/Dalamud/Game/Internal/Gui/Toast/QuestToastPosition.cs b/Dalamud/Game/Gui/Toast/QuestToastPosition.cs
old mode 100755
new mode 100644
similarity index 92%
rename from Dalamud/Game/Internal/Gui/Toast/QuestToastPosition.cs
rename to Dalamud/Game/Gui/Toast/QuestToastPosition.cs
index a6ea499b1..cc107ab6e
--- a/Dalamud/Game/Internal/Gui/Toast/QuestToastPosition.cs
+++ b/Dalamud/Game/Gui/Toast/QuestToastPosition.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui.Toast
+namespace Dalamud.Game.Gui.Toast
{
///
/// The alignment of native quest toast windows.
diff --git a/Dalamud/Game/Internal/Gui/Toast/ToastOptions.cs b/Dalamud/Game/Gui/Toast/ToastOptions.cs
old mode 100755
new mode 100644
similarity index 92%
rename from Dalamud/Game/Internal/Gui/Toast/ToastOptions.cs
rename to Dalamud/Game/Gui/Toast/ToastOptions.cs
index 5be757393..0939bb5bb
--- a/Dalamud/Game/Internal/Gui/Toast/ToastOptions.cs
+++ b/Dalamud/Game/Gui/Toast/ToastOptions.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui.Toast
+namespace Dalamud.Game.Gui.Toast
{
///
/// This class represents options that can be used with the class.
diff --git a/Dalamud/Game/Internal/Gui/Toast/ToastPosition.cs b/Dalamud/Game/Gui/Toast/ToastPosition.cs
old mode 100755
new mode 100644
similarity index 89%
rename from Dalamud/Game/Internal/Gui/Toast/ToastPosition.cs
rename to Dalamud/Game/Gui/Toast/ToastPosition.cs
index 4c01cb709..14f489711
--- a/Dalamud/Game/Internal/Gui/Toast/ToastPosition.cs
+++ b/Dalamud/Game/Gui/Toast/ToastPosition.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui.Toast
+namespace Dalamud.Game.Gui.Toast
{
///
/// The positioning of native toast windows.
diff --git a/Dalamud/Game/Internal/Gui/Toast/ToastSpeed.cs b/Dalamud/Game/Gui/Toast/ToastSpeed.cs
old mode 100755
new mode 100644
similarity index 90%
rename from Dalamud/Game/Internal/Gui/Toast/ToastSpeed.cs
rename to Dalamud/Game/Gui/Toast/ToastSpeed.cs
index 620c65301..0f54df273
--- a/Dalamud/Game/Internal/Gui/Toast/ToastSpeed.cs
+++ b/Dalamud/Game/Gui/Toast/ToastSpeed.cs
@@ -1,4 +1,4 @@
-namespace Dalamud.Game.Internal.Gui.Toast
+namespace Dalamud.Game.Gui.Toast
{
///
/// The speed at which native toast windows will persist.
diff --git a/Dalamud/Game/Internal/Gui/ToastGui.cs b/Dalamud/Game/Gui/ToastGui.cs
old mode 100755
new mode 100644
similarity index 99%
rename from Dalamud/Game/Internal/Gui/ToastGui.cs
rename to Dalamud/Game/Gui/ToastGui.cs
index 4c1ce497f..c16066a09
--- a/Dalamud/Game/Internal/Gui/ToastGui.cs
+++ b/Dalamud/Game/Gui/ToastGui.cs
@@ -2,11 +2,11 @@ using System;
using System.Collections.Generic;
using System.Text;
-using Dalamud.Game.Internal.Gui.Toast;
+using Dalamud.Game.Gui.Toast;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Hooking;
-namespace Dalamud.Game.Internal.Gui
+namespace Dalamud.Game.Gui
{
///
/// This class facilitates interacting with and creating native toast windows.
diff --git a/Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs b/Dalamud/Game/Gui/ToastGuiAddressResolver.cs
old mode 100755
new mode 100644
similarity index 95%
rename from Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs
rename to Dalamud/Game/Gui/ToastGuiAddressResolver.cs
index 93b8eba04..adf5e3190
--- a/Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs
+++ b/Dalamud/Game/Gui/ToastGuiAddressResolver.cs
@@ -1,6 +1,8 @@
using System;
-namespace Dalamud.Game.Internal.Gui
+using Dalamud.Game.Internal;
+
+namespace Dalamud.Game.Gui
{
///
/// An address resolver for the class.
diff --git a/Dalamud/Game/Internal/AntiDebug.cs b/Dalamud/Game/Internal/AntiDebug.cs
index 57c7fdeb4..59e2a1df4 100644
--- a/Dalamud/Game/Internal/AntiDebug.cs
+++ b/Dalamud/Game/Internal/AntiDebug.cs
@@ -8,7 +8,7 @@ namespace Dalamud.Game.Internal
///
/// This class disables anti-debug functionality in the game client.
///
- public sealed partial class AntiDebug
+ internal sealed partial class AntiDebug
{
private readonly byte[] nop = new byte[] { 0x31, 0xC0, 0x90, 0x90, 0x90, 0x90 };
private byte[] original;
@@ -79,7 +79,7 @@ namespace Dalamud.Game.Internal
///
/// Implementing IDisposable.
///
- public sealed partial class AntiDebug : IDisposable
+ internal sealed partial class AntiDebug : IDisposable
{
private bool disposed = false;
diff --git a/Dalamud/Game/Addon/DalamudSystemMenu.cs b/Dalamud/Game/Internal/DalamudSystemMenu.cs
similarity index 99%
rename from Dalamud/Game/Addon/DalamudSystemMenu.cs
rename to Dalamud/Game/Internal/DalamudSystemMenu.cs
index e735b6154..673bcb55b 100644
--- a/Dalamud/Game/Addon/DalamudSystemMenu.cs
+++ b/Dalamud/Game/Internal/DalamudSystemMenu.cs
@@ -8,7 +8,7 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
-namespace Dalamud.Game.Addon
+namespace Dalamud.Game.Internal
{
///
/// This class implements in-game Dalamud options in the in-game System menu.
diff --git a/Dalamud/Game/Internal/Gui/Structs/Addon.cs b/Dalamud/Game/Internal/Gui/Structs/Addon.cs
deleted file mode 100644
index 57595a2c7..000000000
--- a/Dalamud/Game/Internal/Gui/Structs/Addon.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System.Runtime.InteropServices;
-
-using FFXIVClientStructs.FFXIV.Component.GUI;
-
-namespace Dalamud.Game.Internal.Gui.Structs
-{
- ///
- /// Native memory representation of an FFXIV UI addon.
- ///
- [StructLayout(LayoutKind.Explicit)]
- public struct Addon
- {
- ///
- /// The name of the addon.
- ///
- [FieldOffset(AddonOffsets.Name)]
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
- public string Name;
-
- ///
- /// Various flags that can be set on the addon.
- ///
- ///
- /// This is a bitfield.
- ///
- [FieldOffset(AddonOffsets.Flags)]
- public byte Flags;
-
- ///
- /// The X position of the addon on screen.
- ///
- [FieldOffset(AddonOffsets.X)]
- public short X;
-
- ///
- /// The Y position of the addon on screen.
- ///
- [FieldOffset(AddonOffsets.Y)]
- public short Y;
-
- ///
- /// The scale of the addon.
- ///
- [FieldOffset(AddonOffsets.Scale)]
- public float Scale;
-
- ///
- /// The root node of the addon's node tree.
- ///
- [FieldOffset(AddonOffsets.RootNode)]
- public unsafe AtkResNode* RootNode;
- }
-
- ///
- /// Memory offsets for the type.
- ///
- public static class AddonOffsets
- {
- public const int Name = 0x8;
- public const int RootNode = 0xC8;
- public const int Flags = 0x182;
- public const int X = 0x1BC;
- public const int Y = 0x1BE;
- public const int Scale = 0x1AC;
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/Structs/PartyFinder.cs b/Dalamud/Game/Internal/Gui/Structs/PartyFinder.cs
deleted file mode 100755
index 8fe3204b0..000000000
--- a/Dalamud/Game/Internal/Gui/Structs/PartyFinder.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-using System.Linq;
-using System.Runtime.InteropServices;
-
-namespace Dalamud.Game.Internal.Gui.Structs
-{
- ///
- /// PartyFinder related network structs and static constants.
- ///
- internal static class PartyFinder
- {
- ///
- /// The structure of the PartyFinder packet.
- ///
- [StructLayout(LayoutKind.Sequential)]
- internal readonly struct Packet
- {
- internal readonly int BatchNumber;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- private readonly byte[] padding1;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- internal readonly Listing[] Listings;
- }
-
- ///
- /// The structure of an individual listing within a packet.
- ///
- [StructLayout(LayoutKind.Sequential)]
- internal readonly struct Listing
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- private readonly byte[] header1;
-
- internal readonly uint Id;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
- private readonly byte[] header2;
-
- internal readonly uint ContentIdLower;
- private readonly ushort unknownShort1;
- private readonly ushort unknownShort2;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
- private readonly byte[] header3;
-
- internal readonly byte Category;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
- private readonly byte[] header4;
-
- internal readonly ushort Duty;
- internal readonly byte DutyType;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
- private readonly byte[] header5;
-
- internal readonly ushort World;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- private readonly byte[] header6;
-
- internal readonly byte Objective;
- internal readonly byte BeginnersWelcome;
- internal readonly byte Conditions;
- internal readonly byte DutyFinderSettings;
- internal readonly byte LootRules;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
- private readonly byte[] header7; // all zero in every pf I've examined
-
- private readonly uint lastPatchHotfixTimestamp; // last time the servers were restarted?
- internal readonly ushort SecondsRemaining;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
- private readonly byte[] header8; // 00 00 01 00 00 00 in every pf I've examined
-
- internal readonly ushort MinimumItemLevel;
- internal readonly ushort HomeWorld;
- internal readonly ushort CurrentWorld;
-
- private readonly byte header9;
-
- internal readonly byte NumSlots;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
- private readonly byte[] header10;
-
- internal readonly byte SearchArea;
-
- private readonly byte header11;
-
- internal readonly byte NumParties;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
- private readonly byte[] header12; // 00 00 00 always. maybe numParties is a u32?
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- internal readonly uint[] Slots;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- internal readonly byte[] JobsPresent;
-
- // Note that ByValTStr will not work here because the strings are UTF-8 and there's only a CharSet for UTF-16 in C#.
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- internal readonly byte[] Name;
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 192)]
- internal readonly byte[] Description;
-
- internal bool IsNull()
- {
- // a valid party finder must have at least one slot set
- return this.Slots.All(slot => slot == 0);
- }
- }
-
- ///
- /// PartyFinder packet constants.
- ///
- public static class PacketInfo
- {
- ///
- /// The size of the PartyFinder packet.
- ///
- public static readonly int PacketSize = Marshal.SizeOf();
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Gui/Structs/PartyFinderTypes.cs b/Dalamud/Game/Internal/Gui/Structs/PartyFinderTypes.cs
deleted file mode 100644
index 7482b3ba3..000000000
--- a/Dalamud/Game/Internal/Gui/Structs/PartyFinderTypes.cs
+++ /dev/null
@@ -1,397 +0,0 @@
-using System;
-
-using Dalamud.Data;
-using Lumina.Excel.GeneratedSheets;
-
-namespace Dalamud.Game.Internal.Gui.Structs
-{
- ///
- /// Search area flags for the class.
- ///
- [Flags]
- public enum SearchAreaFlags : uint
- {
- ///
- /// Datacenter.
- ///
- DataCentre = 1 << 0,
-
- ///
- /// Private.
- ///
- Private = 1 << 1,
-
- ///
- /// Alliance raid.
- ///
- AllianceRaid = 1 << 2,
-
- ///
- /// World.
- ///
- World = 1 << 3,
-
- ///
- /// One player per job.
- ///
- OnePlayerPerJob = 1 << 5,
- }
-
- ///
- /// Job flags for the class.
- ///
- [Flags]
- public enum JobFlags
- {
- ///
- /// Gladiator (GLD).
- ///
- Gladiator = 1 << 1,
-
- ///
- /// Pugilist (PGL).
- ///
- Pugilist = 1 << 2,
-
- ///
- /// Marauder (MRD).
- ///
- Marauder = 1 << 3,
-
- ///
- /// Lancer (LNC).
- ///
- Lancer = 1 << 4,
-
- ///
- /// Archer (ARC).
- ///
- Archer = 1 << 5,
-
- ///
- /// Conjurer (CNJ).
- ///
- Conjurer = 1 << 6,
-
- ///
- /// Thaumaturge (THM).
- ///
- Thaumaturge = 1 << 7,
-
- ///
- /// Paladin (PLD).
- ///
- Paladin = 1 << 8,
-
- ///
- /// Monk (MNK).
- ///
- Monk = 1 << 9,
-
- ///
- /// Warrior (WAR).
- ///
- Warrior = 1 << 10,
-
- ///
- /// Dragoon (DRG).
- ///
- Dragoon = 1 << 11,
-
- ///
- /// Bard (BRD).
- ///
- Bard = 1 << 12,
-
- ///
- /// White mage (WHM).
- ///
- WhiteMage = 1 << 13,
-
- ///
- /// Black mage (BLM).
- ///
- BlackMage = 1 << 14,
-
- ///
- /// Arcanist (ACN).
- ///
- Arcanist = 1 << 15,
-
- ///
- /// Summoner (SMN).
- ///
- Summoner = 1 << 16,
-
- ///
- /// Scholar (SCH).
- ///
- Scholar = 1 << 17,
-
- ///
- /// Rogue (ROG).
- ///
- Rogue = 1 << 18,
-
- ///
- /// Ninja (NIN).
- ///
- Ninja = 1 << 19,
-
- ///
- /// Machinist (MCH).
- ///
- Machinist = 1 << 20,
-
- ///
- /// Dark Knight (DRK).
- ///
- DarkKnight = 1 << 21,
-
- ///
- /// Astrologian (AST).
- ///
- Astrologian = 1 << 22,
-
- ///
- /// Samurai (SAM).
- ///
- Samurai = 1 << 23,
-
- ///
- /// Red mage (RDM).
- ///
- RedMage = 1 << 24,
-
- ///
- /// Blue mage (BLM).
- ///
- BlueMage = 1 << 25,
-
- ///
- /// Gunbreaker (GNB).
- ///
- Gunbreaker = 1 << 26,
-
- ///
- /// Dancer (DNC).
- ///
- Dancer = 1 << 27,
- }
-
- ///
- /// Objective flags for the class.
- ///
- [Flags]
- public enum ObjectiveFlags : uint
- {
- ///
- /// No objective.
- ///
- None = 0,
-
- ///
- /// The duty completion objective.
- ///
- DutyCompletion = 1,
-
- ///
- /// The practice objective.
- ///
- Practice = 2,
-
- ///
- /// The loot objective.
- ///
- Loot = 4,
- }
-
- ///
- /// Condition flags for the class.
- ///
- [Flags]
- public enum ConditionFlags : uint
- {
- ///
- /// No duty condition.
- ///
- None = 1,
-
- ///
- /// The duty complete condition.
- ///
- DutyComplete = 2,
-
- ///
- /// The duty incomplete condition.
- ///
- DutyIncomplete = 4,
- }
-
- ///
- /// Duty finder settings flags for the class.
- ///
- [Flags]
- public enum DutyFinderSettingsFlags : uint
- {
- ///
- /// No duty finder settings.
- ///
- None = 0,
-
- ///
- /// The undersized party setting.
- ///
- UndersizedParty = 1 << 0,
-
- ///
- /// The minimum item level setting.
- ///
- MinimumItemLevel = 1 << 1,
-
- ///
- /// The silence echo setting.
- ///
- SilenceEcho = 1 << 2,
- }
-
- ///
- /// Loot rule flags for the class.
- ///
- [Flags]
- public enum LootRuleFlags : uint
- {
- ///
- /// No loot rules.
- ///
- None = 0,
-
- ///
- /// The greed only rule.
- ///
- GreedOnly = 1,
-
- ///
- /// The lootmaster rule.
- ///
- Lootmaster = 2,
- }
-
- ///
- /// Category flags for the class.
- ///
- public enum Category
- {
- ///
- /// The duty category.
- ///
- Duty = 0,
-
- ///
- /// The quest battle category.
- ///
- QuestBattles = 1 << 0,
-
- ///
- /// The fate category.
- ///
- Fates = 1 << 1,
-
- ///
- /// The treasure hunt category.
- ///
- TreasureHunt = 1 << 2,
-
- ///
- /// The hunt category.
- ///
- TheHunt = 1 << 3,
-
- ///
- /// The gathering forays category.
- ///
- GatheringForays = 1 << 4,
-
- ///
- /// The deep dungeons category.
- ///
- DeepDungeons = 1 << 5,
-
- ///
- /// The adventuring forays category.
- ///
- AdventuringForays = 1 << 6,
- }
-
- ///
- /// Duty type flags for the class.
- ///
- public enum DutyType
- {
- ///
- /// No duty type.
- ///
- Other = 0,
-
- ///
- /// The roulette duty type.
- ///
- Roulette = 1 << 0,
-
- ///
- /// The normal duty type.
- ///
- Normal = 1 << 1,
- }
-
- ///
- /// Extensions for the enum.
- ///
- public static class JobFlagsExt
- {
- ///
- /// Get the actual ClassJob from the in-game sheets for this JobFlags.
- ///
- /// A JobFlags enum member.
- /// A DataManager to get the ClassJob from.
- /// A ClassJob if found or null if not.
- public static ClassJob ClassJob(this JobFlags job, DataManager data)
- {
- var jobs = data.GetExcelSheet();
-
- uint? row = job switch
- {
- JobFlags.Gladiator => 1,
- JobFlags.Pugilist => 2,
- JobFlags.Marauder => 3,
- JobFlags.Lancer => 4,
- JobFlags.Archer => 5,
- JobFlags.Conjurer => 6,
- JobFlags.Thaumaturge => 7,
- JobFlags.Paladin => 19,
- JobFlags.Monk => 20,
- JobFlags.Warrior => 21,
- JobFlags.Dragoon => 22,
- JobFlags.Bard => 23,
- JobFlags.WhiteMage => 24,
- JobFlags.BlackMage => 25,
- JobFlags.Arcanist => 26,
- JobFlags.Summoner => 27,
- JobFlags.Scholar => 28,
- JobFlags.Rogue => 29,
- JobFlags.Ninja => 30,
- JobFlags.Machinist => 31,
- JobFlags.DarkKnight => 32,
- JobFlags.Astrologian => 33,
- JobFlags.Samurai => 34,
- JobFlags.RedMage => 35,
- JobFlags.BlueMage => 36,
- JobFlags.Gunbreaker => 37,
- JobFlags.Dancer => 38,
- _ => null,
- };
-
- return row == null ? null : jobs.GetRow((uint)row);
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Resource/ResourceManager.cs b/Dalamud/Game/Internal/Resource/ResourceManager.cs
deleted file mode 100644
index 7e3c2b045..000000000
--- a/Dalamud/Game/Internal/Resource/ResourceManager.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.InteropServices;
-
-using Dalamud.Hooking;
-using Serilog;
-
-namespace Dalamud.Game.Internal.File
-{
- ///
- /// This class facilitates modifying how the game loads resources from disk.
- ///
- public class ResourceManager
- {
- private readonly Dalamud dalamud;
- private readonly ResourceManagerAddressResolver address;
- private readonly Hook getResourceAsyncHook;
- private readonly Hook getResourceSyncHook;
-
- private Dictionary resourceHookMap = new();
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The Dalamud instance.
- /// The SigScanner instance.
- internal ResourceManager(Dalamud dalamud, SigScanner scanner)
- {
- this.dalamud = dalamud;
- this.address = new ResourceManagerAddressResolver();
- this.address.Setup(scanner);
-
- Log.Verbose("===== R E S O U R C E M A N A G E R =====");
- Log.Verbose("GetResourceAsync address {GetResourceAsync}", this.address.GetResourceAsync);
- Log.Verbose("GetResourceSync address {GetResourceSync}", this.address.GetResourceSync);
-
- this.getResourceAsyncHook = new Hook(this.address.GetResourceAsync, this.GetResourceAsyncDetour);
- this.getResourceSyncHook = new Hook(this.address.GetResourceSync, this.GetResourceSyncDetour);
- }
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetResourceAsyncDelegate(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pathPtr, IntPtr a6, byte a7);
-
- [UnmanagedFunctionPointer(CallingConvention.ThisCall)]
- private delegate IntPtr GetResourceSyncDelegate(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pathPtr, IntPtr a6);
-
- ///
- /// Check if a filepath has any invalid characters.
- ///
- /// The filepath to check.
- /// A value indicating whether the filepath is safe to use.
- public static bool FilePathHasInvalidChars(string path)
- {
- return !string.IsNullOrEmpty(path) && path.IndexOfAny(Path.GetInvalidPathChars()) >= 0;
- }
-
- ///
- /// Enable this module.
- ///
- public void Enable()
- {
- this.getResourceAsyncHook.Enable();
- this.getResourceSyncHook.Enable();
- }
-
- ///
- /// Dispose of managed and unmanaged resources.
- ///
- public void Dispose()
- {
- this.getResourceAsyncHook.Dispose();
- this.getResourceSyncHook.Dispose();
- }
-
- private IntPtr GetResourceAsyncDetour(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pathPtr, IntPtr a6, byte a7)
- {
- try
- {
- var path = Marshal.PtrToStringAnsi(pathPtr);
-
- var resourceHandle = this.getResourceAsyncHook.Original(manager, a2, a3, a4, IntPtr.Zero, a6, a7);
- // var resourceHandle = IntPtr.Zero;
-
- Log.Verbose("GetResourceAsync CALL - this:{0} a2:{1} a3:{2} a4:{3} a5:{4} a6:{5} a7:{6} => RET:{7}", manager, a2, a3, a4, pathPtr, a6, a7, resourceHandle);
-
- Log.Verbose($"->{path}");
-
- this.HandleGetResourceHookAcquire(resourceHandle, path);
-
- return resourceHandle;
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception on ReadResourceAsync hook.");
-
- return this.getResourceAsyncHook.Original(manager, a2, a3, a4, pathPtr, a6, a7);
- }
- }
-
- private IntPtr GetResourceSyncDetour(IntPtr manager, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr pathPtr, IntPtr a6)
- {
- try
- {
- var resourceHandle = this.getResourceSyncHook.Original(manager, a2, a3, a4, pathPtr, a6);
-
- Log.Verbose("GetResourceSync CALL - this:{0} a2:{1} a3:{2} a4:{3} a5:{4} a6:{5} => RET:{6}", manager, a2, a3, a4, pathPtr, a6, resourceHandle);
-
- var path = Marshal.PtrToStringAnsi(pathPtr);
-
- Log.Verbose($"->{path}");
-
- this.HandleGetResourceHookAcquire(resourceHandle, path);
-
- return resourceHandle;
- }
- catch (Exception ex)
- {
- Log.Error(ex, "Exception on ReadResourceSync hook.");
-
- return this.getResourceSyncHook.Original(manager, a2, a3, a4, pathPtr, a6);
- }
- }
-
- private void HandleGetResourceHookAcquire(IntPtr handlePtr, string path)
- {
- if (FilePathHasInvalidChars(path))
- return;
-
- if (this.resourceHookMap.ContainsKey(handlePtr))
- {
- Log.Verbose($"-> Handle {handlePtr.ToInt64():X}({path}) was cached!");
- return;
- }
-
- var hookInfo = new ResourceHandleHookInfo
- {
- Path = path,
- };
-
- var hookPath = Path.Combine(this.dalamud.StartInfo.WorkingDirectory, "ResourceHook", path);
-
- if (System.IO.File.Exists(hookPath))
- {
- hookInfo.DetourFile = new FileStream(hookPath, FileMode.Open);
- Log.Verbose("-> Added resource hook detour at {0}", hookPath);
- }
-
- this.resourceHookMap.Add(handlePtr, hookInfo);
- }
-
- private class ResourceHandleHookInfo
- {
- public string Path { get; set; }
-
- public Stream DetourFile { get; set; }
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs b/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs
deleted file mode 100644
index b92ea8209..000000000
--- a/Dalamud/Game/Internal/Resource/ResourceManagerAddressResolver.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-namespace Dalamud.Game.Internal.File
-{
- ///
- /// The address resolver for the class.
- ///
- internal class ResourceManagerAddressResolver : BaseAddressResolver
- {
- ///
- /// Gets the address of the GetResourceAsync method.
- ///
- public IntPtr GetResourceAsync { get; private set; }
-
- ///
- /// Gets the address of the GetResourceSync method.
- ///
- public IntPtr GetResourceSync { get; private set; }
-
- ///
- protected override void Setup64Bit(SigScanner sig)
- {
- this.GetResourceAsync = sig.ScanText("48 89 5C 24 08 48 89 54 24 10 57 48 83 EC 20 B8 03 00 00 00 48 8B F9 86 82 A1 00 00 00 48 8B 5C 24 38 B8 01 00 00 00 87 83 90 00 00 00 85 C0 74");
- this.GetResourceSync = sig.ScanText("48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 30 48 8B F9 49 8B E9 48 83 C1 30 4D 8B F0 4C 8B EA FF 15 CE F6");
- // ReadResourceSync = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05");
- }
- }
-}
diff --git a/Dalamud/Game/Internal/Libc/LibcFunction.cs b/Dalamud/Game/Libc/LibcFunction.cs
similarity index 98%
rename from Dalamud/Game/Internal/Libc/LibcFunction.cs
rename to Dalamud/Game/Libc/LibcFunction.cs
index 33990caae..cfab061c3 100644
--- a/Dalamud/Game/Internal/Libc/LibcFunction.cs
+++ b/Dalamud/Game/Libc/LibcFunction.cs
@@ -2,7 +2,7 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
-namespace Dalamud.Game.Internal.Libc
+namespace Dalamud.Game.Libc
{
///
/// This class handles creating cstrings utilizing native game methods.
diff --git a/Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs b/Dalamud/Game/Libc/LibcFunctionAddressResolver.cs
similarity index 94%
rename from Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs
rename to Dalamud/Game/Libc/LibcFunctionAddressResolver.cs
index b96a37493..4d30a1e74 100644
--- a/Dalamud/Game/Internal/Libc/LibcFunctionAddressResolver.cs
+++ b/Dalamud/Game/Libc/LibcFunctionAddressResolver.cs
@@ -1,6 +1,8 @@
using System;
-namespace Dalamud.Game.Internal.Libc
+using Dalamud.Game.Internal;
+
+namespace Dalamud.Game.Libc
{
///
/// The address resolver for the class.
diff --git a/Dalamud/Game/Internal/Libc/OwnedStdString.cs b/Dalamud/Game/Libc/OwnedStdString.cs
similarity index 98%
rename from Dalamud/Game/Internal/Libc/OwnedStdString.cs
rename to Dalamud/Game/Libc/OwnedStdString.cs
index 7969e4947..1939e068e 100644
--- a/Dalamud/Game/Internal/Libc/OwnedStdString.cs
+++ b/Dalamud/Game/Libc/OwnedStdString.cs
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Dalamud.Game.Internal.Libc
+namespace Dalamud.Game.Libc
{
///
/// An address wrapper around the class.
diff --git a/Dalamud/Game/Internal/Libc/StdString.cs b/Dalamud/Game/Libc/StdString.cs
similarity index 98%
rename from Dalamud/Game/Internal/Libc/StdString.cs
rename to Dalamud/Game/Libc/StdString.cs
index 9b627c88d..4d4478687 100644
--- a/Dalamud/Game/Internal/Libc/StdString.cs
+++ b/Dalamud/Game/Libc/StdString.cs
@@ -2,7 +2,7 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
-namespace Dalamud.Game.Internal.Libc
+namespace Dalamud.Game.Libc
{
///
/// Interation with std::string.
diff --git a/Dalamud/Game/Internal/Network/GameNetwork.cs b/Dalamud/Game/Network/GameNetwork.cs
similarity index 98%
rename from Dalamud/Game/Internal/Network/GameNetwork.cs
rename to Dalamud/Game/Network/GameNetwork.cs
index dff3ac535..0b982b2b0 100644
--- a/Dalamud/Game/Internal/Network/GameNetwork.cs
+++ b/Dalamud/Game/Network/GameNetwork.cs
@@ -6,18 +6,13 @@ using Dalamud.Game.Network;
using Dalamud.Hooking;
using Serilog;
-namespace Dalamud.Game.Internal.Network
+namespace Dalamud.Game.Network
{
///
/// This class handles interacting with game network events.
///
public sealed class GameNetwork : IDisposable
{
- ///
- /// Event that is called when a network message is sent/received.
- ///
- public OnNetworkMessageDelegate OnNetworkMessage;
-
private readonly GameNetworkAddressResolver address;
private readonly Hook processZonePacketDownHook;
private readonly Hook processZonePacketUpHook;
@@ -58,6 +53,11 @@ namespace Dalamud.Game.Internal.Network
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate byte ProcessZonePacketUpDelegate(IntPtr a1, IntPtr dataPtr, IntPtr a3, byte a4);
+ ///
+ /// Event that is called when a network message is sent/received.
+ ///
+ public event OnNetworkMessageDelegate OnNetworkMessage;
+
///
/// Enable this module.
///
diff --git a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs b/Dalamud/Game/Network/GameNetworkAddressResolver.cs
similarity index 95%
rename from Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs
rename to Dalamud/Game/Network/GameNetworkAddressResolver.cs
index 9c5eb00fc..130986197 100644
--- a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs
+++ b/Dalamud/Game/Network/GameNetworkAddressResolver.cs
@@ -1,6 +1,8 @@
using System;
-namespace Dalamud.Game.Internal.Network
+using Dalamud.Game.Internal;
+
+namespace Dalamud.Game.Network
{
///
/// The address resolver for the class.
diff --git a/Dalamud/Game/Position3.cs b/Dalamud/Game/Position3.cs
index 3812376df..ed477d511 100644
--- a/Dalamud/Game/Position3.cs
+++ b/Dalamud/Game/Position3.cs
@@ -23,6 +23,19 @@ namespace Dalamud.Game
///
public float Y;
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The X position.
+ /// The Z position.
+ /// The Y position.
+ public Position3(float x, float z, float y)
+ {
+ this.X = x;
+ this.Z = z;
+ this.Y = y;
+ }
+
///
/// Convert this Position3 to a System.Numerics.Vector3.
///
diff --git a/Dalamud/Game/Text/SeStringHandling/Payload.cs b/Dalamud/Game/Text/SeStringHandling/Payload.cs
index ebf689646..3ace4ebf1 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payload.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using Dalamud.Data;
@@ -21,15 +22,15 @@ namespace Dalamud.Game.Text.SeStringHandling
///
public abstract partial class Payload
{
- ///
- /// The Lumina instance to use for any necessary data lookups.
- ///
- public DataManager DataResolver;
-
- // private for now, since subclasses shouldn't interact with this
+ // private for now, since subclasses shouldn't interact with this.
// To force-invalidate it, Dirty can be set to true
private byte[] encodedData;
+ ///
+ /// Gets or sets the Lumina instance to use for any necessary data lookups.
+ ///
+ public DataManager DataResolver { get; set; }
+
///
/// Gets the type of this payload.
///
@@ -233,11 +234,13 @@ namespace Dalamud.Game.Text.SeStringHandling
///
/// The start byte of a payload.
///
+ [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "This is prefered.")]
protected const byte START_BYTE = 0x02;
///
/// The end byte of a payload.
///
+ [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "This is prefered.")]
protected const byte END_BYTE = 0x03;
///
diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/IconPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/IconPayload.cs
index e526d9c70..04bcd1029 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/IconPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/IconPayload.cs
@@ -19,17 +19,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
this.Icon = icon;
}
- ///
- /// Initializes a new instance of the class.
- /// Create a Icon payload for the specified icon.
- ///
- /// Index of the icon.
- [Obsolete("IconPayload(uint) is deprecated, please use IconPayload(BitmapFontIcon).")]
- public IconPayload(uint iconIndex)
- : this((BitmapFontIcon)iconIndex)
- {
- }
-
///
/// Initializes a new instance of the class.
/// Create a Icon payload for the specified icon.
@@ -41,12 +30,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
///
public override PayloadType Type => PayloadType.Icon;
- ///
- /// Gets the index of the icon.
- ///
- [Obsolete("Use IconPayload.Icon")]
- public uint IconIndex => (uint)this.Icon;
-
///
/// Gets or sets the icon the payload represents.
///
diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs
index fbcb447c7..a6e6c2e49 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/MapLinkPayload.cs
@@ -222,7 +222,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
var c = scale / 100.0f;
var scaledPos = pos * c / 1000.0f;
- return ((41.0f / c) * ((scaledPos + 1024.0f) / 2048.0f)) + 1.0f;
+ return (41.0f / c * ((scaledPos + 1024.0f) / 2048.0f)) + 1.0f;
}
// Created as the inverse of ConvertRawPositionToMapCoordinate(), since no one seemed to have a version of that
@@ -230,7 +230,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
{
var c = scale / 100.0f;
- var scaledPos = ((((pos - 1.0f) * c / 41.0f) * 2048.0f) - 1024.0f) / c;
+ var scaledPos = (((pos - 1.0f) * c / 41.0f * 2048.0f) - 1024.0f) / c;
scaledPos *= 1000.0f;
return (int)scaledPos;
diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs
index ae3754839..0d80f015d 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/RawPayload.cs
@@ -84,12 +84,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
///
public override int GetHashCode()
{
- // Generated random values.
- var hashCode = 1216194372;
- hashCode = (hashCode * -1521134295) + this.Type.GetHashCode();
- hashCode = (hashCode * -1521134295) + this.chunkType.GetHashCode();
- hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(this.data);
- return hashCode;
+ return HashCode.Combine(this.Type, this.chunkType, this.data);
}
///
diff --git a/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs b/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs
index 9d05fb440..d12bdd3a7 100644
--- a/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs
+++ b/Dalamud/Game/Text/SeStringHandling/Payloads/TextPayload.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -67,7 +68,7 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
// this may change or go away
if (string.IsNullOrEmpty(this.text))
{
- return new byte[] { };
+ return Array.Empty();
}
return Encoding.UTF8.GetBytes(this.text);
diff --git a/Dalamud/Game/Text/XivChatType.cs b/Dalamud/Game/Text/XivChatType.cs
index 9658078f0..d89fc5f0c 100644
--- a/Dalamud/Game/Text/XivChatType.cs
+++ b/Dalamud/Game/Text/XivChatType.cs
@@ -1,6 +1,3 @@
-using System;
-using System.Linq;
-
namespace Dalamud.Game.Text
{
///
@@ -237,77 +234,4 @@ namespace Dalamud.Game.Text
[XivChatTypeInfo("Crossworld Linkshell 8", "cw8", 0xFF1E90FF)]
CrossLinkShell8 = 107,
}
-
- ///
- /// Extension methods for the type.
- ///
- public static class XivChatTypeExtensions
- {
- ///
- /// Get the InfoAttribute associated with this chat type.
- ///
- /// The chat type.
- /// The info attribute.
- public static XivChatTypeInfoAttribute GetDetails(this XivChatType chatType)
- {
- return chatType.GetAttribute();
- }
- }
-
- ///
- /// Storage for relevant information associated with the chat type.
- ///
- public class XivChatTypeInfoAttribute : Attribute
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The fancy name.
- /// The name slug.
- /// The default color.
- internal XivChatTypeInfoAttribute(string fancyName, string slug, uint defaultColor)
- {
- this.FancyName = fancyName;
- this.Slug = slug;
- this.DefaultColor = defaultColor;
- }
-
- ///
- /// Gets the "fancy" name of the type.
- ///
- public string FancyName { get; }
-
- ///
- /// Gets the type name slug or short-form.
- ///
- public string Slug { get; }
-
- ///
- /// Gets the type default color.
- ///
- public uint DefaultColor { get; }
- }
-
- ///
- /// Extension methods for enums.
- ///
- public static class EnumExtensions
- {
- ///
- /// Gets an attribute on an enum.
- ///
- /// The type of attribute to get.
- /// The enum value that has an attached attribute.
- /// The attached attribute, if any.
- public static TAttribute GetAttribute(this Enum value)
- where TAttribute : Attribute
- {
- var type = value.GetType();
- var name = Enum.GetName(type, value);
- return type.GetField(name) // I prefer to get attributes this way
- .GetCustomAttributes(false)
- .OfType()
- .SingleOrDefault();
- }
- }
}
diff --git a/Dalamud/Game/Text/XivChatTypeExtensions.cs b/Dalamud/Game/Text/XivChatTypeExtensions.cs
new file mode 100644
index 000000000..a26687c47
--- /dev/null
+++ b/Dalamud/Game/Text/XivChatTypeExtensions.cs
@@ -0,0 +1,20 @@
+using Dalamud.Utility;
+
+namespace Dalamud.Game.Text
+{
+ ///
+ /// Extension methods for the type.
+ ///
+ public static class XivChatTypeExtensions
+ {
+ ///
+ /// Get the InfoAttribute associated with this chat type.
+ ///
+ /// The chat type.
+ /// The info attribute.
+ public static XivChatTypeInfoAttribute GetDetails(this XivChatType chatType)
+ {
+ return chatType.GetAttribute();
+ }
+ }
+}
diff --git a/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs b/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs
new file mode 100644
index 000000000..e549ac761
--- /dev/null
+++ b/Dalamud/Game/Text/XivChatTypeInfoAttribute.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace Dalamud.Game.Text
+{
+ ///
+ /// Storage for relevant information associated with the chat type.
+ ///
+ [AttributeUsage(AttributeTargets.Field)]
+ public class XivChatTypeInfoAttribute : Attribute
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The fancy name.
+ /// The name slug.
+ /// The default color.
+ internal XivChatTypeInfoAttribute(string fancyName, string slug, uint defaultColor)
+ {
+ this.FancyName = fancyName;
+ this.Slug = slug;
+ this.DefaultColor = defaultColor;
+ }
+
+ ///
+ /// Gets the "fancy" name of the type.
+ ///
+ public string FancyName { get; }
+
+ ///
+ /// Gets the type name slug or short-form.
+ ///
+ public string Slug { get; }
+
+ ///
+ /// Gets the type default color.
+ ///
+ public uint DefaultColor { get; }
+ }
+}
diff --git a/Dalamud/Hooking/Internal/HookInfo.cs b/Dalamud/Hooking/Internal/HookInfo.cs
index c2850b806..73db6864b 100644
--- a/Dalamud/Hooking/Internal/HookInfo.cs
+++ b/Dalamud/Hooking/Internal/HookInfo.cs
@@ -67,7 +67,7 @@ namespace Dalamud.Hooking.Internal
internal Delegate Delegate { get; }
///
- /// Gets the hooked assembly.
+ /// Gets the assembly implementing the hook.
///
internal Assembly Assembly { get; }
}
diff --git a/Dalamud/Interface/FontAwesomeExtensions.cs b/Dalamud/Interface/FontAwesomeExtensions.cs
new file mode 100644
index 000000000..734ec128d
--- /dev/null
+++ b/Dalamud/Interface/FontAwesomeExtensions.cs
@@ -0,0 +1,30 @@
+// Font-Awesome - Version 5.0.9
+
+namespace Dalamud.Interface
+{
+ ///
+ /// Extension methods for .
+ ///
+ public static class FontAwesomeExtensions
+ {
+ ///
+ /// Convert the FontAwesomeIcon to a type.
+ ///
+ /// The icon to convert.
+ /// The converted icon.
+ public static char ToIconChar(this FontAwesomeIcon icon)
+ {
+ return (char)icon;
+ }
+
+ ///
+ /// Conver the FontAwesomeIcon to a type.
+ ///
+ /// The icon to convert.
+ /// The converted icon.
+ public static string ToIconString(this FontAwesomeIcon icon)
+ {
+ return string.Empty + (char)icon;
+ }
+ }
+}
diff --git a/Dalamud/Interface/FontAwesomeIcon.cs b/Dalamud/Interface/FontAwesomeIcon.cs
index a8b93e9e7..c2267766c 100644
--- a/Dalamud/Interface/FontAwesomeIcon.cs
+++ b/Dalamud/Interface/FontAwesomeIcon.cs
@@ -7047,30 +7047,4 @@ namespace Dalamud.Interface
///
Zhihu = 0xF63F,
}
-
- ///
- /// Extension methods for .
- ///
- public static class FontAwesomeExtensions
- {
- ///
- /// Convert the FontAwesomeIcon to a type.
- ///
- /// The icon to convert.
- /// The converted icon.
- public static char ToIconChar(this FontAwesomeIcon icon)
- {
- return (char)icon;
- }
-
- ///
- /// Conver the FontAwesomeIcon to a type.
- ///
- /// The icon to convert.
- /// The converted icon.
- public static string ToIconString(this FontAwesomeIcon icon)
- {
- return string.Empty + (char)icon;
- }
- }
}
diff --git a/Dalamud/Interface/Internal/DalamudCommands.cs b/Dalamud/Interface/Internal/DalamudCommands.cs
index 6e0f5e7a6..1a4f64815 100644
--- a/Dalamud/Interface/Internal/DalamudCommands.cs
+++ b/Dalamud/Interface/Internal/DalamudCommands.cs
@@ -242,7 +242,7 @@ namespace Dalamud.Interface.Internal
if (string.IsNullOrEmpty(arguments))
this.dalamud.DalamudUi.ToggleDataWindow();
else
- this.dalamud.DalamudUi.ToggleDataWindow(arguments);
+ this.dalamud.DalamudUi.OpenDataWindow(arguments);
}
private void OnOpenLog(string command, string arguments)
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index 630f01296..3afcbe331 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -9,6 +9,7 @@ using Dalamud.Interface.Windowing;
using Dalamud.Logging;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal;
+using Dalamud.Utility;
using ImGuiNET;
using Serilog.Events;
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index 825495dd1..1976ac336 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -8,9 +8,11 @@ using System.Threading;
using Dalamud.Game;
using Dalamud.Game.ClientState;
+using Dalamud.Game.ClientState.GamePad;
using Dalamud.Game.Internal.DXGI;
using Dalamud.Hooking;
using Dalamud.Hooking.Internal;
+using Dalamud.Utility;
using ImGuiNET;
using ImGuiScene;
using Serilog;
@@ -322,9 +324,7 @@ namespace Dalamud.Interface.Internal
private static void ShowFontError(string path)
{
- Util.Fatal(
- $"One or more files required by XIVLauncher were not found.\nPlease restart and report this error if it occurs again.\n\n{path}",
- "Error");
+ Util.Fatal($"One or more files required by XIVLauncher were not found.\nPlease restart and report this error if it occurs again.\n\n{path}", "Error");
}
private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
diff --git a/Dalamud/Interface/Internal/Scratchpad/ScratchExecutionManager.cs b/Dalamud/Interface/Internal/Scratchpad/ScratchExecutionManager.cs
index 729827b1e..ba3a501eb 100644
--- a/Dalamud/Interface/Internal/Scratchpad/ScratchExecutionManager.cs
+++ b/Dalamud/Interface/Internal/Scratchpad/ScratchExecutionManager.cs
@@ -83,7 +83,7 @@ namespace Dalamud.Interface.Internal.Scratchpad
{
var script = CSharpScript.Create(code, options);
- var pi = new DalamudPluginInterface(this.dalamud, "Scratch-" + doc.Id, null, PluginLoadReason.Unknown);
+ var pi = new DalamudPluginInterface(this.dalamud, "Scratch-" + doc.Id, PluginLoadReason.Unknown);
var plugin = script.ContinueWith("return new ScratchPlugin() as IDalamudPlugin;")
.RunAsync().GetAwaiter().GetResult().ReturnValue;
diff --git a/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs b/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs
index 4fdbd64f5..e39741072 100644
--- a/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs
+++ b/Dalamud/Interface/Internal/Scratchpad/ScratchMacroProcessor.cs
@@ -131,7 +131,7 @@ public class ScratchPlugin : IDalamudPlugin {
case ParseContext.Dispose:
break;
default:
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(paramName: nameof(input));
}
ctx = ParseContext.None;
@@ -156,7 +156,7 @@ public class ScratchPlugin : IDalamudPlugin {
disposeBody += line + "\n";
break;
default:
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(paramName: nameof(input));
}
}
diff --git a/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs b/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs
index 69c2ade06..0420fe591 100644
--- a/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/ChangelogWindow.cs
@@ -1,6 +1,7 @@
using System.Diagnostics;
using Dalamud.Interface.Windowing;
+using Dalamud.Utility;
using ImGuiNET;
namespace Dalamud.Interface.Internal.Windows
diff --git a/Dalamud/Interface/Internal/Windows/DataWindow.cs b/Dalamud/Interface/Internal/Windows/DataWindow.cs
index c2ad77d1b..868ea7592 100644
--- a/Dalamud/Interface/Internal/Windows/DataWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/DataWindow.cs
@@ -4,17 +4,20 @@ using System.Dynamic;
using System.Linq;
using System.Numerics;
+using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
+using Dalamud.Game.ClientState.Conditions;
+using Dalamud.Game.ClientState.GamePad;
using Dalamud.Game.ClientState.Structs.JobGauge;
-using Dalamud.Game.Internal;
+using Dalamud.Game.Gui.Addons;
+using Dalamud.Game.Gui.Toast;
using Dalamud.Game.Internal.Gui;
-using Dalamud.Game.Internal.Gui.Addon;
-using Dalamud.Game.Internal.Gui.Toast;
using Dalamud.Game.Text;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
+using Dalamud.Utility;
using ImGuiNET;
using ImGuiScene;
using Newtonsoft.Json;
@@ -117,6 +120,17 @@ namespace Dalamud.Interface.Internal.Windows
Gamepad,
}
+ ///
+ public override void OnOpen()
+ {
+ }
+
+ ///
+ public override void OnClose()
+ {
+ this.resultAddon = null;
+ }
+
///
/// Set the DataKind dropdown menu.
///
@@ -303,11 +317,11 @@ namespace Dalamud.Interface.Internal.Windows
foreach (var valueTuple in debugScannedValue.Value)
{
ImGui.TextUnformatted(
- $" {valueTuple.Item1} - 0x{valueTuple.Item2.ToInt64():x}");
+ $" {valueTuple.ClassName} - 0x{valueTuple.Address.ToInt64():x}");
ImGui.SameLine();
if (ImGui.Button($"C##copyAddress{this.copyButtonIndex++}"))
- ImGui.SetClipboardText(valueTuple.Item2.ToInt64().ToString("x"));
+ ImGui.SetClipboardText(valueTuple.Address.ToInt64().ToString("x"));
}
}
}
@@ -486,8 +500,8 @@ namespace Dalamud.Interface.Internal.Windows
private void DrawPluginIPC()
{
#pragma warning disable CS0618 // Type or member is obsolete
- var i1 = new DalamudPluginInterface(this.dalamud, "DalamudTestSub", null, PluginLoadReason.Unknown);
- var i2 = new DalamudPluginInterface(this.dalamud, "DalamudTestPub", null, PluginLoadReason.Unknown);
+ var i1 = new DalamudPluginInterface(this.dalamud, "DalamudTestSub", PluginLoadReason.Unknown);
+ var i2 = new DalamudPluginInterface(this.dalamud, "DalamudTestPub", PluginLoadReason.Unknown);
if (ImGui.Button("Add test sub"))
{
@@ -579,9 +593,7 @@ namespace Dalamud.Interface.Internal.Windows
if (ImGui.Button("Get Addon"))
{
- this.resultAddon =
- this.dalamud.Framework.Gui.GetAddonByName(
- this.inputAddonName, this.inputAddonIndex);
+ this.resultAddon = this.dalamud.Framework.Gui.GetAddonByName(this.inputAddonName, this.inputAddonIndex);
}
if (ImGui.Button("Find Agent"))
@@ -589,14 +601,12 @@ namespace Dalamud.Interface.Internal.Windows
if (this.resultAddon != null)
{
- ImGui.TextUnformatted(
- $"{this.resultAddon.Name} - 0x{this.resultAddon.Address.ToInt64():x}\n v:{this.resultAddon.Visible} x:{this.resultAddon.X} y:{this.resultAddon.Y} s:{this.resultAddon.Scale}, w:{this.resultAddon.Width}, h:{this.resultAddon.Height}");
+ ImGui.TextUnformatted($"{this.resultAddon.Name} - 0x{this.resultAddon.Address.ToInt64():x}\n v:{this.resultAddon.Visible} x:{this.resultAddon.X} y:{this.resultAddon.Y} s:{this.resultAddon.Scale}, w:{this.resultAddon.Width}, h:{this.resultAddon.Height}");
}
if (this.findAgentInterfacePtr != IntPtr.Zero)
{
- ImGui.TextUnformatted(
- $"Agent: 0x{this.findAgentInterfacePtr.ToInt64():x}");
+ ImGui.TextUnformatted($"Agent: 0x{this.findAgentInterfacePtr.ToInt64():x}");
ImGui.SameLine();
if (ImGui.Button("C"))
@@ -807,13 +817,13 @@ namespace Dalamud.Interface.Internal.Windows
$"R3 {resolve(GamepadButtons.R3)} ");
}
#if DEBUG
- ImGui.Text($"GamepadInput 0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
+ ImGui.Text($"GamepadInput 0x{this.dalamud.ClientState.GamepadState.GamepadInputAddress.ToInt64():X}");
if (ImGui.IsItemHovered())
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
if (ImGui.IsItemClicked())
- ImGui.SetClipboardText($"0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
+ ImGui.SetClipboardText($"0x{this.dalamud.ClientState.GamepadState.GamepadInputAddress.ToInt64():X}");
#endif
DrawHelper(
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs
index 870251645..a1c2954e5 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstallerWindow.cs
@@ -18,6 +18,7 @@ using Dalamud.Plugin;
using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Internal.Exceptions;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Utility;
using ImGuiNET;
using ImGuiScene;
@@ -613,6 +614,8 @@ namespace Dalamud.Interface.Internal.Windows
label += Locs.PluginTitleMod_TestingVersion;
}
+ ImGui.PushID($"available{index}{manifest.InternalName}");
+
if (this.DrawPluginCollapsingHeader(label, manifest, false, false, index))
{
ImGuiHelpers.ScaledDummy(5);
@@ -708,6 +711,8 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.EndPopup();
}
+
+ ImGui.PopID();
}
private void DrawInstalledPlugin(LocalPlugin plugin, int index, bool showInstalled = false)
@@ -781,6 +786,8 @@ namespace Dalamud.Interface.Internal.Windows
trouble = true;
}
+ ImGui.PushID($"installed{index}{plugin.Manifest.InternalName}");
+
if (this.DrawPluginCollapsingHeader(label, plugin.Manifest, trouble, availablePluginUpdate != default, index))
{
var manifest = plugin.Manifest;
@@ -791,7 +798,9 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.Text(manifest.Name);
// Download count
- var downloadText = manifest.DownloadCount > 0
+ var downloadText = plugin.IsDev
+ ? Locs.PluginBody_AuthorWithoutDownloadCount(manifest.Author)
+ : manifest.DownloadCount > 0
? Locs.PluginBody_AuthorWithDownloadCount(manifest.Author, manifest.DownloadCount)
: Locs.PluginBody_AuthorWithDownloadCountUnavailable(manifest.Author);
@@ -799,12 +808,15 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadText);
// Installed from
- if (!string.IsNullOrEmpty(manifest.InstalledFromUrl))
+ if (plugin.IsDev)
+ {
+ var fileText = Locs.PluginBody_DevPluginPath(plugin.DllFile.FullName);
+ ImGui.TextColored(ImGuiColors.DalamudGrey3, fileText);
+ }
+ else if (!string.IsNullOrEmpty(manifest.InstalledFromUrl))
{
var repoText = Locs.PluginBody_Plugin3rdPartyRepo(manifest.InstalledFromUrl);
ImGui.TextColored(ImGuiColors.DalamudGrey3, repoText);
-
- ImGuiHelpers.ScaledDummy(2);
}
// Description
@@ -879,6 +891,8 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.EndPopup();
}
+
+ ImGui.PopID();
}
private void DrawPluginControlButton(LocalPlugin plugin)
@@ -1493,10 +1507,14 @@ namespace Dalamud.Interface.Internal.Windows
#region Plugin body
+ public static string PluginBody_AuthorWithoutDownloadCount(string author) => Loc.Localize("InstallerAuthorWithoutDownloadCount", " by {0}").Format(author);
+
public static string PluginBody_AuthorWithDownloadCount(string author, long count) => Loc.Localize("InstallerAuthorWithDownloadCount", " by {0}, {1} downloads").Format(author, count);
public static string PluginBody_AuthorWithDownloadCountUnavailable(string author) => Loc.Localize("InstallerAuthorWithDownloadCountUnavailable", " by {0}, download count unavailable").Format(author);
+ public static string PluginBody_DevPluginPath(string path) => Loc.Localize("InstallerDevPluginPath", "From {0}").Format(path);
+
public static string PluginBody_Plugin3rdPartyRepo(string url) => Loc.Localize("InstallerPlugin3rdPartyRepo", "From custom plugin repository {0}").Format(url);
public static string PluginBody_AvailableDevPlugin => Loc.Localize("InstallerDevPlugin", " This plugin is available in one of your repos, please remove it from the devPlugins folder.");
diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
index cdb60d9b0..733baa454 100644
--- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs
@@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Reflection;
+using Dalamud.Game;
using Dalamud.Game.Internal;
using Dalamud.Hooking.Internal;
using Dalamud.Interface.Windowing;
diff --git a/Dalamud/Interface/Internal/Windows/SettingsWindow.cs b/Dalamud/Interface/Internal/Windows/SettingsWindow.cs
index f5c13dd0a..fde2ad0c7 100644
--- a/Dalamud/Interface/Internal/Windows/SettingsWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/SettingsWindow.cs
@@ -44,16 +44,21 @@ namespace Dalamud.Interface.Internal.Windows
private bool doDocking;
private bool doViewport;
private bool doGamepad;
+
private List thirdRepoList;
private bool thirdRepoListChanged;
+ private string thirdRepoTempUrl = string.Empty;
+ private string thirdRepoAddError = string.Empty;
+
+ private List devPluginLocations;
+ private bool devPluginLocationsChanged;
+ private string devPluginTempLocation = string.Empty;
+ private string devPluginLocationAddError = string.Empty;
private bool printPluginsWelcomeMsg;
private bool autoUpdatePlugins;
private bool doButtonsSystemMenu;
- private string thirdRepoTempUrl = string.Empty;
- private string thirdRepoAddError = string.Empty;
-
#region Experimental
private bool doPluginTest;
@@ -88,6 +93,7 @@ namespace Dalamud.Interface.Internal.Windows
this.doPluginTest = this.dalamud.Configuration.DoPluginTest;
this.thirdRepoList = this.dalamud.Configuration.ThirdRepoList.Select(x => x.Clone()).ToList();
+ this.devPluginLocations = this.dalamud.Configuration.DevPluginLoadLocations.Select(x => x.Clone()).ToList();
this.printPluginsWelcomeMsg = this.dalamud.Configuration.PrintPluginsWelcomeMsg;
this.autoUpdatePlugins = this.dalamud.Configuration.AutoUpdatePlugins;
@@ -144,14 +150,15 @@ namespace Dalamud.Interface.Internal.Windows
public override void OnOpen()
{
this.thirdRepoListChanged = false;
+ this.devPluginLocationsChanged = false;
}
///
public override void OnClose()
{
ImGui.GetIO().FontGlobalScale = this.dalamud.Configuration.GlobalUiScale;
-
this.thirdRepoList = this.dalamud.Configuration.ThirdRepoList.Select(x => x.Clone()).ToList();
+ this.devPluginLocations = this.dalamud.Configuration.DevPluginLoadLocations.Select(x => x.Clone()).ToList();
}
///
@@ -252,12 +259,18 @@ namespace Dalamud.Interface.Internal.Windows
if (ImGui.BeginTabItem(Loc.Localize("DalamudSettingsExperimental", "Experimental")))
{
+ #region Plugin testing
+
ImGui.Checkbox(Loc.Localize("DalamudSettingsPluginTest", "Get plugin testing builds"), ref this.doPluginTest);
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingsPluginTestHint", "Receive testing prereleases for plugins."));
ImGui.TextColored(this.warnTextColor, Loc.Localize("DalamudSettingsPluginTestWarning", "Testing plugins may not have been vetted before being published. Please only enable this if you are aware of the risks."));
+ #endregion
+
ImGuiHelpers.ScaledDummy(12);
+ #region Hidden plugins
+
if (ImGui.Button(Loc.Localize("DalamudSettingsClearHidden", "Clear hidden plugins")))
{
this.dalamud.Configuration.HiddenPluginInternalName.Clear();
@@ -266,10 +279,12 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingsClearHiddenHint", "Restore plugins you have previously hidden from the plugin installer."));
- ImGuiHelpers.ScaledDummy(12);
+ #endregion
ImGuiHelpers.ScaledDummy(12);
+ #region Custom repos
+
ImGui.Text(Loc.Localize("DalamudSettingsCustomRepo", "Custom Plugin Repositories"));
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingCustomRepoHint", "Add custom plugin repositories."));
ImGui.TextColored(this.warnTextColor, Loc.Localize("DalamudSettingCustomRepoWarning", "We cannot take any responsibility for third-party plugins and repositories.\nTake care when installing third-party plugins from untrusted sources."));
@@ -278,7 +293,7 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.Columns(4);
ImGui.SetColumnWidth(0, 18 + (5 * ImGuiHelpers.GlobalScale));
- ImGui.SetColumnWidth(1, ImGui.GetWindowWidth() - (18 + 16 + 14) - ((5 + 45 + 26) * ImGuiHelpers.GlobalScale));
+ ImGui.SetColumnWidth(1, ImGui.GetWindowContentRegionWidth() - (18 + 16 + 14) - ((5 + 45 + 26) * ImGuiHelpers.GlobalScale));
ImGui.SetColumnWidth(2, 16 + (45 * ImGuiHelpers.GlobalScale));
ImGui.SetColumnWidth(3, 14 + (26 * ImGuiHelpers.GlobalScale));
@@ -303,7 +318,7 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.NextColumn();
ImGui.Separator();
- ThirdPartyRepoSettings toRemove = null;
+ ThirdPartyRepoSettings repoToRemove = null;
var repoNumber = 1;
foreach (var thirdRepoSetting in this.thirdRepoList)
@@ -325,7 +340,7 @@ namespace Dalamud.Interface.Internal.Windows
if (ImGuiComponents.IconButton(FontAwesomeIcon.Trash))
{
- toRemove = thirdRepoSetting;
+ repoToRemove = thirdRepoSetting;
}
ImGui.NextColumn();
@@ -336,9 +351,9 @@ namespace Dalamud.Interface.Internal.Windows
repoNumber++;
}
- if (toRemove != null)
+ if (repoToRemove != null)
{
- this.thirdRepoList.Remove(toRemove);
+ this.thirdRepoList.Remove(repoToRemove);
this.thirdRepoListChanged = true;
}
@@ -377,6 +392,115 @@ namespace Dalamud.Interface.Internal.Windows
{
ImGui.TextColored(new Vector4(1, 0, 0, 1), this.thirdRepoAddError);
}
+
+ #endregion
+
+ ImGuiHelpers.ScaledDummy(12);
+
+ #region Custom dev plugin load locations
+
+ ImGui.Text(Loc.Localize("DalamudSettingsDevPluginLocation", "Dev Plugin Locations"));
+ ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingsDevPluginLocationsHint", "Add additional dev plugin load locations.\nThese can be either the directory or DLL path."));
+
+ ImGuiHelpers.ScaledDummy(5);
+
+ ImGui.Columns(4);
+ ImGui.SetColumnWidth(0, 18 + (5 * ImGuiHelpers.GlobalScale));
+ ImGui.SetColumnWidth(1, ImGui.GetWindowContentRegionWidth() - (18 + 16 + 14) - ((5 + 45 + 26) * ImGuiHelpers.GlobalScale));
+ ImGui.SetColumnWidth(2, 16 + (45 * ImGuiHelpers.GlobalScale));
+ ImGui.SetColumnWidth(3, 14 + (26 * ImGuiHelpers.GlobalScale));
+
+ ImGui.Separator();
+
+ ImGui.Text("#");
+ ImGui.NextColumn();
+ ImGui.Text("Path");
+ ImGui.NextColumn();
+ ImGui.Text("Enabled");
+ ImGui.NextColumn();
+ ImGui.Text(string.Empty);
+ ImGui.NextColumn();
+
+ ImGui.Separator();
+
+ DevPluginLocationSettings locationToRemove = null;
+
+ var locNumber = 1;
+ foreach (var devPluginLocationSetting in this.devPluginLocations)
+ {
+ var isEnabled = devPluginLocationSetting.IsEnabled;
+
+ ImGui.PushID($"devPluginLocation_{devPluginLocationSetting.Path}");
+
+ ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (ImGui.GetColumnWidth() / 2) - 8 - (ImGui.CalcTextSize(repoNumber.ToString()).X / 2));
+ ImGui.Text(locNumber.ToString());
+ ImGui.NextColumn();
+
+ ImGui.TextWrapped(devPluginLocationSetting.Path);
+ ImGui.NextColumn();
+
+ ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (ImGui.GetColumnWidth() / 2) - 7 - (12 * ImGuiHelpers.GlobalScale));
+ ImGui.Checkbox("##devPluginLocationCheck", ref isEnabled);
+ ImGui.NextColumn();
+
+ if (ImGuiComponents.IconButton(FontAwesomeIcon.Trash))
+ {
+ locationToRemove = devPluginLocationSetting;
+ }
+
+ ImGui.NextColumn();
+ ImGui.Separator();
+
+ devPluginLocationSetting.IsEnabled = isEnabled;
+
+ locNumber++;
+ }
+
+ if (locationToRemove != null)
+ {
+ this.devPluginLocations.Remove(locationToRemove);
+ this.devPluginLocationsChanged = true;
+ }
+
+ ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (ImGui.GetColumnWidth() / 2) - 8 - (ImGui.CalcTextSize(locNumber.ToString()).X / 2));
+ ImGui.Text(locNumber.ToString());
+ ImGui.NextColumn();
+ ImGui.SetNextItemWidth(-1);
+ ImGui.InputText("##devPluginLocationInput", ref this.devPluginTempLocation, 300);
+ ImGui.NextColumn();
+ // Enabled button
+ ImGui.NextColumn();
+ if (!string.IsNullOrEmpty(this.devPluginTempLocation) && ImGuiComponents.IconButton(FontAwesomeIcon.Plus))
+ {
+ if (this.devPluginLocations.Any(r => string.Equals(r.Path, this.devPluginTempLocation, StringComparison.InvariantCultureIgnoreCase)))
+ {
+ this.devPluginLocationAddError = Loc.Localize("DalamudDevPluginLocationExists", "Location already exists.");
+ Task.Delay(5000).ContinueWith(t => this.devPluginLocationAddError = string.Empty);
+ }
+ else
+ {
+ this.devPluginLocations.Add(new DevPluginLocationSettings
+ {
+ Path = this.devPluginTempLocation,
+ IsEnabled = true,
+ });
+ this.devPluginLocationsChanged = true;
+ this.devPluginTempLocation = string.Empty;
+ }
+ }
+
+ ImGui.Columns(1);
+
+ ImGui.EndTabItem();
+
+ if (!string.IsNullOrEmpty(this.devPluginLocationAddError))
+ {
+ ImGui.TextColored(new Vector4(1, 0, 0, 1), this.devPluginLocationAddError);
+ }
+
+ #endregion
+
+ ImGuiHelpers.ScaledDummy(12);
}
ImGui.EndTabBar();
@@ -384,20 +508,18 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.EndChild();
- if (ImGui.Button(Loc.Localize("Save", "Save")))
- {
- this.Save();
+ var buttonSave = false;
+ var buttonClose = false;
- if (this.thirdRepoListChanged)
- {
- this.dalamud.PluginManager.SetPluginReposFromConfig(true);
- this.thirdRepoListChanged = false;
- }
- }
+ if (ImGui.Button(Loc.Localize("Save", "Save")))
+ buttonSave = true;
ImGui.SameLine();
if (ImGui.Button(Loc.Localize("SaveAndClose", "Save and Close")))
+ buttonSave = buttonClose = true;
+
+ if (buttonSave)
{
this.Save();
@@ -407,6 +529,15 @@ namespace Dalamud.Interface.Internal.Windows
this.thirdRepoListChanged = false;
}
+ if (this.devPluginLocationsChanged)
+ {
+ this.dalamud.PluginManager.ScanDevPlugins();
+ this.devPluginLocationsChanged = false;
+ }
+ }
+
+ if (buttonClose)
+ {
this.IsOpen = false;
}
}
@@ -456,6 +587,7 @@ namespace Dalamud.Interface.Internal.Windows
this.dalamud.Configuration.DoPluginTest = this.doPluginTest;
this.dalamud.Configuration.ThirdRepoList = this.thirdRepoList.Select(x => x.Clone()).ToList();
+ this.dalamud.Configuration.DevPluginLoadLocations = this.devPluginLocations.Select(x => x.Clone()).ToList();
this.dalamud.Configuration.PrintPluginsWelcomeMsg = this.printPluginsWelcomeMsg;
this.dalamud.Configuration.AutoUpdatePlugins = this.autoUpdatePlugins;
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index e24ab8bc1..71ce244f7 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using Dalamud.Game.ClientState;
+using Dalamud.Game.ClientState.Conditions;
using Dalamud.Interface.Internal;
using ImGuiNET;
using ImGuiScene;
diff --git a/Dalamud/Logging/PluginLog.cs b/Dalamud/Logging/PluginLog.cs
index fefb386c5..a21363854 100644
--- a/Dalamud/Logging/PluginLog.cs
+++ b/Dalamud/Logging/PluginLog.cs
@@ -8,6 +8,131 @@ namespace Dalamud.Logging
///
public static class PluginLog
{
+ #region "Log" prefixed Serilog style methods
+
+ ///
+ /// Log a templated message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void Log(string messageTemplate, params object[] values)
+ => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void Log(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated verbose message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogVerbose(string messageTemplate, params object[] values)
+ => Serilog.Log.Verbose($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated verbose message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogVerbose(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Verbose(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated debug message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogDebug(string messageTemplate, params object[] values)
+ => Serilog.Log.Debug($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated debug message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogDebug(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Debug(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated information message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogInformation(string messageTemplate, params object[] values)
+ => Serilog.Log.Information($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated information message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogInformation(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Information(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated warning message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogWarning(string messageTemplate, params object[] values)
+ => Serilog.Log.Warning($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated warning message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogWarning(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Warning(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated error message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogError(string messageTemplate, params object[] values)
+ => Serilog.Log.Error($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated error message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogError(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Error(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated fatal message to the in-game debug log.
+ ///
+ /// The message template.
+ /// Values to log.
+ public static void LogFatal(string messageTemplate, params object[] values)
+ => Serilog.Log.Fatal($"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ ///
+ /// Log a templated fatal message to the in-game debug log.
+ ///
+ /// The exception that caused the error.
+ /// The message template.
+ /// Values to log.
+ public static void LogFatal(Exception exception, string messageTemplate, params object[] values)
+ => Serilog.Log.Fatal(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ #endregion
+
+ #region Serilog style methods
+
///
/// Log a templated verbose message to the in-game debug log.
///
@@ -109,5 +234,7 @@ namespace Dalamud.Logging
/// Values to log.
public static void Fatal(Exception exception, string messageTemplate, params object[] values)
=> Serilog.Log.Fatal(exception, $"[{Assembly.GetCallingAssembly().GetName().Name}] {messageTemplate}", values);
+
+ #endregion
}
}
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index 8814e494a..0cd7007a4 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -35,9 +35,8 @@ namespace Dalamud.Plugin
///
/// The dalamud instance to expose.
/// The internal name of the plugin.
- /// The equivalent of what Assembly.GetExecutingAssembly().Location should return.
/// The reason the plugin was loaded.
- internal DalamudPluginInterface(Dalamud dalamud, string pluginName, string assemblyLocation, PluginLoadReason reason)
+ internal DalamudPluginInterface(Dalamud dalamud, string pluginName, PluginLoadReason reason)
{
this.CommandManager = dalamud.CommandManager;
this.Framework = dalamud.Framework;
@@ -50,7 +49,6 @@ namespace Dalamud.Plugin
this.dalamud = dalamud;
this.pluginName = pluginName;
this.configs = dalamud.PluginManager.PluginConfigs;
- this.AssemblyLocation = assemblyLocation;
this.Reason = reason;
this.GeneralChatType = this.dalamud.Configuration.GeneralChatType;
@@ -88,11 +86,6 @@ namespace Dalamud.Plugin
///
public PluginLoadReason Reason { get; }
- ///
- /// Gets the plugin assembly location.
- ///
- public string AssemblyLocation { get; private set; }
-
///
/// Gets the directory Dalamud assets are stored in.
///
@@ -124,7 +117,7 @@ namespace Dalamud.Plugin
public Framework Framework { get; private set; }
///
- /// Gets the UiBuilder instance which allows you to draw UI into the game via ImGui draw calls.
+ /// Gets the instance which allows you to draw UI into the game via ImGui draw calls.
///
public UiBuilder UiBuilder { get; private set; }
@@ -172,6 +165,8 @@ namespace Dalamud.Plugin
///
internal Action AnyPluginIpcAction { get; private set; }
+ #region Configuration
+
///
/// Save a plugin configuration(inheriting IPluginConfiguration).
///
@@ -223,6 +218,8 @@ namespace Dalamud.Plugin
/// directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc.
public string GetPluginLocDirectory() => this.configs.GetDirectory(Path.Combine(this.pluginName, "loc"));
+ #endregion
+
#region Chat Links
///
diff --git a/Dalamud/Plugin/Internal/LocalPlugin.cs b/Dalamud/Plugin/Internal/LocalPlugin.cs
index f5b3481f8..3299feced 100644
--- a/Dalamud/Plugin/Internal/LocalPlugin.cs
+++ b/Dalamud/Plugin/Internal/LocalPlugin.cs
@@ -272,7 +272,7 @@ namespace Dalamud.Plugin.Internal
this.Manifest.Save(this.manifestFile);
}
- this.DalamudInterface = new DalamudPluginInterface(this.dalamud, this.pluginAssembly.GetName().Name, this.DllFile.FullName, reason);
+ this.DalamudInterface = new DalamudPluginInterface(this.dalamud, this.pluginAssembly.GetName().Name, reason);
if (this.IsDev)
{
diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index a3f4f250e..cec465f9e 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Compression;
using System.Linq;
-using System.Net;
+using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@@ -17,6 +17,7 @@ using Dalamud.Game.Text;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal.Exceptions;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Utility;
using HarmonyLib;
using JetBrains.Annotations;
using Newtonsoft.Json;
@@ -185,7 +186,22 @@ namespace Dalamud.Plugin.Internal
}
// devPlugins are more freeform. Look for any dll and hope to get lucky.
- var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories);
+ var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories).ToList();
+
+ foreach (var setting in this.dalamud.Configuration.DevPluginLoadLocations)
+ {
+ if (!setting.IsEnabled)
+ continue;
+
+ if (Directory.Exists(setting.Path))
+ {
+ devDllFiles.AddRange(new DirectoryInfo(setting.Path).GetFiles("*.dll", SearchOption.AllDirectories));
+ }
+ else if (File.Exists(setting.Path))
+ {
+ devDllFiles.Add(new FileInfo(setting.Path));
+ }
+ }
foreach (var dllFile in devDllFiles)
{
@@ -298,7 +314,22 @@ namespace Dalamud.Plugin.Internal
this.devPluginDirectory.Create();
// devPlugins are more freeform. Look for any dll and hope to get lucky.
- var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories);
+ var devDllFiles = this.devPluginDirectory.GetFiles("*.dll", SearchOption.AllDirectories).ToList();
+
+ foreach (var setting in this.dalamud.Configuration.DevPluginLoadLocations)
+ {
+ if (!setting.IsEnabled)
+ continue;
+
+ if (Directory.Exists(setting.Path))
+ {
+ devDllFiles.AddRange(new DirectoryInfo(setting.Path).GetFiles("*.dll", SearchOption.AllDirectories));
+ }
+ else if (File.Exists(setting.Path))
+ {
+ devDllFiles.Add(new FileInfo(setting.Path));
+ }
+ }
var listChanged = false;
@@ -359,16 +390,17 @@ namespace Dalamud.Plugin.Internal
// ignored, since the plugin may be loaded already
}
- using var client = new WebClient();
-
var tempZip = new FileInfo(Path.GetTempFileName());
try
{
Log.Debug($"Downloading plugin to {tempZip} from {downloadUrl}");
- client.DownloadFile(downloadUrl, tempZip.FullName);
+ using var client = new HttpClient();
+ var response = client.GetAsync(downloadUrl).Result;
+ using var fs = new FileStream(tempZip.FullName, FileMode.CreateNew);
+ response.Content.CopyToAsync(fs).GetAwaiter().GetResult();
}
- catch (WebException ex)
+ catch (HttpRequestException ex)
{
Log.Error(ex, $"Download of plugin {repoManifest.Name} failed unexpectedly.");
throw;
@@ -593,7 +625,7 @@ namespace Dalamud.Plugin.Internal
continue;
}
- if (manifest.ApplicableVersion < this.dalamud.StartInfo.GameVersion)
+ if (manifest.ApplicableVersion < this.dalamud.StartInfo.GameVersion - TimeSpan.FromDays(90))
{
Log.Information($"Inapplicable version: cleaning up {versionDir.FullName}");
versionDir.Delete(true);
@@ -977,26 +1009,21 @@ namespace Dalamud.Plugin.Internal
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Enforced naming for special injected parameters")]
private static void AssemblyLocationPatch(Assembly __instance, ref string __result)
{
- // Assembly.GetExecutingAssembly can return this.
- // Check for it as a special case and find the plugin.
- if (__result.EndsWith("System.Private.CoreLib.dll", StringComparison.InvariantCultureIgnoreCase))
+ if (string.IsNullOrEmpty(__result))
{
foreach (var assemblyName in GetStackFrameAssemblyNames())
{
if (PluginLocations.TryGetValue(assemblyName, out var data))
{
__result = data.Location;
- return;
+ break;
}
}
}
- else if (string.IsNullOrEmpty(__result))
- {
- if (PluginLocations.TryGetValue(__instance.FullName, out var data))
- {
- __result = data.Location;
- }
- }
+
+ __result ??= string.Empty;
+
+ Log.Verbose($"Assembly.Location // {__instance.FullName} // {__result}");
}
///
@@ -1009,26 +1036,21 @@ namespace Dalamud.Plugin.Internal
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Enforced naming for special injected parameters")]
private static void AssemblyCodeBasePatch(Assembly __instance, ref string __result)
{
- // Assembly.GetExecutingAssembly can return this.
- // Check for it as a special case and find the plugin.
- if (__result.EndsWith("System.Private.CoreLib.dll"))
+ if (string.IsNullOrEmpty(__result))
{
foreach (var assemblyName in GetStackFrameAssemblyNames())
{
if (PluginLocations.TryGetValue(assemblyName, out var data))
{
- __result = data.Location;
- return;
+ __result = data.CodeBase;
+ break;
}
}
}
- else if (string.IsNullOrEmpty(__result))
- {
- if (PluginLocations.TryGetValue(__instance.FullName, out var data))
- {
- __result = data.Location;
- }
- }
+
+ __result ??= string.Empty;
+
+ Log.Verbose($"Assembly.CodeBase // {__instance.FullName} // {__result}");
}
private static IEnumerable GetStackFrameAssemblyNames()
diff --git a/Dalamud/Plugin/Internal/PluginRepository.cs b/Dalamud/Plugin/Internal/PluginRepository.cs
index e76aa67d1..d90efaee8 100644
--- a/Dalamud/Plugin/Internal/PluginRepository.cs
+++ b/Dalamud/Plugin/Internal/PluginRepository.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Net;
+using System.Net.Http;
using System.Threading.Tasks;
using Dalamud.Logging.Internal;
@@ -74,11 +74,10 @@ namespace Dalamud.Plugin.Internal
return Task.Run(() =>
{
- using var client = new WebClient();
-
Log.Information($"Fetching repo: {this.PluginMasterUrl}");
-
- var data = client.DownloadString(this.PluginMasterUrl);
+ using var client = new HttpClient();
+ using var response = client.GetAsync(this.PluginMasterUrl).Result;
+ var data = response.Content.ReadAsStringAsync().Result;
var pluginMaster = JsonConvert.DeserializeObject>(data);
pluginMaster.Sort((pm1, pm2) => pm1.Name.CompareTo(pm2.Name));
diff --git a/Dalamud/Troubleshooting.cs b/Dalamud/Troubleshooting.cs
index 69b0df23e..7aba6ec2c 100644
--- a/Dalamud/Troubleshooting.cs
+++ b/Dalamud/Troubleshooting.cs
@@ -4,8 +4,8 @@ using System.Linq;
using System.Text;
using Dalamud.Configuration;
-using Dalamud.Plugin;
using Dalamud.Plugin.Internal.Types;
+using Dalamud.Utility;
using Newtonsoft.Json;
using Serilog;
diff --git a/Dalamud/Utility/EnumExtensions.cs b/Dalamud/Utility/EnumExtensions.cs
new file mode 100644
index 000000000..5a2d9172b
--- /dev/null
+++ b/Dalamud/Utility/EnumExtensions.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Linq;
+
+namespace Dalamud.Utility
+{
+ ///
+ /// Extension methods for enums.
+ ///
+ public static class EnumExtensions
+ {
+ ///
+ /// Gets an attribute on an enum.
+ ///
+ /// The type of attribute to get.
+ /// The enum value that has an attached attribute.
+ /// The attached attribute, if any.
+ public static TAttribute GetAttribute(this Enum value)
+ where TAttribute : Attribute
+ {
+ var type = value.GetType();
+ var name = Enum.GetName(type, value);
+ return type.GetField(name) // I prefer to get attributes this way
+ .GetCustomAttributes(false)
+ .OfType()
+ .SingleOrDefault();
+ }
+ }
+}
diff --git a/Dalamud/Utility/StringExtensions.cs b/Dalamud/Utility/StringExtensions.cs
new file mode 100644
index 000000000..f452a2a0f
--- /dev/null
+++ b/Dalamud/Utility/StringExtensions.cs
@@ -0,0 +1,30 @@
+namespace Dalamud.Utility
+{
+ ///
+ /// Extension methods for strings.
+ ///
+ public static class StringExtensions
+ {
+ ///
+ /// An extension method to chain usage of string.Format.
+ ///
+ /// Format string.
+ /// Format arguments.
+ /// Formatted string.
+ public static string Format(this string format, params object[] args) => string.Format(format, args);
+
+ ///
+ /// Indicates whether the specified string is null or an empty string ("").
+ ///
+ /// The string to test.
+ /// true if the value parameter is null or an empty string (""); otherwise, false.
+ public static bool IsNullOrEmpty(this string value) => string.IsNullOrEmpty(value);
+
+ ///
+ /// Indicates whether a specified string is null, empty, or consists only of white-space characters.
+ ///
+ /// The string to test.
+ /// true if the value parameter is null or an empty string (""), or if value consists exclusively of white-space characters.
+ public static bool IsNullOrWhitespace(this string value) => string.IsNullOrWhiteSpace(value);
+ }
+}
diff --git a/Dalamud/Data/LuminaExtensions/TexFileExtensions.cs b/Dalamud/Utility/TexFileExtensions.cs
similarity index 95%
rename from Dalamud/Data/LuminaExtensions/TexFileExtensions.cs
rename to Dalamud/Utility/TexFileExtensions.cs
index d2bb7b736..ddfccba9c 100644
--- a/Dalamud/Data/LuminaExtensions/TexFileExtensions.cs
+++ b/Dalamud/Utility/TexFileExtensions.cs
@@ -1,7 +1,7 @@
using ImGuiScene;
using Lumina.Data.Files;
-namespace Dalamud.Data.LuminaExtensions
+namespace Dalamud.Utility
{
///
/// Extensions to .
diff --git a/Dalamud/Util.cs b/Dalamud/Utility/Util.cs
similarity index 94%
rename from Dalamud/Util.cs
rename to Dalamud/Utility/Util.cs
index 3084e1bab..edd2d8c97 100644
--- a/Dalamud/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -7,10 +7,11 @@ using System.Text;
using Dalamud.Game;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
+using Dalamud.Logging.Internal;
using ImGuiNET;
using Serilog;
-namespace Dalamud
+namespace Dalamud.Utility
{
///
/// Class providing various helper methods for use in Dalamud and plugins.
@@ -196,13 +197,5 @@ namespace Dalamud
// TODO: Someone implement GetUTF8String with some IntPtr overloads.
// while(Marshal.ReadByte(0, sz) != 0) { sz++; }
-
- ///
- /// An extension method to chain usage of string.Format.
- ///
- /// Format string.
- /// Format arguments.
- /// Formatted string.
- public static string Format(this string format, params object[] args) => string.Format(format, args);
}
}
diff --git a/Dalamud/Utility/VectorExtensions.cs b/Dalamud/Utility/VectorExtensions.cs
new file mode 100644
index 000000000..0a14299c2
--- /dev/null
+++ b/Dalamud/Utility/VectorExtensions.cs
@@ -0,0 +1,52 @@
+using System.Numerics;
+
+namespace Dalamud.Utility
+{
+ ///
+ /// Extension methods for System.Numerics.VectorN and SharpDX.VectorN.
+ ///
+ public static class VectorExtensions
+ {
+ ///
+ /// Converts a SharpDX vector to System.Numerics.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static Vector2 ToSystem(this SharpDX.Vector2 vec) => new(x: vec.X, y: vec.Y);
+
+ ///
+ /// Converts a SharpDX vector to System.Numerics.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static Vector3 ToSystem(this SharpDX.Vector3 vec) => new(x: vec.X, y: vec.Y, z: vec.Z);
+
+ ///
+ /// Converts a SharpDX vector to System.Numerics.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static Vector4 ToSystem(this SharpDX.Vector4 vec) => new(x: vec.X, y: vec.Y, z: vec.Z, w: vec.W);
+
+ ///
+ /// Converts a System.Numerics vector to SharpDX.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static SharpDX.Vector2 ToSharpDX(this Vector2 vec) => new(x: vec.X, y: vec.Y);
+
+ ///
+ /// Converts a System.Numerics vector to SharpDX.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static SharpDX.Vector3 ToSharpDX(this Vector3 vec) => new(x: vec.X, y: vec.Y, z: vec.Z);
+
+ ///
+ /// Converts a System.Numerics vector to SharpDX.
+ ///
+ /// Vector to convert.
+ /// A converted vector.
+ public static SharpDX.Vector4 ToSharpDX(this Vector4 vec) => new(x: vec.X, y: vec.Y, z: vec.Z, w: vec.W);
+ }
+}