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

playerRequestTrade { evolution } bug

El Man

«لَا إِلَٰهَ إِلَّا ٱللَّٰهُ»
Joined
Mar 23, 2013
Messages
161
Reaction score
33
C++:
bool Game::playerRequestTrade(Player* player, const Position& pos, uint8_t stackPos,
uint32_t playerId, uint16_t spriteId)
{
OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerRequestTrade()");
if(player->isRemoved())
return false;
Player* tradePartner = getPlayerByID(playerId);
if(!tradePartner || tradePartner == player) {
player->sendTextMessage(MSG_INFO_DESCR, "Sorry, not possible.");
return false;
}

if(!Position::areInRange<2,2,0>(tradePartner->getPosition(), player->getPosition())){
std::stringstream ss;
ss << tradePartner->getName() << " tells you to move closer.";
player->sendTextMessage(MSG_INFO_DESCR, ss.str());
return false;
}
Item* tradeItem = dynamic_cast<Item*>(internalGetThing(player, pos, stackPos, spriteId, STACKPOS_USE));
if(!tradeItem || tradeItem->getClientID() != spriteId || !tradeItem->isPickupable()) {
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
}
else if(player->getPosition().z > tradeItem->getPosition().z){
player->sendCancelMessage(RET_FIRSTGOUPSTAIRS);
return false;
}
else if(player->getPosition().z < tradeItem->getPosition().z){
player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS);
return false;
}
else if(!Position::areInRange<1,1,0>(tradeItem->getPosition(), player->getPosition())){
player->sendCancelMessage(RET_TOOFARAWAY);
return false;
}
std::map<Item*, unsigned long>::const_iterator it;
const Container* container = NULL;
for(it = tradeItems.begin(); it != tradeItems.end(); it++) {
if(tradeItem == it->first ||
((container = dynamic_cast<const Container*>(tradeItem)) && container->isHoldingItem(it->first)) ||
((container = dynamic_cast<const Container*>(it->first)) && container->isHoldingItem(tradeItem)))
{
player->sendTextMessage(MSG_INFO_DESCR, "This item is already being traded.");
return false;
}
}
Container* tradeContainer = tradeItem->getContainer();
if(tradeContainer && tradeContainer->getItemHoldingCount() + 1 > 100){
player->sendTextMessage(MSG_INFO_DESCR, "You can not trade more than 100 items.");
return false;
}
return internalStartTrade(player, tradePartner, tradeItem);
}
 
Last edited:
I havent solved it yet : in my opnion need someone add exhausted code to solve it
 
Pretty sure the server he is using has many problems that need to be fixed.
1) If you close a door with too many items under it. Crash.
2) If you buy and sell from an NPC really fast. Crash.
3) Apparently if you trade request fast? Crash.

That's just what I remember from old crashes.

The first one is probably what is being abused as it always is.
 
3) Apparently if you trade request fast? Crash. // that problem i have. how i fix it ? i can upload the code or source
 
Can you post the trade complete code?
in my opnion or as i see on another source its need add exhausted only in request trade
C++:
bool Game::playerRequestTrade(Player* player, const Position& pos, uint8_t stackPos,
    uint32_t playerId, uint16_t spriteId)
{
    OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerRequestTrade()");
    if(player->isRemoved())
        return false;

    Player* tradePartner = getPlayerByID(playerId);
    if(!tradePartner || tradePartner == player) {
        player->sendTextMessage(MSG_INFO_DESCR, "Sorry, not possible.");
        return false;
    }
    
    if(!Position::areInRange<2,2,0>(tradePartner->getPosition(), player->getPosition())){
        std::stringstream ss;
        ss << tradePartner->getName() << " tells you to move closer.";
        player->sendTextMessage(MSG_INFO_DESCR, ss.str());
        return false;
    }

    Item* tradeItem = dynamic_cast<Item*>(internalGetThing(player, pos, stackPos, spriteId, STACKPOS_USE));
    if(!tradeItem || tradeItem->getClientID() != spriteId || !tradeItem->isPickupable()) {
        player->sendCancelMessage(RET_NOTPOSSIBLE);
        return false;
    }
    else if(player->getPosition().z > tradeItem->getPosition().z){
        player->sendCancelMessage(RET_FIRSTGOUPSTAIRS);
        return false;
    }
    else if(player->getPosition().z < tradeItem->getPosition().z){
        player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS);
        return false;
    }
    else if(!Position::areInRange<1,1,0>(tradeItem->getPosition(), player->getPosition())){
        player->sendCancelMessage(RET_TOOFARAWAY);
        return false;
    }

    std::map<Item*, unsigned long>::const_iterator it;
    const Container* container = NULL;
    for(it = tradeItems.begin(); it != tradeItems.end(); it++) {
        if(tradeItem == it->first ||
            ((container = dynamic_cast<const Container*>(tradeItem)) && container->isHoldingItem(it->first)) ||
            ((container = dynamic_cast<const Container*>(it->first)) && container->isHoldingItem(tradeItem)))
        {
            player->sendTextMessage(MSG_INFO_DESCR, "This item is already being traded.");
            return false;
        }
    }

    Container* tradeContainer = tradeItem->getContainer();
    if(tradeContainer && tradeContainer->getItemHoldingCount() + 1 > 100){
        player->sendTextMessage(MSG_INFO_DESCR, "You can not trade more than 100 items.");
        return false;
    }

    return internalStartTrade(player, tradePartner, tradeItem);
}

bool Game::internalStartTrade(Player* player, Player* tradePartner, Item* tradeItem)
{
    if(player->tradeState != TRADE_NONE && !(player->tradeState == TRADE_ACKNOWLEDGE && player->tradePartner == tradePartner)) {
        player->sendCancelMessage(RET_YOUAREALREADYTRADING);
        return false;
    }
    else if(tradePartner->tradeState != TRADE_NONE && tradePartner->tradePartner != player) {
        player->sendCancelMessage(RET_THISPLAYERISALREADYTRADING);
        return false;
    }
    
    player->tradePartner = tradePartner;
    player->tradeItem = tradeItem;
    player->tradeState = TRADE_INITIATED;
    tradeItem->useThing2();
    tradeItems[tradeItem] = player->getID();

    player->sendTradeItemRequest(player, tradeItem, true);

    if(tradePartner->tradeState == TRADE_NONE){
        std::stringstream trademsg;
        trademsg << player->getName() <<" wants to trade with you.";
        tradePartner->sendTextMessage(MSG_INFO_DESCR, trademsg.str());
        tradePartner->tradeState = TRADE_ACKNOWLEDGE;
        tradePartner->tradePartner = player;
    }
    else{
        Item* counterOfferItem = tradePartner->tradeItem;
        player->sendTradeItemRequest(tradePartner, counterOfferItem, false);
        tradePartner->sendTradeItemRequest(player, tradeItem, false);
    }

    return true;

}

bool Game::playerAcceptTrade(Player* player)
{
player->sendTextMessage(MSG_STATUS_SMALL, "Trade cancelled.");
}

bool Game::playerLookInTrade(Player* player, bool lookAtCounterOffer, int index)
{
    OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerLookInTrade()");
    if(player->isRemoved())
        return false;

    Player* tradePartner = player->tradePartner;
    if(!tradePartner)
        return false;

    Item* tradeItem = NULL;

    if(lookAtCounterOffer)
        tradeItem = tradePartner->getTradeItem();
    else
        tradeItem = player->getTradeItem();

    if(!tradeItem)
        return false;

    int32_t lookDistance = std::max(std::abs(player->getPosition().x - tradeItem->getPosition().x),
        std::abs(player->getPosition().y - tradeItem->getPosition().y));

    if(index == 0){
        std::stringstream ss;
        ss << "You see " << tradeItem->getDescription(lookDistance);
        player->sendTextMessage(MSG_INFO_DESCR, ss.str());
        return false;
    }

    Container* tradeContainer = tradeItem->getContainer();
    if(!tradeContainer || index > (int)tradeContainer->getItemHoldingCount())
        return false;

    bool foundItem = false;
    std::list<const Container*> listContainer;
    ItemList::const_iterator it;
    Container* tmpContainer = NULL;

    listContainer.push_back(tradeContainer);

    while(!foundItem && listContainer.size() > 0){
        const Container* container = listContainer.front();
        listContainer.pop_front();

        for(it = container->getItems(); it != container->getEnd(); ++it){
            if(tmpContainer = (*it)->getContainer()){
                listContainer.push_back(tmpContainer);
            }

            --index;
            if(index == 0){
                tradeItem = *it;
                foundItem = true;
                break;
            }
        }
    }
    
    if(foundItem){
        std::stringstream ss;
        ss << "You see " << tradeItem->getDescription(lookDistance);
        player->sendTextMessage(MSG_INFO_DESCR, ss.str());
    }

    return foundItem;
}

bool Game::playerCloseTrade(Player* player)
{
    OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerCloseTrade()");
    if(player->isRemoved())
        return false;

    Player* tradePartner = player->tradePartner;
    if((tradePartner && tradePartner->getTradeState() == TRADE_TRANSFER) ||
          player->getTradeState() == TRADE_TRANSFER){
         std::cout << "Warning: [Game::playerCloseTrade] TradeState == TRADE_TRANSFER. " <<
              player->getName() << " " << player->getTradeState() << " , " <<
              tradePartner->getName() << " " << tradePartner->getTradeState() << std::endl;
        return true;
    }

    std::vector<Item*>::iterator it;
    if(player->getTradeItem()){
        std::map<Item*, unsigned long>::iterator it = tradeItems.find(player->getTradeItem());
        if(it != tradeItems.end()) {
            FreeThing(it->first);
            tradeItems.erase(it);
        }
    
        player->tradeItem->onTradeEvent(ON_TRADE_CANCEL, player);
        player->tradeItem = NULL;
    }
    
    player->setTradeState(TRADE_NONE);
    player->tradePartner = NULL;

    player->sendTextMessage(MSG_STATUS_SMALL, "Trade cancelled.");
    player->sendTradeClose();

    if(tradePartner){
        if(tradePartner->getTradeItem()){
            std::map<Item*, unsigned long>::iterator it = tradeItems.find(tradePartner->getTradeItem());
            if(it != tradeItems.end()) {
                FreeThing(it->first);
                tradeItems.erase(it);
            }

            tradePartner->tradeItem->onTradeEvent(ON_TRADE_CANCEL, tradePartner);
            tradePartner->tradeItem = NULL;
        }

        tradePartner->setTradeState(TRADE_NONE);       
        tradePartner->tradePartner = NULL;

        tradePartner->sendTextMessage(MSG_STATUS_SMALL, "Trade cancelled.");
        tradePartner->sendTradeClose();
    }

    return true;
}
 
Adding an exhaust doesn't fix the actual issue though. It does stop it from happening but that doesn't mean its fixed.

When you use the trade script does it automatically cancel the trade and do the trade again repeatedly?
 
Adding an exhaust doesn't fix the actual issue though. It does stop it from happening but that doesn't mean its fixed.

When you use the trade script does it automatically cancel the trade and do the trade again repeatedly?
someone use code in botng and he make trade fast by 2 player after do this the server was crashing
 

Similar threads

Back
Top