This commit is contained in:
Lenheart 2025-04-28 23:02:20 +08:00
parent bfb9be65b5
commit 1fddc97e20
12 changed files with 756 additions and 81 deletions

View File

@ -562,15 +562,6 @@ public:
{
httplib::Client cli(ym);
//cli.set_ca_cert_path("./ca-bundle.crt");
// Disable cert verification
cli.enable_server_certificate_verification(false);
//cli.set_read_timeout(30); // ¶ÁÈ¡³¬Ê±30Ãë
//cli.set_connection_timeout(30);
//cli.set_write_timeout(30);
httplib::Params ParamsObj;//新建 Params 对象
ParamsObj.emplace("ip", ippack.c_str());//加入账号数据进数据包
@ -607,12 +598,8 @@ public:
timestamp.pop_back(); // Remove trailing newline character
ParamsObj.emplace("l", timestamp);//时间戳
//CliObj->set_connection_timeout(0, 1000000); // 300 milliseconds
//CliObj->set_read_timeout(5, 0); // 5 seconds
//CliObj->set_write_timeout(5, 0); // 5 seconds
auto res = cli.Post("/c/user2/getproclient2", ParamsObj);
//auto res = cli.Get("/c/user/getproclient");
if (res) {
if (res->status == 200)//如果返回包正常
{
@ -656,6 +643,7 @@ xe4DWCUH/DAGq5f6EwIDAQAB
if (nutres->status == 200)//如果返回包正常
{
Unski(nutres->body, Ti, Dom["k2"].GetString(), Dom["k"].GetString());
MessageBox(NULL, L"完成!", NULL, NULL);
return true;
}
else {

View File

@ -3,9 +3,12 @@
#include "MinHook.h"
#include "inlinehook.h"
#include "RegisterSquirrel.hpp"
#include "IO_Ex.hpp"
//游戏初始化完毕Flag
static bool InitGameFlag = false;
//宽屏百级UI
static bool Yosin百级UIFlag = false;
@ -30,7 +33,11 @@ int Sq_mycompilebuffer(HSQUIRRELVM v, const wchar_t* s, int size, const wchar_t*
buf.ptr = 0;
return SQ_Compile(v, (LSQLEXREADFUNC)0x1359AD0, &buf, filename, printerror);
}
void Suxn() {
size_t Ds = BaseData.size();
for (size_t i = 0; i < Ds; i++)
@ -304,7 +311,7 @@ void __declspec(naked)Damage_Hook() {
if (InitGameFlag)
{
int Address = Damage_HookAsm.EBX;//只要等于 red 或者 等于0 就说明是我自己的伤害
int Address = Damage_HookAsm.EBX;//只要等于 read 或者 等于0 就说明是我自己的伤害
int Damage = *(DWORD*)(Damage_HookAsm.EBP - 0x17c);
Damage_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
@ -333,6 +340,127 @@ void __declspec(naked)Damage_Hook() {
}
typedef struct REG1
{
DWORD EAX;
DWORD EBX;
DWORD ECX;
DWORD EDX;
DWORD ESI;
DWORD EDI;
DWORD ESP;
DWORD EBP;
DWORD VmAddress;
BYTE Cl;
SQBool flag;
int vm_data1;
} REG1;
REG1 DiscardItem_HookAsm = { 0 };
void __declspec(naked)DiscardItem_Hook() {
static int address = 0xE71EAB;
static int func = 0xE6E070;
_asm
{
pushad
pushfd
mov DiscardItem_HookAsm.ESI, esi
mov DiscardItem_HookAsm.EBX, ebx
}
if (InitGameFlag)
{
DiscardItem_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"Sq_DiscardItem", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookAsm.ESI);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 2, 1, 1);
Sq_getbool(*(HSQUIRRELVM*)0x1AF3544, -1, &DiscardItem_HookAsm.flag);
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookAsm.VmAddress);
if (!DiscardItem_HookAsm.flag) {
_asm {
popfd
popad
mov eax,0
jmp address
}
}
}
_asm {
popfd
popad
push 1
push DiscardItem_HookAsm.ESI
push 0xFB
mov ecx, DiscardItem_HookAsm.EBX
call func
jmp address
}
}
REG1 DiscardItem_HookBAsm = { 0 };
void __declspec(naked)DiscardItemB_Hook() {
static int address = 0xE71E95;
static int func = 0x10086C0;
_asm
{
pushad
pushfd
mov DiscardItem_HookBAsm.EAX, eax
mov DiscardItem_HookBAsm.ESI, esi
mov DiscardItem_HookBAsm.ECX, ecx
}
if (InitGameFlag)
{
DiscardItem_HookBAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"Sq_DiscardItem", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookBAsm.ESI);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 2, 1, 1);
Sq_getbool(*(HSQUIRRELVM*)0x1AF3544, -1, &DiscardItem_HookBAsm.flag);
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookBAsm.VmAddress);
if (!DiscardItem_HookBAsm.flag) {
_asm {
popfd
popad
mov eax, 0
jmp address
}
}
}
_asm {
popfd
popad
push 0
push 0
push 0
push 0x1C
push DiscardItem_HookBAsm.EAX
push 0
push 0
call func
jmp address
}
}
void __declspec(naked)SelectCharacter_Hook() {
static int address = 0x10F79D1;
_asm
@ -504,6 +632,56 @@ void __declspec(naked)ReadStringBin_HookB() {
}
}
REG1 MonsetrRace_HookAsm = { 0 };
void __declspec(naked)MonsetrRace_Hook() {
static int address = 0x43A8BA;
static int address1 = 0x43A86A;
_asm
{
mov MonsetrRace_HookAsm.EBX, ebx
mov MonsetrRace_HookAsm.EDX, edx
xor ebx, ebx
push edi
mov edi, [ebp + 0x8]
test eax, eax
pushad
pushfd
mov MonsetrRace_HookAsm.ESI, esi
mov MonsetrRace_HookAsm.vm_data1, 34
}
MonsetrRace_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"L_Rindro_MonsterEXControl_Race", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.ESI);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.EBX);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.EDX);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 4, 1, 1);
Sq_getinteger(*(HSQUIRRELVM*)0x1AF3544, -1, &MonsetrRace_HookAsm.vm_data1);
}
else {
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.VmAddress);
_asm {
popfd
popad
jmp address1
}
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.VmAddress);
_asm {
popfd
popad
mov edi, MonsetrRace_HookAsm.vm_data1
jmp address
}
}
@ -618,9 +796,10 @@ void __declspec(naked)ReadStringBin_HookB() {
//窗口打开事件Hook
typedef void(__fastcall _OpenWindow)(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD a3);
typedef void(__fastcall _OpenWindow)(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2, DWORD a3);
static _OpenWindow* OldOpenWindow;
void __fastcall NewOpenWindow(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD a3) {
void __fastcall NewOpenWindow(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2, DWORD a3) {
if (InitGameFlag) {
if (*(DWORD*)0x1A5FB20 == thisc) {
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
@ -633,6 +812,8 @@ void __fastcall NewOpenWindow(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD
}
Sq_settop(v, Top);
}
}
OldOpenWindow(thisc, 0, a1, a2, a3);
}
@ -775,7 +956,7 @@ void Pack_Control(int idx, int code, void* p3, void* p4)
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
#ifdef SELL
#if defined(SELL) || defined(EXPRESS)
Sq_pushstring(v, L"Sq_Pack_Control", -1);
#else
Sq_pushstring(v, L"Sq_Pack_ControlLocal", -1);
@ -849,19 +1030,75 @@ DWORD _fastcall New4C61F0(DWORD thisc, DWORD Seat)
}
static void InitBin() {
void* buf = malloc(81443744);
int readsize;
typedef bool(_59E3D0)(wchar_t* path, void* buffer, int a3, int* a4);
_59E3D0* SUB_59E3D0 = (_59E3D0*)0x59E3D0;
bool a = SUB_59E3D0(L"stringtable.bin", buf, 81443744, &readsize);
if (a) {
IO_Ex pvf((char*)buf, readsize);
int Count = pvf.GetInt();
int CurrentIndex = 0;
for (int i = 0; i < Count; i++) {
pvf.seek(CurrentIndex * 4 + 4);
int StartPos = pvf.GetInt();
int EndPos = pvf.GetInt();
int Len = EndPos - StartPos;
pvf.seek(StartPos + 4);
std::string Str = pvf.GetString(Len);
StringBin.push_back(Str);
CurrentIndex++;
}
}
free(buf);
}
void PFunc(HSQUIRRELVM v, const SQChar* s, ...) {
va_list vl;
va_start(vl, s);
// 使用_vsnwprintf正确计算格式化后的宽字符字符串长度
int len = _vsnwprintf(nullptr, 0, s, vl);
va_end(vl);
va_start(vl, s);
// 动态分配足够的内存空间注意长度计算需要考虑宽字符的字节数通常一个宽字符占2字节或更多取决于平台和编码
wchar_t* buffer = new wchar_t[len + 1];
// 将格式化后的宽字符字符串拼接到动态分配的内存中
_vsnwprintf(buffer, len + 1, s, vl);
va_end(vl);
std::wofstream outFile("test.txt", std::ios::out | std::ios::app | std::ios::binary); // 以二进制模式打开文件用于追加写入
if (outFile) {
outFile << buffer << std::endl; // 将宽字符字符串写入文件,并添加换行符
outFile.close(); // 关闭文件流
std::wcout << L"宽字符字符串已成功追加写入文件。" << std::endl;
}
else {
std::wcerr << L"无法打开文件进行追加写入。" << std::endl;
}
std::wcout << buffer << std::endl; // 使用std::wcout输出宽字符字符串
delete[] buffer;
}
//HookNut函数注册
typedef void(__cdecl _Register_Nut)();
static _Register_Nut* Register_Nut_Old;
void __cdecl H_Register_Nut()
{
InitBin();
Register_Nut_Old();
static bool Init = false;
if (!Init) {
Init = true;
//sq_setprintfunc(*(HSQUIRRELVM*)0x1AF3544, PFunc);
R_Register_Nut();
std::string BaseFile = "YosinBaseC";
std::string Base = R"(
FFI_FIRST_ABI <- 0;
@ -927,7 +1164,9 @@ getroottable().LenheartBaseFuncTab <- {};
getroottable().LenheartFuncTab <- {};
getroottable().Rindro_Scr_Width <- L_sq_RA(0x4D848E);
getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
)";
//是否为本地
FILE* file = fopen("sqr/DofileList.nut", "rb");
if (file)
@ -954,6 +1193,7 @@ getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
delete[]str;
#ifndef SELL//本地模式要加在整体脚本
#ifndef EXPRESS//本地模式要加在整体脚本
Sq_pushroottable(v);
Sq_pushstring(v, L"dofile", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
@ -963,6 +1203,8 @@ getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
}
Sq_pop(v, 2);
#endif // !SELL
#endif // !SELL
}
}
@ -987,7 +1229,7 @@ void _fastcall H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, int a5
delete[]clone;
if (GameStr.find("商城") != std::string::npos) {
if (GameStr.find("将帐号金库中的物品存入金库中") != std::string::npos) {
std::cout << GameStr << std::endl;
}
@ -1662,8 +1904,49 @@ int _fastcall New4017F0(int thisc, void* a2, char* str, int a3) {
return Old4017F0(thisc, a2, str,a3);
}
//怪物头像绘制HOOK
typedef int(__fastcall _43A1B0)(DWORD thisc, DWORD Seat, int Xpos , int Ypos);
static _43A1B0* Old43A1B0;
int __fastcall New43A1B0(DWORD thisc, DWORD Seat, int Xpos, int Ypos) {
SQBool Flag = true;
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
Sq_pushstring(v, L"L_Rindro_MonsterEXControl_Face", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
Sq_pushroottable(v);
Sq_pushinteger(v, *(DWORD*)(thisc + 8));
Sq_pushinteger(v, Xpos);
Sq_pushinteger(v, Ypos);
Sq_call(v, 4, SQTrue, SQTrue);
Sq_getbool(v, -1, &Flag);
}
Sq_settop(v, Top);
if(Flag)return Old43A1B0(thisc, Seat, Xpos, Ypos);
return 0;
}
void RegisterHook() {
#ifdef EXPRESS
InitGameFlag = true;
MH_Initialize();
//Hook收包
MH_CreateHook((void*)0x721EA0, &H_Register_Pack, reinterpret_cast<void**>(&Lpfn_Init));
MH_EnableHook((void*)0x721EA0);
//HookNut函数注册
MH_CreateHook((void*)0x67B910, &H_Register_Nut, reinterpret_cast<void**>(&Register_Nut_Old));
MH_EnableHook((void*)0x67B910);
return;
#endif // EXPRESS
//InlineHook///
//玩家菜单选项HOOK 有回调
@ -1678,12 +1961,20 @@ void RegisterHook() {
//伤害HOOK
inlinehook DamageHook(0xE5A2DE, (int)&Damage_Hook);
DamageHook.Motify_address();
//丢弃道具的HOOK
inlinehook DiscardItemHook(0xE71E9C, (int)&DiscardItem_Hook);
DiscardItemHook.Motify_address();
inlinehook DiscardItemHookB(0xE71E83, (int)&DiscardItemB_Hook);
DiscardItemHookB.Motify_address();
//怪物种族绘制HOOK
inlinehook MonsetrRaceHook(0x43A862, (int)&MonsetrRace_Hook);
MonsetrRaceHook.Motify_address();
//读取StringBin文件
inlinehook ReadStringBinHookA(0x119F2F8, (int)&ReadStringBin_HookA);
ReadStringBinHookA.Motify_address();
inlinehook ReadStringBinHookB(0x119F2C0, (int)&ReadStringBin_HookB);
ReadStringBinHookB.Motify_address();
////读取StringBin文件
//inlinehook ReadStringBinHookA(0x119F2F8, (int)&ReadStringBin_HookA);
//ReadStringBinHookA.Motify_address();
//inlinehook ReadStringBinHookB(0x119F2C0, (int)&ReadStringBin_HookB);
//ReadStringBinHookB.Motify_address();
@ -1761,8 +2052,8 @@ void RegisterHook() {
//Hook发包相关
//HOOK发包类型
//MH_CreateHook((void*)0x1127D60, &NewSendPacksType, reinterpret_cast<void**>(&_OldSendPackType));
//MH_EnableHook((void*)0x1127D60);
MH_CreateHook((void*)0x1127D60, &NewSendPacksType, reinterpret_cast<void**>(&_OldSendPackType));
MH_EnableHook((void*)0x1127D60);
//MH_CreateHook((void*)0x1128550, &NewSendPacksByte, reinterpret_cast<void**>(&_OldSendPackByte));
//MH_EnableHook((void*)0x1128550);
//MH_CreateHook((void*)0x1128580, &NewSendPacksWord, reinterpret_cast<void**>(&_OldSendPackWord));
@ -1789,6 +2080,7 @@ void RegisterHook() {
//如果加载了百级UI
FILE* file = fopen("ImagePacks2/!HUD_Yosin百级UI.NPK", "rb");
if (file) {
Yosin百级UIFlag = true;
//BUFF图标 显示
inlinehook BuffIconHook(0x04C8C14, (int)&BuffIcon_Hook);
BuffIconHook.Motify_address();
@ -1857,6 +2149,9 @@ void RegisterHook() {
//MH_CreateHook((void*)0x11D43A0, &New11D43A0, reinterpret_cast<void**>(&Old11D43A0));
//MH_EnableHook((void*)0x11D43A0);
//怪物头像绘制 Hook
MH_CreateHook((void*)0x43A1B0, &New43A1B0, reinterpret_cast<void**>(&Old43A1B0));
MH_EnableHook((void*)0x43A1B0);
//他人信息Hook 数值
MH_CreateHook((void*)0xFA42D0, &NewFA42D0, reinterpret_cast<void**>(&OldFA42D0));

126
Include/IO_Ex.hpp Normal file
View File

@ -0,0 +1,126 @@
#pragma once
#include <iostream>
#include <fstream>
#include <cctype>
#include <algorithm>
#include <vector>
using namespace std;
// 定义宏用于注册获取不同类型值的函数
#define REGISTER_GET_FUNCTION(Type, FunctionName) \
Type Get##FunctionName() { \
char buffer[sizeof(Type)]; \
read(buffer, sizeof(Type)); \
Type result; \
std::memcpy(&result, buffer, sizeof(Type)); \
return result; \
}
class IO_Ex
{
public:
//原始数据
char* _Data;
//最大长度
int _MaxLen = 0;
//当前位置
int _CurPos = 0;
//上一次读取的实际大小
int _LastReadSize = 0;
public:
IO_Ex(char* data,int len) {
_Data = data;
_MaxLen = len;
}
~IO_Ex();
public:
int tellg() {
return _CurPos;
}
void read(char* ptr, int size) {
if ((size + _CurPos) > _MaxLen) {
size = _MaxLen - _CurPos;
}
memcpy(ptr, _Data + _CurPos, size);
_CurPos += size;
_LastReadSize = size;
}
int gcount() {
return _LastReadSize;
}
void seek(int _jidx) {
_CurPos = _jidx;
}
public:
unsigned int charPtrToInt(const char* bytes) {
unsigned int result;
std::memcpy(&result, bytes, sizeof(int));
return result;
}
void CrcDecode(const int Length, const int crc32) {
int num = 0x81A79011;
for (int i = 0; i < Length; i += 4)
{
int Pos = tellg();
char buffer[4];
read(buffer, 4);
unsigned int anInt = charPtrToInt(buffer);
unsigned int val = (anInt ^ num ^ crc32);
unsigned int jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF);
_Data[Pos] = ((jiemi >> 0) & 0xFF);;
_Data[Pos + 1] = ((jiemi >> 8) & 0xFF);
_Data[Pos + 2] = ((jiemi >> 16) & 0xFF);
_Data[Pos + 3] = ((jiemi >> 24) & 0xFF);
}
}
std::string tolower(std::string str) {
for (size_t i = 0; i < str.length(); ++i) {
str[i] = std::tolower(str[i]);
}
return str;
}
std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
std::vector<std::string> tokens;
size_t pos = 0;
size_t found;
while ((found = str.find(delimiter, pos)) != std::string::npos) {
tokens.push_back(str.substr(pos, found - pos));
pos = found + delimiter.length();
}
tokens.push_back(str.substr(pos));
return tokens;
}
public:
REGISTER_GET_FUNCTION(int, Int);
REGISTER_GET_FUNCTION(short, Short);
REGISTER_GET_FUNCTION(unsigned short, UShort);
std::string GetString(const int size) {
char* buffer = new char[size];
read(buffer, size);
if (gcount() != size) {
std::cerr << "未能成功读取指定字节数的数据!" << std::endl;
delete[] buffer;
return "";
}
std::string result(buffer, size);
delete[] buffer;
return result;
}
private:
};
IO_Ex::~IO_Ex()
{
}

209
Include/PVF_IO.hpp Normal file
View File

@ -0,0 +1,209 @@
#pragma once
#include "IO_Ex.hpp"
#include <iostream>
#include <map>
#include <cstdint>
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
class PVF_IO : public IO_Ex
{
struct PvfFileInfo
{
int ROffset;
int Cr32;
int Length;
bool DecodeFlag = false;
};
private:
int StartPos = 0;
std::map<std::string, PvfFileInfo>FileInfo;
std::map<int, std::string>BinStringM;
std::map<std::string, std::string>LoadStringM;
public:
// 构造函数
PVF_IO(const char* defaultFilename = "Script.pvf") : IO_Ex(defaultFilename) {}
// 析构函数在对象销毁时基类fstream的析构函数会自动被调用一般不需要额外特殊处理
~PVF_IO() {}
// 显式删除拷贝构造函数,禁止拷贝操作
PVF_IO(const PVF_IO&) = delete;
// 也可以考虑同时删除拷贝赋值运算符,保持一致的语义,避免误用
PVF_IO& operator=(const PVF_IO&) = delete;
public:
void Init() {
//读取头建立树
InitHeader();
//读取bin文件
InitBin();
//读取LoadString
InitLoadString();
}
void InitHeader() {
//读取UUID的长度
int UUID_LENGTH = GetInt();
//UUID 读 1 - 36位 构造 UTF8 string
std::string UUID = GetString(UUID_LENGTH);
//版本号
int Version = GetInt();
// 文件路径数据的大小
int AlignedIndexHeaderSize = GetInt();
// 解密密钥
int IndexHeaderCrc = GetInt();
// 文件数量
int IndexSize = GetInt();
//文件起始位置
int FristPos = tellg();
//std::cout << "UUID_LENGTH: " << UUID_LENGTH << std::endl;
//std::cout << "UUID: " << UUID << std::endl;
//std::cout << "Version: " << Version << std::endl;
//std::cout << "AlignedIndexHeaderSize: " << AlignedIndexHeaderSize << std::endl;
//std::cout << "IndexHeaderCrc: " << IndexHeaderCrc << std::endl;
//std::cout << "IndexSize: " << IndexSize << std::endl;
CrcDecode(AlignedIndexHeaderSize, IndexHeaderCrc);
int CurrPos = 0;
StartPos = AlignedIndexHeaderSize + 56;
//建立pvf文件索引表
for (size_t i = 0; i < IndexSize; i++)
{
seek(FristPos + CurrPos);
int FileNumber = GetInt();
int FilePathLength = GetInt();
std::string FileName = tolower(GetString(FilePathLength));
int FileLength = GetInt();
int Cre32 = GetInt();
int RelativeOffset = GetInt();
if (FileLength > 0) {
int RealFileLength = (FileLength + 3) & 4294967292;
PvfFileInfo Info;
Info.ROffset = RelativeOffset;
Info.Cr32 = Cre32;
Info.Length = RealFileLength;
Info.DecodeFlag = false;
FileInfo[FileName] = Info;
}
CurrPos += 20;
CurrPos += FilePathLength;
}
}
void InitBin() {
if (FileInfo.count("stringtable.bin") == 0) {
std::cout << "bin文件不存在" << std::endl;
return;
}
PvfFileInfo BinInfo = FileInfo["stringtable.bin"];
seek(StartPos + BinInfo.ROffset);
CrcDecode(BinInfo.Length, BinInfo.Cr32);
seek(StartPos + BinInfo.ROffset);
int FileHPos = tellg();
int Count = GetInt();
int CurrentIndex = 0;
for (int i = 0; i < Count; i++) {
seek(FileHPos + CurrentIndex * 4 + 4);
int StartPos = GetInt();
int EndPos = GetInt();
int Len = EndPos - StartPos;
seek(FileHPos + StartPos + 4);
std::string Str = GetString(Len);
BinStringM[CurrentIndex] = Str;
CurrentIndex++;
}
}
void InitLoadString() {
if (FileInfo.count("n_string.lst") == 0) {
std::cout << "LoadString文件不存在" << std::endl;
return;
}
PvfFileInfo Info = FileInfo["n_string.lst"];
seek(StartPos + Info.ROffset);
CrcDecode(Info.Length, Info.Cr32);
seek(StartPos + Info.ROffset);
int FileHPos = tellg();
int Flag = GetShort();
int i = 2;
while (i < Info.Length)
{
if ((Info.Length - i) >= 10) {
seek(FileHPos + i + 6);
int FindKey = GetInt();
std::string Key = GetBinString(FindKey);
if (Key.length() > 0) {
PvfFileInfo* FileInfo = GetFileInfo(Key);
if (FileInfo == nullptr)continue;
seek(StartPos + FileInfo->ROffset);
CrcDecode(FileInfo->Length, FileInfo->Cr32);
seek(StartPos + FileInfo->ROffset);
std::string Str = GetString(FileInfo->Length);
std::vector<std::string> StrArr = split(Str, "\r\n");
for (auto it = StrArr.begin(); it != StrArr.end(); ++it) {
std::string strobj = *it;
if (strobj.find(">") != std::string::npos) {
std::vector<std::string> strobjarr = split(strobj, ">");
if (strobjarr.size() > 1)
LoadStringM[strobjarr[0]] = strobjarr[1];
}
}
}
}
else break;
i += 10;
}
}
public:
std::string GetBinString(int Key) {
if (BinStringM.count(Key))return BinStringM[Key];
return "";
}
std::string GetLoadString(std::string Key) {
if (LoadStringM.count(Key))return LoadStringM[Key];
return "";
}
PvfFileInfo* GetFileInfo(std::string path) {
path = tolower(path);
if (FileInfo.count(path))return &FileInfo[path];
return nullptr;
}
void LoadFileToBlob(HSQUIRRELVM v ,std::string path, SQUserPointer blobp) {
path = tolower(path);
if (FileInfo.count(path)) {
seek(StartPos + FileInfo[path].ROffset);
if (FileInfo[path].DecodeFlag == false) {
CrcDecode(FileInfo[path].Length, FileInfo[path].Cr32);
seek(StartPos + FileInfo[path].ROffset);
FileInfo[path].DecodeFlag = true;
}
read((char*)blobp, FileInfo[path].Length);
return;
}
sq_pushnull(v);
return;
}
};

View File

@ -97,7 +97,8 @@ static SQInteger sq_LongLongOperation(HSQUIRRELVM v)
std::string RetString = "";
if (Type == "+") {
RetString = std::to_string(value1 + value2);
}else if(Type == "-") {
}
else if (Type == "-") {
RetString = std::to_string(value1 - value2);
}
else if (Type == "*") {
@ -1228,6 +1229,8 @@ static SQInteger sq_DrawItem(HSQUIRRELVM v)
//获取SQR的对象转换为原始对象地址
typedef int(_cdecl __GetSqrObject)(HSQUIRRELVM a1, int a2);
typedef int(_cdecl __PushDnfobject)(HSQUIRRELVM a1, wchar_t* Type, DWORD ObjectAddress, DWORD S);
static __PushDnfobject* PushDnfobject = (__PushDnfobject*)0x11809C0;
static __GetSqrObject* GetSqrObject = (__GetSqrObject*)0x5c1420;
static __GetSqrObject* GetExeObject = (__GetSqrObject*)0x5c13A0;
//获取对象地址
@ -1237,6 +1240,18 @@ static SQInteger GetObjectAddress(HSQUIRRELVM v)
Sq_pushinteger(v, objAddress);
return 1;
}
//对象地址转换为Sqr对象
static SQInteger ObjectAddressToSqrObject(HSQUIRRELVM v)
{
int objAddress;
Sq_getinteger(v, 2, &objAddress);
const SQChar* Type;
Sq_getstring(v, 3, &Type);
int Flag;
Sq_getinteger(v, 4, &Flag);
PushDnfobject(v, (wchar_t*)Type, objAddress, 0);
return 1;
}
//获取对象名称
static SQInteger GetObjectName(HSQUIRRELVM v)
{
@ -1249,6 +1264,18 @@ static SQInteger GetObjectName(HSQUIRRELVM v)
delete[]name;
return 1;
}
//设置对象名称
static SQInteger DeleteObjectName(HSQUIRRELVM v)
{
int objAddress = GetSqrObject(v, 2);
wchar_t* objNameAddress = *(wchar_t**)(objAddress + 0x258);
// 遍历字符串直到遇到宽字符空终止符
for (wchar_t* p = objNameAddress; *p != L'\0'; ++p) {
// 将每个字符替换为空格
*p = L' ';
}
return 0;
}
//获取对象名称
static SQInteger GetObjectNameByAddress(HSQUIRRELVM v)
{
@ -1521,10 +1548,10 @@ static _FloatDecode FloatDecode = (_FloatDecode)0x5B0090;
//获取对象属性
static SQInteger GetObjectAttribute(HSQUIRRELVM v)
{
int objAddress ,Type;
int objAddress, Type;
Sq_getinteger(v, 2, &objAddress);
Sq_getinteger(v, 3, &Type);
int Ret = GetObjectAttributeFunc(objAddress,0, Type);
int Ret = GetObjectAttributeFunc(objAddress, 0, Type);
Ret = FloatDecode(Ret);
Sq_pushinteger(v, Ret);
return 1;
@ -1603,25 +1630,25 @@ static SQInteger SetCharacterAttribute(HSQUIRRELVM v)
//获取城镇编号
static SQInteger GetTownIndex(HSQUIRRELVM v)
{
Sq_pushinteger(v, DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD4+",0));
Sq_pushinteger(v, DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD4+", 0));
return 1;
}
//获取城镇区域编号
static SQInteger GetRegionIndex(HSQUIRRELVM v)
{
Sq_pushinteger(v, *(int*)(DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD8+",0)));
Sq_pushinteger(v, *(int*)(DNFTOOL::GetHook(0x1A5E258, "0xAC+0xD8+", 0)));
return 1;
}
//获取城镇X坐标
static SQInteger GetTownXpos(HSQUIRRELVM v)
{
Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2BC+",0));
Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2BC+", 0));
return 1;
}
//获取城镇Y坐标
static SQInteger GetTownYpos(HSQUIRRELVM v)
{
Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2C0+",0));
Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2C0+", 0));
return 1;
}
//获取疲劳值
@ -2074,7 +2101,7 @@ static SQInteger LReadAddress(HSQUIRRELVM v)
Sq_getinteger(v, 2, &Address);
Sq_getstring(v, 3, &offset);
int Value = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar((wchar_t*)offset),0);
int Value = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar((wchar_t*)offset), 0);
Sq_pushinteger(v, Value);
return 1;
}
@ -2743,7 +2770,7 @@ static SQInteger sq_Test(HSQUIRRELVM v)
sq_getstring(v, 2, &Path);
char* a = new char[1024];
//wchar_t* path = L"region/region.lst";
SUB_11A2030(0x1D17638,0, (int)Path,(int)a, 0x100000, 0x19DAF4);
SUB_11A2030(0x1D17638, 0, (int)Path, (int)a, 0x100000, 0x19DAF4);
//std::cout << a << std::endl;
return 0;
@ -2967,6 +2994,7 @@ static SQInteger L_Str_Ptr(HSQUIRRELVM v)
Sq_pushuserpointer(v, (void*)str);
return 1;
}
static SQInteger New_Point(HSQUIRRELVM v)
{
SQInteger Len;
@ -3111,7 +3139,7 @@ static SQInteger ConvertWideChar(HSQUIRRELVM v)
if (CONTAINS_STRING(fromEncoding, "big5")) {
char* csa = DNFTOOL::wchar_tTochar((wchar_t*) Str);
char* csa = DNFTOOL::wchar_tTochar((wchar_t*)Str);
wchar_t* name = DNFTOOL::BIG5ToUnicode(csa);
char* str = DNFTOOL::UnicodeToUtf8(name);
wchar_t* realname = DNFTOOL::charTowchar_t(str);
@ -3222,8 +3250,10 @@ void R_Register_Nut() {
RegisterMyNutApi(L"L_Sq_DrawItem", sq_DrawItem);//绘制Item
RegisterMyNutApi(L"L_Sq_GetObjectAddress", GetObjectAddress);//获取对象地址
RegisterMyNutApi(L"L_Sq_ObjectAddressToSqrObject", ObjectAddressToSqrObject);//对象地址转换为Sqr对象
RegisterMyNutApi(L"L_Sq_GetRidingObjectAddress", GetRidingObjectAddress);//获取骑乘对象地址
RegisterMyNutApi(L"L_Sq_GetObjectName", GetObjectName);//获取对象名字
RegisterMyNutApi(L"L_Sq_DeleteObjectName", DeleteObjectName);//设置对象名字
RegisterMyNutApi(L"L_Sq_GetObjectNameByAddress", GetObjectNameByAddress);//获取对象名字
RegisterMyNutApi(L"L_Sq_GetObjectInfo", GetObjectInfo);//获取对象信息
RegisterMyNutApi(L"L_Sq_GetObjectDeInfo", GetObjectDeInfo);//获取对象加密信息

View File

@ -11,8 +11,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squirrel", "F:\nut\SQUIRREL
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqstdlib", "F:\nut\SQUIRREL2\sqstdlib\sqstdlib.vcxproj", "{5B802548-C7C1-4993-B338-472AF8B11730}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffi", "F:\zhuomian\Libffi-master\Libffi-master\build\ffi.vcxproj", "{E76C4B11-4165-3C69-89CE-954037C7BB5B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -107,26 +105,6 @@ Global
{5B802548-C7C1-4993-B338-472AF8B11730}.Template|x64.Build.0 = Template|Win32
{5B802548-C7C1-4993-B338-472AF8B11730}.Template|x86.ActiveCfg = Template|Win32
{5B802548-C7C1-4993-B338-472AF8B11730}.Template|x86.Build.0 = Template|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Debug|x64.ActiveCfg = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Debug|x64.Build.0 = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Debug|x86.ActiveCfg = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Debug|x86.Build.0 = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.MinSizeRel|x64.ActiveCfg = MinSizeRel|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.MinSizeRel|x64.Build.0 = MinSizeRel|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.MinSizeRel|x86.ActiveCfg = MinSizeRel|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.MinSizeRel|x86.Build.0 = MinSizeRel|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Release|x64.ActiveCfg = Release|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Release|x64.Build.0 = Release|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Release|x86.ActiveCfg = Release|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Release|x86.Build.0 = Release|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Template|x64.ActiveCfg = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Template|x64.Build.0 = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Template|x86.ActiveCfg = Debug|Win32
{E76C4B11-4165-3C69-89CE-954037C7BB5B}.Template|x86.Build.0 = Debug|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -158,8 +158,11 @@
<ClInclude Include="Include\Hook.hpp" />
<ClInclude Include="Include\HookUi.hpp" />
<ClInclude Include="Include\inlinehook.h" />
<ClInclude Include="Include\IO_Ex.hpp" />
<ClInclude Include="Include\PVF_IO.hpp" />
<ClInclude Include="Include\RegisterSquirrel.hpp" />
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
@ -182,11 +185,18 @@
<ProjectReference Include="F:\nut\SQUIRREL2\squirrel\squirrel.vcxproj">
<Project>{055a88b6-e28d-4155-a0db-b2b60dd6c7ae}</Project>
</ProjectReference>
<ProjectReference Include="F:\zhuomian\Libffi-master\Libffi-master\build\ffi.vcxproj">
<Project>{e76c4b11-4165-3c69-89ce-954037c7bb5b}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\zlib-msvc-x86.1.2.11.8900\build\native\zlib-msvc-x86.targets" Condition="Exists('packages\zlib-msvc-x86.1.2.11.8900\build\native\zlib-msvc-x86.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\zlib-msvc-x86.1.2.11.8900\build\native\zlib-msvc-x86.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\zlib-msvc-x86.1.2.11.8900\build\native\zlib-msvc-x86.targets'))" />
</Target>
</Project>

View File

@ -42,6 +42,15 @@
<ClInclude Include="ActiveHook.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Include\IO_Ex.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="Include\PVF_IO.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@ -57,4 +66,7 @@
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@ -42,8 +42,10 @@ void LenheartThread()
}
}
//初始化入口
void Init() {
//是否加载百级UI
FILE* file = fopen("ImagePacks2/!HUD_Yosin百级UI.NPK", "rb");
if (file)
@ -51,12 +53,13 @@ void Init() {
HookHudUi();
fclose(file);
}
//是否开启控制台
FILE* file2 = fopen("ip.txt", "rb");
if (file2)
{
AllocConsole();
SetConsoleTitleA("Rindro_Console");
SetConsoleTitle(L"Rindro_Console");
SetConsoleOutputCP(65001);
freopen(("CONOUT$"), ("w"), stdout);
freopen(("CONOUT$"), ("w"), stderr);
@ -78,9 +81,13 @@ void Init() {
//注册HOOK
RegisterHook();
#ifdef SELL
//多线程验证
DWORD threadID;
HANDLE Thand = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LenheartThread, NULL, 0, &threadID);
#endif
}

4
packages.config Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="zlib-msvc-x86" version="1.2.11.8900" targetFramework="native" />
</packages>

6
pch.h
View File

@ -24,9 +24,9 @@
//# define SELL "售出模式"
#define INVERSION "24081701"
//# define EXPRESS "学习版"
# define SELL "售出模式"
#define INVERSION "24112901"

16
resource.h Normal file
View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 Rindro_Plugin.rc 使用
//
#define IDR_X1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif