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

Compiling prof and level in the login.

Scrappy Coco

Member
Joined
Dec 27, 2014
Messages
95
Reaction score
17
It is possible that in tfs 1.2

LK3SG.jpg
 
Maybe.. you can try.
Here is code that list characters on account:
https://github.com/otland/forgottenserver/blob/master/src/protocollogin.cpp#L79

As we can see it sends 1 world ID and world name is server name. You must send more world names (and put there description of characters).

Orginal code:
PHP:
    //Add char list
    output->addByte(0x64);

    output->addByte(1); // number of worlds

    output->addByte(0); // world id
    output->addString(g_config.getString(ConfigManager::SERVER_NAME));
    output->addString(g_config.getString(ConfigManager::IP));
    output->add<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
    output->addByte(0);

    uint8_t size = std::min<size_t>(std::numeric_limits<uint8_t>::max(), account.characters.size());
    output->addByte(size);
    for (uint8_t i = 0; i < size; i++) {
        output->addByte(0);
        output->addString(account.characters[i]);
    }

Modified code that should show levels:
PHP:
    //Add char list
    output->addByte(0x64);

    uint8_t size = std::min<size_t>(std::numeric_limits<uint8_t>::max(), account.characters.size());

    output->addByte(size); // number of worlds = number of characters

    // load characters levels
    std::ostringstream query;
    query.str(std::string());
    query << "SELECT `name`, `level`, `deletion` FROM `players` WHERE `account_id` = " << account.id << " ORDER BY `name` ASC";
    DBResult_ptr result = db->storeQuery(query.str());

    uint8_t fakeWorldId = 0;
    if (result) {
        do {
            if (result->getNumber<uint64_t>("deletion") == 0) {
                output->addByte(fakeWorldId); // world id

                std::ostringstream description;
                description.str(std::string());
                // here generate description
                description << "Level " << result->getNumber<uint32_t>("level");

                output->addString(description.str());

                output->addString(g_config.getString(ConfigManager::IP));
                output->add<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
                output->addByte(0); // idk what about that byte, is it end of list or end of list element?

                ++fakeWorldId;
            }
        } while (result->next());
    }

    output->addByte(size);
    for (uint8_t i = 0; i < size; i++) {
        output->addByte(i); // i'm almost sure it's world id, so we put there character description
        output->addString(account.characters[i]);
    }

It first code debug client at login try second version [I don't know what does 1 bit in login protocol, I put it in different places in these codes]:
PHP:
[PHP]
    //Add char list
    output->addByte(0x64);

    uint8_t size = std::min<size_t>(std::numeric_limits<uint8_t>::max(), account.characters.size());

    output->addByte(size); // number of worlds = number of characters

    // load characters levels
    std::ostringstream query;
    query.str(std::string());
    query << "SELECT `name`, `level`, `deletion` FROM `players` WHERE `account_id` = " << account.id << " ORDER BY `name` ASC";
    DBResult_ptr result = db->storeQuery(query.str());

    uint8_t fakeWorldId = 0;
    if (result) {
        do {
            if (result->getNumber<uint64_t>("deletion") == 0) {
                output->addByte(fakeWorldId); // world id

                std::ostringstream description;
                description.str(std::string());
                // here generate description
                description << "Level " << result->getNumber<uint32_t>("level");

                output->addString(description.str());

                output->addString(g_config.getString(ConfigManager::IP));
                output->add<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));

                ++fakeWorldId;
            }
        } while (result->next());
    }
    output->addByte(0); // idk what about that byte, is it end of list or end of list element?

    output->addByte(size);
    for (uint8_t i = 0; i < size; i++) {
        output->addByte(i); // i'm almost sure it's world id, so we put there character description
        output->addString(account.characters[i]);
    }
 
Back
Top