#pragma once

#include "DNFTOOL.hpp"

#include "zlib.h"
#include <ctime>
#include <sstream>
#include <chrono>
#include "json.hpp"
#include "Register_System.hpp"

using json = nlohmann::json;



#include "ffi.h"
#include "ActiveHook.hpp"


//StringBin文件缓存
static std::vector<std::string> StringBin;



std::map< int, int>ItemColorMap;
int RegisterItemColor_STL(HSQUIRRELVM v)
{
    int ItemID, Clolr;
    int ParameterNum = Sq_gettop(v);
    if (ParameterNum == 3)
    {
        Sq_getinteger(v, 2, &ItemID);
        Sq_getinteger(v, 3, &Clolr);
        ItemColorMap[ItemID] = Clolr;
    }
    return 0;
}
























static SQInteger sq_StringBinById(HSQUIRRELVM v)
{
    SQInteger Idx;
    Sq_getinteger(v, 2, &Idx);

    char* uncode = (char*)(StringBin[Idx]).c_str();

    //char* ss = DNFTOOL::GBKTOUTF8(std::string(uncode));
    std::wstring cfg = DNFTOOL::charTowchar_t(uncode);

    Sq_pushstring(v, cfg.c_str(), -1);

    return 1;
}

static SQInteger sq_LongLongOperation(HSQUIRRELVM v)
{
    const SQChar* valuebuf1;
    Sq_getstring(v, 2, &valuebuf1);
    char* OutPutText = DNFTOOL::SquirrelU2W(valuebuf1);
    LONGLONG value1 = std::atoll(OutPutText);
    delete[]OutPutText;

    const SQChar* valuebuf2;
    Sq_getstring(v, 3, &valuebuf2);
    char* OutPutText2 = DNFTOOL::SquirrelU2W(valuebuf2);
    LONGLONG value2 = std::atoll(OutPutText2);
    delete[]OutPutText2;

    const SQChar* TypeBuf;
    Sq_getstring(v, 4, &TypeBuf);
    char* TypecharBuf = DNFTOOL::SquirrelU2W(TypeBuf);
    std::string Type(TypecharBuf);
    delete[]TypecharBuf;

    std::string RetString = "";
    if (Type == "+") {
        RetString = std::to_string(value1 + value2);
    }
    else if (Type == "-") {
        RetString = std::to_string(value1 - value2);
    }
    else if (Type == "*") {
        RetString = std::to_string((static_cast<double>(value1) * static_cast<double>(value2)));
    }
    else if (Type == "/") {
        RetString = std::to_string((static_cast<double>(value1) / static_cast<double>(value2)));
    }
    else if (Type == "%") {
        RetString = std::to_string(value1 % value2);
    }
    else if (Type == "format") {
        if (value1 < 1000) {
            RetString = std::to_string(value1);
        }
        else if (value1 < 1000000) {
            RetString = std::to_string(value1 / 1000.0) + "k";
        }
        else if (value1 < 1000000000) {
            RetString = std::to_string(value1 / 1000000.0) + "M";
        }
        else if (value1 < 1000000000000LL) {
            RetString = std::to_string(value1 / 1000000000.0) + "G";
        }
        else {
            RetString = std::to_string(value1 / 1000000000000.0) + "T";
        }
    }


    std::wstring ss = DNFTOOL::charTowchar_t((char*)RetString.c_str());
    Sq_pushstring(v, ss.c_str(), -1);

    return 1;
}





//zlib解压
std::string gzip_decompress(const std::string& compressed) {
    z_stream zs;
    memset(&zs, 0, sizeof(zs));

    if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK) {
        //throw std::runtime_error("inflateInit failed");
        return "null";
    }

    zs.next_in = (Bytef*)compressed.data();
    zs.avail_in = compressed.size();

    int ret;
    char outbuffer[32768];
    std::string outstring;

    do {
        zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
        zs.avail_out = sizeof(outbuffer);

        ret = inflate(&zs, 0);

        if (outstring.size() < zs.total_out) {
            outstring.append(outbuffer, zs.total_out - outstring.size());
        }

    } while (ret == Z_OK);

    inflateEnd(&zs);

    if (ret != Z_STREAM_END) {
        //throw std::runtime_error("Exception during zlib decompression: (" + std::to_string(ret) + ") " + zs.msg);
        return "null";
    }

    return outstring;
}
static SQInteger sq_Dezlib(HSQUIRRELVM v)
{
    const SQChar* Str;
    Sq_getstring(v, 2, &Str);
    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    std::string RealStr = OutPutText;
    delete[]OutPutText;

    LenheartBase::CBASE64 bb;
    std::string StrBuf = bb.decode(RealStr);
    StrBuf = gzip_decompress(StrBuf);

    std::wstring ss = DNFTOOL::charTowchar_t((char*)StrBuf.c_str());
    Sq_pushstring(v, ss.c_str(), -1);

    //std::cout << StrBuf << std::endl;
    return 1;
}



//绘制Img
typedef int(_fastcall _Load_Npk)(int thisc, void*, int a2, wchar_t* a3);
typedef int(_fastcall _Get_Img)(int thisc, void*, int a2);
typedef int(_fastcall _Draw_Img)(int thisc, void*, int X, int Y, int Img);
typedef int(_fastcall _Ex_Draw_Img)(DWORD thisc, DWORD Seat, int X, int Y, DWORD Img, int a5, int a6, int a7, int a8, float a9, float a10);
typedef int(_fastcall _Ex_Draw_Num)(DWORD thisc, DWORD Seat, int X, int Y, DWORD Value, DWORD RGBA, int a6);
typedef int(_fastcall _Ex_Draw_Init)(DWORD thisc, DWORD Seat, DWORD Value, DWORD RGBA, DWORD asadsd, DWORD asads3d);
typedef int(_cdecl _Get_Draw_This)(DWORD thisc);

static _Load_Npk* Load_Npk = (_Load_Npk*)0x11C0410;
static _Get_Img* Get_Img = (_Get_Img*)0x11AA190;
static _Draw_Img* Draw_Img = (_Draw_Img*)0x11A8F60;
static _Ex_Draw_Img* Ex_Draw_Img = (_Ex_Draw_Img*)0x11A97E0;
static _Ex_Draw_Num* Ex_Draw_Num = (_Ex_Draw_Num*)0x11b2390;
static _Ex_Draw_Init* Ex_Draw_Init = (_Ex_Draw_Init*)0x11B22C0;
static _Get_Draw_This* Get_Draw_This = (_Get_Draw_This*)0x11A5990;

static SQInteger sq_DrawImg(HSQUIRRELVM v)
{
    int Top = Sq_gettop(v);
    if (Top == 4) {
        int imgbuf;
        Sq_getinteger(v, 2, &imgbuf);
        int X;
        Sq_getinteger(v, 3, &X);
        int Y;
        Sq_getinteger(v, 4, &Y);
        Draw_Img(*(int*)0x1B45B94, 0, X, Y, imgbuf);
        return 0;
    }
    if (Top == 5)
    {
        const SQChar* File;
        Sq_getstring(v, 2, &File);
        int Idx;
        Sq_getinteger(v, 3, &Idx);
        int X;
        Sq_getinteger(v, 4, &X);
        int Y;
        Sq_getinteger(v, 5, &Y);


        int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);
        int imgbuf = Get_Img(npkbuf, 0, Idx);
        Draw_Img(*(int*)0x1B45B94, 0, X, Y, imgbuf);
        return 0;
    }
    else if (Top == 6) {
        const SQChar* File;
        Sq_getstring(v, 2, &File);
        int Value;
        Sq_getinteger(v, 3, &Value);
        int X;
        Sq_getinteger(v, 4, &X);
        int Y;
        Sq_getinteger(v, 5, &Y);
        int rgba;
        Sq_getinteger(v, 6, &rgba);

        int thisc = Get_Draw_This(56);
        int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);
        int intibuf = Ex_Draw_Init(thisc, 0, *(int*)0x1B45B94, npkbuf, X, Y);//偏移多少的数值 -1 == 0  所需偏移 -  1
        *(int*)0x1A70190 = intibuf;
        Ex_Draw_Num(intibuf, 0, 100, 100, Value, rgba, 0);


    }
    else if (Top == 9 || Top == 10) {
        const SQChar* File;
        Sq_getstring(v, 2, &File);
        int Idx;
        Sq_getinteger(v, 3, &Idx);
        int X;
        Sq_getinteger(v, 4, &X);
        int Y;
        Sq_getinteger(v, 5, &Y);
        int Model;
        Sq_getinteger(v, 6, &Model);
        int rgba;
        Sq_getinteger(v, 7, &rgba);

        int Xf;
        Sq_getfloat(v, 8, (FLOAT*)&Xf);
        int Yf;
        Sq_getfloat(v, 9, (FLOAT*)&Yf);

        int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);
        int imgbuf = Get_Img(npkbuf, 0, Idx);
        Ex_Draw_Img(*(int*)0x1B45B94, 0, X, Y, imgbuf, Xf, Yf, Model, rgba, 0, 0);
        return 0;
    }
    return 0;
}
//设置渲染模式
typedef int(_cdecl _SetDrawImgModel)(int a1, int a2);
static _SetDrawImgModel* SetDrawImgModel = (_SetDrawImgModel*)0x11A8A50;
//还原渲染模式
typedef int(_cdecl _ReleaseDrawImgModel)();
static _ReleaseDrawImgModel* ReleaseDrawImgModel = (_ReleaseDrawImgModel*)0x11A8B60;
static SQInteger sq_SetDrawImgModel(HSQUIRRELVM v)
{
    int M1;
    Sq_getinteger(v, 2, &M1);
    int M2;
    Sq_getinteger(v, 3, &M2);
    SetDrawImgModel(M1, M2);
    return 0;
}
static SQInteger sq_ReleaseDrawImgModel(HSQUIRRELVM v)
{
    ReleaseDrawImgModel();
    return 0;
}

//初始化数字绘制
typedef struct DamageFontInfo
{
    int Type[8][10];

} DamageFontInfo;
static DamageFontInfo MyFont = { 0 };
static SQInteger sq_IntiNumberDraw(HSQUIRRELVM v)
{
    const SQChar* File;
    Sq_getstring(v, 2, &File);
    int Idx;
    Sq_getinteger(v, 3, &Idx);
    int Type;
    Sq_getinteger(v, 4, &Type);

    int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);

    for (size_t i = 0; i < 10; i++)
    {
        int imgbuf = Get_Img(npkbuf, 0, Idx + i);
        MyFont.Type[Type][i] = imgbuf;
    }
    return 0;
}
//绘制数字
static SQInteger sq_DrawNumber(HSQUIRRELVM v)
{
    int X;
    Sq_getinteger(v, 2, &X);
    int Y;
    Sq_getinteger(v, 3, &Y);
    int rgba;
    Sq_getinteger(v, 4, &rgba);
    int Xf;
    Sq_getfloat(v, 5, (FLOAT*)&Xf);
    int Yf;
    Sq_getfloat(v, 6, (FLOAT*)&Yf);
    int Type;
    Sq_getinteger(v, 7, &Type);
    int Number;
    Sq_getinteger(v, 8, &Number);
    std::string Value = std::to_string(Number);

    float fValue;
    // 通过指针类型转换
    reinterpret_cast<unsigned int*>(&fValue)[0] = Xf;


    int mathoffset = 0;
    for (size_t i = 0; i < Value.size(); i++)
    {
        int Idx = Value[i] - 48;
        Ex_Draw_Img(*(int*)0x1B45B94, 0, X + mathoffset, Y, MyFont.Type[Type][Idx], Xf, Yf, 0, rgba, 0, 0);

        mathoffset += (((*(short*)(MyFont.Type[Type][Idx] + 0x1C)) * fValue) - 5);
    }
    return 0;
}
//绘制九宫格
static SQInteger sq_DrawWindow(HSQUIRRELVM v)
{
    int Top = Sq_gettop(v);
    int X;
    Sq_getinteger(v, 2, &X);
    int Y;
    Sq_getinteger(v, 3, &Y);
    int WindowWidth;
    Sq_getinteger(v, 4, &WindowWidth);
    int WindowHeight;
    Sq_getinteger(v, 5, &WindowHeight);

    //路径
    wchar_t* File = L"interface/windowcommon.img";
    int StartIdx = 0;

    int leftWidth = 11;//最左边的拼接的宽度
    int centerWidth = 12;//中间部分拼接的宽度

    int topHeight = 11;//最上面拼接的高度
    int centerHeight = 13;//中间部分拼接的高度

    if (Top == 11) {
        const SQChar* bFile;
        Sq_getstring(v, 6, &bFile);
        int Idx;
        Sq_getinteger(v, 7, &Idx);
        File = (wchar_t*)bFile;
        StartIdx = Idx;
        Sq_getinteger(v, 8, &leftWidth);
        Sq_getinteger(v, 9, &centerWidth);
        Sq_getinteger(v, 10, &topHeight);
        Sq_getinteger(v, 11, &centerHeight);
    }

    int widthCount = round(WindowWidth / centerWidth);
    int heightCount = round(WindowHeight / centerWidth);

    int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, File);
    int leftTopFrame = Get_Img(npkbuf, 0, 0 + StartIdx);
    int topCenterFrame = Get_Img(npkbuf, 0, 1 + StartIdx);
    int rightTopFrame = Get_Img(npkbuf, 0, 2 + StartIdx);
    int leftCenterFrame = Get_Img(npkbuf, 0, 3 + StartIdx);
    int centerFrame = Get_Img(npkbuf, 0, 4 + StartIdx);
    int rightCenterFrame = Get_Img(npkbuf, 0, 5 + StartIdx);
    int leftBottomFrame = Get_Img(npkbuf, 0, 6 + StartIdx);
    int centerBottomFrame = Get_Img(npkbuf, 0, 7 + StartIdx);
    int rightBottomFrame = Get_Img(npkbuf, 0, 8 + StartIdx);

    Draw_Img(*(int*)0x1B45B94, 0, X, Y, leftTopFrame);

    for (int i = 0; i < widthCount; i++) {
        Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * i, Y, topCenterFrame);
    }

    Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * widthCount, Y, rightTopFrame);


    //拼接中间和下面部分的
    //j为往下数的第几行
    for (int j = 0; j < heightCount; j++) {
        Draw_Img(*(int*)0x1B45B94, 0, X, Y + topHeight + centerHeight * j, leftCenterFrame);
        //绘制最左边的部分

        if (j == 0)
            Draw_Img(*(int*)0x1B45B94, 0, X, Y + topHeight + centerHeight * heightCount, leftBottomFrame);
        //这是绘制最下左边的拐角

    //绘制中间的部分
        for (int i = 0; i < widthCount; i++) {
            Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * i, Y + topHeight + centerHeight * j, centerFrame);
            if (j == 0)
                Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * i, Y + topHeight + centerHeight * heightCount, centerBottomFrame);
            //绘制中间最下面的部分
        }

        Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * widthCount, Y + topHeight + centerHeight * j, rightCenterFrame);
        //绘制最右边的部分

        if (j == 0)
            Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * widthCount, Y + topHeight + centerHeight * heightCount, rightBottomFrame);
        //绘制最右边最下面拐角处

    }


    if (heightCount == 0) {
        Draw_Img(*(int*)0x1B45B94, 0, X, Y + topHeight + centerHeight * heightCount, leftBottomFrame);
        for (int i = 0; i < widthCount; i++) {
            Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * i, Y + topHeight + centerHeight * heightCount, centerBottomFrame);
        }
        //绘制中间最下面的部分
        Draw_Img(*(int*)0x1B45B94, 0, X + leftWidth + centerWidth * widthCount, Y + topHeight + centerHeight * heightCount, rightBottomFrame);
        //绘制最右边最下面拐角处
    }


    return 0;
}
//绘制三图
static SQInteger sq_DrawButton(HSQUIRRELVM v)
{
    int Top = Sq_gettop(v);
    int X;
    Sq_getinteger(v, 2, &X);
    int Y;
    Sq_getinteger(v, 3, &Y);
    int WindowWidth;
    Sq_getinteger(v, 4, &WindowWidth);
    const SQChar* File;
    Sq_getstring(v, 5, &File);
    int StartIdx;
    Sq_getinteger(v, 6, &StartIdx);
    //填充宽度
    int FillWidth;
    Sq_getinteger(v, 7, &FillWidth);
    //首节宽度
    int FirstWidth;
    Sq_getinteger(v, 8, &FirstWidth);

    int widthCount = round(WindowWidth / 2);

    int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);
    int leftFrame = Get_Img(npkbuf, 0, 0 + StartIdx);
    int CenterFrame = Get_Img(npkbuf, 0, 1 + StartIdx);
    int rightFrame = Get_Img(npkbuf, 0, 2 + StartIdx);

    Draw_Img(*(int*)0x1B45B94, 0, X, Y, leftFrame);
    for (int i = 0; i < widthCount; i++) {
        Draw_Img(*(int*)0x1B45B94, 0, X + FirstWidth + FillWidth * i, Y, CenterFrame);
    }

    Draw_Img(*(int*)0x1B45B94, 0, X + FirstWidth + FillWidth * widthCount, Y, rightFrame);
    return 0;
}

static SQInteger sq_Draw3Image_Vertical(HSQUIRRELVM v)
{
    int Top = Sq_gettop(v);
    int X;
    Sq_getinteger(v, 2, &X);
    int Y;
    Sq_getinteger(v, 3, &Y);
    int WindowHeight;
    Sq_getinteger(v, 4, &WindowHeight);
    const SQChar* File;
    Sq_getstring(v, 5, &File);
    int StartIdx;
    Sq_getinteger(v, 6, &StartIdx);
    //填充高度
    int FillHeight;
    Sq_getinteger(v, 7, &FillHeight);
    //首节高度
    int FirstHeight;
    Sq_getinteger(v, 8, &FirstHeight);

    int heightCount = round(WindowHeight / 2);

    int npkbuf = Load_Npk(*(int*)0x1B4684C, 0, 0, (wchar_t*)File);
    int topFrame = Get_Img(npkbuf, 0, 0 + StartIdx);
    int centerFrame = Get_Img(npkbuf, 0, 1 + StartIdx);
    int bottomFrame = Get_Img(npkbuf, 0, 2 + StartIdx);

    Draw_Img(*(int*)0x1B45B94, 0, X, Y, topFrame);
    for (int i = 0; i < heightCount; i++) {
        Draw_Img(*(int*)0x1B45B94, 0, X, Y + FirstHeight + FillHeight * i, centerFrame);
    }

    Draw_Img(*(int*)0x1B45B94, 0, X, Y + FirstHeight + FillHeight * heightCount, bottomFrame);
    return 0;
}

//获取文字绘制长度
static std::map<std::string, int>LenheartCodeWidth;
static SQInteger Sq_getstringDrawLength(HSQUIRRELVM v) {

    const SQChar* Str;
    Sq_getstring(v, 2, &Str);

    if (Str == NULL)Str = L"";
    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    std::string RealStr = OutPutText;
    delete[]OutPutText;

    if (!LenheartCodeWidth.count("0")) {
        LenheartCodeWidth[" "] = 4;
        LenheartCodeWidth["0"] = 7;
        LenheartCodeWidth["1"] = 5;
        LenheartCodeWidth["2"] = 7;
        LenheartCodeWidth["3"] = 7;
        LenheartCodeWidth["4"] = 7;
        LenheartCodeWidth["5"] = 7;
        LenheartCodeWidth["6"] = 7;
        LenheartCodeWidth["7"] = 6;
        LenheartCodeWidth["8"] = 7;
        LenheartCodeWidth["9"] = 7;
        LenheartCodeWidth["z"] = 6;
        LenheartCodeWidth["y"] = 8;
        LenheartCodeWidth["x"] = 7;
        LenheartCodeWidth["w"] = 7;
        LenheartCodeWidth["v"] = 7;
        LenheartCodeWidth["u"] = 8;
        LenheartCodeWidth["t"] = 6;
        LenheartCodeWidth["s"] = 6;
        LenheartCodeWidth["r"] = 7;
        LenheartCodeWidth["q"] = 7;
        LenheartCodeWidth["p"] = 7;
        LenheartCodeWidth["o"] = 6;
        LenheartCodeWidth["n"] = 8;
        LenheartCodeWidth["m"] = 7;
        LenheartCodeWidth["l"] = 7;
        LenheartCodeWidth["k"] = 7;
        LenheartCodeWidth["j"] = 6;
        LenheartCodeWidth["i"] = 5;
        LenheartCodeWidth["h"] = 8;
        LenheartCodeWidth["g"] = 7;
        LenheartCodeWidth["f"] = 7;
        LenheartCodeWidth["e"] = 6;
        LenheartCodeWidth["d"] = 7;
        LenheartCodeWidth["c"] = 6;
        LenheartCodeWidth["b"] = 7;
        LenheartCodeWidth["a"] = 7;
        LenheartCodeWidth["A"] = 8;
        LenheartCodeWidth["B"] = 7;
        LenheartCodeWidth["C"] = 7;
        LenheartCodeWidth["D"] = 7;
        LenheartCodeWidth["E"] = 7;
        LenheartCodeWidth["F"] = 7;
        LenheartCodeWidth["G"] = 8;
        LenheartCodeWidth["H"] = 8;
        LenheartCodeWidth["I"] = 5;
        LenheartCodeWidth["J"] = 8;
        LenheartCodeWidth["K"] = 8;
        LenheartCodeWidth["L"] = 8;
        LenheartCodeWidth["M"] = 8;
        LenheartCodeWidth["N"] = 8;
        LenheartCodeWidth["O"] = 7;
        LenheartCodeWidth["P"] = 7;
        LenheartCodeWidth["Q"] = 7;
        LenheartCodeWidth["R"] = 8;
        LenheartCodeWidth["S"] = 7;
        LenheartCodeWidth["T"] = 7;
        LenheartCodeWidth["U"] = 8;
        LenheartCodeWidth["V"] = 8;
        LenheartCodeWidth["W"] = 7;
        LenheartCodeWidth["X"] = 7;
        LenheartCodeWidth["Y"] = 7;
        LenheartCodeWidth["Z"] = 7;
        LenheartCodeWidth[","] = 4;
        LenheartCodeWidth["，"] = 4;
        LenheartCodeWidth["."] = 3;
        LenheartCodeWidth["。"] = 6;
        LenheartCodeWidth["!"] = 3;
        LenheartCodeWidth["！"] = 4;
        LenheartCodeWidth["?"] = 7;
        LenheartCodeWidth["？"] = 8;
        LenheartCodeWidth[";"] = 3;
        LenheartCodeWidth["；"] = 4;
        LenheartCodeWidth["["] = 5;
        LenheartCodeWidth["]"] = 5;
        LenheartCodeWidth["{"] = 5;
        LenheartCodeWidth["}"] = 5;
        LenheartCodeWidth["("] = 5;
        LenheartCodeWidth[")"] = 5;
        LenheartCodeWidth["\\"] = 6;
        LenheartCodeWidth["“"] = 7;
        LenheartCodeWidth["”"] = 7;
        LenheartCodeWidth["\""] = 4;
        LenheartCodeWidth["’"] = 4;
        LenheartCodeWidth["+"] = 7;
        LenheartCodeWidth["-"] = 8;
        LenheartCodeWidth["*"] = 7;
        LenheartCodeWidth["/"] = 8;
        LenheartCodeWidth["="] = 8;
    }

    int L = 0;

    int StrTextLength = 0;
    for (size_t i = 0; i < RealStr.length();)
    {
        int cplen = 1;
        if (RealStr[i] < 0)cplen = 2;
        std::string c = RealStr.substr(i, cplen);
        if (LenheartCodeWidth.count(c)) {
            L += LenheartCodeWidth[c];
        }
        else {
            L += 13;
        }
        i += cplen;
        StrTextLength++;
    }
    L -= StrTextLength;

    Sq_pushinteger(v, L);
    return 1;
}
//获取文字换行返回数组
static SQInteger Sq_getstringDrawArray(HSQUIRRELVM v) {

    const SQChar* Str;
    Sq_getstring(v, 2, &Str);

    int Len;
    Sq_getinteger(v, 3, &Len);

    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    std::string RealStr = OutPutText;
    delete[]OutPutText;

    if (!LenheartCodeWidth.count("0")) {
        LenheartCodeWidth[" "] = 4;
        LenheartCodeWidth["0"] = 7;
        LenheartCodeWidth["1"] = 5;
        LenheartCodeWidth["2"] = 7;
        LenheartCodeWidth["3"] = 7;
        LenheartCodeWidth["4"] = 7;
        LenheartCodeWidth["5"] = 7;
        LenheartCodeWidth["6"] = 7;
        LenheartCodeWidth["7"] = 6;
        LenheartCodeWidth["8"] = 7;
        LenheartCodeWidth["9"] = 7;
        LenheartCodeWidth["z"] = 6;
        LenheartCodeWidth["y"] = 8;
        LenheartCodeWidth["x"] = 7;
        LenheartCodeWidth["w"] = 7;
        LenheartCodeWidth["v"] = 7;
        LenheartCodeWidth["u"] = 8;
        LenheartCodeWidth["t"] = 6;
        LenheartCodeWidth["s"] = 6;
        LenheartCodeWidth["r"] = 7;
        LenheartCodeWidth["q"] = 7;
        LenheartCodeWidth["p"] = 7;
        LenheartCodeWidth["o"] = 6;
        LenheartCodeWidth["n"] = 8;
        LenheartCodeWidth["m"] = 7;
        LenheartCodeWidth["l"] = 7;
        LenheartCodeWidth["k"] = 7;
        LenheartCodeWidth["j"] = 6;
        LenheartCodeWidth["i"] = 5;
        LenheartCodeWidth["h"] = 8;
        LenheartCodeWidth["g"] = 7;
        LenheartCodeWidth["f"] = 7;
        LenheartCodeWidth["e"] = 6;
        LenheartCodeWidth["d"] = 7;
        LenheartCodeWidth["c"] = 6;
        LenheartCodeWidth["b"] = 7;
        LenheartCodeWidth["a"] = 7;
        LenheartCodeWidth["A"] = 8;
        LenheartCodeWidth["B"] = 7;
        LenheartCodeWidth["C"] = 7;
        LenheartCodeWidth["D"] = 7;
        LenheartCodeWidth["E"] = 7;
        LenheartCodeWidth["F"] = 7;
        LenheartCodeWidth["G"] = 8;
        LenheartCodeWidth["H"] = 8;
        LenheartCodeWidth["I"] = 5;
        LenheartCodeWidth["J"] = 8;
        LenheartCodeWidth["K"] = 8;
        LenheartCodeWidth["L"] = 8;
        LenheartCodeWidth["M"] = 8;
        LenheartCodeWidth["N"] = 8;
        LenheartCodeWidth["O"] = 7;
        LenheartCodeWidth["P"] = 7;
        LenheartCodeWidth["Q"] = 7;
        LenheartCodeWidth["R"] = 8;
        LenheartCodeWidth["S"] = 7;
        LenheartCodeWidth["T"] = 7;
        LenheartCodeWidth["U"] = 8;
        LenheartCodeWidth["V"] = 8;
        LenheartCodeWidth["W"] = 7;
        LenheartCodeWidth["X"] = 7;
        LenheartCodeWidth["Y"] = 7;
        LenheartCodeWidth["Z"] = 7;
        LenheartCodeWidth[","] = 4;
        LenheartCodeWidth["，"] = 4;
        LenheartCodeWidth["."] = 3;
        LenheartCodeWidth["。"] = 6;
        LenheartCodeWidth["!"] = 3;
        LenheartCodeWidth["！"] = 4;
        LenheartCodeWidth["?"] = 7;
        LenheartCodeWidth["？"] = 8;
        LenheartCodeWidth[";"] = 3;
        LenheartCodeWidth["；"] = 4;
        LenheartCodeWidth["["] = 5;
        LenheartCodeWidth["]"] = 5;
        LenheartCodeWidth["{"] = 5;
        LenheartCodeWidth["}"] = 5;
        LenheartCodeWidth["("] = 5;
        LenheartCodeWidth[")"] = 5;
        LenheartCodeWidth["\\"] = 6;
        LenheartCodeWidth["“"] = 7;
        LenheartCodeWidth["”"] = 7;
        LenheartCodeWidth["\""] = 4;
        LenheartCodeWidth["’"] = 4;
        LenheartCodeWidth["+"] = 7;
        LenheartCodeWidth["-"] = 8;
        LenheartCodeWidth["*"] = 7;
        LenheartCodeWidth["/"] = 8;
        LenheartCodeWidth["="] = 8;
    }

    std::vector<std::string>StrBuf;

    int StrTextLength = 0;
    for (size_t i = 0; i < RealStr.length();)
    {
        int cplen = 1;
        if (RealStr[i] < 0)cplen = 2;
        std::string c = RealStr.substr(i, cplen);

        StrBuf.push_back(c);
        i += cplen;
    }

    std::vector<std::string>PushStrBuf;
    std::string Ostr = "";
    for (unsigned int i = 0; i < StrBuf.size(); ++i)
    {
        int AddLen = 0;
        if (LenheartCodeWidth.count(StrBuf[i])) {
            AddLen = LenheartCodeWidth[StrBuf[i]];
        }
        else {
            AddLen = 13;
        }

        //超过了
        if (AddLen + StrTextLength > Len) {
            PushStrBuf.push_back(Ostr);
            StrTextLength = AddLen;
            Ostr = StrBuf[i];
        }
        else {
            Ostr += StrBuf[i];
            StrTextLength += AddLen;
            //最后一段
            if (i == StrBuf.size() - 1) {
                PushStrBuf.push_back(Ostr);
            }
        }

    }

    sq_newarray((HSQUIRRELVM)v, 0);

    for (unsigned int i = 0; i < PushStrBuf.size(); ++i)
    {
        std::string Buf = PushStrBuf[i];
        char* ss = DNFTOOL::GBKTOUTF8(Buf);
        std::wstring aa = DNFTOOL::charTowchar_t(ss);
        Sq_pushstring(v, aa.c_str(), -1);
        sq_arrayappend((HSQUIRRELVM)v, -2);
    }
    return 1;
}
//反序列化Json
static SQInteger DecondeJson(HSQUIRRELVM v) {
    const SQChar* OutPutBuffer;
    Sq_getstring(v, 2, &OutPutBuffer);
    char* OutPutText = DNFTOOL::wchar_tTochar((wchar_t*)OutPutBuffer);
    std::string str = OutPutText;
    delete[]OutPutText;

    size_t pos = 0;
    bool Ars = false;
    while ((pos = str.find("\"", pos)) != std::string::npos) {
        // 判断双引号是否在Key的位置
        if (pos > 0) {
            if (str[pos - 1] == '[') {
                Ars = true;
            }
            if ((str[pos - 1] == '{' || str[pos + 1] == ':' || str[pos - 1] == ',') && !Ars) {
                // 删除双引号
                str.erase(pos, 1);
            }
            else {
                pos++;
            }
            if (str[pos] == ']') {
                Ars = false;
            }
        }
        else {
            pos++;
        }
    }

    str = DNFTOOL::ReplaceAll(str, ":", "=");

    std::wstring ss = DNFTOOL::charTowchar_t((char*)str.c_str());
    Sq_pushstring(v, ss.c_str(), -1);
    return 1;
}
//序列化Json
std::string EncodeARRAY(HSQUIRRELVM v, std::string Jso);
std::string EncodeTABLE(HSQUIRRELVM v, std::string Jso);
std::string EncodeARRAY(HSQUIRRELVM v, std::string Jso) {
    Jso += "[";

    sq_pushnull((HSQUIRRELVM)v);  // null iterator
    while (SQ_SUCCEEDED(sq_next((HSQUIRRELVM)v, -2)))
    {
        SQObjectType Type = sq_gettype((HSQUIRRELVM)v, -1);
        switch (Type)
        {
        case OT_INTEGER: {
            static SQInteger value;
            Sq_getinteger(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
                       break;
        case OT_FLOAT:
        {
            SQFloat value;
            Sq_getfloat(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
        break;
        case OT_BOOL:
        {
            SQBool value;
            Sq_getbool(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
        break;
        case OT_STRING:
        {
            const SQChar* value;
            Sq_getstring((HSQUIRRELVM)v, -1, &value);

            char* vOutPutText = DNFTOOL::SquirrelU2W(value);
            std::string vstr = vOutPutText;
            delete[]vOutPutText;
            Jso += "\"";
            Jso += vstr;
            Jso += "\"";
            Jso += ",";
        }
        break;
        case OT_TABLE:
        {
            static SQInteger Top = Sq_gettop(v);
            SQObject obj;
            sq_getstackobj(v, -1, &obj);
            sq_pushobject(v, obj);
            Jso = EncodeTABLE(v, Jso);
            sq_settop(v, Top);
            Jso += ",";
        }
        break;
        case OT_ARRAY:
        {
            static SQInteger Top = Sq_gettop(v);
            SQObject obj;
            sq_getstackobj(v, -1, &obj);
            sq_pushobject(v, obj);
            Jso = EncodeARRAY(v, Jso);
            sq_settop(v, Top);
            Jso += ",";
        }
        break;
        default:
            break;
        }

        //这里-1是值，-2是键
        sq_pop((HSQUIRRELVM)v, 2); //在下一次迭代之前弹出键和值
    }
    sq_pop((HSQUIRRELVM)v, 1); //在下一次迭代之前弹出键和值
    Jso = Jso.substr(0, Jso.length() - 1);
    Jso += "]";
    return Jso;
}
std::string EncodeTABLE(HSQUIRRELVM v, std::string Jso) {

    Jso += "{";

    sq_pushnull((HSQUIRRELVM)v);  // null iterator
    while (SQ_SUCCEEDED(sq_next((HSQUIRRELVM)v, -2)))
    {
        const SQChar* Key;
        Sq_getstring((HSQUIRRELVM)v, -2, &Key);


        char* OutPutText = DNFTOOL::SquirrelU2W(Key);
        std::string str = OutPutText;
        delete[]OutPutText;


        Jso += "\"";
        Jso += str;
        Jso += "\"";
        Jso += ":";

        SQObjectType Type = sq_gettype((HSQUIRRELVM)v, -1);
        switch (Type)
        {
        case OT_INTEGER: {
            static SQInteger value;
            Sq_getinteger(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
                       break;
        case OT_FLOAT:
        {
            SQFloat value;
            Sq_getfloat(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
        break;
        case OT_BOOL:
        {
            SQBool value;
            Sq_getbool(v, -1, &value);
            Jso += std::to_string(value);
            Jso += ",";
        }
        break;
        case OT_STRING:
        {
            const SQChar* value;
            Sq_getstring((HSQUIRRELVM)v, -1, &value);

            char* vOutPutText = DNFTOOL::SquirrelU2W(value);
            std::string vstr = vOutPutText;
            delete[]vOutPutText;
            Jso += "\"";
            Jso += vstr;
            Jso += "\"";
            Jso += ",";
        }
        break;
        case OT_TABLE:
        {
            static SQInteger Top = Sq_gettop(v);
            SQObject obj;
            sq_getstackobj(v, -1, &obj);
            sq_pushobject(v, obj);
            Jso = EncodeTABLE(v, Jso);
            sq_settop(v, Top);
            Jso += ",";
        }
        break;
        case OT_ARRAY:
        {
            static SQInteger Top = Sq_gettop(v);
            SQObject obj;
            sq_getstackobj(v, -1, &obj);
            sq_pushobject(v, obj);
            Jso = EncodeARRAY(v, Jso);
            sq_settop(v, Top);
            Jso += ",";
        }
        break;
        default:
            break;
        }

        //这里-1是值，-2是键
        sq_pop((HSQUIRRELVM)v, 2); //在下一次迭代之前弹出键和值
    }
    sq_pop((HSQUIRRELVM)v, 1); //在下一次迭代之前弹出键和值
    Jso = Jso.substr(0, Jso.length() - 1);
    Jso += "}";
    return Jso;
}
static SQInteger EncondeJson(HSQUIRRELVM v) {

    std::string Jso = "";
    std::string RealJso = EncodeTABLE((HSQUIRRELVM)v, Jso);
    char* sbuf = DNFTOOL::GBKTOUTF8(RealJso);
    std::wstring ss = DNFTOOL::charTowchar_t(sbuf);
    Sq_pushstring(v, ss.c_str(), -1);
    return 1;
}

//按键是否按下
static SQInteger sq_IsKeyDown(HSQUIRRELVM v) {

    int KeyCode;
    Sq_getinteger(v, 2, &KeyCode);

    if (KEY_DOWN(KeyCode)) {
        Sq_pushbool(v, true);
    }
    else {
        Sq_pushbool(v, false);
    }
    return 1;
}
//打开特殊窗口
//窗口CALL
typedef void(*NNoticeTCall)(DWORD thisc, DWORD Seat, DWORD a1, wchar_t* a2, DWORD a3, DWORD a4, DWORD a5);
static NNoticeTCall _ANoticeTcall = (NNoticeTCall)0xE6E070;
typedef void(_fastcall _Open_ExWindow)(int thisc, void*, int a2, char a3, char a4);
static _Open_ExWindow* Open_ExWindow = (_Open_ExWindow*)0xE718A0;
static _Open_ExWindow* Open_ExWindow2 = (_Open_ExWindow*)0xE6E070;
static SQInteger sq_Open_ExWindow(HSQUIRRELVM v) {
    int a1, a2, a3, a4;
    Sq_getinteger(v, 2, &a1);
    Sq_getinteger(v, 3, &a2);
    Sq_getinteger(v, 4, &a3);
    Sq_getinteger(v, 5, &a4);
    Open_ExWindow(a1, 0, a2, a3, a4);
    return 0;
}
static SQInteger sq_Open_ExWindow2(HSQUIRRELVM v) {
    int a1, a2, a3, a4;
    Sq_getinteger(v, 2, &a1);
    Sq_getinteger(v, 3, &a2);
    Sq_getinteger(v, 4, &a3);
    Sq_getinteger(v, 5, &a4);
    Open_ExWindow2(a1, 0, a2, a3, a4);
    return 0;
}
typedef int(_cdecl _GetWindowByIdx)(int Idx);
static _GetWindowByIdx* GetWindowByIdx = (_GetWindowByIdx*)0x5A2A00;
static SQInteger sq_GetWindowById(HSQUIRRELVM v) {
    int Idx;
    Sq_getinteger(v, 2, &Idx);
    int WindowAddress = GetWindowByIdx(Idx);
    Sq_pushinteger(v, WindowAddress);

    return 1;
}
//选择大地图区域
static SQInteger sq_Select_MiniMap_Index(HSQUIRRELVM v) {
    int ReIndex;
    Sq_getinteger(v, 2, &ReIndex);
    static int dnf_103E030 = 0x103E030;
    static int dnf_287FA88 = 0x287FA88;
    static int dnf_103DCD0 = 0x103DCD0;
    static int dnf_103B240 = 0x103B240;
    static int dnf_2878D95 = 0x2878D95;
    static int dnf_1194FC0 = 0x1194FC0;
    static int dnf_410230 = 0x410230;
    static int dnf_102F4D0 = 0x102F4D0;
    _asm
    {
        mov ecx, dword ptr ds : [0x1A5FB20]
        mov esi, dword ptr ds : [ecx + 0x42DC]
        push ReIndex
        call dnf_103E030
        mov ecx, eax
        call dnf_287FA88
        push ReIndex
        call dnf_103E030
        mov ecx, eax
        call dnf_103DCD0
        mov ecx, eax
        mov dword ptr ds : [esi + 0x24] , eax
        call dnf_103B240
        mov ecx, dword ptr ds : [esi + 0x24]
        call dnf_2878D95
        push 0x1556138
        call dnf_1194FC0
        mov ecx, eax
        add esp, 4
        lea edi, dword ptr ds : [ecx + 2]
        dnf_1031651 :
        mov dx, word ptr ds : [ecx]
        add ecx, 2
        test dx, dx
        jne dnf_1031651
        sub ecx, edi
        sar ecx, 1
        push ecx
        push eax
        lea ecx, dword ptr ds : [esi + 0x144]
        call dnf_410230
    }
    return 0;
}
//绘制技能
typedef  void(_fastcall _DrawSkill)(int a1, int seat, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11);
static _DrawSkill* DrawSkill = (_DrawSkill*)0x909d70;
static SQInteger sq_DrawSkill(HSQUIRRELVM v)
{
    int a1, x, y, a4, a5, a6, a7, a8, a9, a10;
    //a1技能地址
    Sq_getinteger(v, 2, &a1);
    Sq_getinteger(v, 3, &x);
    Sq_getinteger(v, 4, &y);
    Sq_getinteger(v, 5, &a4);
    Sq_getinteger(v, 6, &a5);
    Sq_getinteger(v, 7, &a6);
    Sq_getinteger(v, 8, &a7);
    Sq_getinteger(v, 9, &a8);
    Sq_getinteger(v, 10, &a9);
    Sq_getinteger(v, 11, &a10);
    DrawSkill(a1, 0, *(int*)0x1AB7CDC, x, y, a4, a5, a6, a7, a8, a9, a10);
    return 1;
}
//使用技能
static SQInteger sq_UseSkill(HSQUIRRELVM v)
{
    int Key_Value;
    Sq_getinteger(v, 2, &Key_Value);
    BYTE* thisc = (BYTE*)(*(DWORD*)(0x1B470E0));
    thisc[269 + Key_Value] = 0x80;
    return 0;
}
//获取当前选择交互角色姓名
static SQInteger sq_GetPlayerEachName(HSQUIRRELVM v)
{
    int objNameAddress = *(int*)(0x1ade0e0);
    char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)(objNameAddress + 0x20));
    std::wstring name = DNFTOOL::charTowchar_t(str);
    free(str);
    Sq_pushstring(v, name.c_str(), -1);
    return 1;
}
//获取技能地址
typedef int __fastcall _Funcsub_GetSkillAddress(int a1, int a2, int a3);
static _Funcsub_GetSkillAddress* Funcsub_GetSkillAddress = (_Funcsub_GetSkillAddress*)0x8406C0;
static SQInteger sq_GetSkillAddress(HSQUIRRELVM v)
{
    int SkillId;
    Sq_getinteger(v, 2, &SkillId);
    DWORD ADDRESS = Funcsub_GetSkillAddress(*(int*)0x1AB7CDC, 0, SkillId);
    Sq_pushinteger(v, ADDRESS);
    return 1;
}
//顺图
static SQInteger sq_MoveMap(HSQUIRRELVM v)
{
    int dct;
    Sq_getinteger(v, 2, &dct);
    DWORD Address1 = 0x1A5FB18;
    DWORD Address2 = 0x7CE9E0;
    _asm
    {
        mov ecx, [Address1]
        mov ecx, [ecx]
        mov ecx, [ecx + 0x20a050]
        mov ecx, [ecx + 0x4c]
        push  0x1
        push  0x1
        push  0x0
        push  0x0
        push  0x0
        push  0x0
        push  0x0
        push  dct
        call Address2
    }
    return 0;
}

//通过Item编号获取图标Img
typedef int(_cdecl _sub7AAB60)(int a1);
static _sub7AAB60* getitemimg = (_sub7AAB60*)0x7aab60;
static SQInteger sq_GetImg(HSQUIRRELVM v)
{
    int a1;
    Sq_getinteger(v, 2, &a1);
    int img = getitemimg(a1);
    Sq_pushinteger(v, img);
    return 1;
}
//绘制Item
typedef int(_cdecl _sub7AA800)(int a1, int a2, int a3, int a4, int a5, int a6, char a7);
static _sub7AA800* drawimg = (_sub7AA800*)0x7aa800;
static SQInteger sq_DrawItem(HSQUIRRELVM v)
{
    int a1, a2, a3, a4, a5, a6, a7;
    Sq_getinteger(v, 2, &a1);
    Sq_getinteger(v, 3, &a2);
    Sq_getinteger(v, 4, &a3);
    Sq_getinteger(v, 5, &a4);
    Sq_getinteger(v, 6, &a5);
    Sq_getinteger(v, 7, &a6);
    Sq_getinteger(v, 8, &a7);
    int img = getitemimg(a3);
    drawimg(a1, a2, img, a4, a5, a6, a7);
    return 0;
}





//获取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;
//获取对象地址
static SQInteger GetObjectAddress(HSQUIRRELVM v)
{
    int objAddress = GetSqrObject(v, 2);
    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)
{
    int objAddress = GetSqrObject(v, 2);
    int objNameAddress = *(int*)(objAddress + 0x258);
    char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)objNameAddress);
    std::wstring name = DNFTOOL::charTowchar_t(str);
    free(str);
    Sq_pushstring(v, name.c_str(), -1);
    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)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int objNameAddress = *(int*)(objAddress + 0x258);
    char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)objNameAddress);
    std::wstring name = DNFTOOL::charTowchar_t(str);
    free(str);
    Sq_pushstring(v, name.c_str(), -1);
    return 1;
}

//获取对象属性
static SQInteger GetObjectInfo(HSQUIRRELVM v)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int ParameterNum = Sq_gettop(v);
    if (ParameterNum == 4)
    {
        int InfoAddress;
        Sq_getinteger(v, 3, &InfoAddress);
        int Value = (objAddress + InfoAddress);

        SQBool Type;
        Sq_getbool(v, 4, &Type);
        if (Type == TRUE)
        {
            Sq_pushinteger(v, *(int*)Value);
        }
        else if (Type == FALSE)
        {
            Sq_pushfloat(v, *(FLOAT*)Value);
        }
    }
    else if (ParameterNum == 5)
    {
        int EquAddress;
        Sq_getinteger(v, 3, &EquAddress);
        int InfoAddress;
        Sq_getinteger(v, 4, &InfoAddress);
        int Value = (objAddress + EquAddress);
        Value = *(int*)Value;

        Value = Value + InfoAddress;
        SQBool Type;
        Sq_getbool(v, 5, &Type);
        if (Type == TRUE)
        {
            Sq_pushinteger(v, *(int*)Value);
        }
        else if (Type == FALSE)
        {
            Sq_pushfloat(v, *(FLOAT*)Value);
        }
    }
    else
    {
        sq_throwerror(v, L"Incorrect function argument");
        return 0;
    }

    return 1;
}
//获取骑乘对象地址
static SQInteger GetRidingObjectAddress(HSQUIRRELVM v)
{
    int objAddress = GetSqrObject(v, 2);
    Sq_pushinteger(v, *(int*)(objAddress + 0x54d0));
    return 1;
}
//解密获取对象属性
static SQInteger GetObjectDeInfo(HSQUIRRELVM v)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int ParameterNum = Sq_gettop(v);
    if (ParameterNum == 4)
    {
        int InfoAddress;
        Sq_getinteger(v, 3, &InfoAddress);
        int Value = (objAddress + InfoAddress);

        SQBool Type;
        Sq_getbool(v, 4, &Type);
        if (Type == TRUE)
        {
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(Value));
        }
        else if (Type == FALSE)
        {
            Sq_pushfloat(v, (FLOAT)DNFTOOL::DNFDeCode(Value));
        }
    }
    else if (ParameterNum == 5)
    {
        int EquAddress;
        Sq_getinteger(v, 3, &EquAddress);
        int InfoAddress;
        Sq_getinteger(v, 4, &InfoAddress);
        int Value = (objAddress + EquAddress);
        Value = *(int*)Value;

        Value = Value + InfoAddress;
        SQBool Type;
        Sq_getbool(v, 5, &Type);
        if (Type == TRUE)
        {
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(Value));
        }
        else if (Type == FALSE)
        {
            Sq_pushfloat(v, (FLOAT)DNFTOOL::DNFDeCode(Value));
        }
    }
    else
    {
        sq_throwerror(v, L"Incorrect function argument");
        return 0;
    }

    return 1;
}
//设置对象属性
static SQInteger SetObjectInfo(HSQUIRRELVM v)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int ParameterNum = Sq_gettop(v);
    if (ParameterNum == 5)
    {
        int InfoAddress;
        Sq_getinteger(v, 3, &InfoAddress);
        int Value = (objAddress + InfoAddress);

        SQBool Type;
        Sq_getbool(v, 4, &Type);
        if (Type == TRUE)
        {
            int W_Value;
            Sq_getinteger(v, 5, &W_Value);
            *(int*)Value = W_Value;
        }
        else if (Type == FALSE)
        {
            FLOAT W_Value;
            Sq_getfloat(v, 5, &W_Value);
            *(FLOAT*)Value = W_Value;
        }
    }
    else if (ParameterNum == 6)
    {
        int EquAddress;
        Sq_getinteger(v, 3, &EquAddress);
        int InfoAddress;
        Sq_getinteger(v, 4, &InfoAddress);
        int Value = (objAddress + EquAddress);
        Value = *(int*)Value;

        Value = Value + InfoAddress;
        SQBool Type;
        Sq_getbool(v, 5, &Type);
        if (Type == TRUE)
        {
            int W_Value;
            Sq_getinteger(v, 6, &W_Value);
            *(int*)Value = W_Value;
        }
        else if (Type == FALSE)
        {
            FLOAT W_Value;
            Sq_getfloat(v, 6, &W_Value);
            *(FLOAT*)Value = W_Value;
        }
    }
    else
    {
        sq_throwerror(v, L"Incorrect function argument");
        return 0;
    }
    return 1;
}
//加密设置对象属性
static SQInteger SetObjectDeInfo(HSQUIRRELVM v)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int ParameterNum = Sq_gettop(v);
    if (ParameterNum == 5)
    {
        int InfoAddress;
        Sq_getinteger(v, 3, &InfoAddress);
        int Value = (objAddress + InfoAddress);

        SQBool Type;
        Sq_getbool(v, 4, &Type);
        if (Type == TRUE)
        {
            int W_Value;
            Sq_getinteger(v, 5, &W_Value);
            DNFTOOL::DNFEnCode(Value, W_Value);
        }
        else if (Type == FALSE)
        {
            FLOAT W_Value;
            Sq_getfloat(v, 5, &W_Value);
            DNFTOOL::DNFEnCode(Value, (int)W_Value);
        }
    }
    else if (ParameterNum == 6)
    {
        int EquAddress;
        Sq_getinteger(v, 3, &EquAddress);
        int InfoAddress;
        Sq_getinteger(v, 4, &InfoAddress);
        int Value = (objAddress + EquAddress);
        Value = *(int*)Value;

        Value = Value + InfoAddress;
        SQBool Type;
        Sq_getbool(v, 5, &Type);
        if (Type == TRUE)
        {
            int W_Value;
            Sq_getinteger(v, 6, &W_Value);
            DNFTOOL::DNFEnCode(Value, W_Value);
        }
        else if (Type == FALSE)
        {
            FLOAT W_Value;
            Sq_getfloat(v, 6, &W_Value);
            DNFTOOL::DNFEnCode(Value, (int)W_Value);
        }
    }
    else
    {
        sq_throwerror(v, L"Incorrect function argument");
        return 0;
    }
    return 1;
}
//获取对象等级
static SQInteger GetObjectLevel(HSQUIRRELVM v)
{
    int objAddress = GetSqrObject(v, 2);
    int Level = DNFTOOL::DNFDeCode(objAddress + 0x1A4C);
    Sq_pushinteger(v, Level);
    return 1;
}

//获取对象是否是玩家函数地址
typedef DWORD IsCharacter(int Address);
static IsCharacter* _IsCharacter = (IsCharacter*)0x5A36F0;
//获取对象是否是玩家
static SQInteger GetObjectIsCharacter(HSQUIRRELVM v)
{
    int objAddress;
    Sq_getinteger(v, 2, &objAddress);
    int Ret = _IsCharacter(objAddress);
    Sq_pushinteger(v, Ret);
    return 1;
}

typedef int(__fastcall* _GetObjectAttribute)(DWORD thisc, int Seat, int Type);
typedef int(__fastcall* _FloatDecode)(int Address);
static _GetObjectAttribute GetObjectAttributeFunc = (_GetObjectAttribute)0xD07390;
static _FloatDecode FloatDecode = (_FloatDecode)0x5B0090;
//获取对象属性
static SQInteger GetObjectAttribute(HSQUIRRELVM v)
{
    int objAddress, Type;
    Sq_getinteger(v, 2, &objAddress);
    Sq_getinteger(v, 3, &Type);
    int Ret = GetObjectAttributeFunc(objAddress, 0, Type);
    Ret = FloatDecode(Ret);
    Sq_pushinteger(v, Ret);
    return 1;
}

//读人物 或 装备属性
static SQInteger GetCharacterAttribute(HSQUIRRELVM v)
{
    int n1, n2;
    int num = Sq_gettop(v);

    int CharAddr = *(int*)(0x1AB7CDC);
    if (num == 3)
    {
        Sq_getinteger(v, 2, &n1);
        Sq_getinteger(v, 3, &n2);
        int TValue = *(int*)(CharAddr + DNFTOOL::GetEquAddr(n2));
        int SValue = (TValue + n1);
        if (SValue < 0x400000)
            Sq_pushinteger(v, 0);
        else if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4 && n1 != 0x854)
            Sq_pushinteger(v, (DNFTOOL::DNFDeCode(SValue)));
        else
            Sq_pushinteger(v, (*(int*)(SValue)));
    }
    else if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
        int Value = (CharAddr + n1);

        Sq_pushinteger(v, (DNFTOOL::DNFDeCode(Value)));
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//写人物 或 装备属性
static SQInteger SetCharacterAttribute(HSQUIRRELVM v)
{
    int n1, n2, n3;
    int num = Sq_gettop(v);
    int CharAddr = *(int*)(0x1AB7CDC);
    if (num == 4)
    {
        Sq_getinteger(v, 2, &n1);
        Sq_getinteger(v, 3, &n2);
        Sq_getinteger(v, 4, &n3);

        int TValue = *(int*)(CharAddr + DNFTOOL::GetEquAddr(n2));
        int SValue = (TValue + n1);
        if (SValue < 0x400000)
            Sq_pushbool(v, false);
        else if (n1 != 0x8 && n1 != 0x1C && n1 != 0xF4)
            DNFTOOL::DNFEnCode(SValue, n3);
        else
            *(int*)SValue = n3;
        Sq_pushbool(v, true);
    }
    else if (num == 3)
    {
        Sq_getinteger(v, 2, &n1);
        Sq_getinteger(v, 3, &n2);

        int Value = (CharAddr + n1);
        DNFTOOL::DNFEnCode(Value, n2);
        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
    }
    return 1;
}
//获取城镇编号
static SQInteger GetTownIndex(HSQUIRRELVM v)
{
    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)));
    return 1;
}
//获取城镇X坐标
static SQInteger GetTownXpos(HSQUIRRELVM v)
{
    Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2BC+", 0));
    return 1;
}
//获取城镇Y坐标
static SQInteger GetTownYpos(HSQUIRRELVM v)
{
    Sq_pushinteger(v, DNFTOOL::GetHook(0x1AB7CE0, "0x2C0+", 0));
    return 1;
}
//获取疲劳值
static SQInteger GetFatigue(HSQUIRRELVM v)
{
    int Type;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &Type);

        switch (Type)
        {
        case 0:
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(0x1AB7E1C));
            break;
        case 1:
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(0x1AB7E10));
            break;
        default:
            Sq_pushbool(v, false);
            break;
        }
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//获取经验值
static SQInteger GetExp(HSQUIRRELVM v)
{
    int Type;

    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &Type);

        switch (Type)
        {
        case 0:
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(DNFTOOL::GetHook(0x1AB7CDC, "0x3C4C+", 1)));
            break;
        case 1:
            Sq_pushinteger(v, DNFTOOL::DNFDeCode(DNFTOOL::GetHook(0x1AB7CDC, "0x3C40+", 1)));
            break;
        default:
            Sq_pushbool(v, false);
            break;
        }
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//获取sp点
typedef  int(_fastcall _9166B0)(int a1, int seat);
static _9166B0* GetSp = (_9166B0*)0x9166B0;
static SQInteger sq_GetSp(HSQUIRRELVM v)
{
    int num = Sq_gettop(v);
    if (num == 1)
    {
        Sq_pushinteger(v, GetSp(NULL, 0));
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//获取冒险团等级
typedef  int(_61A5F0)();
static _61A5F0* GetPass = (_61A5F0*)0x61A5F0;
static SQInteger sq_GetPassLevel(HSQUIRRELVM v)
{
    int Passobj = GetPass();
    int l = *(int*)Passobj;
    Sq_pushinteger(v, l);
    return 1;
}
//刷新活动图标
typedef  int(_fastcall _4DE680)(int a1, int seat);
static _4DE680* RefreshEventIcon = (_4DE680*)0x4DE680;
static SQInteger sq_RefreshEventIcon(HSQUIRRELVM v)
{
    RefreshEventIcon(0x01A39B78, 0);
    return 0;
}
//发包类型
typedef DWORD SendClass;
static  SendClass* _SendClass = (SendClass*)0x1AEB6E4;
static SQInteger SendPackType(HSQUIRRELVM v)
{
    int n1;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
        _SendpacksType(*_SendClass, 0, n1);

        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//发包Byte
static SQInteger SendPackByte(HSQUIRRELVM v)
{
    int n1;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
        _SendPacksByte(*_SendClass, 0, n1);
        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//发包Word
static SQInteger SendPackWord(HSQUIRRELVM v)
{
    int n1;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
        _SendPacksWord(*_SendClass, 0, n1);
        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//发包DWord
static SQInteger SendPackDWord(HSQUIRRELVM v)
{
    int n1;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
        _SendPacksDWord(*_SendClass, 0, n1);
        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//发包wchar_t*  (转了char*)
static SQInteger SendPackWChar(HSQUIRRELVM v)
{
    const SQChar* n1;
    int num = Sq_gettop(v);
    if (num == 2)
    {
        Sq_getstring(v, 2, &n1);
        //wchar_t* 转 char*
        char* fname = DNFTOOL::wchar_tTochar((wchar_t*)n1);
        _SendPacksChar(*_SendClass, 0, fname, strlen(fname));
        delete[]fname;
        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//发包
static SQInteger SendPack(HSQUIRRELVM v)
{
    int num = Sq_gettop(v);
    if (num == 1)
    {
        _SendPacks();
        Sq_pushbool(v, true);
    }
    else
    {
        sq_throwerror(v, L"parameter error");
    }
    return 1;
}
//去副本
static SQInteger GoDungeon(HSQUIRRELVM v)
{
    int n1 = 0;
    int n2 = 0;
    int n3 = 0;
    int n4 = 0;

    int num = Sq_gettop(v);

    if (num == 2)
    {
        Sq_getinteger(v, 2, &n1);
    }
    else if (num == 5)
    {
        Sq_getinteger(v, 2, &n1);
        Sq_getinteger(v, 3, &n2);
        Sq_getinteger(v, 4, &n3);
        Sq_getinteger(v, 5, &n4);
    }
    else
    {
        Sq_pushbool(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();

    Sq_pushbool(v, true);
    return 1;
}
//回城
static SQInteger GoTown(HSQUIRRELVM v)
{
    int num = Sq_gettop(v);
    if (num == 1)
    {
        _SendpacksType(*_SendClass, 0, 0x2D);
        _SendPacks();
        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
    }
    return 1;
}
//移动城镇
static SQInteger MoveTown(HSQUIRRELVM v)
{
    int TownIndex;
    int ReIndex;
    int XPos;
    int YPos;
    int num = Sq_gettop(v);
    if (num == 5)
    {
        Sq_getinteger(v, 2, &TownIndex);
        Sq_getinteger(v, 3, &ReIndex);
        Sq_getinteger(v, 4, &XPos);
        Sq_getinteger(v, 5, &YPos);

        _SendpacksType(*_SendClass, 0, 38);
        _SendPacksByte(*_SendClass, 0, TownIndex);
        _SendPacksByte(*_SendClass, 0, ReIndex);
        _SendPacksWord(*_SendClass, 0, XPos);
        _SendPacksWord(*_SendClass, 0, YPos);
        _SendPacksByte(*_SendClass, 0, 5);
        _SendPacksWord(*_SendClass, 0, 0);
        _SendPacksWord(*_SendClass, 0, 0);
        _SendPacks();

        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
    }
    return 1;
}
//绘制字符
typedef void(__fastcall* DrawCode)(DWORD thisc, int Seat, int a3, int a4, int a5, int a6);
typedef DWORD(_fastcall _FontInit)(DWORD thisc, DWORD Seat);
static _FontInit* sub_11BE9A0 = (_FontInit*)0x11BE9A0;
static _FontInit* sub_11BE980 = (_FontInit*)0x11BE980;
typedef DWORD(_fastcall _BFontInit)(DWORD thisc, DWORD Seat);
static _BFontInit* sub_1206570 = (_BFontInit*)0x1206570;
typedef DWORD(_fastcall _FontC)(DWORD thisc, DWORD Seat, DWORD Font);
static _FontC* sub_1206550 = (_FontC*)0x1206550;
static DrawCode NewDrawCodeF = (DrawCode)0x01206BD0;

static SQInteger sq_DrawCode(HSQUIRRELVM v)
{
    const SQChar* Str;
    int XPos;
    int YPos;
    int Color;
    int Type;
    int Stroke;

    int ParameterNum = Sq_gettop(v);

    if (ParameterNum == 4)
    {
        Color = (int)0xfffffffff;
        Type = 1;
        Stroke = 0;

        Sq_pushbool(v, true);
    }
    else if (ParameterNum == 5)
    {
        //获取颜色
        Sq_getinteger(v, 5, &Color);
        Type = 1;
        Stroke = 0;

        Sq_pushbool(v, true);
    }
    else if (ParameterNum == 6)
    {
        //获取颜色
        Sq_getinteger(v, 5, &Color);
        //获取类型
        Sq_getinteger(v, 6, &Type);
        Stroke = 0;

        Sq_pushbool(v, true);
    }
    else if (ParameterNum == 7)
    {
        //获取颜色
        Sq_getinteger(v, 5, &Color);
        //获取类型
        Sq_getinteger(v, 6, &Type);
        //获取描边
        Sq_getinteger(v, 7, &Stroke);

        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
        return 1;
    }

    //获取字符串内容
    Sq_getstring(v, 2, &Str);
    //获取X坐标
    Sq_getinteger(v, 3, &XPos);
    //获取X坐标
    Sq_getinteger(v, 4, &YPos);
    //松鼠 Wchar_t  转换为  Unicode
    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    //转为正确的Unicode字符
    wchar_t* str = DNFTOOL::char2wchar(OutPutText);

    //申请笔
    unsigned char* font = new unsigned char[1000];
    //初始化笔
    sub_11BE9A0((DWORD)font, 0);
    sub_11BE980((DWORD)font, 0);
    //是否描边
    font[1] = Stroke;

    int FontObj;

    switch (Type)
    {
    case 1:
        FontObj = *(int*)0x1B468CC;
        break;
    case 2:
        FontObj = *(int*)0x1B468DC;
        break;
    case 3:
        FontObj = *(int*)0x1B468D4;
        break;
    default:
        FontObj = *(int*)0x1B468CC;
        break;
    }

    //字体
    *(int*)((int)font + 8) = FontObj;

    //得到绘制句柄
    DWORD base = *(int*)0x1B45B94;
    //设置笔
    sub_1206550(base, 0, (DWORD)font);
    //绘制字体
    NewDrawCodeF(base, 0, XPos, YPos, Color, (int)str);
    //取消笔
    sub_1206570(base, 0);


    delete[]OutPutText;
    delete[]str;
    delete[]font;
    return 1;
}
//读内存
static SQInteger LReadAddress(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;

    //获取参数个数
    int ParameterNum = Sq_gettop(v);

    //1个参数时
    if (ParameterNum == 2)
    {
        //获取值的类型
        int ParameterType = sq_gettype(v, 2);

        switch (ParameterType)
        {
        case OT_INTEGER://int类型
        {
            //获取地址
            Sq_getinteger(v, 2, &Address);
            if (Address >= 0x400000) {
                int Value = *(int*)Address;
                Sq_pushinteger(v, Value);
            }
            else {
                Sq_pushinteger(v, -1);
            }
            return 1;
        }
        break;
        }
    }
    if (ParameterNum == 3)
    {
        //地址
        int Address;
        //偏移
        const SQChar* offset;

        Sq_getinteger(v, 2, &Address);
        Sq_getstring(v, 3, &offset);

        int Value = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar((wchar_t*)offset), 0);
        Sq_pushinteger(v, Value);
        return 1;
    }
    return 0;
}
//读内存
static SQInteger LReadAddressB(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;

    //获取参数个数
    int ParameterNum = Sq_gettop(v);
    //1个参数时
    if (ParameterNum == 2)
    {
        //获取地址
        Sq_getinteger(v, 2, &Address);
        int Value = *(BYTE*)Address;
        Sq_pushinteger(v, Value);
        return 1;
    }
    if (ParameterNum == 3)
    {
        ////地址
        //int Address;
        ////偏移
        //wchar_t* offset;

        //Sq_getinteger(v, 2, &Address);
        //SQGetString(v, 3, &offset);

        //int Value = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar(offset));
        //SQPushInt(v, Value);
        std::cout << "未完成" << std::endl;
        return 0;
    }
    else
    {
        Sq_pushbool(v, false);
        return 1;
    }
    return 0;
}
//读内存
static SQInteger LReadAddressFloat(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;
    Sq_getinteger(v, 2, &Address);
    Sq_pushfloat(v, *(float*)Address);
    return 1;
}
//写内存
static SQInteger LWriteAddressB(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;

    //获取参数个数
    int ParameterNum = Sq_gettop(v);
    //1个参数时
    if (ParameterNum == 3)
    {
        //获取地址
        Sq_getinteger(v, 2, &Address);
        //获取修改的值
        int WriteValue;
        Sq_getinteger(v, 3, &WriteValue);
        *(BYTE*)Address = (BYTE)WriteValue;
        Sq_pushbool(v, true);
        return 1;
    }
    if (ParameterNum == 4)
    {
        //地址
        int Address;
        //偏移
        const SQChar* offset;
        //修改值
        int WriteValue;

        Sq_getinteger(v, 2, &Address);
        Sq_getstring(v, 3, &offset);
        Sq_getinteger(v, 4, &WriteValue);
        int SelectAddress = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar((wchar_t*)offset), 1);
        *(BYTE*)Address = (BYTE)WriteValue;
    }
    else
    {
        Sq_pushbool(v, false);
        return 1;
    }
    return 0;
}
//写内存
static SQInteger LWriteAddress(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;

    //获取参数个数
    int ParameterNum = Sq_gettop(v);
    //1个参数时
    if (ParameterNum == 3)
    {
        //获取地址
        Sq_getinteger(v, 2, &Address);
        //获取修改的值
        int WriteValue;
        Sq_getinteger(v, 3, &WriteValue);

        *(int*)Address = WriteValue;
        Sq_pushbool(v, true);
        return 1;
    }
    if (ParameterNum == 4)
    {
        //地址
        int Address;
        //偏移
        const SQChar* offset;
        //修改值
        int WriteValue;

        Sq_getinteger(v, 2, &Address);
        Sq_getstring(v, 3, &offset);
        Sq_getinteger(v, 4, &WriteValue);

        int SelectAddress = DNFTOOL::GetHook(Address, DNFTOOL::wchar_tTochar((wchar_t*)offset), 1);
        *(int*)SelectAddress = WriteValue;
    }
    else
    {
        Sq_pushbool(v, false);
        return 1;
    }
    return 0;
}
//Int转指针
static SQInteger sq_I2P(HSQUIRRELVM v)
{
    //内存地址 int型
    int Address;
    Sq_getinteger(v, 2, &Address);
    Sq_pushuserpointer(v, (void*)Address);
    return 1;
}
//指针转Int
static SQInteger sq_P2I(HSQUIRRELVM v)
{
    //内存地址 int型
    SQUserPointer Address;
    Sq_getuserpointer(v, 2, &Address);
    Sq_pushinteger(v, (int)Address);
    return 1;
}
//输出
static SQInteger Sout(HSQUIRRELVM v)
{
    const SQChar* Str;
    Sq_getstring(v, 2, &Str);

    char* OutPutText = DNFTOOL::SquirrelU2WOut(Str);

    std::cout << OutPutText << std::endl;

    delete[] OutPutText;


    return 0;
}

static SQInteger Clock(HSQUIRRELVM v)
{
    Sq_pushinteger(v, clock());
    return 1;
}

static SQInteger Getmicroseconds(HSQUIRRELVM v)
{
    auto now = std::chrono::high_resolution_clock::now();
    auto duration = now.time_since_epoch();
    auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
    Sq_pushfloat(v, microseconds / 1000);
    return 1;
}
static SQInteger SQTime(HSQUIRRELVM v)
{
    time_t t;
    time(&t);
    sq_pushinteger(v, *((SQInteger*)&t));
    return 1;
}
//新建窗口
//窗口CALL
typedef void(__fastcall* NoticeTCall)(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD a3);
static NoticeTCall _NoticeTcall = (NoticeTCall)0xE6E070;
static void WindowsNotice(char* str, int type, int b)
{
    DWORD thisc = 0x1A5FB20;
    thisc = *(DWORD*)thisc;
    _NoticeTcall(thisc, 0, type, str, b);
}
static SQInteger NewWindows(HSQUIRRELVM v)
{
    const SQChar* str = NULL;
    int type = NULL;
    int color = NULL;
    int num = Sq_gettop(v);

    if (num == 2 || num == 3 || num == 4)
    {
        switch (num)
        {
        case 2:
            Sq_getstring(v, 2, &str);
            break;
        case 3:
            Sq_getstring(v, 2, &str);
            Sq_getinteger(v, 3, &type);
            break;
        case 4:
            Sq_getstring(v, 2, &str);
            Sq_getinteger(v, 3, &type);
            Sq_getinteger(v, 4, &color);
            break;
        }

        char* OutPutText = DNFTOOL::SquirrelU2W(str);
        WindowsNotice(OutPutText, type, color);
        delete[]OutPutText;
        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
    }

    return 1;
}
static SQInteger sq_Cmd(HSQUIRRELVM v)
{
    const SQChar* OutPutBuffer;
    Sq_getstring(v, 2, &OutPutBuffer);
    char* OutPutText = DNFTOOL::SquirrelU2W(OutPutBuffer);

    system(OutPutText);
    delete[]OutPutText;
    return 0;
}
static SQInteger sq_CmdEx(HSQUIRRELVM v)
{
    const SQChar* OutPutBuffer;
    Sq_getstring(v, 2, &OutPutBuffer);
    char* OutPutText = DNFTOOL::SquirrelU2W((wchar_t*)OutPutBuffer);

    STARTUPINFOA si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;

    // 创建新进程
    BOOL result = CreateProcessA(
        NULL,                   // 应用程序名称
        OutPutText,   // 命令行参数
        NULL,                   // 进程安全属性
        NULL,                   // 线程安全属性
        FALSE,                  // 继承句柄选项
        0,                      // 创建标志
        NULL,                   // 环境变量
        NULL,                   // 当前目录
        &si,                    // STARTUPINFO
        &pi                     // PROCESS_INFORMATION
    );

    if (result) {
        // 不等待新进程结束，直接关闭句柄
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    else {
    }

    delete[]OutPutText;
    return 0;
}
//设置UI槽坐标
static SQInteger SetSlot(HSQUIRRELVM v)
{
    int Type = NULL;
    int Index = NULL;
    int Xpos = NULL;
    int Ypos = NULL;


    int OneAddr = NULL;
    int* xpos = NULL;
    int* ypos = NULL;

    int ParameterNum = Sq_gettop(v);

    if (ParameterNum == 5)
    {
        Sq_getinteger(v, 2, &Type);
        Sq_getinteger(v, 3, &Index);
        Sq_getinteger(v, 4, &Xpos);
        Sq_getinteger(v, 5, &Ypos);

        Sq_pop(v, ParameterNum);

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

        Sq_pushbool(v, true);
    }
    else
    {
        Sq_pushbool(v, false);
    }

    return 1;
}

//输入框相关
struct InputWindowInfoS {
    int x;
    int y;
    int width;
    int height;
    std::string str;
};
LRESULT CALLBACK LenheartCode(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         	hdc;
    PAINTSTRUCT 	ps;
    static int  	mX, mY;
    static HWND 	hwndButton;
    static HWND 	hwndEditbox;
    std::string			strXy;
    const int		IDcmdButton = 1;
    const int		IDeditBox = 2;
    static InputWindowInfoS* WInfo;


    switch (message) {
    case WM_CREATE:
    {
        RECT rect;
        GetWindowRect(hwnd, &rect); // 获取窗口的矩形区域

        // 获取传递的参数
        CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
        WInfo = (InputWindowInfoS*)pCreate->lpCreateParams;

        hwndEditbox = CreateWindowA("edit", NULL,
            WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE,
            0, 0,
            WInfo->width, WInfo->height,
            hwnd, (HMENU)IDeditBox, NULL, NULL);

        ShowWindow(hwndEditbox, SW_SHOW);
        UpdateWindow(hwndEditbox);


        HFONT hFont = CreateFont(13.5, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Fonts\\msjh.ttf"));
        SendMessage(hwndEditbox, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
        SetForegroundWindow(hwndEditbox);

        //如果有字先写进去
        if (WInfo->str.length() > 0)SetWindowTextA(hwndEditbox, WInfo->str.c_str());
        // 获取当前文本长度
        int length = GetWindowTextLengthA(hwndEditbox);

        // 将光标移动到文本末尾
        SendMessage(hwndEditbox, EM_SETSEL, length, length);

        return 0;
    }
    case WM_CTLCOLOREDIT:
    {
        HDC ahdc = (HDC)wParam;
        SetTextColor(ahdc, RGB(0, 0, 0));
        //SetTextColor(ahdc, RGB(255, 255, 255));
        SetBkMode(ahdc, TRANSPARENT); // 设置背景透明
        return (INT_PTR)GetStockObject(NULL_BRUSH); // 返回空画刷
        //return 0; //返回句柄画刷时，背景颜色变为对应的背景颜色
    }
    case WM_PAINT:
    {
        hdc = BeginPaint(hwnd, &ps);
        EndPaint(hwnd, &ps);
        return 0;
    }
    case WM_SIZE:
    {

        return 0;
    }

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case 0:
            PostQuitMessage(0);
            break;
        case IDeditBox:
            if (HIWORD(wParam) == EN_CHANGE) {
                char strbuf[256];
                // 编辑框内容发生变化
                GetWindowTextA(hwndEditbox, strbuf, 256);
                //std::cout << strbuf << std::endl;
                WInfo->str = strbuf;
            }

            if (HIWORD(wParam) == EN_SETFOCUS) {
            }
            else if (HIWORD(wParam) == EN_KILLFOCUS) {
                DestroyWindow(hwnd);  //销毁窗口
                WInfo->str = "LenheartNULL";
                //CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
                //delete[](InputWindowInfoS*)pCreate->lpCreateParams;
                //pCreate->lpCreateParams = NULL;
                //exit(0);
            }
            break;
        }
        return 0;

    case WM_MOUSEACTIVATE:
        break;

    case WM_CLOSE:
        DestroyWindow(hwnd);  //销毁窗口
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

void LenheartWindows(LPVOID lpParam) {

    HWND DNFW = FindWindow(L"DNF Taiwan", L"DNF Taiwan"); // 替换"Window Title"为你要查找的窗口标题
    RECT rect;
    GetWindowRect(DNFW, &rect); // 获取窗口的矩形区域

    InputWindowInfoS* WInfo = (InputWindowInfoS*)lpParam;

    const wchar_t* className = L"myInputBoxClass";
    HINSTANCE hInstance = GetModuleHandle(NULL);

    WNDCLASS wc = {};
    wc.lpfnWndProc = LenheartCode;
    wc.hInstance = hInstance;
    wc.lpszClassName = className;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
    //wc.hbrBackground = NULL;

    RegisterClass(&wc);

    // 创建输入框
    HWND hwnd = CreateWindowEx(
        0, className, L"Input Box",
        WS_POPUP | WS_EX_TOOLWINDOW,
        rect.left + WInfo->x, rect.top + WInfo->y, WInfo->width, WInfo->height,
        NULL, NULL, hInstance, lpParam);


    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TOOLWINDOW);
    SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);


    ShowWindow(hwnd, SW_SHOW);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
static SQInteger sq_NewInputBox(HSQUIRRELVM v)
{
    InputWindowInfoS* WInfo = new InputWindowInfoS();
    Sq_getinteger(v, 2, &WInfo->x);
    Sq_getinteger(v, 3, &WInfo->y);
    Sq_getinteger(v, 4, &WInfo->width);
    Sq_getinteger(v, 5, &WInfo->height);
    const SQChar* Str;
    Sq_getstring(v, 6, &Str);
    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    std::string RealStr = OutPutText;
    delete[]OutPutText;
    WInfo->str = RealStr;


    DWORD threadID3;
    HANDLE Thand3 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LenheartWindows, WInfo, 0, &threadID3);

    Sq_pushinteger(v, (int)WInfo);
    return 1;
}

static SQInteger sq_GetInputBoxStr(HSQUIRRELVM v)
{
    int Addr;
    Sq_getinteger(v, 2, &Addr);
    InputWindowInfoS* WInfo = (InputWindowInfoS*)Addr;

    std::string str = WInfo->str;
    char* ss = DNFTOOL::GBKTOUTF8(str);
    std::wstring aa = DNFTOOL::charTowchar_t(ss);
    Sq_pushstring(v, aa.c_str(), -1);
    return 1;

}

static SQInteger sq_SetInputBoxStr(HSQUIRRELVM v)
{
    int Addr;
    Sq_getinteger(v, 2, &Addr);
    const SQChar* Str;
    Sq_getstring(v, 3, &Str);
    char* OutPutText = DNFTOOL::SquirrelU2W(Str);
    std::string RealStr = OutPutText;
    delete[]OutPutText;

    InputWindowInfoS* WInfo = (InputWindowInfoS*)Addr;
    WInfo->str = RealStr;
    return 0;

}

static SQInteger sq_MouseClick(HSQUIRRELVM v)
{
    // 模拟鼠标左键按下
    INPUT input = { 0 };
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    SendInput(1, &input, sizeof(INPUT));

    // 模拟鼠标左键抬起
    input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(1, &input, sizeof(INPUT));
    return 0;
}


int __declspec(naked)Get_Item(int ItemId) {
    __asm {
        push ebp
        mov ebp, esp
        sub esp, 0xD0
        push ebx
        mov eax, ItemId
        mov dword ptr ss : [ebp - 0x04] , eax
        lea ecx, dword ptr ss : [ebp - 0xD0]
        mov eax, 0x65DE50
        call eax
        mov ecx, dword ptr ss : [ebp - 0x04]
        mov ebx, 0x01
        push ebx
        push eax
        push ecx
        mov eax, 0x972220
        call eax
        add esp, 0x0C
        pop ebx
        mov esp, ebp
        pop ebp
        ret 0x4
    }
}
static SQInteger sq_GetItem(HSQUIRRELVM v)
{
    int Idx;
    Sq_getinteger(v, 2, &Idx);
    int A = Get_Item(Idx);
    Sq_pushinteger(v, A);
    return 1;
}


// 定义2D顶点结构（位置+纹理坐标）
struct Vertex2D {
    float x, y, z;       // 位置（z=0表示2D平面）
    float u, v;          // 纹理坐标
};

// 初始化顶点缓冲区（创建一次即可，不必每次绘制都创建）
LPDIRECT3DVERTEXBUFFER9 CreateVertexBuffer(LPDIRECT3DDEVICE9 pDevice, float x, float y, float width, float height) {
    LPDIRECT3DVERTEXBUFFER9 pVB = nullptr;

    // 定义矩形的四个顶点（左上角、右上角、左下角、右下角）
    Vertex2D vertices[] = {
        {x, y, 0.0f, 0.0f, 0.0f},                  // 左上角
        {x + width, y, 0.0f, 1.0f, 0.0f},          // 右上角
        {x, y + height, 0.0f, 0.0f, 1.0f},         // 左下角
        {x + width, y + height, 0.0f, 1.0f, 1.0f}  // 右下角
    };

    // 创建顶点缓冲区
    if (FAILED(pDevice->CreateVertexBuffer(
        4 * sizeof(Vertex2D),         // 大小
        D3DUSAGE_WRITEONLY,           // 用法
        D3DFVF_XYZ | D3DFVF_TEX1,     // 顶点格式（位置+1套纹理坐标）
        D3DPOOL_MANAGED,              // 内存池
        &pVB,
        nullptr))) {
        return nullptr;
    }

    // 锁定并写入顶点数据
    void* pData = nullptr;
    if (SUCCEEDED(pVB->Lock(0, 0, &pData, 0))) {
        memcpy(pData, vertices, sizeof(vertices));
        pVB->Unlock();
    }
    else {
        pVB->Release();
        return nullptr;
    }

    return pVB;
}

void DrawMyImage(LPDIRECT3DDEVICE9 pDevice) {
    // 1. 准备RGBA数据（100x100红色图像）
    int width = 100, height = 100;
    std::vector<BYTE> rgbaData(width * height * 4);
    for (int i = 0; i < width * height; i++) {
        rgbaData[i * 4 + 0] = 0;   // R
        rgbaData[i * 4 + 1] = 0;     // G
        rgbaData[i * 4 + 2] = 255;     // B
        rgbaData[i * 4 + 3] = 255;   // A
    }

    // 2. 创建纹理
    LPDIRECT3DTEXTURE9 pTexture = nullptr;
    if (FAILED(pDevice->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pTexture, nullptr))) {
        return;
    }

    // 3. 锁定纹理写入数据
    D3DLOCKED_RECT lockedRect;
    if (FAILED(pTexture->LockRect(0, &lockedRect, nullptr, 0))) {
        pTexture->Release();
        return;
    }
    BYTE* dst = (BYTE*)lockedRect.pBits;
    const BYTE* src = rgbaData.data();
    for (int y = 0; y < height; y++) {
        memcpy(dst, src, width * 4);
        src += width * 4;
        dst += lockedRect.Pitch;
    }
    pTexture->UnlockRect(0);

    // 4. 创建顶点缓冲区（绘制位置(0,0)，大小800x600）
    LPDIRECT3DVERTEXBUFFER9 pVB = CreateVertexBuffer(pDevice, 0, 0, 800, 600);
    if (!pVB) {
        pTexture->Release();
        return;
    }

    // --------------------------
    // 关键：保存原始渲染状态
    // --------------------------
    DWORD originalFVF, originalZEnable;
    LPDIRECT3DBASETEXTURE9 originalTexture = nullptr;
    pDevice->GetFVF(&originalFVF);                  // 保存原始顶点格式
    pDevice->GetTexture(0, &originalTexture);       // 保存原始纹理
    pDevice->GetRenderState(D3DRS_ZENABLE, &originalZEnable); // 保存Z缓冲状态

    // --------------------------
    // 设置绘制所需状态
    // --------------------------
    pDevice->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1);      // 恢复顶点格式
    pDevice->SetTexture(0, pTexture);               // 绑定你的纹理
    pDevice->SetStreamSource(0, pVB, 0, sizeof(Vertex2D)); // 绑定顶点缓冲区
    pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); // 临时禁用Z缓冲

    // 5. 绘制
    pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

    // --------------------------
    // 关键：恢复原始渲染状态
    // --------------------------
    pDevice->SetFVF(originalFVF);                   // 恢复顶点格式
    pDevice->SetTexture(0, originalTexture);        // 恢复原始纹理
    pDevice->SetRenderState(D3DRS_ZENABLE, originalZEnable); // 恢复Z缓冲
    if (originalTexture) originalTexture->Release(); // 释放引用

    // 6. 释放资源（必须释放，避免泄漏）
    pVB->Release();
    pTexture->Release();
}

typedef int(_fastcall _11A2030)(int thisc, void*, int a2, int a3, int a4, int a5);
static _11A2030* SUB_11A2030 = (_11A2030*)0x11A2030;
static SQInteger sq_Test(HSQUIRRELVM v)
{
    SQInteger FuncAddressbuf;
    Sq_getinteger(v, 2, &FuncAddressbuf);

    DrawMyImage((LPDIRECT3DDEVICE9)FuncAddressbuf);
    return 0;
}

static SQInteger Sq_ActiveCallFunc(HSQUIRRELVM v)
{
    // 得到参数个数
    SQInteger Count = sq_gettop(v);

    // 得到函数地址
    SQInteger FuncAddressbuf;
    Sq_getinteger(v, 2, &FuncAddressbuf);

    void* FuncAddress = (void*)FuncAddressbuf;

    // 得到返回值类型
    const SQChar* RetTypebuf;
    Sq_getstring(v, 3, &RetTypebuf);
    char* OutPutText2 = DNFTOOL::SquirrelU2W(RetTypebuf);
    std::string RetType(OutPutText2);
    delete[]OutPutText2;

    // 得到调用类型
    SQInteger CallType;
    Sq_getinteger(v, 4, &CallType);

    std::vector<std::string> ParameterType;
    // 遍历参数类型数组
    sq_pushnull(v); // null iterator
    while (SQ_SUCCEEDED(sq_next(v, 5)))
    {
        const SQChar* path;
        Sq_getstring(v, -1, &path);
        char* OutPutText = DNFTOOL::SquirrelU2W(path);
        ParameterType.push_back(OutPutText);
        delete[]OutPutText;
        Sq_pop(v, 2);
    }
    Sq_pop(v, 1);

    // 头部信息个数
    int HeaderCount = 5;

    // 计算valist内存
    int AdrSize = 0;
    for (std::string Type : ParameterType)
    {
        if (CONTAINS_STRING(Type, "int"))
            AdrSize += sizeof(int);
        else if (CONTAINS_STRING(Type, "bool"))
            AdrSize += sizeof(bool);
        else if (CONTAINS_STRING(Type, "string"))
            AdrSize += sizeof(char*);
        else if (CONTAINS_STRING(Type, "float"))
            AdrSize += sizeof(float);
        else if (CONTAINS_STRING(Type, "pointer"))
            AdrSize += sizeof(void*);
        else if (CONTAINS_STRING(Type, "short"))
            AdrSize += sizeof(short);
        else if (CONTAINS_STRING(Type, "char"))
            AdrSize += sizeof(char);
    }

    char* m = (char*)malloc(AdrSize);
    void* bm = m;
    // 定义函数签名
    ffi_cif cif;
    ffi_type** args = (ffi_type**)malloc(ParameterType.size() * sizeof(ffi_type*)); // 动态分配参数类型数组
    void** values = (void**)malloc(ParameterType.size() * sizeof(void*));           // 动态分配参数值数组
    ffi_arg result;

    int CFlag = 0;
    for (int i = (HeaderCount + 1); i < (Count + 1); i++)
    {
        if (CONTAINS_STRING(ParameterType[0], "int"))
        {
            Sq_getinteger(v, i, (SQInteger*)m);
            args[CFlag] = &ffi_type_sint;
            values[CFlag] = m;
            m += sizeof(int);
        }
        else if (CONTAINS_STRING(ParameterType[0], "float"))
        {
            Sq_getfloat(v, i, (SQFloat*)m);
            args[CFlag] = &ffi_type_float;
            values[CFlag] = m;
            m += sizeof(float);
        }
        else if (CONTAINS_STRING(ParameterType[0], "bool"))
        {
            Sq_getbool(v, i, (SQBool*)m);
            args[CFlag] = &ffi_type_sint8;
            values[CFlag] = m;
            m += sizeof(bool);
        }
        else if (CONTAINS_STRING(ParameterType[0], "string"))
        {

            Sq_getstring(v, i, (const SQChar**)m);
            args[CFlag] = &ffi_type_pointer;
            values[CFlag] = m;
            m += sizeof(void*);
        }
        else if (CONTAINS_STRING(ParameterType[0], "pointer"))
        {
            Sq_getuserpointer(v, i, (SQUserPointer*)m);
            args[CFlag] = &ffi_type_sint;
            values[CFlag] = m;
            m += sizeof(int);
        }
        else if (CONTAINS_STRING(ParameterType[0], "short"))
        {
            Sq_getinteger(v, i, (SQInteger*)m);
            args[CFlag] = &ffi_type_sint16;
            values[CFlag] = m;
            m += sizeof(short);
        }
        else if (CONTAINS_STRING(ParameterType[0], "char"))
        {
            Sq_getinteger(v, i, (SQInteger*)m);
            args[CFlag] = &ffi_type_schar;
            values[CFlag] = m;
            m += sizeof(char);
        }

        ParameterType.erase(ParameterType.begin());
        CFlag++;
    }

    ffi_type* RetTypeFlag = &ffi_type_void;

    std::string RetTypeString = RetType;
    if (CONTAINS_STRING(RetTypeString, "int"))
        RetTypeFlag = &ffi_type_sint;
    else if (CONTAINS_STRING(RetTypeString, "float"))
        RetTypeFlag = &ffi_type_float;
    else if (CONTAINS_STRING(RetTypeString, "bool"))
        RetTypeFlag = &ffi_type_sint8;
    else if (CONTAINS_STRING(RetTypeString, "string"))
        RetTypeFlag = &ffi_type_pointer;
    else if (CONTAINS_STRING(RetTypeString, "pointer"))
        RetTypeFlag = &ffi_type_pointer;
    else if (CONTAINS_STRING(RetTypeString, "short"))
        RetTypeFlag = &ffi_type_sint16;
    else if (CONTAINS_STRING(RetTypeString, "char"))
        RetTypeFlag = &ffi_type_schar;


    int RetCore = 999;
    if (RetCore = ffi_prep_cif(&cif, (ffi_abi)CallType, CFlag, RetTypeFlag, args) == FFI_OK)
    {
        // 动态调用函数
        ffi_call(&cif, FFI_FN(FuncAddress), &result, values);
    }

    free(args);
    free(values);
    free(bm);

    if (CONTAINS_STRING(RetTypeString, "int"))
        Sq_pushinteger(v, (int)result);
    else if (CONTAINS_STRING(RetTypeString, "float"))
        Sq_pushfloat(v, (float)result);
    else if (CONTAINS_STRING(RetTypeString, "bool"))
        Sq_pushbool(v, (bool)result);
    else if (CONTAINS_STRING(RetTypeString, "string")) {
        std::wstring ss = DNFTOOL::charTowchar_t((char*)result);
        Sq_pushstring(v, ss.c_str(), -1);
    }
    else if (CONTAINS_STRING(RetTypeString, "pointer"))
        Sq_pushuserpointer(v, (void*)result);
    else if (CONTAINS_STRING(RetTypeString, "short"))
        Sq_pushinteger(v, (int)result);
    else if (CONTAINS_STRING(RetTypeString, "char"))
        Sq_pushinteger(v, (int)result);
    else
        return 0;
    return 1;
}


static SQInteger Sq_GetExportByName(HSQUIRRELVM v)
{
    //获取函数符号名
    const SQChar* FuncNamebuf;
    Sq_getstring(v, 2, &FuncNamebuf);
    char* OutPutText2 = DNFTOOL::SquirrelU2W(FuncNamebuf);
    std::string FuncName(OutPutText2);
    delete[]OutPutText2;

    HMODULE hModule = GetModuleHandle(NULL);
    if (!hModule)
        return 0;

    FARPROC funcPtr = GetProcAddress(hModule, FuncName.c_str());
    if (!funcPtr)
        return 0;

    Sq_pushinteger(v, (int)funcPtr);
    return 1;
}

void RegisterMyNutApi(wchar_t* funcName, SQFUNCTION funcAddr)
{
    HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
    Sq_pushroottable(v);
    Sq_pushstring(v, funcName, -1);
    RealSqNewClosure(v, funcAddr, 0);
    SQNewSlot(v, -3, SQFalse);
    SQPopTop(v);
}


static SQInteger L_Str_Ptr(HSQUIRRELVM v)
{
    const SQChar* str;
    Sq_getstring(v, 2, &str);
    Sq_pushuserpointer(v, (void*)str);
    return 1;
}

static SQInteger New_Point(HSQUIRRELVM v)
{
    SQInteger Len;
    Sq_getinteger(v, 2, &Len);
    void* P = malloc(Len);
    Sq_pushuserpointer(v, P);
    return 1;
}
static SQInteger _file_releasehook(SQUserPointer p, SQInteger a)
{
    free((void*)p);
    return 0;
}
// 注册析构函数
static SQInteger Register_Destruction(HSQUIRRELVM v)
{
    // 析构函数测试
    SQUserPointer P;
    sq_getuserpointer(v, 2, &P);

    sq_setinstanceup(v, 3, P);
    sq_setreleasehook(v, 3, _file_releasehook);
    return 0;
}
// 写字节数组
static SQInteger Memory_WriteByteArr(HSQUIRRELVM v)
{
    SQUserPointer P;
    Sq_getuserpointer(v, 2, &P);
    char* Address = (char*)P;

    size_t Idx = 0;
    sq_pushnull(v); // null iterator
    while (SQ_SUCCEEDED(sq_next(v, 3)))
    {
        SQInteger Buf;
        Sq_getinteger(v, -1, &Buf);
        *(BYTE*)(Address + Idx) = (BYTE)Buf;
        // 这里-1是值，-2是键
        Sq_pop(v, 2); // 在下一次迭代之前弹出键和值
        Idx++;
    }
    Sq_pop(v, 1);

    return 0;
}

// 读内存字符串
static SQInteger Memory_ReadString(HSQUIRRELVM v)
{
    // 内存地址
    SQUserPointer Address;
    // 获取地址
    Sq_getuserpointer(v, 2, &Address);
    if (Sq_gettop(v) == 3)
    {
        SQInteger Length;
        Sq_getinteger(v, 3, &Length);

        char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)Address);
        std::wstring name = DNFTOOL::charTowchar_t(str);
        free(str);
        Sq_pushstring(v, name.c_str(), Length);
    }
    else
    {
        char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)Address);
        std::wstring name = DNFTOOL::charTowchar_t(str);
        free(str);
        Sq_pushstring(v, name.c_str(), -1);
    }
    return 1;
}
// 读内存字符串
static SQInteger Memory_ReadStringByUtf8(HSQUIRRELVM v)
{
    // 内存地址
    SQUserPointer Address;
    // 获取地址
    Sq_getuserpointer(v, 2, &Address);
    if (Sq_gettop(v) == 3)
    {
        SQInteger Length;
        Sq_getinteger(v, 3, &Length);

        std::wstring name = DNFTOOL::charTowchar_t((char*)Address);
        Sq_pushstring(v, name.c_str(), Length);
    }
    else
    {
        std::wstring name = DNFTOOL::charTowchar_t((char*)Address);
        Sq_pushstring(v, name.c_str(), -1);
    }
    return 1;
}
// 读内存字符串
static SQInteger Memory_ReadStringByBig5(HSQUIRRELVM v)
{
    // 内存地址
    SQUserPointer Address;
    // 获取地址
    Sq_getuserpointer(v, 2, &Address);
    if (Sq_gettop(v) == 3)
    {
        SQInteger Length;
        Sq_getinteger(v, 3, &Length);

        std::wstring newadd = DNFTOOL::charTowchar_t((char*)Address);
        char* str = DNFTOOL::Big5ToUtf8(newadd.c_str());
        std::wstring name = DNFTOOL::charTowchar_t(str);
        free(str);
        Sq_pushstring(v, name.c_str(), Length);
    }
    else
    {
        std::wstring newadd = DNFTOOL::charTowchar_t((char*)Address);
        char* str = DNFTOOL::Big5ToUtf8(newadd.c_str());
        std::wstring name = DNFTOOL::charTowchar_t(str);
        free(str);
        Sq_pushstring(v, name.c_str(), -1);
    }
    return 1;
}
// 转换字符串
static SQInteger ConvertWideChar(HSQUIRRELVM v)
{
    const SQChar* Str;
    Sq_getstring(v, 2, &Str);

    const SQChar* olgcodepage;
    Sq_getstring(v, 3, &olgcodepage);
    char* OutPutText1 = DNFTOOL::SquirrelU2W(olgcodepage);
    std::string fromEncoding = OutPutText1;
    delete[]OutPutText1;


    if (CONTAINS_STRING(fromEncoding, "big5")) {

        char* csa = DNFTOOL::wchar_tTochar((wchar_t*)Str);
        wchar_t* name = DNFTOOL::BIG5ToUnicode(csa);
        char* str = DNFTOOL::UnicodeToUtf8(name);
        std::wstring realname = DNFTOOL::charTowchar_t(str);
        free(str);

        Sq_pushstring(v, realname.c_str(), -1);
        delete[]csa;
        delete[]name;
    }
    else if (CONTAINS_STRING(fromEncoding, "unicode")) {
        char* str = DNFTOOL::UnicodeToUtf8((wchar_t*)Str);
        std::wstring name = DNFTOOL::charTowchar_t(str);
        free(str);
        Sq_pushstring(v, name.c_str(), -1);
    }

    return 1;
}

// 指针转Blob
static SQInteger L_Point2Blob(HSQUIRRELVM v)
{
    SQInteger P;
    sq_getinteger(v, 2, &P);
    SQInteger Count;
    sq_getinteger(v, 3, &Count);

    char* Address = (char*)P;
    SQUserPointer Blobobj = sqstd_createblob(v, Count);
    memcpy(Blobobj, Address, Count);

    return 1;
}

static SQInteger OutPutTable(HSQUIRRELVM v)
{
    const SQChar* Str;
    sq_getstring(v, 2, &Str);

    char* OutPutText = DNFTOOL::wchar_tTochar((wchar_t*)Str);
    std::string str = OutPutText;
    delete[]OutPutText;

    nlohmann::json ex1 = nlohmann::json::parse(str);

    std::cout << std::setw(4) << ex1 << std::endl;
    return 0;
}



void R_Register_Nut() {
    R_Register_System();

    RegisterMyNutApi(L"L_sq_Test", sq_Test);//zlib解压


    RegisterMyNutApi(L"Sq_OutPutTable", OutPutTable);
    RegisterMyNutApi(L"Sq_HookFunc", L_HookFunc);
    RegisterMyNutApi(L"Sq_DeHookFunc", L_DeHookFunc);
    RegisterMyNutApi(L"Str_Ptr", L_Str_Ptr);
    RegisterMyNutApi(L"Sq_New_Point", New_Point);
    RegisterMyNutApi(L"Register_Destruction", Register_Destruction);
    RegisterMyNutApi(L"Sq_Memory_WriteByteArr", Memory_WriteByteArr);
    RegisterMyNutApi(L"Sq_Memory_ReadString", Memory_ReadString);
    RegisterMyNutApi(L"Sq_Memory_ReadStringByUtf8", Memory_ReadStringByUtf8);
    RegisterMyNutApi(L"Sq_Memory_ReadStringByBig5", Memory_ReadStringByBig5);
    RegisterMyNutApi(L"Sq_ConvertWideChar", ConvertWideChar);
    RegisterMyNutApi(L"Sq_Point2Blob", L_Point2Blob);
    RegisterMyNutApi(L"L_Sq_CallFunc", Sq_ActiveCallFunc);//动态Call
    RegisterMyNutApi(L"L_Sq_GetExportByName", Sq_GetExportByName);//动态Call

    RegisterMyNutApi(L"L_sq_GetItem", sq_GetItem);//获取Item

    RegisterMyNutApi(L"L_sq_StringBinById", sq_StringBinById);//获取字符串在StringBin中
    RegisterMyNutApi(L"L_sq_LongLongOperation", sq_LongLongOperation);//longlong类型运算
    RegisterMyNutApi(L"L_sq_Dezlib", sq_Dezlib);//zlib解压
    RegisterMyNutApi(L"L_sq_DrawImg", sq_DrawImg);//绘制Img
    RegisterMyNutApi(L"L_sq_SetDrawImgModel", sq_SetDrawImgModel);//设置Img绘制模式
    RegisterMyNutApi(L"L_sq_ReleaseDrawImgModel", sq_ReleaseDrawImgModel);//释放Img绘制模式
    RegisterMyNutApi(L"L_sq_IntiNumberDraw", sq_IntiNumberDraw);//初始化数字绘制
    RegisterMyNutApi(L"L_sq_DrawNumber", sq_DrawNumber);//绘制数字
    RegisterMyNutApi(L"L_sq_DrawWindow", sq_DrawWindow);//绘制九宫格
    RegisterMyNutApi(L"L_sq_DrawButton", sq_DrawButton);//绘制三联图
    RegisterMyNutApi(L"L_sq_Draw3Image_Vertical", sq_Draw3Image_Vertical);//绘制三联图
    RegisterMyNutApi(L"L_sq_GetStringDrawLength", Sq_getstringDrawLength);//获取文字绘制长度
    RegisterMyNutApi(L"L_sq_GetStringDrawArray", Sq_getstringDrawArray);//获取文字换行返回数组
    RegisterMyNutApi(L"L_sq_DecondeJson", DecondeJson);//反序列化Json
    RegisterMyNutApi(L"L_sq_EncondeJson", EncondeJson);//序列化Json

    RegisterMyNutApi(L"L_sq_IsKeyDown", sq_IsKeyDown);//按键是否按下
    RegisterMyNutApi(L"L_sq_MouseClick", sq_MouseClick);//按下鼠标左键

    RegisterMyNutApi(L"L_sq_Open_ExWindow", sq_Open_ExWindow);//创建特殊窗口
    RegisterMyNutApi(L"L_sq_Open_ExWindow2", sq_Open_ExWindow2);//创建特殊窗口
    RegisterMyNutApi(L"L_sq_GetWindowById", sq_GetWindowById);//通过ID获取窗口地址
    RegisterMyNutApi(L"L_sq_Select_MiniMap_Index", sq_Select_MiniMap_Index);//选择大地图区域

    RegisterMyNutApi(L"L_Sq_DrawSkill", sq_DrawSkill);//绘制技能
    RegisterMyNutApi(L"L_sq_UseSkill", sq_UseSkill);//使用技能

    RegisterMyNutApi(L"L_Sq_GetPlayerEachName", sq_GetPlayerEachName);//获取当前选择交互角色姓名
    RegisterMyNutApi(L"L_Sq_GetSkillAddress", sq_GetSkillAddress);//获取技能地址

    RegisterMyNutApi(L"L_sq_MoveMap", sq_MoveMap);//顺图

    RegisterMyNutApi(L"L_Sq_GetImg", sq_GetImg);//通过Item编号获取图标Img
    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);//获取对象加密信息
    RegisterMyNutApi(L"L_Sq_SetObjectInfo", SetObjectInfo);//设置对象信息
    RegisterMyNutApi(L"L_Sq_SetObjectDeInfo", SetObjectDeInfo);//设置对象加密信息
    RegisterMyNutApi(L"L_Sq_GetObjectLevel", GetObjectLevel);//获取对象等级
    RegisterMyNutApi(L"L_Sq_GetObjectIsCharacter", GetObjectIsCharacter);//获取对象是否是玩家
    RegisterMyNutApi(L"L_Sq_GetObjectAttribute", GetObjectAttribute);//获取对象属性

    RegisterMyNutApi(L"L_sq_GetCharacterAttribute", GetCharacterAttribute);//获取人物或装备属性
    RegisterMyNutApi(L"L_sq_SetCharacterAttribute", SetCharacterAttribute);//设置人物或装备属性


    RegisterMyNutApi(L"L_sq_GetTownIndex", GetTownIndex);//获取城镇编号
    RegisterMyNutApi(L"L_sq_GetRegionIndex", GetRegionIndex);//获取区域编号
    RegisterMyNutApi(L"L_sq_GetTownXpos", GetTownXpos);//获取城镇X坐标
    RegisterMyNutApi(L"L_sq_GetTownYpos", GetTownYpos);//获取城镇Y坐标

    RegisterMyNutApi(L"L_sq_GetFatigue", GetFatigue);//获取疲劳值
    RegisterMyNutApi(L"L_sq_GetExp", GetExp);//获取经验值
    RegisterMyNutApi(L"L_sq_GetSp", sq_GetSp);//获取SP点
    RegisterMyNutApi(L"L_sq_GetPassLevel", sq_GetPassLevel);//获取冒险团等级
    RegisterMyNutApi(L"L_sq_RefreshEventIcon", sq_RefreshEventIcon);//刷新活动图标

    RegisterMyNutApi(L"L_sq_SendPackType", SendPackType);//发包类型
    RegisterMyNutApi(L"L_sq_SendPackByte", SendPackByte);//包数据Byte
    RegisterMyNutApi(L"L_sq_SendPackWord", SendPackWord);//包数据Word
    RegisterMyNutApi(L"L_sq_SendPackDWord", SendPackDWord);//包数据DWord
    RegisterMyNutApi(L"L_sq_SendPackWChar", SendPackWChar);//包数据DWord
    RegisterMyNutApi(L"L_sq_SendPack", SendPack);//发包

    RegisterMyNutApi(L"L_sq_GoDungeon", GoDungeon);//去副本
    RegisterMyNutApi(L"L_sq_GoTown", GoTown);//去城镇
    RegisterMyNutApi(L"L_sq_MoveTown", MoveTown);//去城镇

    RegisterMyNutApi(L"L_sq_DrawCode", sq_DrawCode);//绘制字符 //TODO

    RegisterMyNutApi(L"L_sq_RA", LReadAddress);//读内存
    RegisterMyNutApi(L"L_sq_WA", LWriteAddress);//写内存

    RegisterMyNutApi(L"L_sq_RAF", LReadAddressFloat);//读内存
    //RegisterMyNutApi(L"L_sq_WAF", LWriteAddressFloat);//写内存

    RegisterMyNutApi(L"L_sq_RAB", LReadAddressB);//读内存
    RegisterMyNutApi(L"L_sq_WAB", LWriteAddressB);//写内存

    RegisterMyNutApi(L"L_sq_I2P", sq_I2P);//int转指针
    RegisterMyNutApi(L"L_sq_P2I", sq_P2I);//指针转int

    RegisterMyNutApi(L"printf", Sout);//输出
    //RegisterMyNutApi(L"L_ReplaceInString", ReplaceInString);//输出
    RegisterMyNutApi(L"Clock", Clock);//输出
    RegisterMyNutApi(L"L_Getmicroseconds", Getmicroseconds);//获取微秒级
    RegisterMyNutApi(L"Sq_Time", SQTime);

    RegisterMyNutApi(L"L_NewWindows", NewWindows);//创建窗口
    RegisterMyNutApi(L"L_Cmd", sq_Cmd);//执行Cmd命令
    RegisterMyNutApi(L"L_CmdEx", sq_CmdEx);//执行Cmd命令Ex

    RegisterMyNutApi(L"L_SetSlot", SetSlot);//设置槽坐标

    RegisterMyNutApi(L"L_RegisterItemColor_STL", RegisterItemColor_STL);//注册Item颜色

    //输入框
    RegisterMyNutApi(L"L_sq_GetInputBoxStr", sq_GetInputBoxStr);
    RegisterMyNutApi(L"L_sq_SetInputBoxStr", sq_SetInputBoxStr);
    RegisterMyNutApi(L"L_sq_NewInputBox", sq_NewInputBox);
}