• 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 How does depot work in [TFS 1.x]

whitevo

Feeling good, thats what I do.
Joined
Jan 2, 2015
Messages
3,454
Solutions
1
Reaction score
627
Location
Estonia
So yesterday when I played it and one thing bothered me. If I wanted to see what items I have in other character depot I had to log out and log in with the second character.

Today I though I'm going to make the depot same for whole account, but the database is a bit more "eh" for me. Besides I don't rly know how the depot works.

So I though I will ask first and maybe someone can answer few of these question, before I start with my trial and error thing.

bg1ahy.jpg
1. What does column "sid" store?
2. What does column "pid" store?
3. How do you store and read item attributes with LUA?
4. How are the items created to depot? (you can guide me the code lines too)

5. How are items registered to database?
6. How are items unregistered from database?


At this state what I would do is create table with columns like that:
accid, itemid, itemaid, itemtext, itemdesc, fluidtype, count

And then when player opens depot I will create these items for him with the data gained from database.
However would be nice if I don't have to reinvent the wheel and there is much easier solution for this.
 
Alright I assumed it will make sense if I see code, but no. That C++ doesn't make sense to me xD

However, If I change player->getGUID() in these lines:
https://github.com/otland/forgotten...d4b997f82d10769f205c/src/iologindata.cpp#L445
https://github.com/otland/forgotten...d4b997f82d10769f205c/src/iologindata.cpp#L548
https://github.com/otland/forgotten...d4b997f82d10769f205c/src/iologindata.cpp#L578
https://github.com/otland/forgotten...d4b997f82d10769f205c/src/iologindata.cpp#L748

to: player->getAccountId()

Would it make the depots shared trough accounts instead of characters?
 
You shouldn't edit the saveItems function if you want to save only the depot because saveItems is used for other things not only for depot.

But yes pretty much you just have to copy the saveItems function and change the name to something else and replace it to getAccountId then you change it here too:

https://github.com/otland/forgotten...7f82d10769f205c/src/iologindata.cpp#L441-L471
https://github.com/otland/forgotten...7f82d10769f205c/src/iologindata.cpp#L755-L777
 
copy pasted the code, changed the name and changed the player:getGUID() to player:getAccountId()
The in save and load depot items I changed also the player:getGUID() to player:getAccountId()

changed the save depot items to this:
Code:
if (!saveItemsAccountDepot(player, itemList, depotQuery, propWriteStream)) {
            return false;
        }

Code:
bool IOLoginData::saveItemsAccountDepot(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream)
{
    std::ostringstream ss;

    typedef std::pair<Container*, int32_t> containerBlock;
    std::list<containerBlock> queue;

    int32_t runningId = 100;

    Database* db = Database::getInstance();
    for (const auto& it : itemList) {
        int32_t pid = it.first;
        Item* item = it.second;
        ++runningId;

        propWriteStream.clear();
        item->serializeAttr(propWriteStream);

        size_t attributesSize;
        const char* attributes = propWriteStream.getStream(attributesSize);

        ss << player->getAccountId() << ',' << pid << ',' << runningId << ',' << item->getID() << ',' << item->getSubType() << ',' << db->escapeBlob(attributes, attributesSize);
        if (!query_insert.addRow(ss)) {
            return false;
        }

        if (Container* container = item->getContainer()) {
            queue.emplace_back(container, runningId);
        }
    }

    while (!queue.empty()) {
        const containerBlock& cb = queue.front();
        Container* container = cb.first;
        int32_t parentId = cb.second;
        queue.pop_front();

        for (Item* item : container->getItemList()) {
            ++runningId;

            Container* subContainer = item->getContainer();
            if (subContainer) {
                queue.emplace_back(subContainer, runningId);
            }

            propWriteStream.clear();
            item->serializeAttr(propWriteStream);

            size_t attributesSize;
            const char* attributes = propWriteStream.getStream(attributesSize);

            ss << player->getAccountId() << ',' << parentId << ',' << runningId << ',' << item->getID() << ',' << item->getSubType() << ',' << db->escapeBlob(attributes, attributesSize);
            if (!query_insert.addRow(ss)) {
                return false;
            }
        }
    }
    return query_insert.execute();
}

Is that all?
 
copy pasted the code, changed the name and changed the player:getGUID() to player:getAccountId()
The in save and load depot items I changed also the player:getGUID() to player:getAccountId()

changed the save depot items to this:
Code:
if (!saveItemsAccountDepot(player, itemList, depotQuery, propWriteStream)) {
            return false;
        }

Code:
bool IOLoginData::saveItemsAccountDepot(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream)
{
    std::ostringstream ss;

    typedef std::pair<Container*, int32_t> containerBlock;
    std::list<containerBlock> queue;

    int32_t runningId = 100;

    Database* db = Database::getInstance();
    for (const auto& it : itemList) {
        int32_t pid = it.first;
        Item* item = it.second;
        ++runningId;

        propWriteStream.clear();
        item->serializeAttr(propWriteStream);

        size_t attributesSize;
        const char* attributes = propWriteStream.getStream(attributesSize);

        ss << player->getAccountId() << ',' << pid << ',' << runningId << ',' << item->getID() << ',' << item->getSubType() << ',' << db->escapeBlob(attributes, attributesSize);
        if (!query_insert.addRow(ss)) {
            return false;
        }

        if (Container* container = item->getContainer()) {
            queue.emplace_back(container, runningId);
        }
    }

    while (!queue.empty()) {
        const containerBlock& cb = queue.front();
        Container* container = cb.first;
        int32_t parentId = cb.second;
        queue.pop_front();

        for (Item* item : container->getItemList()) {
            ++runningId;

            Container* subContainer = item->getContainer();
            if (subContainer) {
                queue.emplace_back(subContainer, runningId);
            }

            propWriteStream.clear();
            item->serializeAttr(propWriteStream);

            size_t attributesSize;
            const char* attributes = propWriteStream.getStream(attributesSize);

            ss << player->getAccountId() << ',' << parentId << ',' << runningId << ',' << item->getID() << ',' << item->getSubType() << ',' << db->escapeBlob(attributes, attributesSize);
            if (!query_insert.addRow(ss)) {
                return false;
            }
        }
    }
    return query_insert.execute();
}

Is that all?
Should be
 
Code:
/home/pi/forgottenserver/src/iologindata.cpp: In static member function ‘static bool IOLoginData::loadPlayer(Player*, DBResult_ptr)’:
/home/pi/forgottenserver/src/iologindata.cpp:448:125: error: ‘class Player’ has no member named ‘getAccountId’
  query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = " << player->getAccountId() << " ORDER BY `sid` DESC";
                                                                                                                             ^
/home/pi/forgottenserver/src/iologindata.cpp: At global scope:
/home/pi/forgottenserver/src/iologindata.cpp:530:150: error: no ‘bool IOLoginData::saveItemsAccountDepot(const Player*, const ItemBlockList&, DBInsert&, PropWriteStream&)’ member function declared in class ‘IOLoginData’
bool IOLoginData::saveItemsAccountDepot(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream)
                                                                                                                                                      ^
/home/pi/forgottenserver/src/iologindata.cpp: In static member function ‘static bool IOLoginData::savePlayer(Player*)’:
/home/pi/forgottenserver/src/iologindata.cpp:821:78: error: ‘class Player’ has no member named ‘getAccountId’
   query << "DELETE FROM `player_depotitems` WHERE `player_id` = " << player->getAccountId();
                                                                              ^
/home/pi/forgottenserver/src/iologindata.cpp:837:75: error: ‘saveItemsAccountDepot’ was not declared in this scope
   if (!saveItemsAccountDepot(player, itemList, depotQuery, propWriteStream)) {
                                                                           ^
CMakeFiles/tfs.dir/build.make:791: recipe for target 'CMakeFiles/tfs.dir/src/iologindata.cpp.o' failed
make[2]: *** [CMakeFiles/tfs.dir/src/iologindata.cpp.o] Error 1
CMakeFiles/Makefile2:122: recipe for target 'CMakeFiles/tfs.dir/all' failed
make[1]: *** [CMakeFiles/tfs.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

I found this in luascript:
Code:
// player:getAccountId()
    Player* player = getUserdata<Player>(L, 1);
    if (player) {
        lua_pushnumber(L, player->getAccount());
    } else {
        lua_pushnil(L);
    }
    return 1;
Going to try player->getAccount() instead of player->getAccountId()
 
Another error now on same file xD
Code:
/home/pi/forgottenserver/src/iologindata.cpp:530:150: error: no ‘bool IOLoginData::saveItemsAccountDepot(const Player*, const ItemBlockList&, DBInsert&, PropWriteStream&)’ member function declared in class ‘IOLoginData’
bool IOLoginData::saveItemsAccountDepot(const Player* player, const ItemBlockList& itemList, DBInsert& query_insert, PropWriteStream& propWriteStream)
                                                                                                                                                      ^
/home/pi/forgottenserver/src/iologindata.cpp: In static member function ‘static bool IOLoginData::savePlayer(Player*)’:
/home/pi/forgottenserver/src/iologindata.cpp:837:75: error: ‘saveItemsAccountDepot’ was not declared in this scope
   if (!saveItemsAccountDepot(player, itemList, depotQuery, propWriteStream)) {
                                                                           ^
CMakeFiles/tfs.dir/build.make:791: recipe for target 'CMakeFiles/tfs.dir/src/iologindata.cpp.o' failed
make[2]: *** [CMakeFiles/tfs.dir/src/iologindata.cpp.o] Error 1
CMakeFiles/Makefile2:122: recipe for target 'CMakeFiles/tfs.dir/all' failed
make[1]: *** [CMakeFiles/tfs.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

EDIT:
had to register the method on IoLoginData.h file
 
Last edited:
Back
Top