refactor: break stuff
This commit is contained in:
parent
5149196b9b
commit
a1505c2f5f
|
@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Dalamud.Game;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
|
@ -13,31 +14,35 @@ namespace XivCommon.Functions {
|
|||
internal const string SendChat = "48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9";
|
||||
}
|
||||
|
||||
private GameFunctions Functions { get; }
|
||||
|
||||
private delegate void ProcessChatBoxDelegate(IntPtr uiModule, IntPtr message, IntPtr unused, byte a4);
|
||||
|
||||
private ProcessChatBoxDelegate? ProcessChatBox { get; }
|
||||
|
||||
internal Chat(GameFunctions functions, SigScanner scanner) {
|
||||
this.Functions = functions;
|
||||
|
||||
internal Chat(SigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.SendChat, out var processChatBoxPtr, "chat sending")) {
|
||||
this.ProcessChatBox = Marshal.GetDelegateForFunctionPointer<ProcessChatBoxDelegate>(processChatBoxPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Send a given message to the chat box. <b>This can send chat to the server.</b>
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>This method is unsafe.</b> This method does no checking on your input and
|
||||
/// may send content to the server that the normal client could not. You must
|
||||
/// verify what you're sending and handle content and length to properly use
|
||||
/// this.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="message">Message to send</param>
|
||||
/// <exception cref="InvalidOperationException">If the signature for this function could not be found</exception>
|
||||
public unsafe void SendMessage(string message) {
|
||||
public unsafe void SendMessageUnsafe(byte[] message) {
|
||||
if (this.ProcessChatBox == null) {
|
||||
throw new InvalidOperationException("Could not find signature for chat sending");
|
||||
}
|
||||
|
||||
var uiModule = (IntPtr) this.Functions.GetFramework()->GetUiModule();
|
||||
var uiModule = (IntPtr) Framework.Instance()->GetUiModule();
|
||||
|
||||
using var payload = new ChatPayload(message);
|
||||
var mem1 = Marshal.AllocHGlobal(400);
|
||||
|
@ -48,6 +53,32 @@ namespace XivCommon.Functions {
|
|||
Marshal.FreeHGlobal(mem1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Send a given message to the chat box. <b>This can send chat to the server.</b>
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This method is slightly less unsafe than <see cref="SendMessageUnsafe"/>. It
|
||||
/// will throw exceptions for certain inputs that the client can't normally send,
|
||||
/// but it is still possible to make mistakes. Use with caution.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <exception cref="ArgumentException">If <paramref name="message"/> is empty or longer than 500 bytes in UTF-8.</exception>
|
||||
/// <exception cref="InvalidOperationException">If the signature for this function could not be found</exception>
|
||||
public void SendMessage(string message) {
|
||||
var bytes = Encoding.UTF8.GetBytes(message);
|
||||
if (bytes.Length == 0) {
|
||||
throw new ArgumentException("message is empty", nameof(message));
|
||||
}
|
||||
|
||||
if (bytes.Length > 500) {
|
||||
throw new ArgumentException("message is longer than 500 bytes", nameof(message));
|
||||
}
|
||||
|
||||
this.SendMessageUnsafe(bytes);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
[SuppressMessage("ReSharper", "PrivateFieldCanBeConvertedToLocalVariable")]
|
||||
private readonly struct ChatPayload : IDisposable {
|
||||
|
@ -63,8 +94,7 @@ namespace XivCommon.Functions {
|
|||
[FieldOffset(24)]
|
||||
private readonly ulong unk2;
|
||||
|
||||
internal ChatPayload(string text) {
|
||||
var stringBytes = Encoding.UTF8.GetBytes(text);
|
||||
internal ChatPayload(byte[] stringBytes) {
|
||||
this.textPtr = Marshal.AllocHGlobal(stringBytes.Length + 30);
|
||||
Marshal.Copy(stringBytes, 0, this.textPtr, stringBytes.Length);
|
||||
Marshal.WriteByte(this.textPtr + stringBytes.Length, 0);
|
||||
|
|
|
@ -11,6 +11,7 @@ using Dalamud.Hooking;
|
|||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using XivCommon.Functions.ContextMenu.Inventory;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
|
||||
|
||||
namespace XivCommon.Functions.ContextMenu {
|
||||
|
@ -286,7 +287,7 @@ namespace XivCommon.Functions.ContextMenu {
|
|||
agent ??= this.Agent;
|
||||
|
||||
IntPtr GetAgent(AgentId id) {
|
||||
return (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(id);
|
||||
return (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(id);
|
||||
}
|
||||
|
||||
var agentType = AgentType.Unknown;
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
|
@ -18,13 +19,10 @@ namespace XivCommon.Functions {
|
|||
|
||||
private delegate IntPtr OpenRouletteDelegate(IntPtr agent, byte roulette, byte a3);
|
||||
|
||||
private GameFunctions Functions { get; }
|
||||
private readonly OpenDutyDelegate? _openDuty;
|
||||
private readonly OpenRouletteDelegate? _openRoulette;
|
||||
|
||||
internal DutyFinder(GameFunctions functions, SigScanner scanner) {
|
||||
this.Functions = functions;
|
||||
|
||||
internal DutyFinder(SigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.OpenRegularDuty, out var openDutyPtr, "Duty Finder (open duty)")) {
|
||||
this._openDuty = Marshal.GetDelegateForFunctionPointer<OpenDutyDelegate>(openDutyPtr);
|
||||
}
|
||||
|
@ -53,7 +51,7 @@ namespace XivCommon.Functions {
|
|||
throw new InvalidOperationException("Could not find signature for open duty function");
|
||||
}
|
||||
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
|
||||
this._openDuty(agent, contentFinderCondition, 0);
|
||||
}
|
||||
|
@ -75,7 +73,7 @@ namespace XivCommon.Functions {
|
|||
throw new InvalidOperationException("Could not find signature for open roulette function");
|
||||
}
|
||||
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ContentsFinder);
|
||||
|
||||
this._openRoulette(agent, roulette, 0);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
|
@ -12,15 +13,11 @@ namespace XivCommon.Functions {
|
|||
internal const string RequestCharacterInfo = "48 89 5C 24 ?? 57 48 83 EC 40 BA ?? ?? ?? ?? 48 8B D9 E8 ?? ?? ?? ?? 48 8B F8 48 85 C0 74 16";
|
||||
}
|
||||
|
||||
private GameFunctions Functions { get; }
|
||||
|
||||
private delegate long RequestCharInfoDelegate(IntPtr ptr);
|
||||
|
||||
private RequestCharInfoDelegate? RequestCharacterInfo { get; }
|
||||
|
||||
internal Examine(GameFunctions functions, SigScanner scanner) {
|
||||
this.Functions = functions;
|
||||
|
||||
internal Examine(SigScanner scanner) {
|
||||
// got this by checking what accesses rciData below
|
||||
if (scanner.TryScanText(Signatures.RequestCharacterInfo, out var rciPtr, "Examine")) {
|
||||
this.RequestCharacterInfo = Marshal.GetDelegateForFunctionPointer<RequestCharInfoDelegate>(rciPtr);
|
||||
|
@ -51,7 +48,7 @@ namespace XivCommon.Functions {
|
|||
// offsets and stuff come from the beginning of case 0x2c (around line 621 in IDA)
|
||||
// if 29f8 ever changes, I'd just scan for it in old binary and find what it is in the new binary at the same spot
|
||||
// 40 55 53 57 41 54 41 55 41 56 48 8D 6C 24 ??
|
||||
var agentModule = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule();
|
||||
var agentModule = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule();
|
||||
var rciData = Marshal.ReadIntPtr(agentModule + 0x1A0);
|
||||
|
||||
// offsets at sig E8 ?? ?? ?? ?? 33 C0 EB 4C
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
|
||||
namespace XivCommon.Functions.FriendList {
|
||||
|
@ -12,8 +13,6 @@ namespace XivCommon.Functions.FriendList {
|
|||
private const int LengthOffset = 0x10;
|
||||
private const int ListOffset = 0x98;
|
||||
|
||||
private GameFunctions Functions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// A live list of the currently-logged-in player's friends.
|
||||
|
@ -24,8 +23,7 @@ namespace XivCommon.Functions.FriendList {
|
|||
/// </summary>
|
||||
public unsafe IList<FriendListEntry> List {
|
||||
get {
|
||||
var friendListAgent = (IntPtr) this.Functions
|
||||
.GetFramework()
|
||||
var friendListAgent = (IntPtr) Framework.Instance()
|
||||
->GetUiModule()
|
||||
->GetAgentModule()
|
||||
->GetAgentByInternalId(AgentId.FriendList);
|
||||
|
@ -58,8 +56,7 @@ namespace XivCommon.Functions.FriendList {
|
|||
}
|
||||
}
|
||||
|
||||
internal FriendList(GameFunctions functions) {
|
||||
this.Functions = functions;
|
||||
internal FriendList() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
|||
using Dalamud.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions {
|
||||
/// <summary>
|
||||
|
@ -14,20 +15,14 @@ namespace XivCommon.Functions {
|
|||
internal const string IsQuestCompleted = "E8 ?? ?? ?? ?? 41 88 84 2C ?? ?? ?? ??";
|
||||
}
|
||||
|
||||
private const int JournalAgentId = 31;
|
||||
|
||||
private delegate IntPtr OpenQuestDelegate(IntPtr agent, int questId, int a3, ushort a4, byte a5);
|
||||
|
||||
private delegate byte IsQuestCompletedDelegate(ushort questId);
|
||||
|
||||
private GameFunctions Functions { get; }
|
||||
|
||||
private readonly OpenQuestDelegate? _openQuest;
|
||||
private readonly IsQuestCompletedDelegate? _isQuestCompleted;
|
||||
|
||||
internal Journal(GameFunctions functions, SigScanner scanner) {
|
||||
this.Functions = functions;
|
||||
|
||||
internal Journal(SigScanner scanner) {
|
||||
if (scanner.TryScanText(Signatures.OpenQuest, out var openQuestPtr, "Journal (open quest)")) {
|
||||
this._openQuest = Marshal.GetDelegateForFunctionPointer<OpenQuestDelegate>(openQuestPtr);
|
||||
}
|
||||
|
@ -56,7 +51,7 @@ namespace XivCommon.Functions {
|
|||
throw new InvalidOperationException("Could not find signature for open quest function");
|
||||
}
|
||||
|
||||
var agent = (IntPtr) this.Functions.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Journal);
|
||||
var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Journal);
|
||||
|
||||
this._openQuest(agent, (int) (questId & 0xFFFF), 1, 0, 1);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using Dalamud.Game.Text.SeStringHandling;
|
|||
using Dalamud.Hooking;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
using Framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework;
|
||||
|
||||
namespace XivCommon.Functions.NamePlates {
|
||||
/// <summary>
|
||||
|
@ -97,7 +98,7 @@ namespace XivCommon.Functions.NamePlates {
|
|||
return;
|
||||
}
|
||||
|
||||
var atkModule = this.Functions.GetFramework()->GetUiModule()->GetRaptureAtkModule();
|
||||
var atkModule = Framework.Instance()->GetUiModule()->GetRaptureAtkModule();
|
||||
|
||||
var active = numbers->IntArray[0];
|
||||
|
||||
|
|
|
@ -100,18 +100,18 @@ namespace XivCommon {
|
|||
var scanner = Util.GetService<SigScanner>();
|
||||
|
||||
this.UiAlloc = new UiAlloc(scanner);
|
||||
this.Chat = new Chat(this, scanner);
|
||||
this.Chat = new Chat(scanner);
|
||||
this.PartyFinder = new PartyFinder(scanner, partyFinderGui, hooks);
|
||||
this.BattleTalk = new BattleTalk(this, scanner, hooks.HasFlag(Hooks.BattleTalk));
|
||||
this.Examine = new Examine(this, scanner);
|
||||
this.BattleTalk = new BattleTalk(scanner, hooks.HasFlag(Hooks.BattleTalk));
|
||||
this.Examine = new Examine(scanner);
|
||||
this.Talk = new Talk(scanner, hooks.HasFlag(Hooks.Talk));
|
||||
this.ChatBubbles = new ChatBubbles(objectTable, scanner, hooks.HasFlag(Hooks.ChatBubbles));
|
||||
this.ContextMenu = new ContextMenu(this, scanner, clientState.ClientLanguage, hooks);
|
||||
this.Tooltips = new Tooltips(scanner, this.GameGui, hooks.HasFlag(Hooks.Tooltips));
|
||||
this.NamePlates = new NamePlates(this, scanner, hooks.HasFlag(Hooks.NamePlates));
|
||||
this.DutyFinder = new DutyFinder(this, scanner);
|
||||
this.Journal = new Journal(this, scanner);
|
||||
this.FriendList = new FriendList(this);
|
||||
this.DutyFinder = new DutyFinder(scanner);
|
||||
this.Journal = new Journal(scanner);
|
||||
this.FriendList = new FriendList();
|
||||
this.Housing = new Housing(scanner);
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,7 @@ namespace XivCommon {
|
|||
/// Convenience method to get a pointer to <see cref="Framework"/>.
|
||||
/// </summary>
|
||||
/// <returns>pointer to struct</returns>
|
||||
[Obsolete("Use Framework.Instance()")]
|
||||
public unsafe Framework* GetFramework() {
|
||||
return (Framework*) this.Framework.Address.BaseAddress;
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ namespace XivCommon {
|
|||
/// Gets the pointer to the UI module
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
[Obsolete("Use GetFramework()->GetUiModule()")]
|
||||
[Obsolete("Use Framework.Instance()->GetUiModule()")]
|
||||
public unsafe IntPtr GetUiModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule();
|
||||
}
|
||||
|
@ -147,7 +148,7 @@ namespace XivCommon {
|
|||
/// Gets the pointer to the RaptureAtkModule
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetRaptureAtkModule()")]
|
||||
[Obsolete("Use Framework.Instance()->GetUiModule()->GetRaptureAtkModule()")]
|
||||
public unsafe IntPtr GetAtkModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetRaptureAtkModule();
|
||||
}
|
||||
|
@ -156,7 +157,7 @@ namespace XivCommon {
|
|||
/// Gets the pointer to the agent module
|
||||
/// </summary>
|
||||
/// <returns>Pointer</returns>
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetAgentModule()")]
|
||||
[Obsolete("Use Framework.Instance()->GetUiModule()->GetAgentModule()")]
|
||||
public unsafe IntPtr GetAgentModule() {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetAgentModule();
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ namespace XivCommon {
|
|||
/// <param name="id">internal id of agent</param>
|
||||
/// <returns>Pointer</returns>
|
||||
/// <exception cref="InvalidOperationException">if the signature for the function could not be found</exception>
|
||||
[Obsolete("Use GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId)")]
|
||||
[Obsolete("Use Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId)")]
|
||||
public unsafe IntPtr GetAgentByInternalId(uint id) {
|
||||
return (IntPtr) this.GetFramework()->GetUiModule()->GetAgentModule()->GetAgentByInternalId((AgentId) id);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue