• 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!

C++ Crash server tfs 1.2 [I can pay for fix]

Lais Prad

Disgusting Scammer
Joined
Apr 12, 2017
Messages
153
Solutions
6
Reaction score
15
Hi, today my server crashed randomly, I run the gdb and got this:

Code:
C++:
void ProtocolGame::updateCoinBalance()
{
    NetworkMessage msg;
    msg.addByte(0xF2);
    msg.addByte(0x00);

    writeToOutputBuffer(msg);

    g_dispatcher.addTask(
        createTask(std::bind([](ProtocolGame_ptr client) {
          /*ERROR LINE:1953*/ auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
            client->player->coinBalance = coinBalance;

            client->sendCoinBalance();
        }, getThis()))
    );
}


CRASH LOG:
C++:
(gdb) bt full
#0  0x00000000005747ac in operator() (__closure=<optimized out>, client=...) at protocolgame.cpp:1953
        coinBalance = <optimized out>
#1  __call<void, 0ul> (__args=<optimized out>, this=<optimized out>) at /usr/include/c++/4.8/functional:1296
No locals.
#2  operator()<, void> (this=<optimized out>) at /usr/include/c++/4.8/functional:1355
No locals.
#3  std::_Function_handler<void(), std::_Bind<ProtocolGame::updateCoinBalance()::__lambda2(std::shared_ptr<ProtocolGame>)> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/4.8/functional:2071
No locals.
#4  0x00000000005ab708 in operator() (this=0x26275ab0) at /usr/include/c++/4.8/functional:2471
No locals.
#5  operator() (this=0x26275aa0) at tasks.h:42
No locals.
#6  Dispatcher::threadMain (this=0x843a60 <g_dispatcher>) at tasks.cpp:50
        task = 0x26275aa0
        taskLockUnique = {_M_device = 0x843a78 <g_dispatcher+24>, _M_owns = false}
#7  0x0000709c1d161a60 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#8  0x0000709c1c199184 in start_thread (arg=0x709c1c093700) at pthread_create.c:312
        __res = <optimized out>
        pd = 0x709c1c093700
        now = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {123815787575040, -3997874979966072208, 0, 0, 123815787575744, 123815787575040,
---Type <return> to continue, or q <return> to quit---
                3007430321369205360, 3007430177759775344}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0,
              cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
        pagesize_m1 = <optimized out>
        sp = <optimized out>
        freesize = <optimized out>
        __PRETTY_FUNCTION__ = "start_thread"
#9  0x0000709c1c8c9bed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
No locals.

Would anyone know why crash and repair please? I can pay if someone know fix 100%..
 
Solution
This is from my code and seems to work. :)
C++:
void ProtocolGame::updateCoinBalance()
{
    NetworkMessage msg;
    msg.AddByte(0xF2);
    msg.AddByte(0x00);

    writeToOutputBuffer(msg);

    g_dispatcher.addTask(
            createTask(std::bind([](ProtocolGame* client) {
                if (client) {
                    auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
                    client->player->coinBalance = coinBalance;
                    client->sendCoinBalance();
                }
            }, this))
    );
}
void ProtocolGame::sendCoinBalance()
{
   NetworkMessage msg;
   msg.AddByte(0xF2);
   msg.AddByte(0x01);

   msg.AddByte(0xDF);
   msg.AddByte(0x01)...
Are you sure this comes from unchanged TFS 1.2? I did check the git repo of TFS and there's no such function anywhere there. Do you have the source code for your server app?

#Edit

I just found this pull request ([WIP] Store System by brunominervino · Pull Request #2143 · otland/forgottenserver · GitHub) for store-ingame, but it seems not to be merged into TFS repo as of now.

You should mention that in your thread to begin with. Then again, do you have the source code for it?

#Edit2

Check tbe post below. This may be one of the reasons this pull request will get rejected.
 
Last edited:
That's not a good idea to pass ProtocolGame to dispatcher. You should pass playerId instead.
Hum.. I dont have knowledge for solve this, but I found another updatecoins:
(I do not know if it will work correctly in my sourcer, the best would be to edit from the code I posted above, if u can help ...)

C++:
void ProtocolGame::sendUpdatedCoinBalance()
{
    NetworkMessage msg;
    msg.addByte(0xF2); //balanceupdating
    msg.addByte(0x01); //this is not the end

    msg.addByte(0xDF); //coinBalance opcode
    msg.addByte(0x01); //as follows

    uint32_t  playerCoinBalance = IOAccount::getCoinBalance(player->getAccount());

    msg.add<uint32_t>(playerCoinBalance);
    msg.add<uint32_t>(playerCoinBalance); //I don't know why this duplicated entry is needed but... better keep it there

    writeToOutputBuffer(msg);
}
 
Well, I wish I could help you, but I'm afraid that this is simply not enough, at least for me, since I'm not that familiar with OTserv structure, I'd need to compile it myself with no optimizations and debug. If you have source code for what version of TFS you use then great, I can give it a try. Otherwise I'm afraid you'll have to rely on someone else (or wait until the PR I've shown you has been tested and fixed).
 
This is from my code and seems to work. :)
C++:
void ProtocolGame::updateCoinBalance()
{
    NetworkMessage msg;
    msg.AddByte(0xF2);
    msg.AddByte(0x00);

    writeToOutputBuffer(msg);

    g_dispatcher.addTask(
            createTask(std::bind([](ProtocolGame* client) {
                if (client) {
                    auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
                    client->player->coinBalance = coinBalance;
                    client->sendCoinBalance();
                }
            }, this))
    );
}
void ProtocolGame::sendCoinBalance()
{
   NetworkMessage msg;
   msg.AddByte(0xF2);
   msg.AddByte(0x01);

   msg.AddByte(0xDF);
   msg.AddByte(0x01);

   msg.add<uint32_t>(player->coinBalance); //total coins
   msg.add<uint32_t>(player->coinBalance); //transferable coins

   writeToOutputBuffer(msg);
}
 
Solution
This is from my code and seems to work. :)
C++:
void ProtocolGame::updateCoinBalance()
{
    NetworkMessage msg;
    msg.AddByte(0xF2);
    msg.AddByte(0x00);

    writeToOutputBuffer(msg);

    g_dispatcher.addTask(
            createTask(std::bind([](ProtocolGame* client) {
                if (client) {
                    auto coinBalance = IOAccount::getCoinBalance(client->player->getAccount());
                    client->player->coinBalance = coinBalance;
                    client->sendCoinBalance();
                }
            }, this))
    );
}
void ProtocolGame::sendCoinBalance()
{
   NetworkMessage msg;
   msg.AddByte(0xF2);
   msg.AddByte(0x01);

   msg.AddByte(0xDF);
   msg.AddByte(0x01);

   msg.add<uint32_t>(player->coinBalance); //total coins
   msg.add<uint32_t>(player->coinBalance); //transferable coins

   writeToOutputBuffer(msg);
}
I'll test man, thanks so much

edit: When I test I'll mark the best awnser if works good xD
 
Last edited:
Back
Top