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

Logging out is not saving

chucky91

Advanced OT User
Joined
Apr 8, 2010
Messages
277
Solutions
9
Reaction score
152
I compiled this project, but when logout player is not saving and the error appears in the console.

Nostalrius - Version 3.0
Compiled with Microsoft Visual C++ version 14.2
Compiled on Feb 11 2022 14:00:44 for platform x64

A server developed by Alejandro Mujica
Visit our forum for updates, support, and resources: OTLand (http://otland.net/).

1644604276014.png
 
Last edited:
You probably have written wrong your schemas when you imported them. Is there a chance that you can post them?
Check this two threads for more information, can't tell you yet what is working wrong.


Regards!
 
With that error info I can only make an educated guess. Whatever comes before lastlogin in IOLogindata::savePlayer is probably being written into the query as uint8_t and implicitly converted to char, try casting that value to uint16_t instead
 
You probably have written wrong your schemas when you imported them. Is there a chance that you can post them?
Check this two threads for more information, can't tell you yet what is working wrong.


Regards!
with the old console it works normally, without touching the DB. This new console was fixing some bugs, but when entering the game it gave this error of not saving. before editing the project i test the original nostalrius project without modifying it and it remains the same error without me changing anything.

C++:
bool IOLoginData::savePlayer(Player* player)
{
    if (player->getHealth() <= 0) {
        player->changeHealth(1);
    }

    Database* db = Database::getInstance();

    std::ostringstream query;
    query << "SELECT `save` FROM `players` WHERE `id` = " << player->getGUID();
    DBResult_ptr result = db->storeQuery(query.str());
    if (!result) {
        return false;
    }

    if (result->getNumber<uint16_t>("save") == 0) {
        query.str(std::string());
        query << "UPDATE `players` SET `lastlogin` = " << player->lastLoginSaved << ", `lastip` = " << player->lastIP << " WHERE `id` = " << player->getGUID();
        return db->executeQuery(query.str());
    }

    //serialize conditions
    PropWriteStream propWriteStream;
    for (Condition* condition : player->conditions) {
        if (condition->isPersistent()) {
            condition->serialize(propWriteStream);
            propWriteStream.write<uint8_t>(CONDITIONATTR_END);
        }
    }

    size_t conditionsSize;
    const char* conditions = propWriteStream.getStream(conditionsSize);

    //First, an UPDATE query to write the player itself
    query.str(std::string());
    query << "UPDATE `players` SET ";
    query << "`level` = " << player->level << ',';
    query << "`group_id` = " << player->group->id << ',';
    query << "`vocation` = " << player->getVocationId() << ',';
    query << "`health` = " << player->health << ',';
    query << "`healthmax` = " << player->healthMax << ',';
    query << "`experience` = " << player->experience << ',';
    query << "`lookbody` = " << static_cast<uint32_t>(player->defaultOutfit.lookBody) << ',';
    query << "`lookfeet` = " << static_cast<uint32_t>(player->defaultOutfit.lookFeet) << ',';
    query << "`lookhead` = " << static_cast<uint32_t>(player->defaultOutfit.lookHead) << ',';
    query << "`looklegs` = " << static_cast<uint32_t>(player->defaultOutfit.lookLegs) << ',';
    query << "`looktype` = " << player->defaultOutfit.lookType << ',';
    query << "`maglevel` = " << player->magLevel << ',';
    query << "`mana` = " << player->mana << ',';
    query << "`manamax` = " << player->manaMax << ',';
    query << "`manaspent` = " << player->manaSpent << ',';
    query << "`soul` = " << static_cast<uint16_t>(player->soul) << ',';
    query << "`town_id` = " << player->town->getID() << ',';

    const Position& loginPosition = player->getLoginPosition();
    query << "`posx` = " << loginPosition.getX() << ',';
    query << "`posy` = " << loginPosition.getY() << ',';
    query << "`posz` = " << loginPosition.getZ() << ',';

    query << "`cap` = " << (player->capacity / 100) << ',';
    query << "`sex` = " << player->sex << ',';

    if (player->lastLoginSaved != 0) {
        query << "`lastlogin` = " << player->lastLoginSaved << ',';
    }

    if (player->lastIP != 0) {
        query << "`lastip` = " << player->lastIP << ',';
    }

    query << "`conditions` = " << db->escapeBlob(conditions, conditionsSize) << ',';

    if (g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) {
        query << "`skulltime` = " << player->getPlayerKillerEnd() << ',';

        Skulls_t skull = SKULL_NONE;
        if (player->skull == SKULL_RED) {
            skull = SKULL_RED;
        }

        query << "`skull` = " << static_cast<uint32_t>(skull) << ',';
    }

    query << "`lastlogout` = " << player->getLastLogout() << ',';
    query << "`balance` = " << player->bankBalance << ',';

    query << "`skill_fist` = " << player->skills[SKILL_FIST].level << ',';
    query << "`skill_fist_tries` = " << player->skills[SKILL_FIST].tries << ',';
    query << "`skill_club` = " << player->skills[SKILL_CLUB].level << ',';
    query << "`skill_club_tries` = " << player->skills[SKILL_CLUB].tries << ',';
    query << "`skill_sword` = " << player->skills[SKILL_SWORD].level << ',';
    query << "`skill_sword_tries` = " << player->skills[SKILL_SWORD].tries << ',';
    query << "`skill_axe` = " << player->skills[SKILL_AXE].level << ',';
    query << "`skill_axe_tries` = " << player->skills[SKILL_AXE].tries << ',';
    query << "`skill_dist` = " << player->skills[SKILL_DISTANCE].level << ',';
    query << "`skill_dist_tries` = " << player->skills[SKILL_DISTANCE].tries << ',';
    query << "`skill_shielding` = " << player->skills[SKILL_SHIELD].level << ',';
    query << "`skill_shielding_tries` = " << player->skills[SKILL_SHIELD].tries << ',';
    query << "`skill_fishing` = " << player->skills[SKILL_FISHING].level << ',';
    query << "`skill_fishing_tries` = " << player->skills[SKILL_FISHING].tries << ',';

    if (!player->isOffline()) {
        query << "`onlinetime` = `onlinetime` + " << (time(nullptr) - player->lastLoginSaved) << ',';
    }
    query << "`blessings` = " << static_cast<uint32_t>(player->blessings);
    query << " WHERE `id` = " << player->getGUID();

    DBTransaction transaction;
    if (!transaction.begin()) {
        return false;
    }

    if (!db->executeQuery(query.str())) {
        return false;
    }

    // learned spells
    query.str(std::string());
    query << "DELETE FROM `player_spells` WHERE `player_id` = " << player->getGUID();
    if (!db->executeQuery(query.str())) {
        return false;
    }

    query.str(std::string());

    DBInsert spellsQuery("INSERT INTO `player_spells` (`player_id`, `name` ) VALUES ");
    for (const std::string& spellName : player->learnedInstantSpellList) {
        query << player->getGUID() << ',' << db->escapeString(spellName);
        if (!spellsQuery.addRow(query)) {
            return false;
        }
    }

    if (!spellsQuery.execute()) {
        return false;
    }

    query.str(std::string());
    query << "DELETE FROM `player_murders` WHERE `player_id` = " << player->getGUID();
    
    if (!db->executeQuery(query.str())) {
        return false;
    }

    query.str(std::string());

    DBInsert murdersQuery("INSERT INTO `player_murders`(`id`, `player_id`, `date`) VALUES ");
    for (time_t timestamp : player->murderTimeStamps) {
        query << "NULL," << player->getGUID() << ',' << timestamp;
        if (!murdersQuery.addRow(query)) {
            return false;
        }
    }

    if (!murdersQuery.execute()) {
        return false;
    }

    //item saving
    query.str(std::string());
    query << "DELETE FROM `player_items` WHERE `player_id` = " << player->getGUID();
    if (!db->executeQuery(query.str())) {
        return false;
    }

    DBInsert itemsQuery("INSERT INTO `player_items` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES ");

    ItemBlockList itemList;
    for (int32_t slotId = 1; slotId <= 10; ++slotId) {
        Item* item = player->inventory[slotId];
        if (item) {
            itemList.emplace_back(slotId, item);
        }
    }

    if (!saveItems(player, itemList, itemsQuery, propWriteStream)) {
        return false;
    }

    //save depot items
    query.str(std::string());
    query << "DELETE FROM `player_depotitems` WHERE `player_id` = " << player->getGUID();

    if (!db->executeQuery(query.str())) {
        return false;
    }

    DBInsert depotQuery("INSERT INTO `player_depotitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES ");
    itemList.clear();

    for (const auto& it : player->depotLockerMap) {
        itemList.emplace_back(it.first, it.second);
    }

    if (!saveItems(player, itemList, depotQuery, propWriteStream)) {
        return false;
    }

    query.str(std::string());
    query << "DELETE FROM `player_storage` WHERE `player_id` = " << player->getGUID();
    if (!db->executeQuery(query.str())) {
        return false;
    }

    query.str(std::string());

    DBInsert storageQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES ");

    for (const auto& it : player->storageMap) {
        query << player->getGUID() << ',' << it.first << ',' << it.second;
        if (!storageQuery.addRow(query)) {
            return false;
        }
    }

    if (!storageQuery.execute()) {
        return false;
    }

    //End the transaction
    return transaction.commit();
}
 
with the old console it works normally, without touching the DB. This new console was fixing some bugs, but when entering the game it gave this error of not saving. before editing the project i test the original nostalrius project without modifying it and it remains the same error without me changing anything.

In that case guess @Alpha is right, check your IOLogindata::savePlayer method at iologindata.cpp and compare the method from your previous sources to your new sources. Here's a reference of how it works Fix depot saving · nekiro/TFS-1.5-Downgrades@de2815e (https://github.com/nekiro/TFS-1.5-Downgrades/commit/de2815e13fda58c9072828a79b670c2dbb326377#diff-6dfa47a7316089c1e8bb940c99dd031d12824616b8dc87aa6c559f2f05ee55ba)
 
Back
Top