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

[TFS 1.2] Ingame Store History

Fortera Global

Intermediate OT User
Joined
Nov 20, 2015
Messages
1,181
Solutions
2
Reaction score
117
I have this function on my protocolgame.cpp

I got debbug when try open History Store
tfs 1.2 protocol 10.99+

protocolgame.cpp
C++:
void ProtocolGame::parsePacket(NetworkMessage& msg)
{
    switch (recvbyte) {
       
        case 0xEF: parseTransferCoins(msg); break;
        case 0xFA: parseStoreOpen(); break;
        case 0xFD: parseStoreOpenHistory(msg); break;
        case 0xFE: parseStoreRequestHistory(msg); break;

        default:
            // std::cout << "Player: " << player->getName() << " sent an unknown packet header: 0x" << std::hex << static_cast<uint16_t>(recvbyte) << std::dec << "!" << std::endl;
            break;
    }

    if (msg.isOverrun()) {
        disconnect();
    }
}

void ProtocolGame::parseStoreOpenHistory(NetworkMessage& msg)
{
    storeHistoryEntriesPerPage = msg.getByte();

    g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::sendStoreHistory, getThis(), 0, storeHistoryEntriesPerPage)));
}

void ProtocolGame::parseStoreRequestHistory(NetworkMessage& msg)
{
    uint16_t page = msg.get<uint16_t>();

    g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::sendStoreHistory, getThis(), page, storeHistoryEntriesPerPage)));
}
 
Last edited by a moderator:
Come on, how do you expect to get help when you don't even include sendStoreHistory? :rolleyes:

P.S. Please use an appropriate title next time, hopefully a more descriptive one (as C++ debbug doesn't really indicate that you're having trouble with the ingame store).
 
Come on, how do you expect to get help when you don't even include sendStoreHistory? :rolleyes:

P.S. Please use an appropriate title next time, hopefully a more descriptive one (as C++ debbug doesn't really indicate that you're having trouble with the ingame store).

Sorry:

C++:
void ProtocolGame::sendStoreHistory(uint16_t page, uint32_t entriesPerPage)
{
    // dispatcher thread
    std::vector<StoreTransaction> storeHistory;
    g_store->getTransactionHistory(player->getAccount(), page, entriesPerPage, storeHistory);

    if (storeHistory.size() == 0) {
        return sendStoreError(STORE_ERROR_HISTORY, "No entries yet.");
    }

    NetworkMessage msg;
    msg.addByte(0xFD);

    msg.add<uint16_t>(page);
    msg.addByte((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00);

    uint8_t entries = std::min<uint8_t>(entriesPerPage, static_cast<uint32_t>(storeHistory.size()));
    msg.addByte(entries);
    size_t count = 0;
    for (const auto& entry : storeHistory) {
        if (count++ == entriesPerPage) {
            break;
        }

        msg.add<uint32_t>(entry.timestamp);
        msg.addByte(0x00); // product type
        msg.add<int32_t>(entry.coins);
        msg.addString(entry.description);
    }

    writeToOutputBuffer(msg);
}
 
Last edited by a moderator:
You should change the types for these two:
C++:
   msg.add<uint16_t>(page);
   msg.addByte((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00);

The client expects two unsigned integers (uint32_t). I believe this change were implemented in the 10.97 update.
 
Last edited by a moderator:
You should change the types for these two:
Code:
   msg.add<uint16_t>(page);
   msg.addByte((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00);

The client expects two unsigned integers (uint32_t). I believe this change were implemented in the 10.97 update.

maybe: ?

msg.add<uint32_t>(page);
msg.addByte((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00);

i'll test here something (thanks) ^^

many many tests here, dont sucess :/
 
Last edited by a moderator:
I told you to change both, not just one of them.

C++:
   msg.add<uint32_t>(page); // currentPage
   msg.add<uint32_t>((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00); // pageCount
 
Last edited by a moderator:
I told you to change both, not just one of them.

Code:
   msg.add<uint32_t>(page); // currentPage
   msg.add<uint32_t>((storeHistory.size() > entriesPerPage) ? 0x01 : 0x00); // pageCount
Humm thanks, I'll test here o_O

@Ninja Its worked, solve my problem for 80% ^^
just for curious, I need to do the same for void ProtocolGame::sendStoreOffers ?

msg.add<uint32_t>

code:
C++:
void ProtocolGame::sendStoreOffers(StoreCategory& category)
{
    NetworkMessage msg;
    msg.addByte(0xFC);

    msg.addString(category.getName());
   
    msg.add<uint16_t>(category.getOffers().size());
    for (auto& offer : category.getOffers()) {
        msg.add<uint32_t>(offer.getId());
        msg.addString(offer.getName());
        msg.addString(offer.getDescription());

        msg.add<uint32_t>(offer.getPrice());
        msg.addByte(offer.getState());
        msg.addByte(!g_store->executeOnRender(player, &offer));

        msg.addByte(offer.getIcons().size());
        for (const auto& icon : offer.getIcons()) {
            msg.addString(icon);
        }

        msg.add<uint16_t>(offer.getSubOffers().size());
        for (auto& subOffer : offer.getSubOffers()) {
            msg.addString(subOffer.getName());
            msg.addString(subOffer.getDescription());

            msg.addByte(subOffer.getIcons().size());
            for (const auto& icon : subOffer.getIcons()) {
                msg.addString(icon);
            }

            msg.addString(subOffer.getParent()); //serviceType
        }
    }

    writeToOutputBuffer(msg);
}

Thanks for everything.
 
Last edited by a moderator:
Humm thanks, I'll test here o_O

@Ninja Its worked, solve my problem for 80% ^^
just for curious, I need to do the same for void ProtocolGame::sendStoreOffers ?

msg.add<uint32_t>

code:
Code:
void ProtocolGame::sendStoreOffers(StoreCategory& category)
{
    NetworkMessage msg;
    msg.addByte(0xFC);

    msg.addString(category.getName());
   
    msg.add<uint16_t>(category.getOffers().size());
    for (auto& offer : category.getOffers()) {
        msg.add<uint32_t>(offer.getId());
        msg.addString(offer.getName());
        msg.addString(offer.getDescription());

        msg.add<uint32_t>(offer.getPrice());
        msg.addByte(offer.getState());
        msg.addByte(!g_store->executeOnRender(player, &offer));

        msg.addByte(offer.getIcons().size());
        for (const auto& icon : offer.getIcons()) {
            msg.addString(icon);
        }

        msg.add<uint16_t>(offer.getSubOffers().size());
        for (auto& subOffer : offer.getSubOffers()) {
            msg.addString(subOffer.getName());
            msg.addString(subOffer.getDescription());

            msg.addByte(subOffer.getIcons().size());
            for (const auto& icon : subOffer.getIcons()) {
                msg.addString(icon);
            }

            msg.addString(subOffer.getParent()); //serviceType
        }
    }

    writeToOutputBuffer(msg);
}

Thanks for everything.
Look this:
https://github.com/brunominervino/forgottenserver/commit/56bc3ce8686e41558cce20de3be43bc47b7c7a04
 
wow, very nice, I'll compare archives and apply, man thanks and kisss
I think it will work 100%

@Bruno Minervino ae ta funcionando certinho, só to com um problema (que acredito que vou resolver logo se olhar direitinho), quando clica na oferta volta a tela de selecionar char, mas o char continua no game ^^ mas devo ter esquecido algo....

Obrigado por ajudar (falei português por que sei que vc é br)
ai tipo, se não for pedir muito (abusado eu né), voce teria as imagens do store? pelo menos 1 pra eu ver o tamanho e ai eu copio as outras do tibiawiki msm

Tá dando esse erro aqui olha:

http://prntscr.com/e2yml3

ai a função é essa:
linha do erro (1049): StoreOfferType_t offerType = static_cast<StoreOfferType_t>(msg.getByte());

C++:
void ProtocolGame::parseStoreSelectCategory(NetworkMessage& msg) {  
    StoreOfferType_t offerType = static_cast<StoreOfferType_t>(msg.getByte());
    std::string categoryName = msg.getString();

    for (auto& category : g_store->getCategories()) {
        if (category.getName() == categoryName) {
            return g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::sendStoreOffers, getThis(), category)));
        }
    }  
}
 
Last edited by a moderator:
About above: I marked the /*StoreOfferType_t offerType = static_cast<StoreOfferType_t>(msg.getByte());*/and this compiled.
But when I click in some offer I logout (dont logout, only go into select characters but char stay online on game).
 

thanks, but this continue kicking to select character when I click in some offer :eek:


mHwbrzS.png


code:
C++:
void ProtocolGame::parseStoreSelectCategory(NetworkMessage& msg)
{  
    std::string categoryName = msg.getString();

    for (auto& category : g_store->getCategories()) {
        if (category.getName() == categoryName) {
            return g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::sendStoreOffers, getThis(), category)));
        }
    }  
}
 
Last edited by a moderator:
thanks, but this continue kicking to select character when I click in some offer :eek:

code:
Code:
void ProtocolGame::parseStoreSelectCategory(NetworkMessage& msg)
{  
    std::string categoryName = msg.getString();

    for (auto& category : g_store->getCategories()) {
        if (category.getName() == categoryName) {
            return g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::sendStoreOffers, getThis(), category)));
        }
    }  
}

Check this:
https://github.com/brunominervino/forgottenserver/blob/Store-Ingame/src/protocolgame.cpp#L2114-L2154
 
Back
Top