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

Nekiro downgrade 8.0 trade system bug

highsanta

Advanced OT User
Joined
Dec 20, 2023
Messages
396
Solutions
3
Reaction score
173
I uncomennted the code but selling items does not work the items dont get highlighted in trade window despite being in backpack ( can not sell ever only buy and even the items that are newly bought cant be sold to same npc)
 
C++:
void ProtocolGame::sendSaleItemList(const std::list<ShopInfo>& shop)
{
    NetworkMessage msg;
    msg.addByte(0x7B);
    msg.add<uint64_t>(player->getMoney() + player->getBankBalance());

    std::map<uint16_t, uint32_t> saleMap;

    // Cache the map of all item counts for the player's backpack
    std::map<uint32_t, uint32_t> backpackItems;
    player->getAllItemTypeCount(backpackItems);

    if (backpackItems.empty()) {
        // No items in the backpack, nothing to sell
        msg.addByte(0);
        writeToOutputBuffer(msg);
        return;
    }

    std::cout << "Items in backpack:\n";
    for (const auto& [itemId, count] : backpackItems) {
        std::cout << "Item ID: " << itemId << ", Count: " << count << "\n";
    }

    // Process items from the shop
    std::cout << "Processing items from the shop:\n";
    for (const ShopInfo& shopInfo : shop) {
        if (shopInfo.sellPrice == 0) {
            continue; // Skip items with a zero sell price
        }

        int8_t subtype = -1;

        const ItemType& itemType = Item::items[shopInfo.itemId];
        if (itemType.hasSubType() && !itemType.stackable) {
            subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType);
        }

        auto it = backpackItems.find(shopInfo.itemId);
        if (it != backpackItems.end() && it->second > 0) {
            // Item found in the backpack, add it to the sale map
            saleMap[shopInfo.itemId] = it->second;
            std::cout << "Added item ID " << shopInfo.itemId << " to saleMap.\n";
        }
        else {
            // Item not found in the sale map even though the player has it, report error
            std::cerr << "Error: Item ID " << shopInfo.itemId << " not added to saleMap "
                << "but the player has it in the backpack.\n";
        }
    }

    // Add items to the message
    msg.addByte(static_cast<uint8_t>(saleMap.size()));
    for (const auto& [itemId, count] : saleMap) {
        msg.addItemId(itemId);
        msg.addByte(std::min<uint32_t>(count, std::numeric_limits<uint8_t>::max()));
    }

    // Write message to output buffer
    writeToOutputBuffer(msg);
}
Post automatically merged:

it works fine on 7.72 protocol only on 8.0 the sell window is broken

ERROR: ProtocolGame parse message exception (1775 bytes, 8 unread, last opcode is 0x00 (0), prev opcode is 0x7b (123)): InputMessage eof reachedPacket has been saved to packet.log, you can use it to find what was wrong. (Protocol: 800)
1711922413248.png
Post automatically merged:

charges are taken instead of items count in this case
this is my old fix, idk if it's work for downgraded tfs
View attachment 83364
1711923004258.png

ur a god send me priuv msg


fixed code:

C++:
void ProtocolGame::sendSaleItemList(const std::list<ShopInfo>& shop)
{
    NetworkMessage msg;
    msg.addByte(0x7B);
    msg.add<uint32_t>(player->getMoney());

    std::map<uint16_t, uint32_t> saleMap;

    if (shop.size() <= 5) {
        // For very small shops it's not worth it to create the complete map
        for (const ShopInfo& shopInfo : shop) {
            if (shopInfo.sellPrice == 0) {
                continue;
            }

            int8_t subtype = -1;

            const ItemType& itemType = Item::items[shopInfo.itemId];
            if (itemType.hasSubType() && !itemType.stackable) {
                subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType);
            }

            uint32_t count = player->getItemTypeCount(shopInfo.itemId, subtype);
            if (count > 0) {
                saleMap[shopInfo.itemId] = count;
            }
        }
    }
    else {
        // Large shop, it's better to get a cached map of all item counts and use it
        // We need a temporary map since the finished map should only contain items
        // available in the shop
        std::map<uint32_t, uint32_t> tempSaleMap;
        player->getAllItemTypeCount(tempSaleMap);

        // We must still check manually for the special items that require subtype matches
        // (That is, fluids such as potions etc., actually these items are very few since
        // health potions now use their own ID)
        for (const ShopInfo& shopInfo : shop) {
            if (shopInfo.sellPrice == 0) {
                continue;
            }

            int8_t subtype = -1;

            const ItemType& itemType = Item::items[shopInfo.itemId];
            if (itemType.hasSubType() && !itemType.stackable) {
                subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType);
            }

            if (subtype != -1) {
                uint32_t count;
                if (itemType.isFluidContainer() || itemType.isSplash()) {
                    count = player->getItemTypeCount(shopInfo.itemId, subtype); // This shop item requires extra checks
                }
                else {

                    auto itShopItem = tempSaleMap.find(shopInfo.itemId);
                    if (itShopItem != tempSaleMap.end())
                    {
                        count = itShopItem->second;
                    }
                    else
                    {
                        count = 0;
                    
                    }
                }

                if (count > 0) {
                    saleMap[shopInfo.itemId] = count;
                }
            }
            else {
                std::map<uint32_t, uint32_t>::const_iterator findIt = tempSaleMap.find(shopInfo.itemId);
                if (findIt != tempSaleMap.end() && findIt->second > 0) {
                    saleMap[shopInfo.itemId] = findIt->second;
                }
            }
        }
    }

    uint8_t itemsToSend = std::min<size_t>(saleMap.size(), std::numeric_limits<uint8_t>::max());
    msg.addByte(itemsToSend);

    uint8_t i = 0;
    for (std::map<uint16_t, uint32_t>::const_iterator it = saleMap.begin(); i < itemsToSend; ++it, ++i) {
        msg.addItemId(it->first);
        msg.addByte(std::min<uint32_t>(it->second, std::numeric_limits<uint8_t>::max()));
    }

    writeToOutputBuffer(msg);
}
 
Last edited:
Back
Top