• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Programmer TFS [0.4] Storage overflow bug [PAID JOB]

Mr.Caffeine

Active Member
Joined
Nov 4, 2018
Messages
79
Reaction score
43
As is known by many there is a storage overflow bug in old versions (tfs.03+) which ends up random changing the storage value to weird characters.
On my server in particular, this bug is pretty rare. Still it's a very annoying bug that needs to be fixed without band-aid solutions
This bug usually occurs when storages are set constantly. Like storages that count monster kills.

For more information on how this bug happens, there are reports in these threads:

I am willing to pay well for this solution if you think you can solve this problem please send me your discord pm.
I will also be sharing the solution with the community if the person that helps me allow it, of course.
 
how to reproduce the issue ?
I don't know how to reproduce. The bug happens randomly. Sometimes it can go hours without happening, sometimes it happens in sequence. The only pattern I've noticed is that it tends to happen in storages that are added frequently. Like counter for monster kills


Does not work. When I change to int what happens is that weird string chars no longer appear in the value. But the storages keep with the bug, resetting.

I'm still looking for someone to solve this problem.
 
I don't know how to reproduce. The bug happens randomly. Sometimes it can go hours without happening, sometimes it happens in sequence. The only pattern I've noticed is that it tends to happen in storages that are added frequently. Like counter for monster kills



Does not work. When I change to int what happens is that weird string chars no longer appear in the value. But the storages keep with the bug, resetting.

I'm still looking for someone to solve this problem.
To make sure I understand; you delete storage table, then restore table with INT; then test in-game and it sets special chars again?
 
it happen to me too, if u find out how to fix it, pls share with the community ;)
 
To make sure I understand; you delete storage table, then restore table with INT; then test in-game and it sets special chars again?
Does not solve, in fact this problem exists since the day one in my server, when the databases were empty

it happen to me too, if u find out how to fix it, pls share with the community ;)

For sure, as soon as I find a way or someone who can help me to fix the problem, I'll be sharing it here
 
Does not solve, in fact this problem exists since the day one in my server, when the databases were empty



For sure, as soon as I find a way or someone who can help me to fix the problem, I'll be sharing it here

change to int is not a work around?
i mean, if u use only ints in your storages values it would be fine, right?
 
change to int is not a work around?
i mean, if u use only ints in your storages values it would be fine, right?
Just changing it to int doesn't fix it. You will no longer have the strange character bug appearing in the storage, but the storage bug will continue to happen resetting the value
 
Just changing it to int doesn't fix it. You will no longer have the strange character bug appearing in the storage, but the storage bug will continue to happen resetting the value

but if the player relog it wont save
not saying that it solve the problem
but its a work around
 
As promised, sharing the storage overflow fix with the community.
Roddet pointed this fix on the OTX-2. I made a small change to the code to fix the problem on my TFS 0.x version.

In luascript.cpp
after
C:
enum
{
    EVENT_ID_LOADING = 1,
    EVENT_ID_USER = 1000,
};
add:
C:
enum STR2INT_ERROR
{
    SUCCESS,
    OVERFLOWS,
    UNDERFLOWS,
    INCONVERTIBLE
};

STR2INT_ERROR str2int(int32_t& i, char const* s, int32_t base = 0)
{
    char* end;
    long  l;
    errno = 0;
    l = strtol(s, &end, base);
    if((errno == ERANGE && l == LONG_MAX) || l > INT_MAX) {
        return OVERFLOWS;
    }
    if((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) {
        return UNDERFLOWS;
    }
    if(*s == '\0' || *end != '\0') {
        return INCONVERTIBLE;
    }
    i = l;
    return SUCCESS;
}

in luascript.cpp replace the whole function luaGetCreatureStorage
C:
int32_t LuaScriptInterface::luaGetCreatureStorage(lua_State* L)
{
    //getCreatureStorage(cid, key)
    uint32_t key = popNumber(L);
    ScriptEnviroment* env = getEnv();
    if(Creature* creature = env->getCreatureByUID(popNumber(L)))
    {
        std::string strValue;
        if(creature->getStorage(key, strValue))
        {
            int32_t intValue;
            STR2INT_ERROR ret = str2int(intValue, strValue.c_str(), 10);
            
            if(ret == SUCCESS) { // The value was successfully converted to a number
                lua_pushnumber(L, intValue);
                } else if(ret == OVERFLOWS) {// The value will overflow, so we'll return the maximum possible value.
                std::clog << "[Warning - getCreatureStorage] The " << std::string(creature->getPlayer() ? " player [" : " creature [") << creature->getName() << "] has exceeded the MAXIMUM value for the storage [" << key << "]!" << std::endl;
                lua_pushnumber(L, INT_MAX);
                } else if(ret == UNDERFLOWS) {// The value will underflow, so we'll return the minimum possible value.
                std::clog << "[Warning - getCreatureStorage] The " << std::string(creature->getPlayer() ? " player [" : " creature [") << creature->getName() << "] has exceeded the MINIMUM value for the storage [" << key << "]!" << std::endl;
                lua_pushnumber(L, INT_MIN);
                } else if(ret == INCONVERTIBLE) {// The value cannot be converted to a number, so we'll return a string.
                lua_pushstring(L, strValue.c_str());
            }
        } else
        lua_pushnumber(L, -1);
        } else {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    return 1;
}

and replace the function luaDoCreatureSetStorage
C:
int32_t LuaScriptInterface::luaDoCreatureSetStorage(lua_State* L)
{
    //doCreatureSetStorage(cid, key[, value])
    std::string value;
    bool nil = true;
    if(lua_gettop(L) > 2)
    {
        if(!lua_isnil(L, -1))
        {
            if(lua_isnumber(L, -1)) {
                value = lua_tostring(L, -1);
                popNumber(L);
            }else
            value = popString(L);
            
            nil = false;
        }
        else
        lua_pop(L, 1);
    }
    
    uint32_t key = popNumber(L);
    ScriptEnviroment* env = getEnv();
    if(Creature* creature = env->getCreatureByUID(popNumber(L)))
    {
        if(!nil)
        nil = creature->setStorage(key, value);
        else
        creature->eraseStorage(key);
        
        lua_pushboolean(L, nil);
    }
    else
    {
        errorEx(getError(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushboolean(L, false);
    }
    
    return 1;
}

Long live the TFS 0.x! :)
 
Back
Top