More cleanup
This commit is contained in:
@@ -7,53 +7,53 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
|
|||||||
|
|
||||||
namespace ChatTwo.GameFunctions;
|
namespace ChatTwo.GameFunctions;
|
||||||
|
|
||||||
internal sealed unsafe class Context {
|
internal sealed unsafe class Context
|
||||||
|
{
|
||||||
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 45 33 C9", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 45 33 C9", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, ulong, ushort, byte*, byte> _inviteToNoviceNetwork = null!;
|
private readonly delegate* unmanaged<IntPtr, ulong, ushort, byte*, byte> InviteToNoviceNetworkNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 35 BA", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 35 BA", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<uint, uint, ulong, uint, byte, byte> _tryOn = null!;
|
private readonly delegate* unmanaged<uint, uint, ulong, uint, byte, byte> TryOnNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 7B 49 8B 06", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 7B 49 8B 06", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, uint, void> _linkItem = null!;
|
private readonly delegate* unmanaged<AgentInterface*, uint, void> LinkItemNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 3F 83 F8 FE", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 3F 83 F8 FE", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, ushort, uint, byte, void> _itemComparison = null!;
|
private readonly delegate* unmanaged<AgentInterface*, ushort, uint, byte, void> ItemComparisonNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 83 F8 0F", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 83 F8 0F", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, uint, void> _searchForRecipesUsingItem = null!;
|
private readonly delegate* unmanaged<IntPtr, uint, void> SearchForRecipesUsingItemNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 45 45 33 C9", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 45 45 33 C9", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<void*, uint, byte, void> _searchForItem = null!;
|
private readonly delegate* unmanaged<void*, uint, byte, void> SearchForItemNative = null!;
|
||||||
|
|
||||||
#region Offsets
|
#region Offsets
|
||||||
|
|
||||||
[Signature(
|
[Signature(
|
||||||
"FF 90 ?? ?? ?? ?? 8B 93 ?? ?? ?? ?? 48 8B C8 E8 ?? ?? ?? ?? 41 0F B6 D4 48 8B CB E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 81 FF ?? ?? ?? ?? 0F 85",
|
"FF 90 ?? ?? ?? ?? 8B 93 ?? ?? ?? ?? 48 8B C8 E8 ?? ?? ?? ?? 41 0F B6 D4 48 8B CB E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 81 FF ?? ?? ?? ?? 0F 85",
|
||||||
Offset = 2
|
Offset = 2
|
||||||
)]
|
)]
|
||||||
private readonly int? _searchForRecipesUsingItemVfunc;
|
private readonly int? SearchForRecipesUsingItemVfunc;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
|
|
||||||
internal Context(Plugin plugin) {
|
internal Context(Plugin plugin)
|
||||||
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InviteToNoviceNetwork(string name, ushort world) {
|
internal void InviteToNoviceNetwork(string name, ushort world)
|
||||||
if (_inviteToNoviceNetwork == null) {
|
{
|
||||||
|
if (InviteToNoviceNetworkNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// 6.3: 221EFD
|
// 6.3: 221EFD
|
||||||
var a1 = Plugin.Functions.GetInfoProxyByIndex(0x14);
|
var a1 = Plugin.Functions.GetInfoProxyByIndex(0x14);
|
||||||
|
|
||||||
|
// can specify content id if we have it, but there's no need
|
||||||
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
||||||
// can specify content id if we have it, but there's no need
|
InviteToNoviceNetworkNative(a1, 0, world, namePtr);
|
||||||
_inviteToNoviceNetwork(a1, 0, world, namePtr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,49 +65,49 @@ internal sealed unsafe class Context {
|
|||||||
// 0x10005: copy item name
|
// 0x10005: copy item name
|
||||||
// 0x10006: search recipes using this material
|
// 0x10006: search recipes using this material
|
||||||
|
|
||||||
internal void TryOn(uint itemId, byte stainId) {
|
internal void TryOn(uint itemId, byte stainId)
|
||||||
if (_tryOn == null) {
|
{
|
||||||
|
if (TryOnNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
_tryOn(0xFF, itemId, stainId, 0, 0);
|
TryOnNative(0xFF, itemId, stainId, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LinkItem(uint itemId) {
|
internal void LinkItem(uint itemId)
|
||||||
if (_linkItem == null) {
|
{
|
||||||
|
if (LinkItemNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ChatLog);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ChatLog);
|
||||||
_linkItem(agent, itemId);
|
LinkItemNative(agent, itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OpenItemComparison(uint itemId) {
|
internal void OpenItemComparison(uint itemId)
|
||||||
if (_itemComparison == null) {
|
{
|
||||||
|
if (ItemComparisonNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemCompare);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemCompare);
|
||||||
_itemComparison(agent, 0x4D, itemId, 0);
|
ItemComparisonNative(agent, 0x4D, itemId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SearchForRecipesUsingItem(uint itemId) {
|
internal void SearchForRecipesUsingItem(uint itemId)
|
||||||
if (_searchForRecipesUsingItem == null || _searchForRecipesUsingItemVfunc is not { } offset) {
|
{
|
||||||
|
if (SearchForRecipesUsingItemNative == null || SearchForRecipesUsingItemVfunc is not { } offset)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var uiModule = Framework.Instance()->GetUiModule();
|
var uiModule = Framework.Instance()->GetUiModule();
|
||||||
var vf = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[offset / 8];
|
var vf = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[offset / 8];
|
||||||
var a1 = vf(uiModule);
|
var a1 = vf(uiModule);
|
||||||
_searchForRecipesUsingItem(a1, itemId);
|
SearchForRecipesUsingItemNative(a1, itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SearchForItem(uint itemId) {
|
internal void SearchForItem(uint itemId)
|
||||||
if (_searchForItem == null) {
|
{
|
||||||
|
if (SearchForItemNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var itemFinder = Framework.Instance()->GetUiModule()->GetItemFinderModule();
|
var itemFinder = Framework.Instance()->GetUiModule()->GetItemFinderModule();
|
||||||
_searchForItem(itemFinder, itemId, 1);
|
SearchForItemNative(itemFinder, itemId, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
|
|||||||
|
|
||||||
namespace ChatTwo.GameFunctions;
|
namespace ChatTwo.GameFunctions;
|
||||||
|
|
||||||
internal unsafe class GameFunctions : IDisposable {
|
internal unsafe class GameFunctions : IDisposable
|
||||||
private static class Signatures {
|
{
|
||||||
|
private static class Signatures
|
||||||
|
{
|
||||||
internal const string IsMentorA1 = "48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 71 0F B6 86";
|
internal const string IsMentorA1 = "48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 84 C0 74 71 0F B6 86";
|
||||||
internal const string ResolveTextCommandPlaceholder = "E8 ?? ?? ?? ?? 49 8D 4F 18 4C 8B E0";
|
internal const string ResolveTextCommandPlaceholder = "E8 ?? ?? ?? ?? 49 8D 4F 18 4C 8B E0";
|
||||||
|
|
||||||
@@ -20,52 +22,47 @@ internal unsafe class GameFunctions : IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Functions
|
#region Functions
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? 8B FD 8B CD", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? 8B FD 8B CD", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, uint, IntPtr> _getInfoProxyByIndex = null!;
|
private readonly delegate* unmanaged<IntPtr, uint, IntPtr> GetInfoProxyByIndexNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? 84 C0 74 0D B0 02", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? 84 C0 74 0D B0 02", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, byte> _isMentor = null!;
|
private readonly delegate* unmanaged<IntPtr, byte> IsMentorNative = null!;
|
||||||
|
|
||||||
[Signature("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9", Fallibility = Fallibility.Fallible)]
|
[Signature("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, ulong, byte> _openPartyFinder = null!;
|
private readonly delegate* unmanaged<AgentInterface*, ulong, byte> OpenPartyFinderNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 20 48 8B 46 28", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 20 48 8B 46 28", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, uint, void> _openAchievement = null!;
|
private readonly delegate* unmanaged<AgentInterface*, uint, void> OpenAchievementNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? 41 8D 4F 08 84 C0", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? 41 8D 4F 08 84 C0", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<byte> _inInstance = null!;
|
private readonly delegate* unmanaged<byte> InInstanceNative = null!;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Hooks
|
#region Hooks
|
||||||
|
|
||||||
private delegate IntPtr ResolveTextCommandPlaceholderDelegate(IntPtr a1, byte* placeholderText, byte a3, byte a4);
|
private delegate IntPtr ResolveTextCommandPlaceholderDelegate(IntPtr a1, byte* placeholderText, byte a3, byte a4);
|
||||||
|
|
||||||
[Signature(Signatures.ResolveTextCommandPlaceholder, DetourName = nameof(ResolveTextCommandPlaceholderDetour))]
|
[Signature(Signatures.ResolveTextCommandPlaceholder, DetourName = nameof(ResolveTextCommandPlaceholderDetour))]
|
||||||
private Hook<ResolveTextCommandPlaceholderDelegate>? ResolveTextCommandPlaceholderHook { get; init; }
|
private Hook<ResolveTextCommandPlaceholderDelegate>? ResolveTextCommandPlaceholderHook { get; init; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#pragma warning disable 0649
|
#pragma warning disable 0649
|
||||||
|
|
||||||
[Signature(Signatures.CurrentChatEntryOffset, Offset = 2)]
|
[Signature(Signatures.CurrentChatEntryOffset, Offset = 2)]
|
||||||
private readonly byte? _currentChatEntryOffset;
|
private readonly byte? CurrentChatEntryOffset;
|
||||||
|
|
||||||
[Signature(Signatures.IsMentorA1, ScanType = ScanType.StaticAddress)]
|
[Signature(Signatures.IsMentorA1, ScanType = ScanType.StaticAddress)]
|
||||||
private readonly IntPtr? _isMentorA1;
|
private readonly IntPtr? IsMentorA1;
|
||||||
|
|
||||||
#pragma warning restore 0649
|
#pragma warning restore 0649
|
||||||
|
|
||||||
[Signature("FF 90 ?? ?? ?? ?? 48 8B C8 BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B F0 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 10 33 ED", Offset = 2)]
|
[Signature("FF 90 ?? ?? ?? ?? 48 8B C8 BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B F0 48 85 C0 0F 84 ?? ?? ?? ?? 48 8B 10 33 ED", Offset = 2)]
|
||||||
private readonly int? _infoModuleVfunc;
|
private readonly int? InfoModuleVfunc;
|
||||||
|
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
internal Party Party { get; }
|
internal Party Party { get; }
|
||||||
internal Chat Chat { get; }
|
internal Chat Chat { get; }
|
||||||
internal Context Context { get; }
|
internal Context Context { get; }
|
||||||
|
|
||||||
internal GameFunctions(Plugin plugin) {
|
internal GameFunctions(Plugin plugin)
|
||||||
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
Party = new Party(Plugin);
|
Party = new Party(Plugin);
|
||||||
Chat = new Chat(Plugin);
|
Chat = new Chat(Plugin);
|
||||||
@@ -76,101 +73,105 @@ internal unsafe class GameFunctions : IDisposable {
|
|||||||
ResolveTextCommandPlaceholderHook?.Enable();
|
ResolveTextCommandPlaceholderHook?.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Chat.Dispose();
|
Chat.Dispose();
|
||||||
|
|
||||||
ResolveTextCommandPlaceholderHook?.Dispose();
|
ResolveTextCommandPlaceholderHook?.Dispose();
|
||||||
|
|
||||||
Marshal.FreeHGlobal(_placeholderNamePtr);
|
Marshal.FreeHGlobal(PlaceholderNamePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr GetInfoModule() {
|
private IntPtr GetInfoModule()
|
||||||
if (_infoModuleVfunc is not { } vfunc) {
|
{
|
||||||
|
if (InfoModuleVfunc is not { } vfunc)
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
|
||||||
|
|
||||||
var uiModule = Framework.Instance()->GetUiModule();
|
var uiModule = Framework.Instance()->GetUiModule();
|
||||||
var getInfoModule = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[vfunc / 8];
|
var getInfoModule = (delegate* unmanaged<UIModule*, IntPtr>) uiModule->vfunc[vfunc / 8];
|
||||||
return getInfoModule(uiModule);
|
return getInfoModule(uiModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IntPtr GetInfoProxyByIndex(uint idx) {
|
internal IntPtr GetInfoProxyByIndex(uint idx)
|
||||||
|
{
|
||||||
var infoModule = GetInfoModule();
|
var infoModule = GetInfoModule();
|
||||||
return infoModule == IntPtr.Zero ? IntPtr.Zero : _getInfoProxyByIndex(infoModule, idx);
|
return infoModule == IntPtr.Zero ? IntPtr.Zero : GetInfoProxyByIndexNative(infoModule, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal uint? GetCurrentChatLogEntryIndex() {
|
internal uint? GetCurrentChatLogEntryIndex()
|
||||||
if (_currentChatEntryOffset == null) {
|
{
|
||||||
|
if (CurrentChatEntryOffset == null)
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
var log = (IntPtr) Framework.Instance()->GetUiModule()->GetRaptureLogModule();
|
var log = (IntPtr) Framework.Instance()->GetUiModule()->GetRaptureLogModule();
|
||||||
return *(uint*) (log + _currentChatEntryOffset.Value);
|
return *(uint*) (log + CurrentChatEntryOffset.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SendFriendRequest(string name, ushort world) {
|
internal void SendFriendRequest(string name, ushort world)
|
||||||
|
{
|
||||||
ListCommand(name, world, "friendlist");
|
ListCommand(name, world, "friendlist");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddToBlacklist(string name, ushort world) {
|
internal void AddToBlacklist(string name, ushort world)
|
||||||
|
{
|
||||||
ListCommand(name, world, "blist");
|
ListCommand(name, world, "blist");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListCommand(string name, ushort world, string commandName) {
|
private void ListCommand(string name, ushort world, string commandName)
|
||||||
|
{
|
||||||
var row = Plugin.DataManager.GetExcelSheet<World>()!.GetRow(world);
|
var row = Plugin.DataManager.GetExcelSheet<World>()!.GetRow(world);
|
||||||
if (row == null) {
|
if (row == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var worldName = row.Name.RawString;
|
var worldName = row.Name.RawString;
|
||||||
_replacementName = $"{name}@{worldName}";
|
ReplacementName = $"{name}@{worldName}";
|
||||||
Plugin.Common.Functions.Chat.SendMessage($"/{commandName} add {_placeholder}");
|
Plugin.Common.Functions.Chat.SendMessage($"/{commandName} add {Placeholder}");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetAddonInteractable(string name, bool interactable) {
|
internal static void SetAddonInteractable(string name, bool interactable)
|
||||||
|
{
|
||||||
var unitManager = AtkStage.GetSingleton()->RaptureAtkUnitManager;
|
var unitManager = AtkStage.GetSingleton()->RaptureAtkUnitManager;
|
||||||
|
|
||||||
var addon = (IntPtr) unitManager->GetAddonByName(name);
|
var addon = (IntPtr) unitManager->GetAddonByName(name);
|
||||||
if (addon == IntPtr.Zero) {
|
if (addon == IntPtr.Zero)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var flags = (uint*) (addon + 0x180);
|
var flags = (uint*) (addon + 0x180);
|
||||||
if (interactable) {
|
if (interactable)
|
||||||
*flags &= ~(1u << 22);
|
*flags &= ~(1u << 22);
|
||||||
} else {
|
else
|
||||||
*flags |= 1 << 22;
|
*flags |= 1 << 22;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetChatInteractable(bool interactable) {
|
internal static void SetChatInteractable(bool interactable)
|
||||||
for (var i = 0; i < 4; i++) {
|
{
|
||||||
|
for (var i = 0; i < 4; i++)
|
||||||
SetAddonInteractable($"ChatLogPanel_{i}", interactable);
|
SetAddonInteractable($"ChatLogPanel_{i}", interactable);
|
||||||
}
|
|
||||||
|
|
||||||
SetAddonInteractable("ChatLog", interactable);
|
SetAddonInteractable("ChatLog", interactable);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool IsAddonInteractable(string name) {
|
internal static bool IsAddonInteractable(string name)
|
||||||
|
{
|
||||||
var unitManager = AtkStage.GetSingleton()->RaptureAtkUnitManager;
|
var unitManager = AtkStage.GetSingleton()->RaptureAtkUnitManager;
|
||||||
|
|
||||||
var addon = (IntPtr) unitManager->GetAddonByName(name);
|
var addon = (IntPtr) unitManager->GetAddonByName(name);
|
||||||
if (addon == IntPtr.Zero) {
|
if (addon == IntPtr.Zero)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
var flags = (uint*) (addon + 0x180);
|
var flags = (uint*) (addon + 0x180);
|
||||||
return (*flags & (1 << 22)) == 0;
|
return (*flags & (1 << 22)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void OpenItemTooltip(uint id) {
|
internal static void OpenItemTooltip(uint id)
|
||||||
|
{
|
||||||
var atkStage = AtkStage.GetSingleton();
|
var atkStage = AtkStage.GetSingleton();
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail);
|
||||||
var addon = atkStage->RaptureAtkUnitManager->GetAddonByName("ItemDetail");
|
var addon = atkStage->RaptureAtkUnitManager->GetAddonByName("ItemDetail");
|
||||||
if (agent == null || addon == null) {
|
|
||||||
// atkStage ain't gonna be null or we have bigger problems
|
// atkStage ain't gonna be null or we have bigger problems
|
||||||
|
if (agent == null || addon == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agentPtr = (IntPtr) agent;
|
var agentPtr = (IntPtr) agent;
|
||||||
|
|
||||||
@@ -203,74 +204,74 @@ internal unsafe class GameFunctions : IDisposable {
|
|||||||
(*vf5)(addon, 0, 15);
|
(*vf5)(addon, 0, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CloseItemTooltip() {
|
internal static void CloseItemTooltip()
|
||||||
|
{
|
||||||
// hide addon first to prevent the "addon close" sound
|
// hide addon first to prevent the "addon close" sound
|
||||||
var addon = AtkStage.GetSingleton()->RaptureAtkUnitManager->GetAddonByName("ItemDetail");
|
var addon = AtkStage.GetSingleton()->RaptureAtkUnitManager->GetAddonByName("ItemDetail");
|
||||||
if (addon != null) {
|
if (addon != null)
|
||||||
addon->Hide(true, false, 0);
|
addon->Hide(true, false, 0);
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ItemDetail);
|
||||||
if (agent != null) {
|
if (agent != null)
|
||||||
agent->Hide();
|
agent->Hide();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void OpenPartyFinder() {
|
internal static void OpenPartyFinder()
|
||||||
|
{
|
||||||
// this whole method: 6.05: 84433A (FF 97 ?? ?? ?? ?? 41 B4 01)
|
// this whole method: 6.05: 84433A (FF 97 ?? ?? ?? ?? 41 B4 01)
|
||||||
var lfg = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup);
|
var lfg = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup);
|
||||||
if (lfg->IsAgentActive()) {
|
if (lfg->IsAgentActive())
|
||||||
|
{
|
||||||
var addonId = lfg->GetAddonID();
|
var addonId = lfg->GetAddonID();
|
||||||
var atkModule = Framework.Instance()->GetUiModule()->GetRaptureAtkModule();
|
var atkModule = Framework.Instance()->GetUiModule()->GetRaptureAtkModule();
|
||||||
var atkModuleVtbl = (void**) atkModule->AtkModule.vtbl;
|
var atkModuleVtbl = (void**) atkModule->AtkModule.vtbl;
|
||||||
var vf27 = (delegate* unmanaged<RaptureAtkModule*, ulong, ulong, byte>) atkModuleVtbl[27];
|
var vf27 = (delegate* unmanaged<RaptureAtkModule*, ulong, ulong, byte>) atkModuleVtbl[27];
|
||||||
vf27(atkModule, addonId, 1);
|
vf27(atkModule, addonId, 1);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// 6.05: 8443DD
|
// 6.05: 8443DD
|
||||||
if (*(uint*) ((IntPtr) lfg + 0x2C20) > 0) {
|
if (*(uint*) ((IntPtr) lfg + 0x2C20) > 0)
|
||||||
lfg->Hide();
|
lfg->Hide();
|
||||||
} else {
|
else
|
||||||
lfg->Show();
|
lfg->Show();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsMentor() {
|
internal bool IsMentor()
|
||||||
if (_isMentor == null || _isMentorA1 == null || _isMentorA1.Value == IntPtr.Zero) {
|
{
|
||||||
|
if (IsMentorNative == null || IsMentorA1 == null || IsMentorA1.Value == IntPtr.Zero)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return _isMentor(_isMentorA1.Value) > 0;
|
return IsMentorNative(IsMentorA1.Value) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OpenPartyFinder(uint id) {
|
internal void OpenPartyFinder(uint id)
|
||||||
if (_openPartyFinder == null) {
|
{
|
||||||
|
if (OpenPartyFinderNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.LookingForGroup);
|
||||||
if (agent != null) {
|
if (agent != null)
|
||||||
_openPartyFinder(agent, id);
|
OpenPartyFinderNative(agent, id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OpenAchievement(uint id) {
|
internal void OpenAchievement(uint id)
|
||||||
if (_openAchievement == null) {
|
{
|
||||||
|
if (OpenAchievementNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Achievement);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Achievement);
|
||||||
if (agent != null) {
|
if (agent != null)
|
||||||
_openAchievement(agent, id);
|
OpenAchievementNative(agent, id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsInInstance() {
|
internal bool IsInInstance()
|
||||||
if (_inInstance == null) {
|
{
|
||||||
|
if (InInstanceNative == null)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return _inInstance() != 0;
|
return InInstanceNative() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool TryOpenAdventurerPlate(ulong playerId)
|
internal bool TryOpenAdventurerPlate(ulong playerId)
|
||||||
@@ -287,36 +288,33 @@ internal unsafe class GameFunctions : IDisposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ClickNoviceNetworkButton() {
|
internal void ClickNoviceNetworkButton()
|
||||||
|
{
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ChatLog);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.ChatLog);
|
||||||
// case 3
|
// case 3
|
||||||
var value = new AtkValue {
|
var value = new AtkValue { Type = ValueType.Int, Int = 3, };
|
||||||
Type = ValueType.Int,
|
|
||||||
Int = 3,
|
|
||||||
};
|
|
||||||
var result = 0;
|
var result = 0;
|
||||||
var vf0 = *(delegate* unmanaged<AgentInterface*, int*, AtkValue*, ulong, ulong, int*>*) agent->VTable;
|
var vf0 = *(delegate* unmanaged<AgentInterface*, int*, AtkValue*, ulong, ulong, int*>*) agent->VTable;
|
||||||
vf0(agent, &result, &value, 0, 0);
|
vf0(agent, &result, &value, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IntPtr _placeholderNamePtr = Marshal.AllocHGlobal(128);
|
private readonly IntPtr PlaceholderNamePtr = Marshal.AllocHGlobal(128);
|
||||||
private readonly string _placeholder = $"<{Guid.NewGuid():N}>";
|
private readonly string Placeholder = $"<{Guid.NewGuid():N}>";
|
||||||
private string? _replacementName;
|
private string? ReplacementName;
|
||||||
|
|
||||||
private IntPtr ResolveTextCommandPlaceholderDetour(IntPtr a1, byte* placeholderText, byte a3, byte a4) {
|
private IntPtr ResolveTextCommandPlaceholderDetour(IntPtr a1, byte* placeholderText, byte a3, byte a4)
|
||||||
if (_replacementName == null) {
|
{
|
||||||
|
if (ReplacementName == null)
|
||||||
goto Original;
|
goto Original;
|
||||||
}
|
|
||||||
|
|
||||||
var placeholder = MemoryHelper.ReadStringNullTerminated((IntPtr) placeholderText);
|
var placeholder = MemoryHelper.ReadStringNullTerminated((IntPtr) placeholderText);
|
||||||
if (placeholder != _placeholder) {
|
if (placeholder != Placeholder)
|
||||||
goto Original;
|
goto Original;
|
||||||
}
|
|
||||||
|
|
||||||
MemoryHelper.WriteString(_placeholderNamePtr, _replacementName);
|
MemoryHelper.WriteString(PlaceholderNamePtr, ReplacementName);
|
||||||
_replacementName = null;
|
ReplacementName = null;
|
||||||
|
|
||||||
return _placeholderNamePtr;
|
return PlaceholderNamePtr;
|
||||||
|
|
||||||
Original:
|
Original:
|
||||||
return ResolveTextCommandPlaceholderHook!.Original(a1, placeholderText, a3, a4);
|
return ResolveTextCommandPlaceholderHook!.Original(a1, placeholderText, a3, a4);
|
||||||
|
|||||||
@@ -6,101 +6,102 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
|
|||||||
|
|
||||||
namespace ChatTwo.GameFunctions;
|
namespace ChatTwo.GameFunctions;
|
||||||
|
|
||||||
internal sealed unsafe class Party {
|
internal sealed unsafe class Party
|
||||||
|
{
|
||||||
[Signature("E8 ?? ?? ?? ?? 33 C0 EB 51", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? 33 C0 EB 51", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, ulong, byte*, ushort, byte> _inviteToParty = null!;
|
private readonly delegate* unmanaged<IntPtr, ulong, byte*, ushort, byte> InviteToPartyNative = null!;
|
||||||
|
|
||||||
[Signature("48 83 EC 38 41 B1 09", Fallibility = Fallibility.Fallible)]
|
[Signature("48 83 EC 38 41 B1 09", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, ulong, ushort, byte> _inviteToPartyContentId = null!;
|
private readonly delegate* unmanaged<IntPtr, ulong, ushort, byte> InviteToPartyContentIdNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B 83 ?? ?? ?? ?? 48 85 C0 74 62", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B 83 ?? ?? ?? ?? 48 85 C0 74 62", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<IntPtr, ulong, byte> _inviteToPartyInInstance = null!;
|
private readonly delegate* unmanaged<IntPtr, ulong, byte> InviteToPartyInInstanceNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 49 8B 56 20", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 49 8B 56 20", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, byte*, ushort, ulong, void> _promote = null!;
|
private readonly delegate* unmanaged<AgentInterface*, byte*, ushort, ulong, void> PromoteNative = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? EB 66 49 8B 4E 20", Fallibility = Fallibility.Fallible)]
|
[Signature("E8 ?? ?? ?? ?? EB 66 49 8B 4E 20", Fallibility = Fallibility.Fallible)]
|
||||||
private readonly delegate* unmanaged<AgentInterface*, byte*, ushort, ulong, void> _kick = null!;
|
private readonly delegate* unmanaged<AgentInterface*, byte*, ushort, ulong, void> KickNative = null!;
|
||||||
|
|
||||||
private Plugin Plugin { get; }
|
private Plugin Plugin { get; }
|
||||||
|
|
||||||
internal Party(Plugin plugin) {
|
internal Party(Plugin plugin)
|
||||||
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InviteSameWorld(string name, ushort world, ulong contentId) {
|
internal void InviteSameWorld(string name, ushort world, ulong contentId)
|
||||||
if (_inviteToParty == null) {
|
{
|
||||||
|
if (InviteToPartyNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// 6.11: 214A55
|
// 6.11: 214A55
|
||||||
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
||||||
|
|
||||||
|
// this only works if target is on the same world
|
||||||
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
||||||
// this only works if target is on the same world
|
InviteToPartyNative(a1, contentId, namePtr, world);
|
||||||
_inviteToParty(a1, contentId, namePtr, world);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InviteOtherWorld(ulong contentId) {
|
internal void InviteOtherWorld(ulong contentId)
|
||||||
if (_inviteToPartyContentId == null) {
|
{
|
||||||
|
if (InviteToPartyContentIdNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// 6.11: 214A55
|
// 6.11: 214A55
|
||||||
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
||||||
if (contentId != 0) {
|
|
||||||
// third param is world, but it requires a specific world
|
// third param is world, but it requires a specific world
|
||||||
// if they're not on that world, it will fail
|
// if they're not on that world, it will fail
|
||||||
// pass 0 and it will work on any world EXCEPT for the world the
|
// pass 0 and it will work on any world EXCEPT for the world the
|
||||||
// current player is on
|
// current player is on
|
||||||
_inviteToPartyContentId(a1, contentId, 0);
|
if (contentId != 0)
|
||||||
}
|
InviteToPartyContentIdNative(a1, contentId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InviteInInstance(ulong contentId) {
|
internal void InviteInInstance(ulong contentId)
|
||||||
if (_inviteToPartyInInstance == null) {
|
{
|
||||||
|
if (InviteToPartyInInstanceNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// 6.11: 214A55
|
// 6.11: 214A55
|
||||||
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
var a1 = Plugin.Functions.GetInfoProxyByIndex(2);
|
||||||
if (contentId != 0) {
|
|
||||||
// third param is world, but it requires a specific world
|
// third param is world, but it requires a specific world
|
||||||
// if they're not on that world, it will fail
|
// if they're not on that world, it will fail
|
||||||
// pass 0 and it will work on any world EXCEPT for the world the
|
// pass 0 and it will work on any world EXCEPT for the world the
|
||||||
// current player is on
|
// current player is on
|
||||||
_inviteToPartyInInstance(a1, contentId);
|
if (contentId != 0)
|
||||||
}
|
InviteToPartyInInstanceNative(a1, contentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Kick(string name, ulong contentId) {
|
internal void Kick(string name, ulong contentId)
|
||||||
if (_kick == null) {
|
{
|
||||||
|
if (KickNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.SocialPartyMember);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.SocialPartyMember);
|
||||||
if (agent == null) {
|
if (agent == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
||||||
_kick(agent, namePtr, 0, contentId);
|
KickNative(agent, namePtr, 0, contentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Promote(string name, ulong contentId) {
|
internal void Promote(string name, ulong contentId)
|
||||||
if (_promote == null) {
|
{
|
||||||
|
if (PromoteNative == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.SocialPartyMember);
|
var agent = Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.SocialPartyMember);
|
||||||
if (agent == null) {
|
if (agent == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
fixed (byte* namePtr = name.ToTerminatedBytes()) {
|
||||||
_promote(agent, namePtr, 0, contentId);
|
PromoteNative(agent, namePtr, 0, contentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ internal class ChannelSwitchInfo {
|
|||||||
internal RotateMode Rotate { get; }
|
internal RotateMode Rotate { get; }
|
||||||
internal string? Text { get; }
|
internal string? Text { get; }
|
||||||
|
|
||||||
internal ChannelSwitchInfo(InputChannel? channel, bool permanent = false, RotateMode rotate = RotateMode.None, string? text = null) {
|
internal ChannelSwitchInfo(InputChannel? channel, bool permanent = false, RotateMode rotate = RotateMode.None, string? text = null)
|
||||||
|
{
|
||||||
Channel = channel;
|
Channel = channel;
|
||||||
Permanent = permanent;
|
Permanent = permanent;
|
||||||
Rotate = rotate;
|
Rotate = rotate;
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal sealed class ChatActivatedArgs {
|
internal sealed class ChatActivatedArgs
|
||||||
|
{
|
||||||
internal string? AddIfNotPresent { get; init; }
|
internal string? AddIfNotPresent { get; init; }
|
||||||
internal string? Input { get; init; }
|
internal string? Input { get; init; }
|
||||||
internal ChannelSwitchInfo ChannelSwitchInfo { get; }
|
internal ChannelSwitchInfo ChannelSwitchInfo { get; }
|
||||||
internal TellReason? TellReason { get; init; }
|
internal TellReason? TellReason { get; init; }
|
||||||
internal TellTarget? TellTarget { get; init; }
|
internal TellTarget? TellTarget { get; init; }
|
||||||
|
|
||||||
internal ChatActivatedArgs(ChannelSwitchInfo channelSwitchInfo) {
|
internal ChatActivatedArgs(ChannelSwitchInfo channelSwitchInfo)
|
||||||
|
{
|
||||||
ChannelSwitchInfo = channelSwitchInfo;
|
ChannelSwitchInfo = channelSwitchInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ using Dalamud.Game.ClientState.Keys;
|
|||||||
|
|
||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal class Keybind {
|
internal class Keybind
|
||||||
|
{
|
||||||
internal VirtualKey Key1 { get; init; }
|
internal VirtualKey Key1 { get; init; }
|
||||||
internal ModifierFlag Modifier1 { get; init; }
|
internal ModifierFlag Modifier1 { get; init; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
internal enum ModifierFlag {
|
internal enum ModifierFlag
|
||||||
|
{
|
||||||
Shift = 1 << 0,
|
Shift = 1 << 0,
|
||||||
Ctrl = 1 << 1,
|
Ctrl = 1 << 1,
|
||||||
Alt = 1 << 2,
|
Alt = 1 << 2,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal enum RotateMode {
|
internal enum RotateMode
|
||||||
|
{
|
||||||
None,
|
None,
|
||||||
Forward,
|
Forward,
|
||||||
Reverse,
|
Reverse,
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal sealed class TellHistoryInfo {
|
internal sealed class TellHistoryInfo
|
||||||
|
{
|
||||||
internal string Name { get; }
|
internal string Name { get; }
|
||||||
internal uint World { get; }
|
internal uint World { get; }
|
||||||
internal ulong ContentId { get; }
|
internal ulong ContentId { get; }
|
||||||
|
|
||||||
internal TellHistoryInfo(string name, uint world, ulong contentId) {
|
internal TellHistoryInfo(string name, uint world, ulong contentId)
|
||||||
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
World = world;
|
World = world;
|
||||||
ContentId = contentId;
|
ContentId = contentId;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal enum TellReason {
|
internal enum TellReason
|
||||||
|
{
|
||||||
Direct = 0,
|
Direct = 0,
|
||||||
PartyFinder = 1,
|
PartyFinder = 1,
|
||||||
Reply = 2,
|
Reply = 2,
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
namespace ChatTwo.GameFunctions.Types;
|
namespace ChatTwo.GameFunctions.Types;
|
||||||
|
|
||||||
internal sealed class TellTarget {
|
internal sealed class TellTarget
|
||||||
|
{
|
||||||
internal string Name { get; }
|
internal string Name { get; }
|
||||||
internal ushort World { get; }
|
internal ushort World { get; }
|
||||||
internal ulong ContentId { get; }
|
internal ulong ContentId { get; }
|
||||||
internal TellReason Reason { get; }
|
internal TellReason Reason { get; }
|
||||||
|
|
||||||
internal TellTarget(string name, ushort world, ulong contentId, TellReason reason) {
|
internal TellTarget(string name, ushort world, ulong contentId, TellReason reason)
|
||||||
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
World = world;
|
World = world;
|
||||||
ContentId = contentId;
|
ContentId = contentId;
|
||||||
|
|||||||
Reference in New Issue
Block a user