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

EnterMarket parse problem

xixigisi

New Member
Joined
May 11, 2023
Messages
16
Reaction score
2
Does someone could help me with the market implementation on OTClient?

I'm using TFS1.5 and using extendedOpcodes (server side) normally. I can send JSON and all I want for other things to OTClient.

But I have a problem with Market Module. My market function on server side is:
C++:
void ProtocolGame::sendMarketEnter(uint32_t depotId)
{
    NetworkMessage msg;
    msg.addByte(0xF6);
    msg.addByte(std::min<uint32_t>(IOMarket::getPlayerOfferCount(player->getGUID()), std::numeric_limits<uint8_t>::max()));
   
    DepotChest* depotChest = player->getDepotChest(depotId, false);
    if (!depotChest) {
        msg.add<uint16_t>(0x00);
        writeToOutputBuffer(msg);
        return;
    }

    player->setInMarket(true);

    msg.add<uint64_t>(player->getBankBalance());

    std::map<uint16_t, uint32_t> depotItems;
    std::forward_list<Container*> containerList { depotChest, player->getInbox() };

    do {
        Container* container = containerList.front();
        containerList.pop_front();
        if (!containerList.empty()) {
            for (Item* item : container->getItemList()) {
                Container* c = item->getContainer();
                if (c && !c->empty()) {
                    containerList.push_front(c);
                    continue;
                }
                const ItemType& itemType = Item::items[item->getID()];

                if(item->getClientID() == 0){
                    continue;
                }

                if (itemType.id == 0) {
                    continue;
                }
                if (c && (!itemType.isContainer() || c->capacity() != itemType.maxItems)) {
                    continue;
                }
                if (!item->hasMarketAttributes()) {
                    continue;
                }
                depotItems[item->getClientID()] += Item::countByType(item, -1);
            }
        }
    } while (!containerList.empty());

    uint16_t itemsToSend = std::min<size_t>(depotItems.size(), std::numeric_limits<uint16_t>::max());
    uint16_t i = 0;

    msg.add<uint16_t>(itemsToSend);
    for (std::map<uint16_t, uint32_t>::const_iterator it = depotItems.begin(); i < itemsToSend; ++it, ++i) {
        const ItemType& itemType = Item::items[it->first];
        msg.add<uint16_t>(itemType.id);
        msg.add<uint16_t>(std::min<uint32_t>(0xFFFF, it->second));
    }

    writeToOutputBuffer(msg);
}

And my function on OTClient is:

Lua:
local function parseMarketEnter(protocol, msg)
  local items
  if g_game.getClientVersion() < 944 then
    items = {}
    local itemsCount = msg:getU16()
    for i = 1, itemsCount do
      local itemId = msg:getU16()
      local category = msg:getU8()
      local name = msg:getString()
      table.insert(items, {
        id = itemId,
        category = category,
        name = name
      })
    end  
  end
 
  local balance = 0
  if g_game.getProtocolVersion() <= 1250 or not g_game.getFeature(GameTibia12Protocol) then
    if g_game.getProtocolVersion() >= 981 or g_game.getProtocolVersion() < 944 then
      balance = msg:getU64()
    else
      balance = msg:getU32()
    end
  end
 
  local vocation = -1
  if g_game.getProtocolVersion() >= 944 and g_game.getProtocolVersion() < 950 then
    vocation = msg:getU8() -- get vocation id
  end
  local offers = msg:getU8()

  local depotItems = {}
  local depotCount = msg:getU16()
  for i = 1, depotCount do
    local itemId = msg:getU16() -- item id
    local itemCount = msg:getU16() -- item count

    depotItems[itemId] = itemCount
  end

  signalcall(Market.onMarketEnter, depotItems, offers, balance, vocation, items)
  return true
end


I got that error:


ERROR: protected lua call failed: C++ call failed: InputMessage eof reached
stack traceback:
[builtin#146]: at 0x0116dab0
[C]: in function 'getU64'
/modules/game_market/marketprotocol.lua:45: in function 'callback'
/modules/gamelib/protocolgame.lua:10: in function </modules/gamelib/protocolgame.lua:7>
ERROR: ProtocolGame parse message exception (8 bytes, 3 unread, last opcode is 0xf6 (246), prev opcode is 0xffffffff (-1)): unhandled opcode 246
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 772)

I understand the basic of packets, I have developed another modules with opcodes but I can't solve this problem.
Post automatically merged:

I simplified the parseMarketEnter function to avoid problems, now it seems like this:

Lua:
  local items = {[0]={id=1781,category=19,name="a small stone"},[1]={id=2853,category=4,name="a bag"},[2]={id=2854,category=4,name="a backpack"},[3]={id=2857,category=4,name="a bag"},[4]={id=3280,category=20,name="a fire sword"}}
  local vocation = -1
  local offers = msg:getU8()
  local balance = msg:getU64()
  local depotCount = msg:getU16()

  local depotItems = {}
  for i = 1, depotCount do
    local itemId = msg:getU16() -- item id
    local itemCount = msg:getU16() -- item count

    depotItems[itemId] = itemCount
  end

The error is the same, it's like the received message is lower than expected. Have no idea about how to solve it, if someone could help me with that problem or how to debug it i'll be grateful.
Post automatically merged:

Solved

The main problem was with the function return with a non existing depot id.
 
Last edited:
Are you able to sell/buy items via market? I have it enabled can see items but can't sell or buy them
 
my bad, didnt see it was solved!
 
Last edited:
Back
Top