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

No Level

yoiker

Member
Joined
Jan 21, 2012
Messages
194
Solutions
1
Reaction score
9
Hello, I have these codes of protocolgame.cpp so that when the player with access not show the level and the player without access yes.

If it works, but when a Monsters says the voices gives me debug both the god and the player

Here codes:

Code:
void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, const Position* pos/* = nullptr*/)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);

    msg.addString(creature->getName());

    //Add level only for players
    const Player* playerSpeak = creature->getPlayer();

    if (const Player* speaker = creature->getPlayer()) {
        if (!playerSpeak->isAccessPlayer()) {
        msg.add<uint16_t>(speaker->getLevel());
    } else {
        msg.add<uint16_t>(0x00);
    }
    }

    msg.addByte(type);
    if (pos) {
        msg.addPosition(*pos);
    } else {
        msg.addPosition(creature->getPosition());
    }

    msg.addString(text);
    writeToOutputBuffer(msg);
}

void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    const Player* playerSpeak = creature->getPlayer();

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (!creature) {
        msg.add<uint32_t>(0x00);
    } else if (type == TALKTYPE_CHANNEL_R2) {
        msg.add<uint32_t>(0x00);
        type = TALKTYPE_CHANNEL_R1;
    } else {
        msg.addString(creature->getName());
        //Add level only for players
        if (const Player* speaker = creature->getPlayer()) {
            if (!playerSpeak->isAccessPlayer()) {
                msg.add<uint16_t>(speaker->getLevel());
            } else {
                msg.add<uint16_t>(0x00);
            }
        }
    }

    msg.addByte(type);
    msg.add<uint16_t>(channelId);
    msg.addString(text);
    writeToOutputBuffer(msg);
}

void ProtocolGame::sendPrivateMessage(const Player* speaker, SpeakClasses type, const std::string& text)
{
    NetworkMessage msg;
    msg.addByte(0xAA);
    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (speaker) {
        msg.addString(speaker->getName());
        if (const Player* playerSpeak = speaker->getPlayer()) {
        if (!playerSpeak->isAccessPlayer()) {
            msg.add<uint16_t>(speaker->getLevel());
        } else {
            msg.add<uint32_t>(0x00);
        }
        }
    }
    msg.addByte(type);
    msg.addString(text);
    writeToOutputBuffer(msg);
}

Any solution? Please.
 
Problem is here in sendCreatureSay, you copied this code from somewhere but didn't indent it properly which makes it hard to distinguish its execution. Plus you have some unneeded extra code.
Code:
    const Player* playerSpeak = creature->getPlayer();

    if (const Player* speaker = creature->getPlayer()) {
        if (!playerSpeak->isAccessPlayer()) {
            msg.add<uint16_t>(speaker->getLevel());
        } else {
            msg.add<uint16_t>(0x00);
        }
    }
As you can see from the code above if a creature speaks it won't send the proper data which causes the client to crash. Initially this block of code checks for a player and nothing else. So any other information which is sent isn't handled by the client.

Now in sendToChannel you are doing the same that as you did in the previous method you are excluding everything but player.
Code:
    } else {
        msg.addString(creature->getName());
        //Add level only for players
        if (const Player* speaker = creature->getPlayer()) {
            if (!playerSpeak->isAccessPlayer()) {
                msg.add<uint16_t>(speaker->getLevel());
            } else {
                msg.add<uint16_t>(0x00);
            }
        }
    }
Again in sendPrivateMessage, you are excluding everyone but the player.
Code:
    if (speaker) {
        msg.addString(speaker->getName());
        if (const Player* playerSpeak = speaker->getPlayer()) {
            if (!playerSpeak->isAccessPlayer()) {
                msg.add<uint16_t>(speaker->getLevel());
            } else {
                msg.add<uint32_t>(0x00);
            }
        }
    }
This is why the client is crashing regardless of the access level of the player when a non-player speaks.
 
Now this should work and not crash the client.
Code:
void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, const Position* pos/* = nullptr*/)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);

    msg.addString(creature->getName());

    //Add level only for players
    if (const Player* speaker = creature->getPlayer()) {
        if (!speaker->isAccessPlayer()) {
            msg.add<uint16_t>(speaker->getLevel());
        } else {
            msg.add<uint16_t>(0x00);
        }
    }
    else {
        msg.add<uint16_t>(0x00);
    }

    msg.addByte(type);
    if (pos) {
        msg.addPosition(*pos);
    } else {
        msg.addPosition(creature->getPosition());
    }

    msg.addString(text);
    writeToOutputBuffer(msg);
}

void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId)
{
    NetworkMessage msg;
    msg.addByte(0xAA);

    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (!creature) {
        msg.add<uint32_t>(0x00);
    } else if (type == TALKTYPE_CHANNEL_R2) {
        msg.add<uint32_t>(0x00);
        type = TALKTYPE_CHANNEL_R1;
    } else {
        msg.addString(creature->getName());
        //Add level only for players
        if (const Player* speaker = creature->getPlayer()) {
            if (!speaker->isAccessPlayer()) {
                msg.add<uint16_t>(speaker->getLevel());
            }else{
                msg.add<uint16_t>(0x00);
            }
        } else {
            msg.add<uint16_t>(0x00);
        }
       
    }

    msg.addByte(type);
    msg.add<uint16_t>(channelId);
    msg.addString(text);
    writeToOutputBuffer(msg);
}

void ProtocolGame::sendPrivateMessage(const Player* speaker, SpeakClasses type, const std::string& text)
{
    NetworkMessage msg;
    msg.addByte(0xAA);
    static uint32_t statementId = 0;
    msg.add<uint32_t>(++statementId);
    if (speaker) {
        msg.addString(speaker->getName());
        if (!speaker->isAccessPlayer()){
            msg.add<uint16_t>(speaker->getLevel());
        }else{
            msg.add<uint32_t>(0x00);
        }
    } else {
        msg.add<uint32_t>(0x00);
    }
    msg.addByte(type);
    msg.addString(text);
    writeToOutputBuffer(msg);
}
 
Crash the client when a player or god send private message to another player private or god
any solution? :D
 
Back
Top