• 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++ adapt multiworld system for tfs 1.5

Felipe93

Ghost Member
Joined
Mar 21, 2015
Messages
1,990
Solutions
9
Reaction score
334
Location
Chile
Hello I'm tryin to add multiworld to my tfs 1.5 Multiworld system by aurelion5670 · Pull Request #929 · opentibiabr/otservbr-global-archived (https://github.com/opentibiabr/otservbr-global-archived/pull/929) i added every commit manually because of the differences among the codes

im having few problems to adapt it. almost all errors are related to the db strings
this is the original code
Lua:
    DBResult_ptr result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'");
    if (result) {
        motdNum = result->getNumber<uint32_t>("value");
    } else {
        std::ostringstream insertQuery;
        db.executeQuery("INSERT INTO `server_config` (`world_id`, `config`, `value`) VALUES (" << worldId << ", 'motd_num', '0')");
        db.executeQuery(insertQuery.str());
    }
    std::ostringstream selectpQuery;
    result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_hash'");
    result = db.storeQuery(selectpQuery.str());
    if (result) {
        motdHash = result->getString("value");
        if (motdHash != transformToSHA1(g_config.getString(ConfigManager::MOTD))) {


here the main code from github
Code:
Database& db = Database::getInstance();
    uint16_t worldId = g_gameworld.getWorldId();

    std::ostringstream selectQuery;
    selectQuery << "SELECT `value` FROM `server_config` WHERE `world_id` = "<< worldId <<" AND `config` = 'motd_num'";

    DBResult_ptr result = db.storeQuery(selectQuery.str());
    if (result) {
        motdNum = result->getNumber<uint32_t>("value");
    } else {
        std::ostringstream insertQuery;
        insertQuery << "INSERT INTO `server_config` (`world_id`, `config`, `value`) VALUES ("<< worldId <<", 'motd_num', '0')";

        db.executeQuery(insertQuery.str());


here's how's looking in the tfs 1.5
Code:
    DBResult_ptr result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'");
    if (result) {
        motdNum = result->getNumber<uint32_t>("value");
    } else {
        std::ostringstream insertQuery;
        db.executeQuery("INSERT INTO `server_config` (`world_id`, `config`, `value`) VALUES (" << worldId << ", 'motd_num', '0')");
        db.executeQuery(insertQuery.str());
    }
    std::ostringstream selectpQuery;
    result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_hash'");
    result = db.storeQuery(selectpQuery.str());
    if (result) {
        motdHash = result->getString("value");
        if (motdHash != transformToSHA1(g_config.getString(ConfigManager::MOTD))) {

few errors
Lua:
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4928,96): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [56]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4933,90): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [69]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4937,83): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [56]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4946,90): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [69]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4946,124): error C2143: error de sintaxis: falta ')' delante de ';'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4955,71): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [39]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4955,160): error C2672: 'fmt::v9::format': no se encontró una función sobrecargada que coincida
1>C:\vcpkg\installed\x64-windows\include\fmt\format.h(4183,13): message : puede ser 'std::string fmt::v9::format(const Locale &,fmt::v9::basic_format_string<char,type_identity<T>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\vcpkg\installed\x64-windows\include\fmt\core.h(3204,31): message : o       'std::string fmt::v9::format(fmt::v9::basic_format_string<char,type_identity<Args>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4956,131): error C2678: '<<' binario: no se encontró un operador que adopte un operando en la parte izquierda de tipo 'const char [39]' (o bien no existe una conversión aceptable)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\position.h(136,15): message : puede ser 'std::ostream &operator <<(std::ostream &,const Direction &)' (compilando archivo de origen ..\src\game.cpp)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\position.h(135,15): message : o       'std::ostream &operator <<(std::ostream &,const Position &)' (compilando archivo de origen ..\src\game.cpp)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4956,131): message : al hacer coincidir la lista de argumentos '(const char [39], std::string)'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4956,259): error C2672: 'fmt::v9::format': no se encontró una función sobrecargada que coincida
1>C:\vcpkg\installed\x64-windows\include\fmt\format.h(4183,13): message : puede ser 'std::string fmt::v9::format(const Locale &,fmt::v9::basic_format_string<char,type_identity<T>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\vcpkg\installed\x64-windows\include\fmt\core.h(3204,31): message : o       'std::string fmt::v9::format(fmt::v9::basic_format_string<char,type_identity<Args>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4977,71): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [39]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4977,178): error C2672: 'fmt::v9::format': no se encontró una función sobrecargada que coincida
1>C:\vcpkg\installed\x64-windows\include\fmt\format.h(4183,13): message : puede ser 'std::string fmt::v9::format(const Locale &,fmt::v9::basic_format_string<char,type_identity<T>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\vcpkg\installed\x64-windows\include\fmt\core.h(3204,31): message : o       'std::string fmt::v9::format(fmt::v9::basic_format_string<char,type_identity<Args>::type...>,T &&...)' (compilando archivo de origen ..\src\game.cpp)
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\game.cpp(4991,90): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [69]'
1>inbox.cpp
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\house.cpp(51,64): error C2296: '<<': no es válido porque el operando izquierdo tiene el tipo 'const char [31]'
1>C:\Users\felip\source\repos\tfs-1.x-8.0-graphics-7-4\src\house.cpp(51,217): error C2672: 'fmt::v9::format': no se encontró una función sobrecargada que coincida
1>C:\vcpkg\installed\x64-windows\include\fmt\format.h(4183,13): message : puede ser 'std::string fmt::v9::format(const Locale &,fmt::v9::basic_format_string<char,type_identity<T>::type...>,T &&...)' (compilando archivo de origen ..\src\house.cpp)
1>C:\vcpkg\installed\x64-windows\include\fmt\core.h(3204,31): message : o       'std::string fmt::v9::format(fmt::v9::basic_format_string<char,type_identity<Args>::type...>,T &&...)' (compilando archivo de origen ..\src\house.cpp)
1>ioguild.cpp
1>iologindata.cpp
1>iomap.cpp
please guide me with just an example doing one string so i could be able to re-write the other ones


thanks
 
Where did you get this line?
C++:
DBResult_ptr result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'");
In otservbr repo you linked it's:
C++:
    std::ostringstream selectQuery;
    selectQuery << "SELECT `value` FROM `server_config` WHERE `world_id` = "<< worldId <<" AND `config` = 'motd_num'";

    DBResult_ptr result = db.storeQuery(selectQuery.str());
In your code:
C++:
"SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'"
is a string. You cannot use << on it. Thing you need to use << is std::ostringstream.

That's why in otservbr commit they first create std::ostringstream object, then generate query using << and finally convert it into string using selectQuery.str().

TFS uses fmt library to generate string with parameters. In your case it would be:
C++:
DBResult_ptr result = db.storeQuery(fmt::format("SELECT `value` FROM `server_config` WHERE `world_id` = {:d} AND `config` = 'motd_num'", worldId));
{:d} in string (d = decimal) will be replaced by integer get from first parameter after string, which is worldId.
 
Last edited:
Where did you get this line?
C++:
DBResult_ptr result = db.storeQuery("SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'");
In otservbr repo you linked it's:
C++:
    std::ostringstream selectQuery;
    selectQuery << "SELECT `value` FROM `server_config` WHERE `world_id` = "<< worldId <<" AND `config` = 'motd_num'";

    DBResult_ptr result = db.storeQuery(selectQuery.str());
In your code:
C++:
"SELECT `value` FROM `server_config` WHERE `world_id` = " << worldId << " AND `config` = 'motd_num'"
is a string. You cannot use << on it. Thing you need to use << is std::ostringstream.

That's why in otservbr commit they first create std::ostringstream object, then generate query using << and finally convert it into string using selectQuery.str().

TFS uses fmt library to generate string with parameters. In your case it would be:
C++:
DBResult_ptr result = db.storeQuery(fmt::format("SELECT `value` FROM `server_config` WHERE `world_id` = {:d} AND `config` = 'motd_num'", worldId));
{:d} in string (d = decimal) will be replaced by integer get from first parameter after string, which is worldId.
thanks for your fast reply, so this should be ok?
main code
Code:
int32_t DatabaseManager::getDatabaseVersion()
{
    uint16_t worldId = g_gameworld.getWorldId();
    if (!tableExists("server_config")) {
        Database& db = Database::getInstance();
        db.executeQuery("CREATE TABLE `server_config` (`config` VARCHAR(50) NOT NULL, `value` VARCHAR(256) NOT NULL DEFAULT '', UNIQUE(`config`)) ENGINE = InnoDB");
        db.executeQuery("INSERT INTO `server_config` VALUES ('db_version', 0)");
        return 0;
    }


edited code
Lua:
int32_t DatabaseManager::getDatabaseVersion()
{
    uint16_t worldId = g_gameworld.getWorldId();
    if (!tableExists("server_config")) {
        Database& db = Database::getInstance();
        db.executeQuery("CREATE TABLE `server_config`, `world_id` INT(11) NOT NULL DEFAULT 0, (`config` VARCHAR(50) NOT NULL, `value` VARCHAR(256) NOT NULL DEFAULT '', UNIQUE(`config`)) ENGINE = InnoDB");
        db.executeQuery("INSERT INTO `server_config` VALUES ('worldId', 'db_version', 0)");
        return 0;
or i shouldn't use quotation marks? because i see in your code it does not have it
Code:
bool DatabaseManager::getDatabaseConfig(const std::string& config, int32_t& value)
{
    Database& db = Database::getInstance();
    uint16_t worldId = g_gameworld.getWorldId();

    DBResult_ptr result = db.storeQuery(fmt::format("SELECT `value` FROM `server_config` WHERE `world_id` = worldId AND `config` = {:s}", db.escapeString(config)));
 
Back
Top