Jump to content

Fix Reading locale_string.txt (on Channel Booting)


Recommended Posts

  • Developer

This release contain a new function which reading the  locale_string.txt on channel booting.
The default ymir's reading function is one of the best example of bad practice (open a .txt file as binary to reading text?).

There the difference between my func and the ymir's func (in the image)

TO USE FIX MUST HAVE C++11

 

Spoiler

service.h or CommonDefines.h


#define ENABLE_NEW_LOCALE_STRING_READING

locale.cpp

 

//at the beginning


#include <fstream>
#include <stdlib.h>


//SEARCH: 


void locale_init(const char *filename)
{
    FILE        *fp = fopen(filename, "rb");
    char        *buf;

    if (!fp) return;

    fseek(fp, 0L, SEEK_END);
    int i = ftell(fp);
    fseek(fp, 0L, SEEK_SET);

    i++;

    buf = M2_NEW char[i];

    memset(buf, 0, i);

    fread(buf, i - 1, sizeof(char), fp);

    fclose(fp);

    const char * tmp;
    const char * end;

    char *    strings[NUM_LOCALES];

    if (!buf)
    {
        sys_err("locale_read: no file %s", filename);
        exit(1);
    }

    tmp = buf;

    do
    {
        for (i = 0; i < NUM_LOCALES; i++)
            strings[i] = NULL;

        if (*tmp == '"')
        {
            for (i = 0; i < NUM_LOCALES; i++)
            {
                if (!(end = quote_find_end(tmp)))
                    break;

                strings[i] = locale_convert(tmp, end - tmp);
                tmp = ++end;

                while (*tmp == '\n' || *tmp == '\r' || *tmp == ' ') tmp++;

                if (i + 1 == NUM_LOCALES)
                    break;

                if (*tmp != '"')
                {
                    sys_err("locale_init: invalid format filename %s", filename);
                    break;
                }
            }

            if (strings[0] == NULL || strings[1] == NULL)
                break;

            locale_add((const char**)strings);

            for (i = 0; i < NUM_LOCALES; i++)
                if (strings[i])
                    M2_DELETE_ARRAY(strings[i]);
        }
        else
        {
            tmp = strchr(tmp, '\n');

            if (tmp)
                tmp++;
        }
    }
    while (tmp && *tmp);

    M2_DELETE_ARRAY(buf);
}

//REPLACE WITH


#ifdef ENABLE_NEW_LOCALE_STRING_READING
void locale_init(const char *filename)
{
    
    auto printError = [] (const char* fmt, ...) -> void {
        char szBuffer[400] = {};

        va_list args;

        va_start(args, fmt);
            vsnprintf(szBuffer, sizeof(szBuffer), fmt, args);
        va_end(args);

        fprintf(stderr, "%s\n", szBuffer);
    };
    

    auto isOutString = [](size_t pos) -> bool {
        return pos==std::string::npos;
    };

    auto isEmptyString = [&isOutString](const std::string& line) ->bool {
        return isOutString(line.find_first_not_of(" \t\r\n"));
    };

    auto getToken = [&isOutString](std::string& line) -> std::string {
        size_t first    = line.find("\"");
        size_t last        = line.find_last_of("\"");

        if( first == last || isOutString(first) || isOutString(last) || first == line.length()-1)
            return "";

        first++;
        return line.substr(first, (last-first));
    };


    //initialize two empty container strings
    std::string header="",line="";

    std::ifstream localestringfile(filename);
    if (!localestringfile.is_open())
    {
        printError("CANNOT OPEN LOCALE_STRING FILE! [%s] -ERROR",filename);
        return;
    }


    int lineIndex =0;
    while (std::getline(localestringfile, line))
    {
        lineIndex++;
        size_t commentIndex = line.find("///");

        if(!isOutString(commentIndex))
            line = line.substr(0,commentIndex);

        if(isEmptyString(line))
            continue;


        std::string token = getToken(line);
        if (isEmptyString(token))
        {
            printError("LOCALE STRING WRONG SYNTAX AT LINE %d - ERROR ", lineIndex);
            return;
        }


        if(header.empty())
            header = token;

        else
        {
            if(localeString.find(header) != localeString.end())
                printError("LOCALE STRING - DOUBLE HEADER FOUND. (header [%s] , line index %d) - WARNING", header.c_str() , lineIndex);

            //printError("header [%s]\nval [%s]\n",header.c_str(), token.c_str());

            localeString[header] = token;
            header = "";
        }
    }

    if(!header.empty())
        printError("LOCALE STRING : !HEADER.EMPTY (bad reading) -ERROR");

    else
        printError("LOCALE STRING : LOADED %u elements in %d lines .",localeString.size() , lineIndex);

}
#else
void locale_init(const char *filename)
{
    FILE        *fp = fopen(filename, "rb");
    char        *buf;

    if (!fp) return;

    fseek(fp, 0L, SEEK_END);
    int i = ftell(fp);
    fseek(fp, 0L, SEEK_SET);

    i++;

    buf = M2_NEW char[i];

    memset(buf, 0, i);

    fread(buf, i - 1, sizeof(char), fp);

    fclose(fp);

    const char * tmp;
    const char * end;

    char *    strings[NUM_LOCALES];

    if (!buf)
    {
        sys_err("locale_read: no file %s", filename);
        exit(1);
    }

    tmp = buf;

    do
    {
        for (i = 0; i < NUM_LOCALES; i++)
            strings[i] = NULL;

        if (*tmp == '"')
        {
            for (i = 0; i < NUM_LOCALES; i++)
            {
                if (!(end = quote_find_end(tmp)))
                    break;

                strings[i] = locale_convert(tmp, end - tmp);
                tmp = ++end;

                while (*tmp == '\n' || *tmp == '\r' || *tmp == ' ') tmp++;

                if (i + 1 == NUM_LOCALES)
                    break;

                if (*tmp != '"')
                {
                    sys_err("locale_init: invalid format filename %s", filename);
                    break;
                }
            }

            if (strings[0] == NULL || strings[1] == NULL)
                break;

            locale_add((const char**)strings);

            for (i = 0; i < NUM_LOCALES; i++)
                if (strings[i])
                    M2_DELETE_ARRAY(strings[i]);
        }
        else
        {
            tmp = strchr(tmp, '\n');

            if (tmp)
                tmp++;
        }
    }
    while (tmp && *tmp);

    M2_DELETE_ARRAY(buf);
}
#endif


 

 

 

 



This is the hidden content, please

Cattura.PNG

  • Metin2 Dev 43
  • Confused 1
  • Lmao 1
  • Good 8
  • Love 22

My youtube channel  on which you can see my works here

Link to comment
Share on other sites

  • 3 weeks later...
  • Developer
On 6/24/2019 at 8:44 AM, Helia01 said:

Like but....
My opinion: Your function is shit (sry dude) bacause GF Function read locale_string.txt and locale_quest.txt on CLIENT SIDE not SERVER SIDE ;)
We implemented it a couple of months ago in our project.

ahah like if say :
"[Mercedes]   [ is a shit]   because    [Pagani exists]."

"[Your function]   [is shit (sry dude)]   bacause   [GF Function read locale_string.txt and locale_quest.txt on CLIENT SIDE not SERVER SIDE] "

I think you didn't understand the changes i made relative the original function.

Anyway , ok 

  • Love 6

My youtube channel  on which you can see my works here

Link to comment
Share on other sites

  • 7 months later...
  • 2 years later...

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.