• 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 Loginprotocol Multi-World Protocol >= 9.71

Becks

New Member
Joined
Jul 20, 2009
Messages
8
Reaction score
2
Hello, I have a easy (hopefully) question regarding to the Loginprotocol:

Im writing on a multi-version + multi-protocol Loginserver to server all my Otservers globally.

So far it works pretty well except for newer protocol version >= 9,71 when character-list protocol has changed:

As taken from [TFS 1.1] in protocollogin.cpp

void ProtocolLogin::getCharacterList(const std::string& accountName, const std::string& password, uint16_t version)

This is the code that adds the character-list.

Code:
        //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]);
        }

How does this needs to be structured to support more then one world?

I tried different methods like including character-list in the server-loop and send one seperate character-list for each server.

Also tried to loop the servers first and then seperately one entire character-list using the unknown 0 byte in character-list to set same as world-ID but this did not work either.

My attempts:

Code:
           //New character-list model: version > 971 => Figure out if this version is correct
            //Add session-key, whatever this is, stay-logged-in for session checkbox?
            //This is new, we have to find out > what version? -> Assuming 9.71
            output->AddByte(0x28);
            output->AddString(accountName + "\n" + password);

            ServerList serverList = account->getServerListByCharacterList();

            //Amount of servers
            output->AddByte((uint8_t)serverList.size());

            std::cout << "serverListSize: " << serverList.size() << std::endl;

            uint8_t serverID = 0;
            for (auto it = serverList.begin(); it != serverList.end(); it++) {
                //World id - just increment me ?
                output->AddByte(serverID);
            
                std::cout << "serverID: " << serverID << std::endl;

                //World credeientials
                output->AddString((*it)->getName());
                output->AddString((*it)->getIPAddress());
                output->AddU16((*it)->getPort());
                output->AddByte(0); //Figure out what this flag is for

                serverID++;
            }

            //Character-list (total-count)
            output->AddByte(account->characterlist.size()); //Size of the character-list

            //Character-list (loop)
            uint8_t worldIDIncrement = 0;
            uint16_t lastServerID = 0;
            std::cout << "characterListSize: " << account->characterlist.size() << std::endl;
            for (auto it = account->characterlist.begin(); it != account->characterlist.end(); it++) {
                if (lastServerID != (*it)->getServer()->getServerID()) {
                    if (lastServerID != 0) {
                        worldIDIncrement++;
                    }

                    lastServerID = (*it)->getServer()->getServerID();
                }
                output->AddByte(lastServerID); //Figure out what this flag is for? it could be the world-ID
                output->AddString((*it)->getName()); //Character-name

            }

Code:
           //New character-list model: version > 971 => Figure out if this version is correct
            //Add session-key, whatever this is, stay-logged-in for session checkbox?
            //This is new, we have to find out > what version? -> Assuming 9.71
            output->AddByte(0x28);
            output->AddString(accountName + "\n" + password);

            ServerList serverList = account->getServerListByCharacterList();

            //Amount of servers
            output->AddByte((uint8_t)serverList.size());

            std::cout << "serverListSize: " << serverList.size() << std::endl;

            uint8_t serverID = 0;
            for (auto it = serverList.begin(); it != serverList.end(); it++) {
                //World id - just increment me ?
                output->AddByte(serverID);
            
                std::cout << "serverID: " << serverID << std::endl;

                //World credeientials
                output->AddString((*it)->getName());
                output->AddString((*it)->getIPAddress());
                output->AddU16((*it)->getPort());
                output->AddByte(0); //Figure out what this flag is for

                //Character-list (total-count)
                CharacterList list = account->getCharacterListForServerByID((*it)->getServerID()); 
                output->AddByte(list.size()); //Size of the character-list

                //Character-list (loop)
                std::cout << "characterListSize: " << account->characterlist.size() << std::endl;
                for (auto it = list.begin();it != list.end(); it++) {
                    output->AddByte(0); //What is this flag for?
                    output->AddString((*it)->getName()); //Character-name
                }

                serverID++;
           }

Im starting to run out of ideas, anyone knows how this is supposed to work?

Thanks alot!
 
Last edited:
Thanks alot, that helped :D

Have slight changes but most stupid error was that I had:

output->AddByte(0x64);

before adding the Session key >.<

My solution:

Code:
      //New character-list model: version > 971 => Figure out if this version is correct

       //Add session-key, whatever this is, stay-logged-in for session checkbox?
       //This is new, we have to find out > what version? -> Assuming 9.71
       output->AddByte(0x28);
       output->AddString(accountName + "\n" + password);

       //Start character-list
       output->AddByte(0x64);

       ServerList serverList = account->getServerListByCharacterList();

       //Amount of servers
       output->AddByte((uint8_t)serverList.size());

       for (auto it = serverList.begin(); it != serverList.end(); it++) {
         //World id - just increment me ?
         output->AddByte((*it)->getServerID());

         //World credeientials
         output->AddString((*it)->getName());
         output->AddString((*it)->getIPAddress());
         output->AddU16((*it)->getPort());
         output->AddByte(0); //World preview-state, what the hell is that?
       }

       //Character-list (total-count)
       output->AddByte(account->characterlist.size()); //Size of the character-list (integer / uint8)

       //Character-list (loop)
       for (auto it = account->characterlist.begin(); it != account->characterlist.end(); it++) {
         output->AddByte((*it)->getServer()->getServerID()); //Figure out what this flag is for, maybe GM or so? it could also be the world-ID
         output->AddString((*it)->getName()); //This is for sure the character Name
       }
 
Back
Top