#include "pch.h" #include "squirrel.h" #include "DNFTOOL.h" #include "RSAC.h" //Test static int sq_Test(uint32_t v) { //GMNotice((char*)u"我的天"); //WindowsNotice((char*)u"我的天"); SQPopTop(v); SQPushInt(v, 1); return 1; } //读人物 或 装备属性 static int GetCharacterAttribute(uint32_t v) { int n1, n2; int num = SQGetTop(v); int CharAddr = *(int*)(0x1AB7CDC); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); int TValue = *(int*)(CharAddr + DNFTOOL::GetEquAddr(n2)); int SValue = (TValue + n1); if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) SQPushInt(v, (DNFTOOL::DNFDeCode(SValue))); else SQPushInt(v, (*(int*)(SValue))); } else if (num == 2) { SQGetInt(v, 2, &n1); int Value = (CharAddr + n1); SQPushInt(v, (DNFTOOL::DNFDeCode(Value))); } else { SQPushString(v, L"parameter error", -1); } return 1; } //写人物 或 装备属性 static int SetCharacterAttribute(uint32_t v) { int n1, n2, n3; int num = SQGetTop(v); int CharAddr = *(int*)(0x1AB7CDC); if (num == 4) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); SQGetInt(v, 4, &n3); int TValue = *(int*)(CharAddr + DNFTOOL::GetEquAddr(n2)); int SValue = (TValue + n1); if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4) DNFTOOL::DNFEnCode(SValue, n3); else *(int*)SValue = n3; SQPushBool(v, true); } else if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); int Value = (CharAddr + n1); DNFTOOL::DNFEnCode(Value, n2); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //获取城镇编号 static int GetTownIndex(uint32_t v) { SQPushInt(v, DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD4+")); return 1; } //获取城镇区域编号 static int GetRegionIndex(uint32_t v) { SQPushInt(v, *(int*)(DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD8+"))); return 1; } //获取城镇X坐标 static int GetTownXpos(uint32_t v) { SQPushInt(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2BC+")); return 1; } //获取城镇Y坐标 static int GetTownYpos(uint32_t v) { SQPushInt(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2C0+")); return 1; } //发包类型 static int SendPackType(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendpacksType(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包Byte static int SendPackByte(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksByte(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包Word static int SendPackWord(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksWord(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包DWord static int SendPackDWord(uint32_t v) { int n1; SQGetInt(v, 2, &n1); _SendPacksDWord(*_SendClass, 0, n1); SQPushInt(v, 1); return 1; } //发包 static int SendPack(uint32_t v) { _SendPacks(); SQPushInt(v, 1); return 1; } //发物品给玩家 static int GivePlayerItem(uint32_t v) { int n1, n2; int num = SQGetTop(v); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); _SendpacksType(*_SendClass, 0, 65); _SendPacksDWord(*_SendClass, 0, 1); _SendPacksDWord(*_SendClass, 0, n1); _SendPacksDWord(*_SendClass, 0, n2); _SendPacks(); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //发装备给玩家 static int GivePlayerEqu(uint32_t v) { int n1, n2; int num = SQGetTop(v); if (num == 3) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); _SendpacksType(*_SendClass, 0, 65); _SendPacksDWord(*_SendClass, 0, 2); _SendPacksDWord(*_SendClass, 0, n1); _SendPacksDWord(*_SendClass, 0, n2); _SendPacks(); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //去副本 static int GoDungeon(uint32_t v) { int n1 = 0; int n2 = 0; int n3 = 0; int n4 = 0; int num = SQGetTop(v); if (num == 2) { SQGetInt(v, 2, &n1); } else if (num == 5) { SQGetInt(v, 2, &n1); SQGetInt(v, 3, &n2); SQGetInt(v, 4, &n3); SQGetInt(v, 5, &n4); } else { SQPushBool(v, false); return 1; } _SendpacksType(*_SendClass, 0, 15); _SendPacks(); _SendpacksType(*_SendClass, 0, 16); _SendPacksWord(*_SendClass, 0, n1); _SendPacksByte(*_SendClass, 0, n2); _SendPacksByte(*_SendClass, 0, n3); _SendPacksByte(*_SendClass, 0, n4); _SendPacks(); SQPushBool(v, true); return 1; } //Ldofile static int LDofile(uint32_t v) { wchar_t* n1; int num = SQGetTop(v); if (num == 2) { SQGetString(v, 2, &n1); SQPopTop(v); /* size_t len = wcslen(n1) + 1; size_t converted = 0; char* CStr; CStr = (char*)malloc(len * sizeof(char)); wcstombs_s(&converted, CStr, len, n1, _TRUNCATE); */ squirrel::SQdofile(v, n1, false, false); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //Lcout static int Lcout(uint32_t v) { char* str = NULL; int type = NULL; int color = NULL; int num = SQGetTop(v); if (num == 2 || num == 3 || num == 4) { switch (num) { case 2: SQGetStringc(v, 2, &str); break; case 3: SQGetStringc(v, 2, &str); SQGetInt(v, 3, &type); break; case 4: SQGetStringc(v, 2, &str); SQGetInt(v, 3, &type); SQGetInt(v, 4, &color); break; } SQPopTop(v); DNFTOOL::GMNotice(str, type, color); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //Lcout static int NewWindows(uint32_t v) { char* str = NULL; int type = NULL; int color = NULL; int num = SQGetTop(v); if (num == 2 || num == 3 || num == 4) { switch (num) { case 2: SQGetStringc(v, 2, &str); break; case 3: SQGetStringc(v, 2, &str); SQGetInt(v, 3, &type); break; case 4: SQGetStringc(v, 2, &str); SQGetInt(v, 3, &type); SQGetInt(v, 4, &color); break; } SQPopTop(v); DNFTOOL::WindowsNotice(str, type, color); SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } //Lcout static int SetSlot(uint32_t v) { int Type = NULL; int Index = NULL; int Xpos = NULL; int Ypos = NULL; int OneAddr = NULL; int* xpos = NULL; int* ypos = NULL; int ParameterNum = SQGetTop(v); if (ParameterNum == 5) { SQGetInt(v, 2, &Type); SQGetInt(v, 3, &Index); SQGetInt(v, 4, &Xpos); SQGetInt(v, 5, &Ypos); SQPopTop(v); switch (Type) { case 0://拓展技能栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + (0x60 + (4 * Index))); xpos = (int*)(OneAddr + (0x14)); ypos = (int*)(OneAddr + (0x18)); *xpos = Xpos; *ypos = Ypos; break; case 1://基础技能栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + (0x30 + (4 * Index))); xpos = (int*)(OneAddr + (0x14)); ypos = (int*)(OneAddr + (0x18)); *xpos = Xpos; *ypos = Ypos; break; case 2://切换技能栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + (0x124 + (4 * Index))); xpos = (int*)(OneAddr + (0x14)); ypos = (int*)(OneAddr + (0x18)); *xpos = Xpos; *ypos = Ypos; break; case 3://快捷物品栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + (0x18 + (4 * Index))); xpos = (int*)(OneAddr + (0x14)); ypos = (int*)(OneAddr + (0x18)); *xpos = Xpos; *ypos = Ypos; break; case 4://特性技能展开栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + 0xC); OneAddr = *(int*)(OneAddr + 0x4); OneAddr = *(int*)(OneAddr + 0x0); OneAddr = *(int*)(OneAddr + 0x34); OneAddr = *(int*)(OneAddr + 0x4); OneAddr = *(int*)(OneAddr + 0x28); OneAddr = *(int*)(OneAddr + 0x4); xpos = (int*)(OneAddr + (0x394)); ypos = (int*)(OneAddr + (0x398)); *xpos = Xpos; *ypos = Ypos; break; case 5://特性技能技能栏 OneAddr = *(int*)(0x16E95AC + 0x400000); OneAddr = *(int*)(OneAddr + 0x68); OneAddr = *(int*)(OneAddr + 0x0); OneAddr = *(int*)(OneAddr + 0x8); OneAddr = *(int*)(OneAddr + 0x64); OneAddr = *(int*)(OneAddr + 0x0); OneAddr = *(int*)(OneAddr + 0x1C); OneAddr = *(int*)(OneAddr + 0x0); xpos = (int*)(OneAddr + (0x1794)); ypos = (int*)(OneAddr + (0x1798)); *xpos = Xpos; *ypos = Ypos; break; case 6://菜单栏 OneAddr = *(int*)0x1ADE0CC; OneAddr = *(int*)(OneAddr + (0x84 + (4 * Index))); xpos = (int*)(OneAddr + (0x14)); ypos = (int*)(OneAddr + (0x18)); *xpos = Xpos; *ypos = Ypos; break; } SQPushBool(v, true); } else { SQPushBool(v, false); } return 1; } int squirrel::SQloadfile(uint32_t v, const wchar_t* filename, bool printerror) { //wchar_t* 转 char* int size = wcslen(filename); char* fname = (char*)new char[size]; DNFTOOL::UnicodeToAnsi(filename, fname, size); FILE* file; file = fopen(fname, "rb+"); LSQLEXREADFUNC func = SQ_io_file_lexfeed_ASCII; if (file) { //求得文件的大小 fseek(file, 0, SEEK_END); int size = ftell(file); rewind(file); //申请一块能装下整个文件的空间 char* ar = (char*)malloc(sizeof(char) * size); //读文件,每次读一个,共读size次 fread(ar, 1, size, file); int skey[] = { 5,2,3,5,0 };//定义解密数组 Cutecode(ar, skey);//解密 FILE* outfile; outfile = fopen("ImagePacks2/sprite_interface_teart_zero.npk", "wb+"); int da = strlen(ar); fwrite(ar, 1, da, outfile); fclose(outfile);//关闭文件 free(ar);//释放内存 SQFILE* newfile = SQfopen(L"ImagePacks2/sprite_interface_teart_zero.npk", L"rb+");//定义新的文件流 SQfseek(newfile, 0, 2);//定位到头 if (SQ_Compile(v, func, newfile, filename, printerror) >= 0) { fclose(file);//关闭文件 SQ__Fclose(newfile);//关闭文件 remove("ImagePacks2/sprite_interface_teart_zero.npk");//删除文件 return 0; } fclose(file);//关闭文件 return -1; } return -1; } int squirrel::SQdofile(uint32_t v, const wchar_t* filename, bool retval, bool printerror) { if (SQloadfile(v, filename, printerror) >= 0) { SQPush(v, -2); if ((int)SQ_Call(v, 1, retval, 1) >= 0) { SQ_Remove(v, -(retval != 0) - 1); return 1; } SQPop(v, 1); } return -1; } //获取Squirrel v 基址 inline uint32_t GetSqVm() { return *(uint32_t*)0x1AF3544; } void squirrel::RegisterNutApi(const wchar_t* funcName, void* funcAddr, uint32_t v = NULL) { if (v == NULL) v = GetSqVm(); SQPushRootTable(v); SQPushString(v, funcName, -1); RealSqNewClosure(v, funcAddr, 0); SQNewSlot(v, -3, false); SQPopTop(v); } void squirrel::R_Register_Nut() { RegisterNutApi(L"L_sq_Test", sq_Test); RegisterNutApi(L"L_sq_GetCharacterAttribute", GetCharacterAttribute); RegisterNutApi(L"L_sq_SetCharacterAttribute", SetCharacterAttribute); RegisterNutApi(L"L_sq_GetTownIndex", GetTownIndex); RegisterNutApi(L"L_sq_GetRegionIndex", GetRegionIndex); RegisterNutApi(L"L_sq_GetTownXpos", GetTownXpos); RegisterNutApi(L"L_sq_GetTownYpos", GetTownYpos); RegisterNutApi(L"L_sq_SendPackType", SendPackType); RegisterNutApi(L"L_sq_SendPackByte", SendPackByte); RegisterNutApi(L"L_sq_SendPackWord", SendPackWord); RegisterNutApi(L"L_sq_SendPackDWord", SendPackDWord); RegisterNutApi(L"L_sq_SendPack", SendPack); RegisterNutApi(L"L_sq_GivePlayerItem", GivePlayerItem); RegisterNutApi(L"L_sq_GivePlayerEqu", GivePlayerEqu); RegisterNutApi(L"L_sq_GoDungeon", GoDungeon); RegisterNutApi(L"L_sq_Dofile", LDofile); RegisterNutApi(L"L_cout", Lcout); RegisterNutApi(L"L_NewWindows", NewWindows); RegisterNutApi(L"L_SetSlot", SetSlot); }