void Item::DeleteMe() { if( IsContainer() ) TO_CONTAINER(this)->Destruct(); else Destruct(); }
void WorldSession::HandleSetTradeItem(WorldPacket & recv_data) { if(!_player->IsInWorld() || _player->mTradeTarget == 0) return; CHECK_PACKET_SIZE(recv_data, 3); uint8 TradeSlot = recv_data.contents()[0]; int8 SourceBag = recv_data.contents()[1]; uint8 SourceSlot = recv_data.contents()[2]; Player* pTarget = _player->GetTradeTarget(); if(pTarget == NULL || !pTarget->IsInWorld() || TradeSlot > 6) return; Item* pItem = _player->GetItemInterface()->GetInventoryItem(SourceBag, SourceSlot); if( pItem == NULL ) return; if(pItem->IsContainer()) { if( pItem->IsContainer() && TO_CONTAINER(pItem)->HasItems() ) { _player->GetItemInterface()->BuildInventoryChangeError( pItem, NULLITEM, INV_ERR_CANT_TRADE_EQUIP_BAGS); return; } } if(pItem->IsAccountbound()) { _player->GetItemInterface()->BuildInventoryChangeError( pItem, NULLITEM, INV_ERR_ACCOUNT_BOUND); return; } for(uint32 i = 0; i < 7; i++) { // duping little shits if(_player->mTradeItems[i] == pItem || pTarget->mTradeItems[i] == pItem) { sWorld.LogCheater(this, "tried to dupe an item through trade"); Disconnect(); uint8 TradeStatus = TRADE_STATUS_CANCELLED; if( pTarget->m_session && pTarget->m_session->GetSocket()) pTarget->m_session->SendTradeStatus(TradeStatus); return; } } _player->mTradeItems[TradeSlot] = pItem; _player->SendTradeUpdate(); }
void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) { if(!_player->IsInWorld() || _player->mTradeTarget == 0) return; uint32 TradeStatus = TRADE_STATUS_ACCEPTED; Player* pTarget = _player->GetTradeTarget(); if(pTarget == NULL || !pTarget->IsInWorld()) TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; // Tell the other player we're green. if(pTarget->m_session && pTarget->m_session->GetSocket()) pTarget->m_session->SendTradeStatus(TradeStatus); _player->mTradeStatus = TradeStatus; //Both sides accepted? Let's trade! if(_player->mTradeStatus == TRADE_STATUS_ACCEPTED && pTarget->mTradeStatus == TRADE_STATUS_ACCEPTED) { // Ready! uint32 ItemCount = 0; uint32 TargetItemCount = 0; Item* pItem; // Count items on both sides, check if bags are empty. for(uint32 Index = 0; Index < 6; Index++) { if(_player->mTradeItems[Index] != NULL) { pItem = _player->mTradeItems[Index]; if( pItem != NULL && pItem->IsContainer() && TO_CONTAINER(pItem)->HasItems()) { sWorld.LogCheater(this, "%s involved in bag-trick trade with %s", _player->GetName(),pTarget->GetName()); _player->GetItemInterface()->BuildInventoryChangeError( pItem, NULLITEM, INV_ERR_CANT_TRADE_EQUIP_BAGS); TradeStatus = TRADE_STATUS_CANCELLED; break; } else ++ItemCount; } if(pTarget->mTradeItems[Index] != NULL) { pItem = pTarget->mTradeItems[Index]; if( pItem != NULL && pItem->IsContainer() && TO_CONTAINER(pItem)->HasItems() ) { sWorld.LogCheater(this, "%s involved in bag-trick trade with %s.", pTarget->GetName(),_player->GetName()); pTarget->GetItemInterface()->BuildInventoryChangeError( pItem, NULLITEM, INV_ERR_CANT_TRADE_EQUIP_BAGS); TradeStatus = TRADE_STATUS_CANCELLED; break; } else ++TargetItemCount; } } //Do we have something to trade? if( ItemCount == 0 && TargetItemCount == 0 && _player->mTradeGold == 0 && pTarget->mTradeGold == 0 ) TradeStatus = TRADE_STATUS_CANCELLED; //Do we have enough free slots on both sides? else if((_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount ) TradeStatus = TRADE_STATUS_CANCELLED; //Everything still ok? if(TradeStatus == TRADE_STATUS_ACCEPTED) { uint64 Guid; //Swapp 6 itemslots (7th will not trade) for(uint32 Index = 0; Index < 6; Index++) { Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( _player->mTradeItems[Index]->IsSoulbound()) _player->GetItemInterface()->BuildInventoryChangeError( _player->mTradeItems[Index], NULLITEM, INV_ERR_CANNOT_TRADE_THAT); else { //Remove from player pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuidRemoveStats(Guid, true); //and add to pTarget if(pItem != NULL) { pItem->SetOwner(pTarget); if( !pTarget->m_ItemInterface->AddItemToFreeSlot(pItem) ) { pItem->DeleteMe(); pItem = NULL; } } if(GetPermissionCount()>0 || pTarget->GetSession()->GetPermissionCount()>0) sWorld.LogGM(this, "trade item %s with %s (soulbound = %d)", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName()); } } Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( pTarget->mTradeItems[Index]->IsSoulbound()) pTarget->GetItemInterface()->BuildInventoryChangeError( pTarget->mTradeItems[Index], NULLITEM, INV_ERR_CANNOT_TRADE_THAT); else { //Remove from pTarget pItem = pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuidRemoveStats(Guid, true); //and add to initiator if(pItem != NULL) { pItem->SetOwner(_player); if( !_player->m_ItemInterface->AddItemToFreeSlot(pItem) ) { pItem->DeleteMe(); pItem = NULL; } } if(GetPermissionCount()>0 || pTarget->GetSession()->GetPermissionCount()>0) sWorld.LogGM(this, "trade item %s with %s", pTarget->mTradeItems[Index]->GetProto()->Name1, _player->GetName()); } } } // Trade Gold if(_player->mTradeGold) { pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, _player->mTradeGold); _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)_player->mTradeGold); } if(pTarget->mTradeGold) { _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, pTarget->mTradeGold); pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pTarget->mTradeGold); } pTarget->SaveToDB(false); _player->SaveToDB(false); TradeStatus = TRADE_STATUS_COMPLETE; } SendTradeStatus(TradeStatus); if(pTarget->m_session && pTarget->m_session->GetSocket()) pTarget->m_session->SendTradeStatus(TradeStatus); // Reset Trade Vars _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); } }
void WorldSession::HandleSendMail(WorldPacket & recv_data ) { MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; vector< ItemPointer > items; vector< ItemPointer >::iterator itr; string recepient; ItemPointer pItem; int8 real_item_slot; recv_data >> gameobject >> recepient; // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if( player == NULL ) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); recv_data >> msg.subject >> msg.body >> msg.stationary; // Check attached items recv_data >> unk2 >> itemcount; for( i = 0; i < itemcount; ++i ) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID( itemguid ); real_item_slot = _player->GetItemInterface()->GetInventorySlotByGuid( itemguid ); if( pItem == NULL || pItem->IsSoulbound() || pItem->HasFlag( ITEM_FIELD_FLAGS, ITEM_FLAG_CONJURED ) || ( pItem->IsContainer() && (TO_CONTAINER( pItem ))->HasItems() ) || real_item_slot >= 0 && real_item_slot < INVENTORY_SLOT_ITEM_START ) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } items.push_back( pItem ); } if( items.size() > 12 || msg.body.find("%") != string::npos || msg.subject.find("%") != string::npos) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } recv_data >> msg.money; recv_data >> msg.cod; // left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 // Check if we're sending mail to ourselves if(msg.player_guid == msg.sender_guid && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } // Check stationary if( msg.stationary == 0x3d && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Set up the cost int32 cost = 0; if( !sMailSystem.MailOption( MAIL_FLAG_DISABLE_POSTAGE_COSTS ) && !( GetPermissionCount() && sMailSystem.MailOption( MAIL_FLAG_NO_COST_FOR_GM ) ) ) { cost = 30; } // Check for attached money if( msg.money > 0 ) cost += msg.money; if( cost < 0 ) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // check that we have enough in our backpack if( (int32)_player->GetUInt32Value( PLAYER_FIELD_COINAGE ) < cost ) { SendMailError( MAIL_ERR_NOT_ENOUGH_MONEY ); return; } // Check we're sending to the same faction (disable this for testing) bool interfaction = (sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION ) || (HasGMPermissions() && sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM ) )); if(!interfaction) { if(player->team != _player->GetTeam()) { SendMailError( MAIL_ERR_NOT_YOUR_ALLIANCE ); return; } } msg.message_id = 0; msg.message_type = 0; msg.copy_made = false; msg.read_flag = false; msg.deleted_flag = false; msg.returned_flag = false; msg.delivery_time = (uint32)UNIXTIME; if(msg.money != 0 || msg.cod != 0 || !items.size() && player->acct != _player->GetSession()->GetAccountId()) { if(!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // +1hr } msg.expire_time = 0; if(!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) { msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * 30); if (msg.cod != 0) { msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * 3); } } // Sending Message // take the money _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -cost); // Check for the item, and required item. if( !items.empty( ) ) { for( itr = items.begin(); itr != items.end(); ++itr ) { pItem = *itr; if( _player->GetItemInterface()->SafeRemoveAndRetreiveItemByGuid(pItem->GetGUID(), false) != pItem ) continue; // should never be hit. pItem->RemoveFromWorld(); pItem->SetOwner( NULLPLR ); pItem->SaveToDB( INVENTORY_SLOT_NOT_SET, 0, true, NULL ); msg.items.push_back( pItem->GetUInt32Value(OBJECT_FIELD_GUID) ); if( GetPermissionCount() > 0 ) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->GetEntry(), player->name, msg.money); } pItem->Destructor(); } } // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(&msg); // Success packet :) SendMailError(MAIL_OK); }