Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 33 additions & 14 deletions PostNamazu/Actions/Command.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using GreyMagic;
using PostNamazu.Attributes;
using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using PostNamazu.Attributes;
using static PostNamazu.Common.I18n;
using GreyMagic;

namespace PostNamazu.Actions
{
Expand All @@ -14,8 +16,21 @@ internal class Command : NamazuModule
public override void GetOffsets()
{
base.GetOffsets();
ProcessChatBoxPtr = SigScanner.ScanText("E8 ?? ?? ?? ?? FE 86 ?? ?? ?? ?? C7 86", nameof(ProcessChatBoxPtr));
GetUiModulePtr = SigScanner.ScanText("E8 ?? ?? ?? ?? 80 7B 1D 01", nameof(GetUiModulePtr));
ProcessChatBoxPtr = SigScanner.ScanText("E8 * * * * FE 86 ? ? ? ? C7 86", nameof(ProcessChatBoxPtr));
GetUiModulePtr = SigScanner.ScanText("E8 * * * * 80 7B 1D 01", nameof(GetUiModulePtr));
}

const string CurrentChannelPrefix = "/current ";
void CheckChannel(ref string command)
{
if (!command.StartsWith("/"))
{
throw new ArgumentException(GetLocalizedString("NoChannelError"));
}
if (command.StartsWith(CurrentChannelPrefix))
{
command = command.Substring(CurrentChannelPrefix.Length);
}
}

/// <summary>
Expand All @@ -26,13 +41,11 @@ public override void GetOffsets()
public void DoTextCommand(string command)
{
CheckBeforeExecution(command);
CheckChannel(ref command);
PluginUI.Log(command);

var assemblyLock = Memory.Executor.AssemblyLock;

var flag = false;
try {
Monitor.Enter(assemblyLock, ref flag);
ExecuteWithLock(() =>
{
var array = Encoding.UTF8.GetBytes(command);
using AllocatedMemory allocatedMemory = Memory.CreateAllocatedMemory(400), allocatedMemory2 = Memory.CreateAllocatedMemory(array.Length + 30);
allocatedMemory2.AllocateOfChunk("cmd", array.Length);
Expand All @@ -48,11 +61,17 @@ public void DoTextCommand(string command)
var uiModulePtr = Memory.CallInjected64<IntPtr>(GetUiModulePtr, PostNamazu.FrameworkPtr);
var raptureModule = Memory.CallInjected64<IntPtr>(Memory.Read<IntPtr>(Memory.Read<IntPtr>(uiModulePtr) + (0x8 * 9)), uiModulePtr);
_ = Memory.CallInjected64<int>(ProcessChatBoxPtr, raptureModule, allocatedMemory.Address, uiModulePtr);
}
finally {
if (flag) Monitor.Exit(assemblyLock);
}
});
}

protected override Dictionary<string, Dictionary<Language, string>> LocalizedStrings { get; } = new()
{
["NoChannelError"] = new()
{
[Language.EN] = $"To avoid sending wrong text to public channels, only commands starting with \"/\" are permitted. Add the prefix \"{CurrentChannelPrefix}\" to post to the current channel.",
[Language.CN] = $"为防止误操作导致错误文本发送至公共频道,仅允许以 \"/\" 开头的指令。如需发送至当前频道,请加前缀 \"{CurrentChannelPrefix}\"。"
},
};
}

}
19 changes: 7 additions & 12 deletions PostNamazu/Actions/Mark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ public override void GetOffsets() {
//char __fastcall sub_1407A6A60(__int64 g_MarkingController, __int64 MarkType, __int64 ActorID)
try
{
MarkingFunc = SigScanner.ScanText("E8 ?? ?? ?? ?? 84 C0 74 ?? 48 8B 06 48 8B CE FF 50 ?? 48 8B C8 BA ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 C0 E9", nameof(MarkingFunc));
MarkingFunc = SigScanner.ScanText("E8 * * * * 84 C0 74 ? 48 8B 06 48 8B CE FF 50 ? 48 8B C8 BA ? ? ? ? E8 ? ? ? ? 33 C0 E9", nameof(MarkingFunc));
}
catch
{
MarkingFunc = SigScanner.ScanText("48 89 5C 24 10 48 89 6C 24 18 57 48 83 EC 20 8D 42", nameof(MarkingFunc));
}
LocalMarkingFunc = SigScanner.ScanText("E8 ?? ?? ?? ?? 4C 8B C5 8B D7 48 8B CB E8", nameof(LocalMarkingFunc)); //正确
MarkingController = SigScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 4C 8B 85", 3, nameof(MarkingController)); //正确
LocalMarkingFunc = SigScanner.ScanText("E8 * * * * 4C 8B C5 8B D7 48 8B CB E8", nameof(LocalMarkingFunc)); //正确
MarkingController = SigScanner.ScanText("48 8D 0D * * * * 4C 8B 85", nameof(MarkingController)); //正确
}

[Command("mark")]
public void DoMarking(string command)
{
Expand Down Expand Up @@ -65,18 +66,12 @@ private void MarkActor(FFXIV_ACT_Plugin.Common.Models.Combatant actor, MarkType
{
PluginUI.Log($"Mark: Actor={actor.Name} (0x{actor.ID:X8}), Type={markingType} ({(int)markingType}), LocalOnly={localOnly}");
}
var assemblyLock = Memory.Executor.AssemblyLock;
var flag = false;
try
ExecuteWithLock(() =>
{
Monitor.Enter(assemblyLock, ref flag);
_ = !localOnly
? Memory.CallInjected64<char>(MarkingFunc, MarkingController, markingType, actor.ID)
? Memory.CallInjected64<char>(MarkingFunc, MarkingController, markingType, actor.ID)
: Memory.CallInjected64<char>(LocalMarkingFunc, MarkingController, markingType - 1, actor.ID, 0); //本地标点的markingType从0开始,因此需要-1
}
finally {
if (flag) Monitor.Exit(assemblyLock);
}
});
}

protected override Dictionary<string, Dictionary<Language, string>> LocalizedStrings { get; } = new()
Expand Down
50 changes: 35 additions & 15 deletions PostNamazu/Actions/NormalCommand.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using PostNamazu.Attributes;
using static PostNamazu.Common.I18n;
using GreyMagic;

namespace PostNamazu.Actions
Expand All @@ -14,13 +16,28 @@ internal class NormalCommand : NamazuModule
public override void GetOffsets()
{
base.GetOffsets();
try
try // 7.1
{
ProcessChatBoxPtr = SigScanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F2 48 8B F9 45 84 C9");
}
catch // 7.0
{
ProcessChatBoxPtr = SigScanner.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 45 84 C9", nameof(ProcessChatBoxPtr));
}catch {
ProcessChatBoxPtr = SigScanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F2 48 8B F9 45 84 C9", nameof(ProcessChatBoxPtr));
}
GetUiModulePtr = SigScanner.ScanText("E8 ?? ?? ?? ?? 80 7B 1D 01", nameof(GetUiModulePtr));
GetUiModulePtr = SigScanner.ScanText("E8 * * * * 80 7B 1D 01", nameof(GetUiModulePtr));
}

const string CurrentChannelPrefix = "/current ";
void CheckChannel(ref string command)
{
if (!command.StartsWith("/"))
{
throw new ArgumentException(GetLocalizedString("NoChannelError"));
}
if (command.StartsWith(CurrentChannelPrefix))
{
command = command.Substring(CurrentChannelPrefix.Length);
}
}

/// <summary>
Expand All @@ -31,14 +48,11 @@ public override void GetOffsets()
public void DoNormalTextCommand(string command)
{
CheckBeforeExecution(command);

CheckChannel(ref command);
PluginUI.Log(command);

var assemblyLock = Memory.Executor.AssemblyLock;

var flag = false;
try {
Monitor.Enter(assemblyLock, ref flag);
ExecuteWithLock(() =>
{
var array = Encoding.UTF8.GetBytes(command);
using AllocatedMemory allocatedMemory = Memory.CreateAllocatedMemory(400), allocatedMemory2 = Memory.CreateAllocatedMemory(array.Length + 30);
allocatedMemory2.AllocateOfChunk("cmd", array.Length);
Expand All @@ -52,11 +66,17 @@ public void DoNormalTextCommand(string command)
allocatedMemory.Write("tLength", array.Length + 1);
allocatedMemory.Write("t3", 0x00);
var uiModulePtr = Memory.CallInjected64<IntPtr>(GetUiModulePtr, PostNamazu.FrameworkPtr);
_ = Memory.CallInjected64<int>(ProcessChatBoxPtr, uiModulePtr,allocatedMemory.Address, IntPtr.Zero, (byte)0);
}
finally {
if (flag) Monitor.Exit(assemblyLock);
}
_ = Memory.CallInjected64<int>(ProcessChatBoxPtr, uiModulePtr, allocatedMemory.Address, IntPtr.Zero, (byte)0);
});
}

protected override Dictionary<string, Dictionary<Language, string>> LocalizedStrings { get; } = new()
{
["NoChannelError"] = new()
{
[Language.EN] = $"To avoid sending wrong text to public channels, only commands starting with \"/\" are permitted. Add the prefix \"{CurrentChannelPrefix}\" to post to the current channel.",
[Language.CN] = $"为防止误操作导致错误文本发送至公共频道,仅允许以 \"/\" 开头的指令。如需发送至当前频道,请加前缀 \"{CurrentChannelPrefix}\"。"
},
};
}
}
4 changes: 2 additions & 2 deletions PostNamazu/Actions/Preset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ internal class Preset : NamazuModule
public override void GetOffsets()
{
base.GetOffsets();
var GetUiModulePtr = SigScanner.ScanText("E8 ?? ?? ?? ?? 80 7B 1D 01", "GetUiModulePtr");
var GetUiModulePtr = SigScanner.ScanText("E8 * * * * 80 7B 1D 01", "GetUiModulePtr");
UIModulePtr = Memory.CallInjected64<IntPtr>(GetUiModulePtr, PostNamazu.FrameworkPtr);

var mapIDOffset = SigScanner.Read<UInt16>(SigScanner.ScanText("44 89 81 ? ? ? ? 0F B7 84 24", "mapIDOffset") + 3);
MapIDPtr = SigScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 0F B6 55 ?? 24", 3, nameof(MapIDPtr)) + mapIDOffset;
MapIDPtr = SigScanner.ScanText("48 8D 0D * * * * 0F B6 55 ?? 24", nameof(MapIDPtr)) + mapIDOffset;
}

private void GetWayMarkSlotOffset()
Expand Down
18 changes: 5 additions & 13 deletions PostNamazu/Actions/WayMark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ public class WayMark : NamazuModule
public override void GetOffsets()
{
base.GetOffsets();
MarkingController = SigScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 4C 8B 85", 3, nameof(MarkingController));
// 41 D1 C0 88 81 ? ? ? ? 8B 42 04
MarkingController = SigScanner.ScanText("48 8D 0D * * * * 4C 8B 85", nameof(MarkingController));
Waymarks = MarkingController + 0x1E0;
try
{
ExecuteCommandPtr = SigScanner.ScanText("E8 ?? ?? ?? ?? 48 83 C4 ?? C3 CC CC CC CC CC CC CC CC CC CC CC CC 48 83 EC ?? 45 0F B6 C0", nameof(ExecuteCommandPtr));
ExecuteCommandPtr = SigScanner.ScanText("E8 * * * * 48 83 C4 ?? C3 CC CC CC CC CC CC CC CC CC CC CC CC 48 83 EC ?? 45 0F B6 C0", nameof(ExecuteCommandPtr));
}
catch
{ // 可能和其他插件冲突,加一个备用
Expand Down Expand Up @@ -201,12 +200,9 @@ private void WriteWaymark(Waymark waymark, int id = -1)
/// <param name="waymarks">标点,传入 null 时清空标点,单个标点为 null 时忽略。</param>
public void Public(WayMarks waymarks)
{
var assemblyLock = Memory.Executor.AssemblyLock;
var flag = false;
try
ExecuteWithLock(() =>
{
Monitor.Enter(assemblyLock, ref flag);
if (waymarks == null || waymarks.All(waymark => waymark?.Active == false))
if (waymarks == null || waymarks.All(waymark => waymark?.Active == false))
{ // clear all
Memory.CallInjected64<IntPtr>(ExecuteCommandPtr, 313, 0, 0, 0, 0);
if (waymarks == null)
Expand All @@ -231,11 +227,7 @@ public void Public(WayMarks waymarks)
}
}
}
}
finally
{
if (flag) Monitor.Exit(assemblyLock);
}
});
}

public bool GetInCombat()
Expand Down
3 changes: 2 additions & 1 deletion PostNamazu/Common/I18n.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public enum Language { EN, CN }
["PostNamazu/XivDetectMemRegionGlobal"] = "Set region to global server (detected by memory).",
["PostNamazu/XivDetectRegionCN"] = "Set region to Chinese server (detected by player name).",
["PostNamazu/XivDetectRegionGlobal"] = "Set region to global server (detected by player name).",
["PostNamazu/XivFrameworkNotFound"] = "Failed to find memory signature for Framework, some features will not be available. The plugin may need to be updated.",
["PostNamazu/XivFrameworkNotFound"] = "Failed to find memory signature for Framework, some features will not be available. The plugin may need to be updated. Exception: {0}",
["PostNamazu/XivProcInject"] = "Found FFXIV process {0}.",
["PostNamazu/XivProcInjectException"] = "Error when injecting into FFXIV process, retry later: \n{0}",
["PostNamazu/XivProcInjectFail"] = "Unable to inject into the current FFXIV process, it may have already been injected by another process. Please try restarting the game.",
Expand All @@ -75,6 +75,7 @@ public enum Language { EN, CN }
["PostNamazuUi/CfgReset"] = "Configuration has been reset.",
["PostNamazuUi/ExportWaymarks"] = "Waymarker text has been copied to the clipboard.",
["PostNamazuUi/ExportWaymarksFail"] = "Failed to read existing waymarkers:\n{0}",
["SigScanner/RelAddressingFormatError"] = "Relative addressing sigcode ({0}) must contain exactly 4 consecutive stars (* * * *) and no additional * elsewhere.",
["SigScanner/ResultMultiple"] = "Scanned{0} and found {1} memory signatures, unable to determine a unique location.",
["SigScanner/ResultNone"] = "Scanned{0} and did not find the required memory signatures.",

Expand Down
29 changes: 29 additions & 0 deletions PostNamazu/Common/NamazuModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using GreyMagic;
using System.Collections.Generic;
using static PostNamazu.Common.I18n;
using System.Threading;

namespace PostNamazu.Actions
{
Expand Down Expand Up @@ -128,6 +129,34 @@ protected string GetLocalizedString(string key, params object[] args)
internal class IgnoredException : Exception {
internal IgnoredException(string msg) : base(msg) { }
}

public static void ExecuteWithLock(Action action)
{
bool lockTaken = false;
try
{
Monitor.Enter(Memory.Executor.AssemblyLock, ref lockTaken);
action();
}
finally
{
if (lockTaken) Monitor.Exit(Memory.Executor.AssemblyLock);
}
}

public static T ExecuteWithLock<T>(Func<T> function)
{
bool lockTaken = false;
try
{
Monitor.Enter(Memory.Executor.AssemblyLock, ref lockTaken);
return function();
}
finally
{
if (lockTaken) Monitor.Exit(Memory.Executor.AssemblyLock);
}
}
}

}
Expand Down
Loading
Loading