Jump to content

Ikarus_

Developer
  • Posts

    404
  • Joined

  • Last visited

  • Days Won

    20
  • Feedback

    0%

Posts posted by Ikarus_

  1. Added a small fix about 0.X% in mob_drop_item.txt
    now you can use 0.X% in the txt files before to convert it but there is a limit.

    the limit depend on the DROP_SCALE_TABLE value (CONSTANT) 

    for example :
    DROP_SCALE_TABLE = 1000 -> min chance to set in txt 0.1% (100%/1000)
    DROP_SCALE_TABLE = 10000 -> min chance to set in txt 0.01% (100%/10000)

     

    obv DROP_SCALE_TABLE must be same value of DROP_SCALE_TABLE in common/length.h (SEE THE THREAD MESSAGE TO KNOW WHAT IS THIS CONSTANT)

    • Love 1
  2. 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 45
    • Confused 1
    • Lmao 1
    • Good 8
    • Love 22
  3. 22 minutes ago, Syriza said:

    Hey @Ikarus_  thank you for the release Buddy im using it but

    you cant place in probability Point numbers. e.g.: prob: 1.5 (This is very important :S)

     

    the drop tables takes by default chance on 1/1000 (so to make chance 0.1% just add 1 as number)
    you can change the scale to make chance on 1/10.000 or 1/100.000 by changing the number in length.h DROP_SCALE_TABLE

    so you can for example make the drop scale on 10.000 and to make 0.01% chance you need to insert in table 1 as number
    if you need 0.001% chance , you can change drop scale on 100.000 and then you need to insert in table 1 as number

    warning
    max drop scale is 1.000.000 (if you put number > the game automatically reduce it)  because ymir using milions as scale to make drop random numbers.

     

    • Love 1
  4. 14 hours ago, OtherChoice said:

    Oh I see, thank you for your time and collaboration.

    Regards

    And about cache sharing, we could make that but then we need to use method of unconcurrency to make sure the cores access to memory one for time. To make this caching system is useless if done just for this system. it make sense only if you want a big shared cache to use for every game stuff.

    When ymir coded this game, the cache sharing wasn't a standard method, so they decided to use the socket between cores to send "cache part" to other cores, and to make a different cache for every core. When i say cache i mean a method to store info, so about your last question, yeah the best way is to allocate the cache in the heap because there is enoght memory space.The stack relative to heap can allocate directly when the compiler compile the program but the stack size is very limited, the heap can allocate a lot of memory without problem but the allocation is a dynamic allocation so the performaces during the allocation will be smaller.

     

  5. 1 hour ago, OtherChoice said:

    Hello @Ikarus_, i'm interested in the cache part you used designing this system and have a few questions, performance-wise is it better than allocating stuffs on heap and freeing? cache is shared thourgh out every core? and last and more important do you mind if I take some parts of your code for a different system? I will neither sell anything nor copy/paste releasing contents.

    I agree to give you license to get a part of my code.

    Anyway i used STL containers (map, vector) to store data in the cache. The stl containers using heap to store data.

    • Love 1
  6. WARNING:

    i noticed some people think this system is a realtime database reading based system.

    i want explain it better , to make sure every body know how  this system works.

    This system works using caching, it reading the tables once on boot, then the db core will update all core during core boot using cache.
    Only if you want to reload (refreshing the cache) the db core will read again the tables and will send to every core the "update".

    • Love 1
  7. On 5/11/2019 at 11:27 PM, HuNterukh said:

    Personally I would not suggest you to move your data from .txt files to database tables. 

    Keeping the data in a file like .txt or .csv or whatever allows you to integrate it in a versioning system like Git, which is a great advantage. If your simply don’t like the txt file parser written by Ymir, you can anytime convert to a different markup language like json or xml.

    The reasons to use table instead of sample file can be various.

    For example:

    1. I think every body makes periodically database backup to save the data, well you can save the drop data too...

    2. You can use query to get filtered information or to edit multiple lines in one shot.

    3. They are easier to edit.

    4. You can connect these infornations with a wiki in your web site every time 100% uptodate because you are using the same table loaded from game...

    Ad more..

    If you need to integrate the tables in the Git Repo, you can also do it using a dumped file (.sql for example)

  8. M2 Download Center

    This is the hidden content, please
    ( Internal )

    I think the title should explain all.
    The system give way to set mob's drops via tables (Database) instead to use mob_drop_item.txt, common_drop_item.txt, drop_item_group.txt which can be buggy (easly, just a wrong space) without trace any error in your game expirience.

    WARNING : The System doens't disable the txts so you can use the txts and the tables without any problems.


    I have inserted "/reload d" command to reload the drop tables without restart channels.
    i will code a small tool in python to convert the txts to tables (i will be added to the repository).

    The drop chance by default is set to 1/1000 (so in table you should set it to 1000 to give 100% drop chance 'base' , it will change via the ymir's algorithm depend on the levels killer/victim).

    you can chance this scale to use 100 instead 1000 basically changing  in lenght.h the value of DROP_SCALE_TABLE 

    This is the hidden content, please
    you can find the repository.

     

    MySkype: live:ikarus.developer

     

     

    update:
    Added a small part to install only if you are using __SEND_TARGET_INFO__ to show the drop in the target board

     

    WARNING:

    i noticed some people think this system is a realtime database reading based system.

    i want explain it better , to make sure every body know how  this system works.

    This system works using cache, it read the tables once on boot, then the db core setup all core during core boot using cache.
    Only if you want to reload (refreshing the cache) the db core will read again the tables and will send to every core the "update".

    • Metin2 Dev 121
    • kekw 1
    • Dislove 1
    • Angry 2
    • Think 3
    • Confused 1
    • Lmao 1
    • Good 33
    • Love 8
    • Love 87
  9. ok so the next step is to debug the code to know what happen during the town.txt reading.

    search:
     

    sys_log( 0, "LoadMapRegion no empire specific start point" );

     

    change like this:

    sys_log( 0, "LoadMapRegion no empire specific start point ,map index %d  town coordinates x %d  y %d",r_setting.iIndex,iX,iY );

     

    now when you starting the channel services that having the map index in the allow map list (config file) , you can read what was the read coordinates from the town.txt in the syslog file.

×
×
  • 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.