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

Solved Crash with Fir3elements 0.4 - Cast System (Log Provided)

vinera0ot

Banned User
Joined
Oct 11, 2019
Messages
48
Reaction score
16
Last edited:
Crash Information:
When 2 players close the cast in same time server crashes

@Fir3element - Any ideas what could be causing this?
@Gesior.pl - And already done this step: Merge pull request #1 from gesior/cast_system_crash_fix · Fir3element/3777@29eb7a6 (https://github.com/Fir3element/3777/commit/29eb7a67e6994950687967f5afb69c39b04dd622)
and still server crashes


C++:
bool getCastingState() const {return cast.isCasting;};
        virtual const std::string& getCastingPassword() const {return cast.password;};

        PlayerCast getCast() {return cast;}

        void setCasting(bool c);
        void setCastPassword(std::string p) {cast.password = p;};

        void setCastDescription(std::string desc) {cast.description = desc;}

        virtual const std::string& getCastDescription() const {return cast.description;}

        void addCastViewer(ProtocolGame* pg)
        {
            cSpectators[nextSpectator] = pg;
            nextSpectator++;

            std::stringstream ss;
            ss << "Viewer " << cast.curId;
            pg->viewerName = ss.str().c_str();
            cast.curId++;
        }

        void removeCastViewer(uint32_t id) {cSpectators.erase(id);}

        uint32_t getCastIpByName(std::string n)
        {
            for(AutoList<ProtocolGame>::iterator it = cSpectators.begin(); it != cSpectators.end(); ++it)
            {
                if(it->second->getViewerName() == n && it->second->getPlayer() == this)
                    return it->second->getIP();
            }
            return false;
        }

        uint32_t getCastViewerCount()
        {
            uint32_t count = 0;
            for(AutoList<ProtocolGame>::iterator it = cSpectators.begin(); it != cSpectators.end(); ++it)
                    if(it->second->getPlayer() == this)
                        count++;

            return count;
        }

        void kickCastViewers()
        {
            AutoList<ProtocolGame>::iterator it = cSpectators.begin();
            while (it != cSpectators.end()) {
                if (it->second->getPlayer() == this) {
                    it->second->disconnect();
                    it->second->unRef();
                    it = cSpectators.erase(it);
                } else {
                    ++it;
                }
            }
            cast = PlayerCast();
        }

        void kickCastViewerByName(std::string n)
        {
            for(AutoList<ProtocolGame>::iterator it = cSpectators.begin(); it != cSpectators.end(); ++it) if(it->second->getPlayer() == this)
                if(it->second->getViewerName() == n && it->second->getPlayer() == this)
                {
                    it->second->disconnect();
                    it->second->unRef();
                    removeCastViewer(it->first);
                    return;
                }
        }

C++:
bool ProtocolGame::logout(bool displayEffect, bool forceLogout)
{
    //dispatcher thread
     if(!player)
        return false;
     
    if(getIsCast() && !player->isAccountManager())
    {
        PlayerCast pc = player->getCast();
        for(AutoList<ProtocolGame>::iterator it = Player::cSpectators.begin(); it != Player::cSpectators.end(); ++it)
            if(it->second == this)
                if(Connection_ptr connection = it->second->getConnection())
                {
                    PrivateChatChannel* channel = g_chat.getPrivateChannel(player);
                    if(channel) {
                        channel->talk("", SPEAK_CHANNEL_RA, (getViewerName() + " has left the cast."));
                    }

                    connection->close();
                    player->removeCastViewer(it->first);
                    return false;
                }
        return false;
    }

    if(!player->isRemoved())
    {
        if(!forceLogout)
        {
            if(!IOLoginData::getInstance()->hasCustomFlag(player->getAccount(), PlayerCustomFlag_CanLogoutAnytime))
            {
                if(player->getTile()->hasFlag(TILESTATE_NOLOGOUT))
                {
                    player->sendCancelMessage(RET_YOUCANNOTLOGOUTHERE);
                    return false;
                }

                if(player->getZone() != ZONE_PROTECTION && player->hasCondition(CONDITION_INFIGHT))
                {
                    player->sendCancelMessage(RET_YOUMAYNOTLOGOUTDURINGAFIGHT);
                    return false;
                }

                if(!g_creatureEvents->playerLogout(player, false)) //let the script handle the error message
                    return false;
            }
            else
                g_creatureEvents->playerLogout(player, true);
        }
        else if(!g_creatureEvents->playerLogout(player, true))
            return false;

        if(displayEffect && !player->isGhost())
            g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
    }

    player->kickCastViewers();

    if(Connection_ptr connection = getConnection())
        connection->close();

    if(player->isRemoved())
        return true;

    return g_game.removeCreature(player);
}

OS: Ubuntu 18:04 LTS

Regards and as always, thank you for any help in advance!
How much memory does your VPS have, and how big is your map?
 
Compile in Debug mode, run in Visual Studio and go up in call stack to check what’s the cause of the crash. Put some breakpoints and try once again and try to find cause.
 
Back
Top