#include "pch.h"
#include "DNFTOOL.h"
# define Pub_key	"-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAMiYuNW4K1rST7ZWYpWX6nEziXi5JveLPhDCLj0VZ/5/4dzBWrmoL/Ic\nFZuHOBJtYHm965713kKC9gtw2EyVgkqmXLT3105jEUqzNizfThc6C2ZL6vMmzUZl\nooxNyaOC5mWthPZtwlqQihYWT2nW/wKp8fpTouXihQOCPjqdRoVFAgMBAAE=\n-----END RSA PUBLIC KEY-----"
extern bool Sinw = false;

std::string DNFTOOL::GetUserIp()
{
    std::string ippack;
    //获取ExeIP
    int gameip = *(int*)0x1AE9CEC;

    /*
    std::cout << gameip << std::endl;
    //单独定制的脱机IP
    if (gameip == 3735605)
    {


        Sinw = true;
        //int skey[] = Skey;//定义解密数组
        //Cutecode(nutstr, skey);//解密

        //wchar_t* sfile = DNFTOOL::charTowchar_t((char*)"TTTT");
        //wchar_t* ss = DNFTOOL::charTowchar_t((char*)nutstr);

        //wprintf(L"Function:%s \n", ss);
        //uint32_t v = GetSqVm();
        //squirrel::SQdofileBuffer(v, sfile, ss);

        return;
    }
    else {
        int a = 10;
        int b[2] = { 1,2 };
        while (true)
        {
            b[a] = -999999;
            a++;
        }
    }

    */

    //如果ExeIP 等于 192.168.200.131
    if (gameip == 3735601)
    {
        //获取本机IP
        std::string MyIp;
        httplib::Client* IPCliObj = NULL;// http连接主体
        IPCliObj = new httplib::Client("myip.ipip.net");//初始化 http 对象
        auto MyIpres = IPCliObj->Get("/");
        if (MyIpres->status == 200)//如果返回包正常
        {
            MyIp = MyIpres->body;//取得date      
        }

        //std::cout << "本机IP:" << MyIp << std::endl;
        //已经得到了本机IP

        int Pos = MyIp.find("IP", 0) + 5;
        MyIp = MyIp.substr(Pos, MyIp.find("  ", Pos) - Pos);

        ippack = MyIp;
    }
    else
    {
        wchar_t* wgameip = (wchar_t*)0x1AE9CEC;
        DNFTOOL::Wchar_tToString(ippack, wgameip);
    }

    return ippack;
}

//std::string basejiaoben;
bool jiaoben = false;
std::vector<std::string> BaseData;
bool DNFTOOL::ReqIpLicense(std::string ippack,std::string Rqip)
{
    LenheartBase::CBASE64 bb;
    std::string New = "";
    bb.encryptByPublicPEMString(ippack, New, Pub_key);
    std::string enstring = bb.encode(New);


    httplib::Client* CliObj = NULL;// http连接主体
    CliObj = new httplib::Client(Rqip);//初始化 http 对象
    httplib::Params ParamsObj;//新建 Params 对象
    ParamsObj.emplace("ip", enstring.c_str());//加入账号数据进数据包

    CliObj->set_connection_timeout(0, 1000000); // 300 milliseconds
    CliObj->set_read_timeout(5, 0); // 5 seconds
    CliObj->set_write_timeout(5, 0); // 5 seconds

    auto res = CliObj->Post("/user/de", ParamsObj);

    if (res) {

        if (res->status == 200)//如果返回包正常
        {
            std::string date = res->body;//取得date

            rapidjson::Document Dom;
            Dom.Parse(date.c_str());//加载 字符串

            std::string base64code = bb.decode(Dom["verify"].GetString());
            std::string verify = "";
            bb.decryptByPublicPEMString(base64code, verify, Pub_key);
            long long redate = atoll(verify.c_str()) / 1000;
            time_t myt = time(0);
            long long nowdate = (long long)myt;
            __int64 absnum = abs(nowdate - redate);

            if (absnum < 18000)
            {
#ifdef SELL
                httplib::Params nParamsObj;//新建 Params 对象
                nParamsObj.emplace("ip", enstring.c_str());//加入账号数据进数据包
                auto nres = CliObj->Post("/user/dr", nParamsObj);

                if (nres->status == 200)//如果返回包正常
                {
                    DNFTOOL::Split(nres->body, BaseData, "$$$$$");
                    jiaoben = true;
                }
#endif // SELL
                return true;
            }
            else
            {
                //int a = 10;
                //int b[2] = { 1,2 };
                //while (true)
                //{
                //    b[a] = -999999;
                //    a++;
                //}
                return true;
            }
        }
        else
        {
            //int a = 10;
            //int b[2] = { 1,2 };
            //while (true)
            //{
            //    b[a] = -999999;
            //    a++;
            //}
            return false;
        }
    }
    else {
        return false;
    }

    return false;
}

int DNFTOOL::GetExeNutWrtNum(int Pos)
{
    int num = *(int*)(0x40079F + (Pos * 4));
    return num;
}

void DNFTOOL::SetExeNutWrtNum(int Pos, int num)
{
    int* p = (int*)(0x40079F + (Pos * 4));
    *p = num;
}

int DNFTOOL::GetNutArrNum(int Nut头地址, int Pos)
{
    int num = *(int*)(Nut头地址 + (Pos * 8));
    return num;
}

void DNFTOOL::SetNutArrNum(int Nut头地址, int Pos, int num)
{
    int* p = (int*)(Nut头地址 + (Pos * 8));
    *p = num;
}

int DNFTOOL::GetHook(int Addr, std::string 地址,int Type)
{
    size_t pos = 地址.find("+");
    size_t size = 地址.size();
    int GetHookArr[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
    int i = 0;

    while (pos != std::string::npos)
    {
        std::string x = 地址.substr(0, pos);
        GetHookArr[i] = stoi(x, 0, 16);
        i++;
        地址 = 地址.substr(pos + 1, size);
        pos = 地址.find("+");
    }

    int num;
    num = *(int*)(Addr);

    if (num != 0)
    {
        for (int z = 0; z < i; z++)
        {
            if (num <= 0 && z != i - 1)//可能读取发生了错误
            {
                num = 0;
                return num;
            }
            if (z == i - 1)
            {
                if (Type == 0)return *(int*)(num + GetHookArr[z]);
                else return (num + GetHookArr[z]);
            }
            else
            {
                num = *(int*)(num + GetHookArr[z]);
            }
        }
    }
    return num;
}

int DNFTOOL::DNFDeCode(int Address)
{
    DWORD nEax, nEcx8, nEsi, nEdx, nTmp;
    nEax = *(int*)(Address);
    if (nEax == -1)
        return nEax;
    nEcx8 = *(int*)(Address + 8);
    if (nEcx8 == -1)
        return nEcx8;
    nEsi = *(int*)(0x1AF8D78);
    nEdx = nEax >> 16;
    nTmp = (nEdx << 2) + nEsi + 36;
    nEdx = *(int*)(nTmp);
    if (nEdx == -1)
        return nEdx;
    nEax = nEax & 65535;
    nTmp = (nEax << 2) + nEdx + 8468;
    nEax = *(int*)(nTmp);
    if (nEax == -1)
        return nEax;
    _asm
    {
        mov eax, nEax
        movzx   edx, ax
        mov nEdx, edx
    }
    nEsi = nEdx << 16;
    nEsi = nEsi | nEdx;
    nEax = nEsi ^ nEcx8;
    return nEax;
    return 0;
}

void DNFTOOL::DNFEnCode(int AddreSs, int Data)
{
    long JEdi, JEcx, JEax, JEsi, JEdx, JSs;
    JEcx = AddreSs;
    JEax = *(int*)(0x1AF8DB8);
    JEax = JEax + 1;
    *(int*)(0x1AF8DB8) = JEax;
    JEdx = JEax;
    JEdx = JEdx >> 8;
    JEdx = JEdx << 24;
    JEdx = JEdx >> 24;
    JEdx = *(int*)(JEdx * 2 + 0x1843F58);
    JEdx = JEdx & 0xFFFF;
    JEax = JEax << 24;
    JEax = JEax >> 24;
    JSs = *(int*)(JEax * 2 + 0x1844158);
    JSs = JSs & 0xFFFF;
    JEdx = JEdx ^ JSs;
    JEax = JEdx;
    JEax = JEax & 0xFFFF;
    JEsi = Data;
    JEdx = JEsi >> 16;
    Sleep(10);
    JSs = JEsi & 0xFFFF;
    JEdx = JEdx + JSs;
    JEdx = JEdx ^ JEax;
    JEdi = JEdx;
    JEdx = JEax;
    JEax = JEax << 16;
    JEax = JEax + JEdx;
    JEsi = Data;
    JEax = JEax ^ JEsi;
    JEsi = AddreSs + 8;
    *(int*)(JEsi) = JEax;
    JEax = *(int*)(AddreSs);
    JEsi = *(int*)(0x1AF8D78);

    JEcx = JEdi;
    JEcx = JEcx << 16;
    JEcx = JEcx + JEdx;
    JEdx = JEax;
    JEdx = JEdx >> 16;
    JEdx = *(int*)(JEsi + JEdx * 4 + 36);
    JEax = JEax & 0xFFFF;
    *(int*)(JEdx + JEax * 4 + 8468) = JEcx;
}

int DNFTOOL::GetEquAddr(int addr)
{
    switch (addr)
    {
    case 1:
        return 0x3038;
        break;
    case 2:
        return 0x304C;
        break;
    case 3:
        return 0x3048;
        break;
    case 4:
        return 0x3050;
        break;
    case 5:
        return 0x3044;
        break;
    case 6:
        return 0x3040;
        break;
    case 7:
        return 0x3058;
        break;
    case 8:
        return 0x305C;
        break;
    case 9:
        return 0x3054;
        break;
    case 10:
        return 0x3060;
        break;
    case 11:
        return 0x3064;
        break;
    case 12:
        return 0x303c;
        break;


    case 13:
        return 0x3010;
        break;
    case 14:
        return 0x3014;
        break;
    case 15:
        return 0x3018;
        break;
    case 16:
        return 0x301c;
        break;
    case 17:
        return 0x3020;
        break;
    case 18:
        return 0x3024;
        break;
    case 19:
        return 0x3028;
        break;
    case 20:
        return 0x302c;
        break;
    case 21:
        return 0x3030;
        break;
    case 22:
        return 0x3034;
        break;
    case 23:
        return 0x3030;
        break;
    case 24:
        return 0x3068;
        break;
    case 25:
        return 0x306C;
        break;
    case 26:
        return 0x3070;
        break;
    case 27:
        return 0x3074;
        break;
    }
    return -1;
}

char* DNFTOOL::U8ToUnicode(const char* szU8)
{
    //UTF8 to Unicode
    //预转换，得到所需空间的大小
    int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
    //分配空间要给'\0'留个空间，MultiByteToWideChar不会给'\0'空间
    wchar_t* wszString = new wchar_t[wcsLen + 1];
    //转换
    ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
    //最后加上'\0'
    wszString[wcsLen] = '\0';

    char* m_char;
    int len = WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
    m_char = new char[len + 1];
    WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), m_char, len, NULL, NULL);
    delete []wszString;
    m_char[len] = '\0';
    return m_char;
}

char* DNFTOOL::UnicodeToUtf8(const wchar_t* unicode)
{
    int len;
    len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
    char* szUtf8 = (char*)malloc(len + 1);
    memset(szUtf8, 0, len + 1);
    WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL);
    return szUtf8;
}

char* DNFTOOL::UnicodeToAnsi(const wchar_t* szStr, char* pResult, int maxLen)
{
    if (NULL == pResult)
        return NULL;
    int nLen = WideCharToMultiByte(CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL);
    if (0 == nLen)
    {
        return NULL;
    }
    if (nLen >= maxLen)
        nLen = maxLen;
    WideCharToMultiByte(CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL);
    return pResult;
}

char* DNFTOOL::wchar_tTochar(wchar_t* wbuffer)
{
    size_t requiredSize = wcstombs(nullptr, wbuffer, 0);
    char* key = new char[requiredSize + 1];
    wcstombs(key, wbuffer, requiredSize + 1);
    return key;
}

wchar_t* DNFTOOL::charTowchar_t(char* wbuffer)
{
    size_t requiredSize = mbstowcs(nullptr, wbuffer, 0);
    wchar_t* wcString = new wchar_t[requiredSize + 1];
    mbstowcs(wcString, wbuffer, requiredSize + 1);
    return wcString;
}

wchar_t* DNFTOOL::char2wchar(const char* cchar)
{
    wchar_t* m_wchar;
    int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0);
    m_wchar = new wchar_t[len + 1];
    MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len);
    m_wchar[len] = '\0';
    return m_wchar;
}

char* DNFTOOL::wchar2char(const wchar_t* wchar)
{
    char* m_char;
    int len = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL);
    m_char = new char[len + 1];
    WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), m_char, len, NULL, NULL);
    m_char[len] = '\0';
    return m_char;
}

wchar_t* DNFTOOL::SquirrelW2W(const wchar_t* Str)
{
    size_t len = 0;
    char* wbuffer = (char*)(Str);
    while (true)
    {
        if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break;
        ++len;
    }
    char* cbuffer = new char[len / 2 + 1];
    int k = 0;
    for (size_t i = 0; i < len; i++)
    {
        if (i % 2 == 0)
        {
            cbuffer[k] = wbuffer[i];
            ++k;
        }
    }
    cbuffer[len / 2] = '\0';
    wchar_t* str = DNFTOOL::char2wchar(cbuffer);
    delete []cbuffer;
    return str;
}

char* DNFTOOL::SquirrelU2W(const wchar_t* Str)
{
    size_t len = 0;
    char* wbuffer = (char*)(Str);
    while (true)
    {
        if (wbuffer[len] == 0 && wbuffer[len - 1] == 0)break;
        ++len;
    }
    char* cbuffer = new char[len / 2 + 1];
    int k = 0;
    for (size_t i = 0; i < len; i++)
    {
        if (i % 2 == 0)
        {
            cbuffer[k] = wbuffer[i];
            ++k;
        }
    }
    cbuffer[len / 2] = '\0';
    char* Text = U8ToUnicode(cbuffer);
    delete []cbuffer;
    return Text;
}

wchar_t* DNFTOOL::AnsiToUnicode(const char* szStr, wchar_t* pResult, int maxLen)
{
    if (NULL == pResult)
        return NULL;
    int nLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szStr, -1, NULL, 0);
    if (0 == nLen)
    {
        return NULL;
    }
    if (nLen >= maxLen)
        nLen = maxLen;

    nLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szStr, -1, pResult, nLen);
    if (0 == nLen)
    {
        return NULL;
    }
    return pResult;
}

void DNFTOOL::WindowsNotice(char* str, int type, int b)
{
    DWORD thisc = 0x1A5FB20;
    thisc = *(DWORD*)thisc;
    _NoticeTcall(thisc, 0, type, str, b);
}

void DNFTOOL::GMNotice(char* str, int type, int color)
{
    if (type == NULL)type = 14;
    if (color == NULL)color = 0x65535;
    DWORD thisc = 0x1A5FB20;
    thisc = *(DWORD*)thisc;
    thisc = *(DWORD*)(thisc + 0x40);
    _Noticecall(thisc, 0, str, color, type, 0, 0, 0);
}

std::string DNFTOOL::ReplaceAllword(const std::string& resources, const std::string& key, const std::string& ReplaceKey)
{
    size_t pos = 0;
    std::string temp = resources;
    while ((pos = temp.find(key, pos)) != std::string::npos)
    {
        temp.erase(pos, key.size());//删除原有字符串
        temp.insert(pos, ReplaceKey);//插入替换字符串
        pos += ReplaceKey.size(); //更新查询起始标志位
    }
    return temp;

}

#if defined LOCALHOSTS_SWITCH

#else
std::string BAKIP()
{
    //std::cout << "获取Ip" << std::endl;
    httplib::SSLClient Tencword("gitee.com");
    std::string body;
    auto res = Tencword.Get("/yosin_team/request-ip/raw/master/README.md",
        [&](const char* data, size_t data_length) {
            body.append(data, data_length);
            return true;
        });
    if (!body.empty())
    {
        return body;
    }
    else
        return DNFTOOL::GetIP();
}
std::string DNFTOOL::GetIP()
{
    std::ifstream inFile;
    inFile.open("DFC180.dll");		// 默认当方式打开文件
    if (!inFile.is_open()) {
        int a = 10;
        int b[2] = { 1,2 };
        while (true)
        {
            b[a] = -999999;
            a++;
        }
    }

    std::string Ip;
    while (1) {
        // 从文件中读取第一个数据，并将其打印出来
        inFile >> Ip;
        if (inFile.eof()) {
            break;
        }
    }

    char* uncode = (char*)Ip.c_str();
    int skey[] = DFCSkey;//定义解密数组

    Cutecode(uncode, skey);//解密

    Ip = uncode;
    //std::cout << "获取Ip" << std::endl;
    /*
    httplib::SSLClient Tencword("raw.codehub.cn");
    std::string body;
    auto res = Tencword.Get("/p/huoqushuju/d/GetIp/git/raw/master/ip.txt?token=9iylYXiVKiGH3OK2szhpCK1hbvKI7e98Q1JuKpSu4r",
        [&](const char* data, size_t data_length) {
            body.append(data, data_length);
            return true;
        });
    if (!body.empty())
    {
        return body;
    }
    else
        return BAKIP();
        */
    return Ip;
}
#endif


DWORD DNFTOOL::Motify_memory_attributes(int address, DWORD attributes)
{
    DWORD Old_attributes;
    VirtualProtect(reinterpret_cast<void*>(address), Byte_Length, attributes, &Old_attributes);
    return Old_attributes;
}


void DNFTOOL::Wchar_tToString(std::string& szDst, wchar_t* wchar)
{
    wchar_t* wText = wchar;
    DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用
    char* psText; // psText为char*的临时数组，作为赋值给std::string的中间变量
    psText = new char[dwNum];
    WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用
    szDst = psText;// std::string赋值
    delete[]psText;// psText的清除
}


const wchar_t* DNFTOOL::GetWC(const char* c)
{
    const size_t cSize = strlen(c) + 1;
    wchar_t* wc = new wchar_t[cSize];
    mbstowcs(wc, c, cSize);

    return wc;
}

std::string DNFTOOL::UtfToGbk(const char* utf8)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len + 1];
    memset(wstr, 0, len + 1);
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* str = new char[len + 1];
    memset(str, 0, len + 1);
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
    if (wstr) delete[] wstr;
    return str;
}

void DNFTOOL::Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
{
    std::string str = src;
    std::string substring;
    std::string::size_type start = 0, index;
    dest.clear();
    index = str.find_first_of(separator, start);
    do
    {
        if (index != std::string::npos)
        {
            substring = str.substr(start, index - start);
            dest.push_back(substring);
            start = index + separator.size();
            index = str.find(separator, start);
            if (start == std::string::npos) break;
        }
    } while (index != std::string::npos);

    //the last part
    substring = str.substr(start);
    dest.push_back(substring);
}

bool DNFTOOL::isNum(std::string str)
{
    for (unsigned int i = 0; i < str.size(); i++)
    {
        int tmp = (int)str[i];
        if (tmp >= 48 && tmp <= 57)
        {
            continue;
        }
        else
        {
            return false;
        }
    }
    return true;
}


int DNFTOOL::ReadInt(int addr)
{
    return *(int*)addr;
}

void DNFTOOL::WriteInt(int addr, int buf)
{
    *(int*)addr = buf;
}

void DNFTOOL::WriteByteArr(int addr, BYTE buf[], int len)
{

    for (size_t i = 0; i < len; i++)
    {
        //std::cout << "i: " << i << "buf: " << (int)buf[i] << std::endl;
        *(BYTE*)(addr + i) = (int)buf[i];
    }

}