Skip to content

Commit

Permalink
[+] NL.RegScriptCallEvent npc脚本luac命令回调事件
Browse files Browse the repository at this point in the history
  • Loading branch information
Muscipular committed Oct 26, 2021
1 parent 0c77675 commit 8f57e15
Showing 1 changed file with 77 additions and 30 deletions.
107 changes: 77 additions & 30 deletions libs/Gmsv/Script.lua
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
local emitter = NL.newEvent('ScriptCall', nil);
local emitter = NL.newEvent('ScriptCallEvent', nil);

local function OnCallBlock(textPtr, npcPtr, playerPtr)
local function OnCallBlock(msgPtr, textPtr, npcPtr, playerPtr)
local c = ffi.cast('uint32_t*', textPtr)[0];
if c == 0x6361756c then
local text = ffi.string(textPtr + 4)
local msg = ffi.string(msgPtr)
local npcIndex = ffi.readMemoryInt32(npcPtr + 4);
local playerIndex = ffi.readMemoryInt32(playerPtr + 4);
print('ScriptCall', text, Char.GetData(npcIndex, CONST.CHAR_Ãû×Ö), Char.GetData(playerIndex, CONST.CHAR_Ãû×Ö));
print('ScriptCall', text, Char.GetData(npcIndex, CONST.CHAR_Ãû×Ö), msg, Char.GetData(playerIndex, CONST.CHAR_Ãû×Ö));
if text then
emitter(npcIndex, playerIndex, s);
emitter(npcIndex, playerIndex, text, msg);
end
return string.len(text) + 4;
end
return 0;
end

ffi.hook.inlineHook('int (__cdecl *)(char* text, uint32_t npc, uint32_t player)', OnCallBlock, 0x0051C9AD, 7,
ffi.hook.inlineHook('int (__cdecl *)(char* msg, char* text, uint32_t npc, uint32_t player)', OnCallBlock, 0x0051C9AD, 7,
{
0x51,
0x52,
Expand All @@ -29,11 +30,14 @@ ffi.hook.inlineHook('int (__cdecl *)(char* text, uint32_t npc, uint32_t player)'
0x8B, 0x85, 0x3C, 0xFB, 0xFF, 0xFF, --mov eax, [ebp-0x4C4]
0x50, --push eax
0x56, --push esi
0x8B, 0x85, 0x08, 0x00, 0x00, 0x00, --mov eax, [ebp+0x8]
0x50, --push eax
},
{
0x59,
0x59,
0x59,
0x59,
0x9d,
0x57 + 8,
0x56 + 8,
Expand All @@ -49,41 +53,79 @@ ffi.hook.inlineHook('int (__cdecl *)(char* text, uint32_t npc, uint32_t player)'
0xff, 0xE0, --jmp eax
}
)
--[[
local function OnCallInline(textPtr, npcPtr, playerPtr)
local text = ffi.string(textPtr)
local npcIndex = ffi.readMemoryInt32(npcPtr + 4);
local playerIndex = ffi.readMemoryInt32(playerPtr + 4);
printAsHex('inline', text, npcPtr, npcIndex, playerPtr, playerIndex)
if string.lower(string.sub(text, 1, 4)) == 'luac' then
local s = string.sub(text, 5)
print('ScriptCall 2', s, Char.GetData(npcIndex, CONST.CHAR_Ãû×Ö), Char.GetData(playerIndex, CONST.CHAR_Ãû×Ö));
if s then
return emitter(npcIndex, playerIndex, s) or 0;

local npc_script_op_list = ffi.new('uint32_t[256]')
for i = 0, 79 do
npc_script_op_list[i] = ffi.readMemoryDWORD(0x006288E0 + i * 4);
end
for i = 80, 255 do
npc_script_op_list[i] = 0;
end
_G.___script_buffer_npc_script_op_list = npc_script_op_list;
npc_script_op_list[254] = 0x6361756c;
npc_script_op_list[80] = ffi.cast('uint32_t', ffi.cast('void*', npc_script_op_list)) + 4 * 254;
npc_script_op_list[253] = ffi.cast('uint32_t', ffi.cast('void*', npc_script_op_list));
local ops = ffi.cast('uint8_t*', ffi.cast('uint32_t', npc_script_op_list) + 253 * 4);
ops = { ops[0], ops[1], ops[2], ops[3] }
ffi.patch(0x0050EBC9 + 3, ops);
ffi.patch(0x0050EC0B + 3, ops);
ffi.patch(0x00516168 + 3, ops);
ffi.patch(0x00516822 + 3, ops);
ffi.patch(0x00518C80 + 3, ops);
ffi.patch(0x0051624B + 2, { 0x51 });
ffi.patch(0x0050EC06 + 2, { 0x51 });
ffi.patch(0x0051688A + 2, { 0x51 });
ffi.patch(0x00518DB1 + 2, { 0x51 });

local function setResult(value)
ffi.setMemoryInt32(0x0111CC00, tonumber(value));
ffi.setMemoryInt32(0x0111CC60, 1);
end

local function OnCallInline(msgPtr, textPtr, npcPtr, playerPtr, type)
if type == 0x3a then
local text = ffi.string(textPtr)
local msg = ffi.string(msgPtr)
local npcIndex = ffi.readMemoryInt32(npcPtr + 4);
local playerIndex = ffi.readMemoryInt32(playerPtr + 4);
local offset = string.find(text, '[><|&=!+-]');
local cmd = string.sub(text, 1, offset - 1);
print('ScriptCall Inline', cmd, Char.GetData(npcIndex, CONST.CHAR_Ãû×Ö), msg, Char.GetData(playerIndex, CONST.CHAR_Ãû×Ö));
local n = tonumber(emitter(npcIndex, playerIndex, cmd, msg)) or 0;
--printAsHex('result', n)
setResult(n);
if offset > 1 then
return offset - 1;
end
return 1;
return 0;
end
return 1;
return 0;
end

ffi.hook.inlineHook('int (__cdecl *)(char* text, uint32_t npc, uint32_t player)', OnCallInline, 0x00516155, 7,
ffi.hook.inlineHook('int (__cdecl *)(char* msg, char* text, uint32_t npc, uint32_t player, int type)', OnCallInline, 0x005135E8, 6,
{
0x51,
--esi ebx eax ecx
0x81, 0xEC, 0xAC, 0x00, 0x00, 0x00, --sub esp, 0x0AC
0x50, --push eax
0x52,
0x53,
0x54,
0x55,
0x56,
0x57,
0x9c,
0x8B, 0x85, 0x70, 0xFF, 0xFF, 0xFF, --mov eax, [ebp-0x4C4]
0x50, --push eax
0x8B, 0x85, 0x64, 0xFF, 0xFF, 0xFF, --mov eax, [ebp-0x4C4]
0x50, --push eax
0x8B, 0x85, 0x74, 0xFF, 0xFF, 0xFF, --mov eax, [ebp-0x4C4]
0x50, --push eax
0x50, --push eax -type
0x51, --push ecx -player
0x52, --push edx -npc
0x8B, 0x85, 0x08, 0x00, 0x00, 0x00, --mov eax, [ebp+0x8]
0x8B, 0x00, --mov eax, [eax]
0x50, --push eax -text
0x8B, 0x85, 0x0C, 0x00, 0x00, 0x00, --mov eax, [ebp+0xC]
0x50, --push eax -msg
},
{
0x59,
0x59,
0x59,
0x59,
0x59,
Expand All @@ -96,10 +138,15 @@ ffi.hook.inlineHook('int (__cdecl *)(char* text, uint32_t npc, uint32_t player)'
0x52 + 8,
0x51 + 8,
0x85, 0xC0, -- test eax, eax
0x74, 0x0D, -- je EIP + 0x0D
0x01, 0x85, 0x44, 0xFB, 0xFF, 0xFF, -- add [ebp-0x4bc], eax
0xB8, 0xD1, 0x9A, 0x51, 0x00, -- mov eax, 0x00519AD1
0xff, 0xE0, --jmp [eax]
0x74, 0x11, -- je EIP + 0x13
0x8B, 0xB5, 0x08, 0x00, 0x00, 0x00, --mov esi, [ebp+0x8]
0x8B, 0x36, --mov ecx, [ecx]
0x01, 0xC6, --add esi, eax
0xB9, 0x47, 0x36, 0x51, 0x00, -- mov eax, 0x00513647
0xff, 0xE1, --jmp [eax]
0x81, 0xC4, 0xAC, 0x00, 0x00, 0x00, --add esp, 0x0AC
0x51, --push ecx
0x50 + 8, --pop eax
}
)
--]]

0 comments on commit 8f57e15

Please sign in to comment.