- 注册时间
- 2011-8-8
- 最后登录
- 1970-1-1
该用户从未签到
|
资料很久了由于忙碌实业一段时间没跟这个游戏了。
把找到的数据分享一次
这个游戏有个很大的特征有holyking.map 这个文件
这个文件会有所有函数的名字和地址例如发包CALL
0001:002063f0 ??1UBI_CCSAcceptQuestPacket@@UAE@XZ 006073f0 f i SH_NpcQuestDialogData.obj、
06073f0这个地址就是发包CALL
MAP 文件可以用记事本打开 找功能非常爽的一个游戏
map文件可以转IDA的脚本文件。具体可以找百度解决。转到IDA脚本的话看函数就非常方便了
至于控件遍历也非常简单的使用 熟悉下CEGUI
然后直接动态库的方式操作调用cegui.dll直接操作游戏内所有控件
例如
void OutChilWndInfo(CEGUI::Window* wnd,int pos)
{
const char *name = (((CEGUI::String*)((DWORD)wnd + 0xf0)))->c_str(); //childWnd->getName().c_str();
const char *text = wnd->getText().c_str();
wstring sTempW;
wstring gR;
for (int i=0;i<pos;i++)
{
gR.append(TEXT("\r"));
}
TraceOut(TEXT("%s [%S][%s]"),gR.c_str(),name,Utf8ToUnicode(text,sTempW).c_str());
for (size_t i = 0; i < wnd->getChildCount(); ++i)
{
OutChilWndInfo(wnd->getChildAtIdx(i),i);
}
TraceOut(TEXT("%s [%S]"),gR.c_str(),name);
}
void CInfoWnd::OnBnClickedButton()
{
OutChilWndInfo(CEGUI::System::getSingleton().getGUISheet(),0); //这样调用就可以遍里游戏内所有游戏窗口的标题和名字了
}
你得到CEGUI的CEGUI::Window 然后就可以得到标题的内容了。如果想下按某一个控件 就要移动鼠标 然后下按一次就OK
// CEGUI::Rect wndRec = childWnd->getInnerRectClipper();
// sprintf_s(buf,"[%f][%f]\n[%f][%f]",wndRec.d_left, wndRec.d_top, wndRec.d_right, wndRec.d_bottom);
// MessageBoxA(NULL,buf,"",MB_OK);
//
//
// float wndWidth =wndRec.d_right - wndRec.d_left;
// float wndHigh = wndRec.d_bottom - wndRec.d_top;
//
// //SetCursorPos(wndRec.d_left+wndWidth/2,wndRec.d_top+wndHigh/2+20);
//
// CEGUI::System::getSingleton().injectMousePosition(wndRec.d_left+wndWidth/2,wndRec.d_top+wndHigh/2);
//
// CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
//
// CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
以上代码就是将鼠标移动到某一个窗口的中心点然后下按一次
使用CEGUI就是这么简单
至于要得到游戏内的数据还是很简单的。比如遍里包裹。移动到某一个点。
这些操作全部可以使用LUA实现
lua直接使用游戏自身注册函数
int LuaDoString(const char *cmd)
{
try
{
_asm
{
pushad
mov eax,call_GetLuaState_A
call eax
mov ecx,eax
push [cmd]
mov eax,call_DoString_A
call eax
popad
}
}
catch (...)
{
TraceOut(TEXT("CGameFunc::LuaDoString 异常"));
}
}
LuaDoStringd("ofile(c:\\\\1.lua);"); 这样调用就可以实现让游戏执行c:\1.lua 这个lua脚本了
lua脚本函数内可以自由使用游戏注册的lua函数
例如移动到某个NPC
SceneMapData:MoveToNPC(0x313d);
这样就可以移动到某个NPC了
注意切换类环境例如
setfenv(1,SceneMap);-- 功能描述 : 场景大地图
setfenv(1,Quest_Management);-- 功能描述:任务管理界面信息
setfenv(1,Activity);-- 活动
这些环境切换错误会导致调用无效或者变量获取不正常
至于怎么加自己的LUA函数接口就自己思考下了。很简单就能实现的
local FrontTask = GetFrontTask();--GetFrontTask()是智辅函数
if (FrontTask == 0) then return end;
local QuestName = MyselfQuestData:GetQuestName(FrontTask);--获得任务名字
TraceOut(tostring(QuestName));-- TraceOut智辅函数
if (QuestName == nil) then
TraceOut("AcceptQuest:"..FrontTask);
AcceptQuest(FrontTask);--AcceptQuest接任务 接任务是可以远程接的。。交任务没测试
return;
end
SceneMapData:MoveToNPC(taskData_CQ[QuestName]["MoveToNpc"]);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
开始挂机
param0:[4][AutoMachine_Button_Start]
setfenv(1,AutoMachine);AutoMachine_StarAutoMachine();
关闭挂机
param0:[4][AutoMachine_Button_Stop]
setfenv(1,AutoMachine);AutoMachine_StopAutoMachine();
关闭任务窗口
param0:[4][NPC_Dialog_Button_Close]
setfenv(1,NPCDialog);NPCDialog_Hide();
param0
param1
param2
。。。。。。
上面这些是可以通过 LuaDoString这个函数来使用的 LuaDoString(“setfenv(1,NPCDialog);NPCDialog_Hide();”); 这样调用
但是param0 param1 这些参数需要挂钩游戏调用才能捕获到
param0 是lua的一个全局变量param1 param2 依次类推 是游戏lua参数通讯
就是游戏调用脚本的时候用的
比如分解装备 选择NPC对话第几项都需要设置这个参数 全是文本类型的
设置函数
.text:00419C50 E8 4B DA 00 00 call ?GetSingleton@UBI_ScriptSystem@@SAAAV1@XZ ; UBI_ScriptSystem::GetSingleton(void)
.text:00419C55 E8 46 DD 00 00 call ?__GetLuaState@UBI_ScriptSystem@@KAPAVLuaState@LuaPlus@@XZ ; UBI_ScriptSystem::__GetLuaState(void)
.text:00419C5A 8D 8D 10 FD FF FF lea ecx, [ebp+var_2F0]
.text:00419C60 51 push ecx
.text:00419C61 8B C8 mov ecx, eax
.text:00419C63 E8 F8 55 2F 00 call ?GetGlobals@LuaState@LuaPlus@@QAE?AVLuaObject@2@XZ ; LuaPlus::LuaState::GetGlobals(void)
.text:00419C68 C6 45 FC 01 mov byte ptr [ebp+var_4], 1
.text:00419C6C 68 63 27 79 00 push offset ??_C@_00CNPNBAHC@?$AA@ ; Str
.text:00419C71 68 5C 27 79 00 push offset ??_C@_06NCJCGBBM@param0?$AA@ ; "param0"
.text:00419C76 8B C8 mov ecx, eax
.text:00419C78 E8 E3 DE 2E 00 call ?SetString@LuaObject@LuaPlus@@QAEAAV12@PBD0@Z ; LuaPlus::LuaObject::SetString(char const *,char const *)
.text:00419C7D C6 45 FC 00 mov byte ptr [ebp+var_4], 0
至于怎么获得游戏脚本。,这个只能DUMP游戏内存。你直接搜索 lua的关键字 然后找到文件的启始位置DUMP 保存成文本。加上UTF8的标志头就可以看到中文的注释和LUA代码了 |
|