mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #477 from daemitus/misc
This commit is contained in:
commit
8d5d290656
20 changed files with 279 additions and 324 deletions
|
|
@ -64,6 +64,21 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
|
|||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
|
||||
dotnet_style_parentheses_in_other_operators=always_for_clarity:silent
|
||||
dotnet_style_object_initializer = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = none
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# ReSharper properties
|
||||
resharper_align_linq_query = true
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ namespace Dalamud.Injector
|
|||
var process = GetProcess(args.ElementAtOrDefault(1));
|
||||
var startInfo = GetStartInfo(args.ElementAtOrDefault(2), process);
|
||||
|
||||
startInfo.WorkingDirectory = Directory.GetCurrentDirectory();
|
||||
|
||||
// This seems to help with the STATUS_INTERNAL_ERROR condition
|
||||
Thread.Sleep(1000);
|
||||
|
||||
|
|
@ -245,7 +243,7 @@ namespace Dalamud.Injector
|
|||
|
||||
startInfo = new DalamudStartInfo
|
||||
{
|
||||
WorkingDirectory = null,
|
||||
WorkingDirectory = Directory.GetCurrentDirectory(),
|
||||
ConfigurationPath = Path.Combine(xivlauncherDir, "dalamudConfig.json"),
|
||||
PluginDirectory = Path.Combine(xivlauncherDir, "installedPlugins"),
|
||||
DefaultPluginDirectory = Path.Combine(xivlauncherDir, "devPlugins"),
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ namespace Dalamud
|
|||
#region Internals
|
||||
|
||||
private readonly ManualResetEvent unloadSignal;
|
||||
|
||||
private readonly ManualResetEvent finishUnloadSignal;
|
||||
|
||||
private bool hasDisposedPlugins = false;
|
||||
|
||||
#endregion
|
||||
|
|
@ -237,6 +235,7 @@ namespace Dalamud
|
|||
|
||||
// Initialize FFXIVClientStructs function resolver
|
||||
FFXIVClientStructs.Resolver.Initialize();
|
||||
|
||||
Log.Information("[T1] FFXIVClientStructs initialized!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
|
|
@ -9,47 +9,47 @@ namespace Dalamud
|
|||
/// Struct containing information needed to initialize Dalamud.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct DalamudStartInfo
|
||||
public record DalamudStartInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The working directory of the XIVLauncher installations.
|
||||
/// Gets the working directory of the XIVLauncher installations.
|
||||
/// </summary>
|
||||
public string WorkingDirectory;
|
||||
public string WorkingDirectory { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the configuration file.
|
||||
/// Gets the path to the configuration file.
|
||||
/// </summary>
|
||||
public string ConfigurationPath;
|
||||
public string ConfigurationPath { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the directory for installed plugins.
|
||||
/// Gets the path to the directory for installed plugins.
|
||||
/// </summary>
|
||||
public string PluginDirectory;
|
||||
public string PluginDirectory { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the directory for developer plugins.
|
||||
/// Gets the path to the directory for developer plugins.
|
||||
/// </summary>
|
||||
public string DefaultPluginDirectory;
|
||||
public string DefaultPluginDirectory { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to core Dalamud assets.
|
||||
/// Gets the path to core Dalamud assets.
|
||||
/// </summary>
|
||||
public string AssetDirectory;
|
||||
public string AssetDirectory { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The language of the game client.
|
||||
/// Gets the language of the game client.
|
||||
/// </summary>
|
||||
public ClientLanguage Language;
|
||||
public ClientLanguage Language { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The current game version code.
|
||||
/// Gets the current game version code.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(GameVersionConverter))]
|
||||
public GameVersion GameVersion;
|
||||
public GameVersion GameVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not market board information should be uploaded by default.
|
||||
/// Gets a value indicating whether or not market board information should be uploaded by default.
|
||||
/// </summary>
|
||||
public bool OptOutMbCollection;
|
||||
public bool OptOutMbCollection { get; init; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,21 +31,14 @@ namespace Dalamud.Game.Command
|
|||
{
|
||||
this.dalamud = dalamud;
|
||||
|
||||
switch (language)
|
||||
this.currentLangCommandRegex = language switch
|
||||
{
|
||||
case ClientLanguage.Japanese:
|
||||
this.currentLangCommandRegex = this.commandRegexJp;
|
||||
break;
|
||||
case ClientLanguage.English:
|
||||
this.currentLangCommandRegex = this.commandRegexEn;
|
||||
break;
|
||||
case ClientLanguage.German:
|
||||
this.currentLangCommandRegex = this.commandRegexDe;
|
||||
break;
|
||||
case ClientLanguage.French:
|
||||
this.currentLangCommandRegex = this.commandRegexFr;
|
||||
break;
|
||||
}
|
||||
ClientLanguage.Japanese => this.commandRegexJp,
|
||||
ClientLanguage.English => this.commandRegexEn,
|
||||
ClientLanguage.German => this.commandRegexDe,
|
||||
ClientLanguage.French => this.commandRegexFr,
|
||||
_ => this.currentLangCommandRegex,
|
||||
};
|
||||
|
||||
dalamud.Framework.Gui.Chat.CheckMessageHandled += this.OnCheckMessageHandled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Memory;
|
||||
|
||||
namespace Dalamud.Game.Gui.Addons
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents an in-game UI "Addon".
|
||||
/// </summary>
|
||||
public unsafe class Addon
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Addon"/> class.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of the addon.</param>
|
||||
public Addon(IntPtr address)
|
||||
{
|
||||
this.Address = address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the addon.
|
||||
/// </summary>
|
||||
public IntPtr Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the addon.
|
||||
/// </summary>
|
||||
public string Name => MemoryHelper.ReadString((IntPtr)this.Struct->Name, 0x20);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the X position of the addon on screen.
|
||||
/// </summary>
|
||||
public short X => this.Struct->X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y position of the addon on screen.
|
||||
/// </summary>
|
||||
public short Y => this.Struct->Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale of the addon.
|
||||
/// </summary>
|
||||
public float Scale => this.Struct->Scale;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the addon. This may include non-visible parts.
|
||||
/// </summary>
|
||||
public unsafe float Width => this.Struct->RootNode->Width * this.Scale;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height of the addon. This may include non-visible parts.
|
||||
/// </summary>
|
||||
public unsafe float Height => this.Struct->RootNode->Height * this.Scale;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the addon is visible.
|
||||
/// </summary>
|
||||
public bool Visible => this.Struct->IsVisible;
|
||||
|
||||
private FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase* Struct => (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)this.Address;
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// </summary>
|
||||
private delegate IntPtr CreateFlyTextDelegate(
|
||||
IntPtr addonFlyText,
|
||||
int kind,
|
||||
FlyTextKind kind,
|
||||
int val1,
|
||||
int val2,
|
||||
IntPtr text2,
|
||||
|
|
@ -126,14 +126,14 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
public unsafe void AddFlyText(FlyTextKind kind, uint actorIndex, uint val1, uint val2, SeString text1, SeString text2, uint color, uint icon)
|
||||
{
|
||||
// Known valid flytext region within the atk arrays
|
||||
int numIndex = 28;
|
||||
int strIndex = 25;
|
||||
uint numOffset = 147;
|
||||
uint strOffset = 28;
|
||||
var numIndex = 28;
|
||||
var strIndex = 25;
|
||||
var numOffset = 147u;
|
||||
var strOffset = 28u;
|
||||
|
||||
// Get the UI module and flytext addon pointers
|
||||
var ui = (UIModule*)this.Dalamud.Framework.Gui.GetUIModule();
|
||||
var flytext = this.Dalamud.Framework.Gui.GetUiObjectByName("_FlyText", 1);
|
||||
var flytext = this.Dalamud.Framework.Gui.GetAddonByName("_FlyText", 1);
|
||||
|
||||
if (ui == null || flytext == IntPtr.Zero)
|
||||
return;
|
||||
|
|
@ -195,7 +195,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
|
||||
private IntPtr CreateFlyTextDetour(
|
||||
IntPtr addonFlyText,
|
||||
int kind,
|
||||
FlyTextKind kind,
|
||||
int val1,
|
||||
int val2,
|
||||
IntPtr text2,
|
||||
|
|
@ -211,7 +211,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
|
||||
var handled = false;
|
||||
|
||||
var tmpKind = (FlyTextKind)kind;
|
||||
var tmpKind = kind;
|
||||
var tmpVal1 = val1;
|
||||
var tmpVal2 = val2;
|
||||
var tmpText1 = MemoryHelper.ReadSeStringNullTerminated(text1);
|
||||
|
|
@ -224,7 +224,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
var cmpText2 = tmpText2.ToString();
|
||||
|
||||
Log.Verbose($"[FlyText] Called with addonFlyText({addonFlyText.ToInt64():X}) " +
|
||||
$"kind({((FlyTextKind)kind).ToString()}) val1({val1}) val2({val2}) " +
|
||||
$"kind({kind}) val1({val1}) val2({val2}) " +
|
||||
$"text1({text1.ToInt64():X}, \"{tmpText1}\") text2({text2.ToInt64():X}, \"{tmpText2}\") " +
|
||||
$"color({color:X}) icon({icon}) yOffset({yOffset})");
|
||||
Log.Verbose("[FlyText] Calling flytext events!");
|
||||
|
|
@ -250,14 +250,14 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
}
|
||||
|
||||
// Check if any values have changed
|
||||
var dirty = tmpKind != (FlyTextKind)kind ||
|
||||
tmpVal1 != val1 ||
|
||||
tmpVal2 != val2 ||
|
||||
tmpText1.ToString() != cmpText1 ||
|
||||
tmpText2.ToString() != cmpText2 ||
|
||||
tmpColor != color ||
|
||||
tmpIcon != icon ||
|
||||
Math.Abs(tmpYOffset - yOffset) > float.Epsilon;
|
||||
var dirty = tmpKind != kind ||
|
||||
tmpVal1 != val1 ||
|
||||
tmpVal2 != val2 ||
|
||||
tmpText1.ToString() != cmpText1 ||
|
||||
tmpText2.ToString() != cmpText2 ||
|
||||
tmpColor != color ||
|
||||
tmpIcon != icon ||
|
||||
Math.Abs(tmpYOffset - yOffset) > float.Epsilon;
|
||||
|
||||
// If not dirty, make the original call
|
||||
if (!dirty)
|
||||
|
|
@ -276,7 +276,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
|
||||
retVal = this.createFlyTextHook.Original(
|
||||
addonFlyText,
|
||||
(int)tmpKind,
|
||||
tmpKind,
|
||||
tmpVal1,
|
||||
tmpVal2,
|
||||
pText2,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// Enum of FlyTextKind values. Members suffixed with
|
||||
/// a number seem to be a duplicate, or perform duplicate behavior.
|
||||
/// </summary>
|
||||
public enum FlyTextKind
|
||||
public enum FlyTextKind : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Val1 in serif font, Text2 in sans-serif as subtitle.
|
||||
|
|
@ -19,8 +19,8 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
DirectHit = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in larger serif font with exclamation, with Text2
|
||||
/// in sans-serif as subtitle. Does a bigger bounce effect on appearance.
|
||||
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle.
|
||||
/// Does a bigger bounce effect on appearance.
|
||||
/// </summary>
|
||||
CriticalHit = 2,
|
||||
|
||||
|
|
@ -75,6 +75,10 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// Icon next to sans-serif Text1.
|
||||
/// </summary>
|
||||
NamedIcon = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Icon next to sans-serif Text1 (2).
|
||||
/// </summary>
|
||||
NamedIcon2 = 13,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -92,8 +96,19 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// </summary>
|
||||
NamedTp = 16,
|
||||
|
||||
/// <summary>
|
||||
/// AutoAttack with sans-serif Text1 to the left of the Val1 (2).
|
||||
/// </summary>
|
||||
NamedAttack2 = 17,
|
||||
|
||||
/// <summary>
|
||||
/// Sans-serif Text1 next to serif Val1 with all caps condensed font MP with Text2 in sans-serif as subtitle (2).
|
||||
/// </summary>
|
||||
NamedMp2 = 18,
|
||||
|
||||
/// <summary>
|
||||
/// Sans-serif Text1 next to serif Val1 with all caps condensed font TP with Text2 in sans-serif as subtitle (2).
|
||||
/// </summary>
|
||||
NamedTp2 = 19,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -122,9 +137,25 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// AutoAttack with no Text2.
|
||||
/// </summary>
|
||||
AutoAttackNoText = 24,
|
||||
|
||||
/// <summary>
|
||||
/// AutoAttack with no Text2 (2).
|
||||
/// </summary>
|
||||
AutoAttackNoText2 = 25,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle. Does a bigger bounce effect on appearance (2).
|
||||
/// </summary>
|
||||
CriticalHit2 = 26,
|
||||
|
||||
/// <summary>
|
||||
/// AutoAttack with no Text2 (3).
|
||||
/// </summary>
|
||||
AutoAttackNoText3 = 27,
|
||||
|
||||
/// <summary>
|
||||
/// CriticalHit with sans-serif Text1 to the left of the Val1 (2).
|
||||
/// </summary>
|
||||
NamedCriticalHit2 = 28,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -148,6 +179,11 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// Same as NamedIcon but Text1 is slightly faded. Used for buff expiration.
|
||||
/// </summary>
|
||||
NamedIconFaded = 32,
|
||||
|
||||
/// <summary>
|
||||
/// Same as NamedIcon but Text1 is slightly faded (2).
|
||||
/// Used for buff expiration.
|
||||
/// </summary>
|
||||
NamedIconFaded2 = 33,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -175,8 +211,19 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// </summary>
|
||||
NamedHasNoEffect = 38,
|
||||
|
||||
/// <summary>
|
||||
/// AutoAttack with sans-serif Text1 to the left of the Val1 (3).
|
||||
/// </summary>
|
||||
NamedAttack3 = 39,
|
||||
|
||||
/// <summary>
|
||||
/// Sans-serif Text1 next to serif Val1 with all caps condensed font MP with Text2 in sans-serif as subtitle (3).
|
||||
/// </summary>
|
||||
NamedMp3 = 40,
|
||||
|
||||
/// <summary>
|
||||
/// Sans-serif Text1 next to serif Val1 with all caps condensed font TP with Text2 in sans-serif as subtitle (3).
|
||||
/// </summary>
|
||||
NamedTp3 = 41,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -194,7 +241,15 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// </summary>
|
||||
NamedIconWithItemOutline = 44,
|
||||
|
||||
/// <summary>
|
||||
/// AutoAttack with no Text2 (4).
|
||||
/// </summary>
|
||||
AutoAttackNoText4 = 45,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle (3).
|
||||
/// Does a bigger bounce effect on appearance.
|
||||
/// </summary>
|
||||
CriticalHit3 = 46,
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -207,8 +262,22 @@ namespace Dalamud.Game.Gui.FlyText
|
|||
/// </summary>
|
||||
Reflected = 48,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in serif font, Text2 in sans-serif as subtitle (2).
|
||||
/// Does a bounce effect on appearance.
|
||||
/// </summary>
|
||||
DirectHit2 = 49,
|
||||
CriticalHit5 = 50,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in larger serif font with exclamation, with Text2 in sans-serif as subtitle (4).
|
||||
/// Does a bigger bounce effect on appearance.
|
||||
/// </summary>
|
||||
CriticalHit4 = 50,
|
||||
|
||||
/// <summary>
|
||||
/// Val1 in even larger serif font with 2 exclamations, Text2 in sans-serif as subtitle (2).
|
||||
/// Does a large bounce effect on appearance. Does not scroll up or down the screen.
|
||||
/// </summary>
|
||||
CriticalDirectHit2 = 51,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ using System;
|
|||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Game.Gui.Addons;
|
||||
using Dalamud.Game.Gui.FlyText;
|
||||
using Dalamud.Game.Gui.PartyFinder;
|
||||
using Dalamud.Game.Gui.Toast;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Interface;
|
||||
|
|
@ -23,10 +23,7 @@ namespace Dalamud.Game.Gui
|
|||
private readonly GameGuiAddressResolver address;
|
||||
|
||||
private readonly GetMatrixSingletonDelegate getMatrixSingleton;
|
||||
private readonly GetUIObjectDelegate getUIObject;
|
||||
private readonly ScreenToWorldNativeDelegate screenToWorldNative;
|
||||
private readonly GetUIObjectByNameDelegate getUIObjectByName;
|
||||
private readonly GetUiModuleDelegate getUiModule;
|
||||
private readonly GetAgentModuleDelegate getAgentModule;
|
||||
|
||||
private readonly Hook<SetGlobalBgmDelegate> setGlobalBgmHook;
|
||||
|
|
@ -61,7 +58,6 @@ namespace Dalamud.Game.Gui
|
|||
Log.Verbose($"HandleItemHover address 0x{this.address.HandleItemHover.ToInt64():X}");
|
||||
Log.Verbose($"HandleItemOut address 0x{this.address.HandleItemOut.ToInt64():X}");
|
||||
Log.Verbose($"HandleImm address 0x{this.address.HandleImm.ToInt64():X}");
|
||||
Log.Verbose($"GetUIObject address 0x{this.address.GetUIObject.ToInt64():X}");
|
||||
Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}");
|
||||
|
||||
this.Chat = new ChatGui(this.address.ChatManager, scanner, dalamud);
|
||||
|
|
@ -79,44 +75,23 @@ namespace Dalamud.Game.Gui
|
|||
|
||||
this.handleImmHook = new Hook<HandleImmDelegate>(this.address.HandleImm, this.HandleImmDetour);
|
||||
|
||||
this.getUIObject = Marshal.GetDelegateForFunctionPointer<GetUIObjectDelegate>(this.address.GetUIObject);
|
||||
|
||||
this.getMatrixSingleton = Marshal.GetDelegateForFunctionPointer<GetMatrixSingletonDelegate>(this.address.GetMatrixSingleton);
|
||||
|
||||
this.screenToWorldNative = Marshal.GetDelegateForFunctionPointer<ScreenToWorldNativeDelegate>(this.address.ScreenToWorld);
|
||||
|
||||
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(this.address.ToggleUiHide, this.ToggleUiHideDetour);
|
||||
|
||||
this.GetBaseUIObject = Marshal.GetDelegateForFunctionPointer<GetBaseUIObjectDelegate>(this.address.GetBaseUIObject);
|
||||
this.getUIObjectByName = Marshal.GetDelegateForFunctionPointer<GetUIObjectByNameDelegate>(this.address.GetUIObjectByName);
|
||||
|
||||
this.getUiModule = Marshal.GetDelegateForFunctionPointer<GetUiModuleDelegate>(this.address.GetUIModule);
|
||||
this.getAgentModule = Marshal.GetDelegateForFunctionPointer<GetAgentModuleDelegate>(this.address.GetAgentModule);
|
||||
}
|
||||
|
||||
// Marshaled delegates
|
||||
|
||||
/// <summary>
|
||||
/// The delegate type of the native method that gets the Client::UI::UIModule address.
|
||||
/// </summary>
|
||||
/// <returns>The Client::UI::UIModule address.</returns>
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate IntPtr GetBaseUIObjectDelegate();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate IntPtr GetMatrixSingletonDelegate();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate IntPtr GetUIObjectDelegate();
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||
private unsafe delegate bool ScreenToWorldNativeDelegate(float* camPos, float* clipPos, float rayDistance, float* worldPos, int* unknown);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Ansi)]
|
||||
private delegate IntPtr GetUIObjectByNameDelegate(IntPtr thisPtr, string uiName, int index);
|
||||
|
||||
private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr);
|
||||
|
||||
private delegate IntPtr GetAgentModuleDelegate(IntPtr uiModule);
|
||||
|
||||
// Hooked delegates
|
||||
|
|
@ -153,12 +128,6 @@ namespace Dalamud.Game.Gui
|
|||
/// </summary>
|
||||
public event EventHandler<bool> OnUiHideToggled;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a callable delegate for the GetBaseUIObject game method.
|
||||
/// </summary>
|
||||
/// <returns>The Client::UI::UIModule address.</returns>
|
||||
public GetBaseUIObjectDelegate GetBaseUIObject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Chat"/> instance.
|
||||
/// </summary>
|
||||
|
|
@ -212,19 +181,19 @@ namespace Dalamud.Game.Gui
|
|||
/// <returns>True if there were no errors and it could open the map.</returns>
|
||||
public bool OpenMapWithMapLink(MapLinkPayload mapLink)
|
||||
{
|
||||
var uiObjectPtr = this.getUIObject();
|
||||
var uiModule = this.GetUIModule();
|
||||
|
||||
if (uiObjectPtr.Equals(IntPtr.Zero))
|
||||
if (uiModule == IntPtr.Zero)
|
||||
{
|
||||
Log.Error("OpenMapWithMapLink: Null pointer returned from getUIObject()");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.getUIMapObject = this.address.GetVirtualFunction<GetUIMapObjectDelegate>(uiObjectPtr, 0, 8);
|
||||
this.getUIMapObject = this.address.GetVirtualFunction<GetUIMapObjectDelegate>(uiModule, 0, 8);
|
||||
|
||||
var uiMapObjectPtr = this.getUIMapObject(uiObjectPtr);
|
||||
var uiMapObjectPtr = this.getUIMapObject(uiModule);
|
||||
|
||||
if (uiMapObjectPtr.Equals(IntPtr.Zero))
|
||||
if (uiMapObjectPtr == IntPtr.Zero)
|
||||
{
|
||||
Log.Error("OpenMapWithMapLink: Null pointer returned from GetUIMapObject()");
|
||||
return false;
|
||||
|
|
@ -407,37 +376,40 @@ namespace Dalamud.Game.Gui
|
|||
/// Gets a pointer to the game's UI module.
|
||||
/// </summary>
|
||||
/// <returns>IntPtr pointing to UI module.</returns>
|
||||
public IntPtr GetUIModule() => this.getUiModule(this.dalamud.Framework.Address.BaseAddress);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the UI Object with the given name and index.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of UI to find.</param>
|
||||
/// <param name="index">Index of UI to find (1-indexed).</param>
|
||||
/// <returns>IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the UI Object.</returns>
|
||||
public IntPtr GetUiObjectByName(string name, int index)
|
||||
public unsafe IntPtr GetUIModule()
|
||||
{
|
||||
var baseUi = this.GetBaseUIObject();
|
||||
if (baseUi == IntPtr.Zero) return IntPtr.Zero;
|
||||
var baseUiProperties = Marshal.ReadIntPtr(baseUi, 0x20);
|
||||
if (baseUiProperties == IntPtr.Zero) return IntPtr.Zero;
|
||||
return this.getUIObjectByName(baseUiProperties, name, index);
|
||||
var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance();
|
||||
if (framework == null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
var uiModule = framework->GetUiModule();
|
||||
if (uiModule == null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
return (IntPtr)uiModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an Addon by it's internal name.
|
||||
/// Gets the pointer to the Addon with the given name and index.
|
||||
/// </summary>
|
||||
/// <param name="name">The addon name.</param>
|
||||
/// <param name="index">The index of the addon, starting at 1.</param>
|
||||
/// <returns>The native memory representation of the addon, if it exists.</returns>
|
||||
public Addon GetAddonByName(string name, int index)
|
||||
/// <param name="name">Name of addon to find.</param>
|
||||
/// <param name="index">Index of addon to find (1-indexed).</param>
|
||||
/// <returns>IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the addon.</returns>
|
||||
public unsafe IntPtr GetAddonByName(string name, int index)
|
||||
{
|
||||
var address = this.GetUiObjectByName(name, index);
|
||||
var atkStage = FFXIVClientStructs.FFXIV.Component.GUI.AtkStage.GetSingleton();
|
||||
if (atkStage == null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
return null;
|
||||
var unitMgr = atkStage->RaptureAtkUnitManager;
|
||||
if (unitMgr == null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
return new Addon(address);
|
||||
var addon = unitMgr->GetAddonByName(name, index);
|
||||
if (addon == null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
return (IntPtr)addon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -447,7 +419,7 @@ namespace Dalamud.Game.Gui
|
|||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public IntPtr FindAgentInterface(string addonName)
|
||||
{
|
||||
var addon = this.dalamud.Framework.Gui.GetUiObjectByName(addonName, 1);
|
||||
var addon = this.GetAddonByName(addonName, 1);
|
||||
return this.FindAgentInterface(addon);
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +428,14 @@ namespace Dalamud.Game.Gui
|
|||
/// </summary>
|
||||
/// <param name="addon">The addon address.</param>
|
||||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public IntPtr FindAgentInterface(IntPtr addon)
|
||||
public unsafe IntPtr FindAgentInterface(void* addon) => this.FindAgentInterface((IntPtr)addon);
|
||||
|
||||
/// <summary>
|
||||
/// Find the agent associated with an addon, if possible.
|
||||
/// </summary>
|
||||
/// <param name="addon">The addon address.</param>
|
||||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public unsafe IntPtr FindAgentInterface(IntPtr addon)
|
||||
{
|
||||
if (addon == IntPtr.Zero)
|
||||
return IntPtr.Zero;
|
||||
|
|
@ -473,9 +452,10 @@ namespace Dalamud.Game.Gui
|
|||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var id = Marshal.ReadInt16(addon, 0x1CE);
|
||||
var unitBase = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)addon;
|
||||
var id = unitBase->ParentID;
|
||||
if (id == 0)
|
||||
id = Marshal.ReadInt16(addon, 0x1CC);
|
||||
id = unitBase->ID;
|
||||
|
||||
if (id == 0)
|
||||
return IntPtr.Zero;
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ namespace Dalamud.Game.Gui
|
|||
/// </summary>
|
||||
public IntPtr HandleImm { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native GetUIObject method.
|
||||
/// </summary>
|
||||
public IntPtr GetUIObject { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native GetMatrixSingleton method.
|
||||
/// </summary>
|
||||
|
|
@ -77,21 +72,6 @@ namespace Dalamud.Game.Gui
|
|||
/// </summary>
|
||||
public IntPtr ToggleUiHide { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native Client::UI::UIModule getter method.
|
||||
/// </summary>
|
||||
public IntPtr GetBaseUIObject { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native GetUIObjectByName method.
|
||||
/// </summary>
|
||||
public IntPtr GetUIObjectByName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native GetUIModule method.
|
||||
/// </summary>
|
||||
public IntPtr GetUIModule { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the native GetAgentModule method.
|
||||
/// </summary>
|
||||
|
|
@ -106,13 +86,9 @@ namespace Dalamud.Game.Gui
|
|||
this.HandleActionHover = sig.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 83 F8 0F");
|
||||
this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
|
||||
this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09");
|
||||
this.GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
|
||||
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
||||
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
|
||||
this.ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
|
||||
this.GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF");
|
||||
this.GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00");
|
||||
this.GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 85 C0 75 2D");
|
||||
|
||||
var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28");
|
||||
this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using Dalamud.Game.Gui.Toast;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Hooking;
|
||||
|
||||
namespace Dalamud.Game.Gui
|
||||
namespace Dalamud.Game.Gui.Toast
|
||||
{
|
||||
/// <summary>
|
||||
/// This class facilitates interacting with and creating native toast windows.
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Game.Internal;
|
||||
|
||||
namespace Dalamud.Game.Gui
|
||||
namespace Dalamud.Game.Gui.Toast
|
||||
{
|
||||
/// <summary>
|
||||
/// An address resolver for the <see cref="ToastGui"/> class.
|
||||
|
|
@ -160,27 +160,25 @@ namespace Dalamud.Game.Network
|
|||
return this.processZonePacketUpHook.Original(a1, dataPtr, a3, a4);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private void InjectZoneProtoPacket(byte[] data)
|
||||
{
|
||||
this.zoneInjectQueue.Enqueue(data);
|
||||
}
|
||||
// private void InjectZoneProtoPacket(byte[] data)
|
||||
// {
|
||||
// this.zoneInjectQueue.Enqueue(data);
|
||||
// }
|
||||
|
||||
private void InjectActorControl(short cat, int param1)
|
||||
{
|
||||
var packetData = new byte[]
|
||||
{
|
||||
0x14, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x17, 0x7C, 0xC5, 0x5D, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x48, 0xB2, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x43, 0x7F, 0x00, 0x00,
|
||||
};
|
||||
|
||||
BitConverter.GetBytes((short)cat).CopyTo(packetData, 0x10);
|
||||
|
||||
BitConverter.GetBytes((uint)param1).CopyTo(packetData, 0x14);
|
||||
|
||||
this.InjectZoneProtoPacket(packetData);
|
||||
}
|
||||
#endif
|
||||
// private void InjectActorControl(short cat, int param1)
|
||||
// {
|
||||
// var packetData = new byte[]
|
||||
// {
|
||||
// 0x14, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x17, 0x7C, 0xC5, 0x5D, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x05, 0x00, 0x48, 0xB2, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// 0x00, 0x00, 0x00, 0x00, 0x43, 0x7F, 0x00, 0x00,
|
||||
// };
|
||||
//
|
||||
// BitConverter.GetBytes((short)cat).CopyTo(packetData, 0x10);
|
||||
//
|
||||
// BitConverter.GetBytes((uint)param1).CopyTo(packetData, 0x14);
|
||||
//
|
||||
// this.InjectZoneProtoPacket(packetData);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,15 @@ namespace Dalamud.Game
|
|||
private IntPtr moduleCopyPtr;
|
||||
private long moduleCopyOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SigScanner"/> class using the main module of the current process.
|
||||
/// </summary>
|
||||
/// <param name="doCopy">Whether or not to copy the module upon initialization for search operations to use, as to not get disturbed by possible hooks.</param>
|
||||
public SigScanner(bool doCopy = false)
|
||||
: this(Process.GetCurrentProcess().MainModule!, doCopy)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SigScanner"/> class.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -84,31 +84,16 @@ namespace Dalamud.Game.Text.Sanitizer
|
|||
};
|
||||
}
|
||||
|
||||
private static IEnumerable<string> SanitizeByLanguage(
|
||||
IEnumerable<string> unsanitizedStrings, ClientLanguage clientLanguage)
|
||||
private static IEnumerable<string> SanitizeByLanguage(IEnumerable<string> unsanitizedStrings, ClientLanguage clientLanguage)
|
||||
{
|
||||
var sanitizedStrings = new List<string>();
|
||||
switch (clientLanguage)
|
||||
return clientLanguage switch
|
||||
{
|
||||
case ClientLanguage.Japanese:
|
||||
case ClientLanguage.English:
|
||||
sanitizedStrings.AddRange(unsanitizedStrings.Select(FilterUnprintableCharacters));
|
||||
return sanitizedStrings;
|
||||
case ClientLanguage.German:
|
||||
sanitizedStrings.AddRange(
|
||||
unsanitizedStrings.Select(
|
||||
unsanitizedString =>
|
||||
FilterByDict(FilterUnprintableCharacters(unsanitizedString), DESanitizationDict)));
|
||||
return sanitizedStrings;
|
||||
case ClientLanguage.French:
|
||||
sanitizedStrings.AddRange(
|
||||
unsanitizedStrings.Select(
|
||||
unsanitizedString =>
|
||||
FilterByDict(FilterUnprintableCharacters(unsanitizedString), FRSanitizationDict)));
|
||||
return sanitizedStrings;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(clientLanguage), clientLanguage, null);
|
||||
}
|
||||
ClientLanguage.Japanese => unsanitizedStrings.Select(FilterUnprintableCharacters),
|
||||
ClientLanguage.English => unsanitizedStrings.Select(FilterUnprintableCharacters),
|
||||
ClientLanguage.German => unsanitizedStrings.Select(original => FilterByDict(FilterUnprintableCharacters(original), DESanitizationDict)),
|
||||
ClientLanguage.French => unsanitizedStrings.Select(original => FilterByDict(FilterUnprintableCharacters(original), FRSanitizationDict)),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(clientLanguage), clientLanguage, null),
|
||||
};
|
||||
}
|
||||
|
||||
private static string FilterUnprintableCharacters(string str)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||
|
||||
using Dalamud.Plugin;
|
||||
using ImGuiNET;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using Serilog;
|
||||
|
|
@ -65,10 +64,10 @@ namespace Dalamud.Interface.Internal.Scratchpad
|
|||
var options = ScriptOptions.Default
|
||||
.AddReferences(typeof(ImGui).Assembly)
|
||||
.AddReferences(typeof(Dalamud).Assembly)
|
||||
.AddReferences(typeof(FFXIVClientStructs.Attributes.Addon).Assembly) // FFXIVClientStructs
|
||||
.AddReferences(typeof(FFXIVClientStructs.Resolver).Assembly) // FFXIVClientStructs
|
||||
.AddReferences(typeof(Lumina.GameData).Assembly) // Lumina
|
||||
.AddReferences(typeof(TerritoryType).Assembly) // Lumina.Excel
|
||||
// .WithReferences(MetadataReference.CreateFromFile(typeof(ScratchExecutionManager).Assembly.Location))
|
||||
.AddReferences(typeof(Lumina.Excel.GeneratedSheets.TerritoryType).Assembly) // Lumina.Excel
|
||||
// .WithReferences(MetadataReference.CreateFromFile(typeof(ScratchExecutionManager).Assembly.Location))
|
||||
.AddImports("System")
|
||||
.AddImports("System.IO")
|
||||
.AddImports("System.Reflection")
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ using Dalamud.Game.ClientState.JobGauge.Enums;
|
|||
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Game.Gui.Addons;
|
||||
using Dalamud.Game.Gui.FlyText;
|
||||
using Dalamud.Game.Gui.Toast;
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Memory;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
|
@ -45,7 +45,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
|
||||
private string inputAddonName = string.Empty;
|
||||
private int inputAddonIndex;
|
||||
private Addon resultAddon;
|
||||
|
||||
private IntPtr findAgentInterfacePtr;
|
||||
|
||||
|
|
@ -130,7 +129,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
/// <inheritdoc/>
|
||||
public override void OnClose()
|
||||
{
|
||||
this.resultAddon = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -843,22 +841,31 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
ImGui.Text($"{command.Key}\n -> {command.Value.HelpMessage}\n -> In help: {command.Value.ShowInHelp}\n\n");
|
||||
}
|
||||
|
||||
private void DrawAddon()
|
||||
private unsafe void DrawAddon()
|
||||
{
|
||||
var gameGui = this.dalamud.Framework.Gui;
|
||||
|
||||
ImGui.InputText("Addon name", ref this.inputAddonName, 256);
|
||||
ImGui.InputInt("Addon Index", ref this.inputAddonIndex);
|
||||
|
||||
if (ImGui.Button("Get Addon"))
|
||||
if (this.inputAddonName.IsNullOrEmpty())
|
||||
return;
|
||||
|
||||
var address = gameGui.GetAddonByName(this.inputAddonName, this.inputAddonIndex);
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
{
|
||||
this.resultAddon = this.dalamud.Framework.Gui.GetAddonByName(this.inputAddonName, this.inputAddonIndex);
|
||||
ImGui.Text("Null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui.Button("Find Agent"))
|
||||
this.findAgentInterfacePtr = this.dalamud.Framework.Gui.FindAgentInterface(this.inputAddonName);
|
||||
var addon = (FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase*)address;
|
||||
var name = MemoryHelper.ReadStringNullTerminated((IntPtr)addon->Name);
|
||||
ImGui.TextUnformatted($"{name} - 0x{address.ToInt64():x}\n v:{addon->IsVisible} x:{addon->X} y:{addon->Y} s:{addon->Scale}, w:{addon->RootNode->Width}, h:{addon->RootNode->Height}");
|
||||
|
||||
if (this.resultAddon != null)
|
||||
if (ImGui.Button("Find Agent"))
|
||||
{
|
||||
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}");
|
||||
this.findAgentInterfacePtr = gameGui.FindAgentInterface(address);
|
||||
}
|
||||
|
||||
if (this.findAgentInterfacePtr != IntPtr.Zero)
|
||||
|
|
@ -869,13 +876,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
if (ImGui.Button("C"))
|
||||
ImGui.SetClipboardText(this.findAgentInterfacePtr.ToInt64().ToString("x"));
|
||||
}
|
||||
|
||||
if (ImGui.Button("Get Base UI object"))
|
||||
{
|
||||
var addr = this.dalamud.Framework.Gui.GetBaseUIObject().ToInt64().ToString("x");
|
||||
Log.Information("{0}", addr);
|
||||
ImGui.SetClipboardText(addr);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAddonInspector()
|
||||
|
|
@ -977,7 +977,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
if (ImGui.BeginCombo("Kind", this.flyKind.ToString()))
|
||||
{
|
||||
var names = Enum.GetNames(typeof(FlyTextKind));
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (ImGui.Selectable($"{names[i]} ({i})"))
|
||||
this.flyKind = (FlyTextKind)i;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
|
@ -20,7 +19,6 @@ namespace Dalamud.Memory
|
|||
public static unsafe class MemoryHelper
|
||||
{
|
||||
private static SeStringManager seStringManager;
|
||||
private static IntPtr handle;
|
||||
|
||||
#region Read
|
||||
|
||||
|
|
@ -174,8 +172,23 @@ namespace Dalamud.Memory
|
|||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <returns>The read in string.</returns>
|
||||
public static string ReadString(IntPtr memoryAddress)
|
||||
=> ReadString(memoryAddress, 256);
|
||||
public static string ReadStringNullTerminated(IntPtr memoryAddress)
|
||||
=> ReadStringNullTerminated(memoryAddress, Encoding.UTF8);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attention! If this is an SeString, use the <see cref="SeStringManager"/> to decode or the applicable helper method.
|
||||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <param name="encoding">The encoding to use to decode the string.</param>
|
||||
/// <returns>The read in string.</returns>
|
||||
public static string ReadStringNullTerminated(IntPtr memoryAddress, Encoding encoding)
|
||||
{
|
||||
var buffer = ReadRawNullTerminated(memoryAddress);
|
||||
return encoding.GetString(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a UTF-8 encoded string from a specified memory address.
|
||||
|
|
@ -189,18 +202,6 @@ namespace Dalamud.Memory
|
|||
public static string ReadString(IntPtr memoryAddress, int maxLength)
|
||||
=> ReadString(memoryAddress, Encoding.UTF8, maxLength);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attention! If this is an SeString, use the <see cref="SeStringManager"/> to decode or the applicable helper method.
|
||||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <param name="encoding">The encoding to use to decode the string.</param>
|
||||
/// <returns>The read in string.</returns>
|
||||
public static string ReadString(IntPtr memoryAddress, Encoding encoding)
|
||||
=> ReadString(memoryAddress, encoding, 256);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
|
|
@ -288,8 +289,20 @@ namespace Dalamud.Memory
|
|||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <param name="value">The read in string.</param>
|
||||
public static void ReadString(IntPtr memoryAddress, out string value)
|
||||
=> value = ReadString(memoryAddress);
|
||||
public static void ReadStringNullTerminated(IntPtr memoryAddress, out string value)
|
||||
=> value = ReadStringNullTerminated(memoryAddress);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attention! If this is an SeString, use the <see cref="SeStringManager"/> to decode or the applicable helper method.
|
||||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <param name="encoding">The encoding to use to decode the string.</param>
|
||||
/// <param name="value">The read in string.</param>
|
||||
public static void ReadStringNullTerminated(IntPtr memoryAddress, Encoding encoding, out string value)
|
||||
=> value = ReadStringNullTerminated(memoryAddress, encoding);
|
||||
|
||||
/// <summary>
|
||||
/// Read a UTF-8 encoded string from a specified memory address.
|
||||
|
|
@ -303,18 +316,6 @@ namespace Dalamud.Memory
|
|||
public static void ReadString(IntPtr memoryAddress, out string value, int maxLength)
|
||||
=> value = ReadString(memoryAddress, maxLength);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Attention! If this is an SeString, use the <see cref="SeStringManager"/> to decode or the applicable helper method.
|
||||
/// </remarks>
|
||||
/// <param name="memoryAddress">The memory address to read from.</param>
|
||||
/// <param name="encoding">The encoding to use to decode the string.</param>
|
||||
/// <param name="value">The read in string.</param>
|
||||
public static void ReadString(IntPtr memoryAddress, Encoding encoding, out string value)
|
||||
=> value = ReadString(memoryAddress, encoding);
|
||||
|
||||
/// <summary>
|
||||
/// Read a string with the given encoding from a specified memory address.
|
||||
/// </summary>
|
||||
|
|
@ -584,7 +585,7 @@ namespace Dalamud.Memory
|
|||
public static void ReadProcessMemory(IntPtr memoryAddress, ref byte[] value)
|
||||
{
|
||||
var length = value.Length;
|
||||
var result = NativeFunctions.ReadProcessMemory(handle, memoryAddress, value, length, out _);
|
||||
var result = NativeFunctions.ReadProcessMemory((IntPtr)0xFFFFFFFF, memoryAddress, value, length, out _);
|
||||
|
||||
if (!result)
|
||||
throw new MemoryReadException($"Unable to read memory at 0x{memoryAddress.ToInt64():X} of length {length} (result={result})");
|
||||
|
|
@ -603,7 +604,7 @@ namespace Dalamud.Memory
|
|||
public static void WriteProcessMemory(IntPtr memoryAddress, byte[] data)
|
||||
{
|
||||
var length = data.Length;
|
||||
var result = NativeFunctions.WriteProcessMemory(handle, memoryAddress, data, length, out _);
|
||||
var result = NativeFunctions.WriteProcessMemory((IntPtr)0xFFFFFFFF, memoryAddress, data, length, out _);
|
||||
|
||||
if (!result)
|
||||
throw new MemoryWriteException($"Unable to write memory at 0x{memoryAddress.ToInt64():X} of length {length} (result={result})");
|
||||
|
|
@ -662,7 +663,6 @@ namespace Dalamud.Memory
|
|||
internal static void Initialize(Dalamud dalamud)
|
||||
{
|
||||
seStringManager = dalamud.SeStringManager;
|
||||
handle = Process.GetCurrentProcess().Handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
|
|
@ -36,12 +35,20 @@ int InitializeClrAndGetEntryPoint(
|
|||
CoreCLR clr;
|
||||
SetEnvironmentVariable(L"DOTNET_MULTILEVEL_LOOKUP", L"0");
|
||||
|
||||
char* env_path = std::getenv("DALAMUD_RUNTIME");
|
||||
wchar_t* dotnet_path;
|
||||
|
||||
wchar_t* _appdata;
|
||||
|
||||
if (!env_path)
|
||||
std::wstring buffer;
|
||||
buffer.resize(0);
|
||||
result = GetEnvironmentVariableW(L"DALAMUD_RUNTIME", &buffer[0], 0);
|
||||
|
||||
if (result)
|
||||
{
|
||||
buffer.resize(result); // The first pass returns the required length
|
||||
result = GetEnvironmentVariableW(L"DALAMUD_RUNTIME", &buffer[0], result);
|
||||
dotnet_path = _wcsdup(buffer.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, nullptr, &_appdata);
|
||||
|
||||
|
|
@ -54,12 +61,6 @@ int InitializeClrAndGetEntryPoint(
|
|||
std::filesystem::path fs_app_data(_appdata);
|
||||
dotnet_path = _wcsdup(fs_app_data.append("XIVLauncher").append("runtime").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t cSize = strlen(env_path)+1;
|
||||
dotnet_path = new wchar_t[cSize];
|
||||
mbstowcs (dotnet_path, env_path, cSize);
|
||||
}
|
||||
|
||||
// =========================================================================== //
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue