DNF_DLL/test/squirrel.cpp

582 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}