<commit_before>/*
 * AscEmu Framework based on ArcEmu MMORPG Server
 * Copyright (c) 2014-2022 AscEmu Team <http://www.ascemu.org>
 * Copyright (C) 2008-2012 ArcEmu Team <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <Auth/MD5.h>
#include "Auth/AutoPatcher.h"

#ifndef WIN32
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#endif
#include <Logging/Logger.hpp>

PatchMgr& PatchMgr::getInstance()
{
    static PatchMgr mInstance;
    return mInstance;
}

void PatchMgr::initialize()
{
    // load patches
#ifdef WIN32
    sLogger.info("PatchMgr : Loading Patches...");
    char Buffer[MAX_PATH * 10];
    char Buffer2[MAX_PATH * 10];
    char Buffer3[MAX_PATH * 10];

    WIN32_FIND_DATA fd;
    HANDLE fHandle;
    MD5Hash md5;
    Patch* pPatch;
    DWORD size, sizehigh;
    HANDLE hFile;
    uint32 srcversion;
    char locality[5];
    uint32 i;

    if (!GetCurrentDirectory(MAX_PATH * 10, Buffer))
        return;

    strcpy(Buffer2, Buffer);
    strcat(Buffer, "\\ClientPatches\\*.*");
    fHandle = FindFirstFile(Buffer, &fd);
    if (fHandle == INVALID_HANDLE_VALUE)
        return;

    do
    {
        snprintf(Buffer3, MAX_PATH * 10, "%s\\ClientPatches\\%s", Buffer2, fd.cFileName);
        if (sscanf(fd.cFileName, "%4s%u.", locality, &srcversion) != 2)
            continue;

        hFile = CreateFile(Buffer3, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
            continue;

        sLogger.info("PatchMgr : Found patch for %u locale `%s`.", srcversion, locality);
        pPatch = new Patch;
        size = GetFileSize(hFile, &sizehigh);
        pPatch->FileSize = size;
        pPatch->Data = new uint8[size];
        pPatch->Version = srcversion;
        for (i = 0; i < 4; ++i)
            pPatch->Locality[i] = static_cast<char>(tolower(locality[i]));
        pPatch->Locality[4] = 0;
        pPatch->uLocality = *(uint32*)pPatch->Locality;

        if (pPatch->Data == NULL)
        {
            // shouldn't really happen
            delete pPatch;
            CloseHandle(hFile);
            continue;
        }

        // read the whole file
        ASSERT(ReadFile(hFile, pPatch->Data, pPatch->FileSize, &size, NULL));
        ASSERT(size == pPatch->FileSize);

        // close the handle, no longer needed
        CloseHandle(hFile);

        // md5hash the file
        md5.Initialize();
        md5.UpdateData(pPatch->Data, pPatch->FileSize);
        md5.Finalize();
        memcpy(pPatch->MD5, md5.GetDigest(), MD5_DIGEST_LENGTH);

        // add the patch to the patchlist
        m_patches.push_back(pPatch);

    } while (FindNextFile(fHandle, &fd));
    FindClose(fHandle);
#else
    /*
     *nix patch loader
     */
    sLogger.info("PatchMgr : Loading Patches...");
    char Buffer[MAX_PATH * 10];
    char Buffer2[MAX_PATH * 10];
    char Buffer3[MAX_PATH * 10];

    struct dirent** list;
    int filecount;
    int read_fd;
    MD5Hash md5;
    Patch* pPatch;
    int size;
    uint32 srcversion;
    char locality[5];
    uint32 i;
    struct stat sb;

    strcpy(Buffer, "./ClientPatches");
    strcpy(Buffer2, Buffer);

    filecount = scandir("./ClientPatches", &list, 0, 0);
    if (filecount <= 0 || list == NULL)
    {
        sLogger.failure("No patches found.");
        return;
    }

    while (filecount--)
    {
        snprintf(Buffer3, MAX_PATH * 10, "./ClientPatches/%s", list[filecount]->d_name);
        if (sscanf(list[filecount]->d_name, "%4s%u.", locality, &srcversion) != 2)
            continue;

        read_fd = open(Buffer3, O_RDONLY);
        if (read_fd < 0)
        {
            sLogger.failure("Cannot open %s", Buffer3);
            continue;
        }<commit_msg>Use our own definition for maximumg lenght of a path<commit_after>/*
 * AscEmu Framework based on ArcEmu MMORPG Server
 * Copyright (c) 2014-2022 AscEmu Team <http://www.ascemu.org>
 * Copyright (C) 2008-2012 ArcEmu Team <http://www.ArcEmu.org/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <Auth/MD5.h>
#include "Auth/AutoPatcher.h"

#ifndef WIN32
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#endif
#include <Logging/Logger.hpp>

PatchMgr& PatchMgr::getInstance()
{
    static PatchMgr mInstance;
    return mInstance;
}

void PatchMgr::initialize()
{
    // load patches
#ifdef WIN32
    sLogger.info("PatchMgr : Loading Patches...");
    char Buffer[maxPathLength * 10];
    char Buffer2[maxPathLength * 10];
    char Buffer3[maxPathLength * 10];

    WIN32_FIND_DATA fd;
    HANDLE fHandle;
    MD5Hash md5;
    Patch* pPatch;
    DWORD size, sizehigh;
    HANDLE hFile;
    uint32 srcversion;
    char locality[5];
    uint32 i;

    if (!GetCurrentDirectory(maxPathLength * 10, Buffer))
        return;

    strcpy(Buffer2, Buffer);
    strcat(Buffer, "\\ClientPatches\\*.*");
    fHandle = FindFirstFile(Buffer, &fd);
    if (fHandle == INVALID_HANDLE_VALUE)
        return;

    do
    {
        snprintf(Buffer3, maxPathLength * 10, "%s\\ClientPatches\\%s", Buffer2, fd.cFileName);
        if (sscanf(fd.cFileName, "%4s%u.", locality, &srcversion) != 2)
            continue;

        hFile = CreateFile(Buffer3, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
            continue;

        sLogger.info("PatchMgr : Found patch for %u locale `%s`.", srcversion, locality);
        pPatch = new Patch;
        size = GetFileSize(hFile, &sizehigh);
        pPatch->FileSize = size;
        pPatch->Data = new uint8[size];
        pPatch->Version = srcversion;
        for (i = 0; i < 4; ++i)
            pPatch->Locality[i] = static_cast<char>(tolower(locality[i]));
        pPatch->Locality[4] = 0;
        pPatch->uLocality = *(uint32*)pPatch->Locality;

        if (pPatch->Data == NULL)
        {
            // shouldn't really happen
            delete pPatch;
            CloseHandle(hFile);
            continue;
        }

        // read the whole file
        ASSERT(ReadFile(hFile, pPatch->Data, pPatch->FileSize, &size, NULL));
        ASSERT(size == pPatch->FileSize);

        // close the handle, no longer needed
        CloseHandle(hFile);

        // md5hash the file
        md5.Initialize();
        md5.UpdateData(pPatch->Data, pPatch->FileSize);
        md5.Finalize();
        memcpy(pPatch->MD5, md5.GetDigest(), MD5_DIGEST_LENGTH);

        // add the patch to the patchlist
        m_patches.push_back(pPatch);

    } while (FindNextFile(fHandle, &fd));
    FindClose(fHandle);
#else
    /*
     *nix patch loader
     */
    sLogger.info("PatchMgr : Loading Patches...");
    char Buffer[maxPathLength * 10];
    char Buffer2[maxPathLength * 10];
    char Buffer3[maxPathLength * 10];

    struct dirent** list;
    int filecount;
    int read_fd;
    MD5Hash md5;
    Patch* pPatch;
    int size;
    uint32 srcversion;
    char locality[5];
    uint32 i;
    struct stat sb;

    strcpy(Buffer, "./ClientPatches");
    strcpy(Buffer2, Buffer);

    filecount = scandir("./ClientPatches", &list, 0, 0);
    if (filecount <= 0 || list == NULL)
    {
        sLogger.failure("No patches found.");
        return;
    }

    while (filecount--)
    {
        snprintf(Buffer3, maxPathLength * 10, "./ClientPatches/%s", list[filecount]->d_name);
        if (sscanf(list[filecount]->d_name, "%4s%u.", locality, &srcversion) != 2)
            continue;

        read_fd = open(Buffer3, O_RDONLY);
        if (read_fd < 0)
        {
            sLogger.failure("Cannot open %s", Buffer3);
            continue;
        }
{'fraction_non_alphanumeric': 0.12338398729870718, 'fraction_numerical': 0.020639600816511682, 'mean_word_length': 2.584959349593496, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2216083', 'n_tokens_mistral': 2945, 'n_tokens_neox': 2774, 'n_words': 777}