void WorldSession::HandleInitiateTrade(WorldPacket & recv_data) { CHECK_INWORLD_RETURN; CHECK_PACKET_SIZE(recv_data, 8); uint64 guid; recv_data >> guid; uint32 TradeStatus = TRADE_STATUS_PROPOSED; Player* pTarget = _player->GetMapMgr()->GetPlayer((uint32)guid); if(pTarget == NULL || !pTarget->IsInWorld()) TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; else { // Handle possible error outcomes if(_player->isDead()) TradeStatus = TRADE_STATUS_DEAD; else if(pTarget->isDead()) TradeStatus = TRADE_STATUS_TARGET_DEAD; else if(_player->IsStunned()) TradeStatus = TRADE_STATUS_YOU_STUNNED; else if(pTarget->IsStunned()) TradeStatus = TRADE_STATUS_TARGET_STUNNED; else if(pTarget->mTradeTarget != 0) TradeStatus = TRADE_STATUS_ALREADY_TRADING; else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0) TradeStatus = TRADE_STATUS_WRONG_FACTION; else if(_player->CalcDistance(pTarget) > 10.0f) // This needs to be checked TradeStatus = TRADE_STATUS_TOO_FAR_AWAY; set<uint32>::iterator itr = pTarget->m_ignores.find(_player->GetLowGUID()); if(itr != pTarget->m_ignores.end()) TradeStatus = TRADE_STATUS_PLAYER_IGNORED; } if(TradeStatus != TRADE_STATUS_PROPOSED) { _player->ResetTradeVariables(); SendTradeStatus(TradeStatus); } else { _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); pTarget->mTradeTarget = _player->GetLowGUID(); _player->mTradeTarget = pTarget->GetLowGUID(); pTarget->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; WorldPacket data(SMSG_TRADE_STATUS, 12); data << TradeStatus; data << _player->GetGUID(); if(pTarget->m_session && pTarget->m_session->GetSocket()) pTarget->m_session->SendPacket(&data); } }
void WorldSession::HandleInitiateTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) return; CHECK_PACKET_SIZE(recv_data, 8); uint64 guid; recv_data >> guid; Player * pTarget = _player->GetMapMgr()->GetPlayer((uint32)guid); uint32 TradeStatus = TRADE_STATUS_PROPOSED; WorldPacket data(SMSG_TRADE_STATUS, 12); if(pTarget == 0) { #ifdef USING_BIG_ENDIAN TradeStatus = swap32(uint32(TRADE_STATUS_PLAYER_NOT_FOUND)); #else TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; #endif OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); return; } // Handle possible error outcomes if(pTarget->CalcDistance(_player) > 10.0f) // This needs to be checked TradeStatus = TRADE_STATUS_TOO_FAR_AWAY; else if(pTarget->isDead()) TradeStatus = TRADE_STATUS_DEAD; else if(pTarget->mTradeTarget != 0) TradeStatus = TRADE_STATUS_ALREADY_TRADING; else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0 && !sWorld.interfaction_trade) TradeStatus = TRADE_STATUS_WRONG_FACTION; data << TradeStatus; if(TradeStatus == TRADE_STATUS_PROPOSED) { _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); pTarget->mTradeTarget = _player->GetLowGUID(); _player->mTradeTarget = pTarget->GetLowGUID(); pTarget->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; data << _player->GetGUID(); } pTarget->m_session->SendPacket(&data); }
void WorldSession::HandleChannelJoin(WorldPacket & recvPacket) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recvPacket, 1); string channelname, pass; uint32 dbc_id = 0; uint16 crap; // crap = some sort of channel type? Channel* chn; recvPacket >> dbc_id >> crap; recvPacket >> channelname; recvPacket >> pass; if(sWorld.GmClientChannel.size() && !stricmp(sWorld.GmClientChannel.c_str(), channelname.c_str()) && !GetPermissionCount()) return; chn = channelmgr.GetCreateChannel(channelname.c_str(), _player, dbc_id); if(chn == NULL) return; chn->AttemptJoin(_player, pass.c_str()); Log.Debug("ChannelJoin", "%s", channelname.c_str()); }
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& recvData) { MailMessage msg; ObjectGuid mailbox; uint32_t unk1, unk2; uint64_t money, COD; std::vector< Item* > items; Item* pItem; recvData >> unk1; recvData >> unk2; recvData >> COD; recvData >> money; uint32_t bodyLength = recvData.readBits(12); uint32_t subjectLength = recvData.readBits(9); uint8_t items_count = static_cast<uint8_t>(recvData.readBits(5)); // attached items count if (items_count > MAIL_MAX_ITEM_SLOT) { SendMailError(MAIL_ERR_TOO_MANY_ATTACHMENTS); return; } mailbox[0] = recvData.readBit(); ObjectGuid itemGUIDs[MAIL_MAX_ITEM_SLOT]; for (uint8_t i = 0; i < items_count; ++i) { itemGUIDs[i][2] = recvData.readBit(); itemGUIDs[i][6] = recvData.readBit(); itemGUIDs[i][3] = recvData.readBit(); itemGUIDs[i][7] = recvData.readBit(); itemGUIDs[i][1] = recvData.readBit(); itemGUIDs[i][0] = recvData.readBit(); itemGUIDs[i][4] = recvData.readBit(); itemGUIDs[i][5] = recvData.readBit(); } mailbox[3] = recvData.readBit(); mailbox[4] = recvData.readBit(); uint32_t receiverLength = recvData.readBits(7); mailbox[2] = recvData.readBit(); mailbox[6] = recvData.readBit(); mailbox[1] = recvData.readBit(); mailbox[7] = recvData.readBit(); mailbox[5] = recvData.readBit(); recvData.ReadByteSeq(mailbox[4]); for (uint8_t i = 0; i < items_count; ++i) { recvData.ReadByteSeq(itemGUIDs[i][6]); recvData.ReadByteSeq(itemGUIDs[i][1]); recvData.ReadByteSeq(itemGUIDs[i][7]); recvData.ReadByteSeq(itemGUIDs[i][2]); recvData.read_skip<uint8_t>(); // item slot in mail, not used recvData.ReadByteSeq(itemGUIDs[i][3]); recvData.ReadByteSeq(itemGUIDs[i][0]); recvData.ReadByteSeq(itemGUIDs[i][4]); recvData.ReadByteSeq(itemGUIDs[i][5]); } recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); std::string subject = recvData.ReadString(subjectLength); std::string receiver = recvData.ReadString(receiverLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[0]); std::string body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[1]); // Search for the recipient PlayerInfo* player_info = ObjectMgr::getSingleton().GetPlayerInfoByName(receiver.c_str()); if (!player_info) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } for (uint8_t i = 0; i < items_count; ++i) { pItem = _player->GetItemInterface()->GetItemByGUID(itemGUIDs[i]); if (pItem == nullptr || pItem->isSoulbound() || pItem->hasFlags(ITEM_FLAG_CONJURED)) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } if (pItem->isAccountbound() && GetAccountId() != player_info->acct) // don't mail account-bound items to another account { WorldPacket data(SMSG_SEND_MAIL_RESULT, 16); data << uint32_t(0); data << uint32_t(0); data << uint32_t(MAIL_ERR_BAG_FULL); data << uint32_t(INV_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); SendPacket(&data); return; } items.push_back(pItem); } if (receiver.empty()) return; bool interfaction = false; if (sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION) || (HasGMPermissions() && sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM))) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if (player_info->team != _player->GetTeam() && !interfaction) { SendMailError(MAIL_ERR_NOT_YOUR_ALLIANCE); return; } // Check if we're sending mail to ourselves if (strcmp(player_info->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if (msg.stationery == MAIL_STATIONERY_GM && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32_t)UNIXTIME; // Set up the cost uint32_t cost = items_count ? 30 * items_count : 30; // price hardcoded in client if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_POSTAGE_COSTS) && !(GetPermissionCount() && sMailSystem.MailOption(MAIL_FLAG_NO_COST_FOR_GM))) { cost += 30; } // check that we have enough in our backpack if (!_player->HasGold(cost)) { SendMailError(MAIL_ERR_NOT_ENOUGH_MONEY); return; } // Check for the item, and required item. if (!items.empty()) { for (std::vector< Item* >::iterator 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(NULL); pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); msg.items.push_back(pItem->getGuidLow()); if (GetPermissionCount() > 0) { /* log the message */ sGMLog.writefromsession(this, "sent mail with item entry %u to %s, with gold %u.", pItem->getEntry(), player_info->name, money); } pItem->DeleteMe(); } } if (money != 0 || COD != 0 || (!items.size() && player_info->acct != _player->GetSession()->GetAccountId())) { if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModGold(-static_cast<int32_t>(cost)); // Fill in the rest of the info msg.player_guid = player_info->guid; msg.sender_guid = _player->getGuid(); msg.money = static_cast<uint32_t>(money); msg.cod = static_cast<uint32_t>(COD); msg.subject = subject; msg.body = body; // 30 day expiry time for unread mail if (!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32_t)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.deleted_flag = false; msg.message_type = 0; msg.checked_flag = msg.body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player_info->guid, &msg); // Save/Update character's gold if they've received gold that is. This prevents a rollback. CharacterDatabase.Execute("UPDATE characters SET gold = %u WHERE guid = %u", _player->GetGold(), _player->m_playerInfo->guid); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::HandleInitiateTrade(WorldPacket & recv_data) { if(!_player->IsInWorld()) { return; } #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) ) { GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" ); return; } // CHECK_PACKET_SIZE(recv_data, 8); // uint64 guid; // recv_data >> guid; uint8 GUID_mask; uint8 GUID_bytes[8]; memset( GUID_bytes, 0, sizeof( GUID_bytes ) ); recv_data >> GUID_mask; if( GUID_mask & BIT_0x01 ) recv_data >> GUID_bytes[2]; if( GUID_mask & BIT_0x02 ) recv_data >> GUID_bytes[1]; if( GUID_mask & BIT_0x40 ) recv_data >> GUID_bytes[3]; if( GUID_mask & BIT_0x04 ) recv_data >> GUID_bytes[0]; uint8 GUID_bytes_obfuscated[8]; *(uint64*)GUID_bytes_obfuscated = *(uint64*)GUID_bytes; GUID_un_obfuscate( GUID_bytes ); Player * pTarget = _player->GetMapMgr()->GetPlayer( *(uint64*)GUID_bytes ); uint32 TradeStatus = TRADE_STATUS_PROPOSED; if(pTarget == 0) { TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND; OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); return; } // Handle possible error outcomes if(pTarget->CalcDistance(_player) > 10.0f) // This needs to be checked TradeStatus = TRADE_STATUS_TOO_FAR_AWAY; else if(pTarget->IsDead()) TradeStatus = TRADE_STATUS_DEAD; else if(pTarget->mTradeTarget != 0) TradeStatus = TRADE_STATUS_ALREADY_TRADING; else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0 && !sWorld.interfaction_trade) TradeStatus = TRADE_STATUS_WRONG_FACTION; if(TradeStatus == TRADE_STATUS_PROPOSED) { _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); pTarget->mTradeTarget = _player->GetLowGUID(); _player->mTradeTarget = pTarget->GetLowGUID(); pTarget->mTradeStatus = TradeStatus; _player->mTradeStatus = TradeStatus; } /* 13329 ME {CLIENT} Packet: (0x4106) CMSG_INITIATE_TRADE PacketSize = 8 TimeStamp = 32130418 8A A9 79 02 00 00 00 04 to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338 0E 69 2B 33 18 8A A9 79 02 00 00 00 04 03 00 00 00 AB 2A 00 00 90 BC 61 58 AB 01 00 00 00 00 00 00 00 -> trade proposed to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209838 80 B9 46 42 98 8A A9 79 02 00 00 00 04 90 BC 61 58 AB 2A 00 00 B3 47 A5 00 00 01 00 00 00 AB 2A 00 00 -> trade proposed him {CLIENT} Packet: (0x4107) CMSG_BEGIN_TRADE PacketSize = 0 TimeStamp = 32209854 to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338 01 00 00 00 00 10 BD 46 42 00 00 00 00 88 E3 29 0E 00 00 00 00 07 01 00 00 00 02 00 00 00 AB 2A 00 00 -> trade initiated to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209994 00 00 00 00 AE 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 09 01 00 00 00 02 00 00 00 00 00 00 00 -> trade initiated to me {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32379442 80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32456725 05 00 00 00 0A 20 B8 46 42 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 04 00 00 00 00 00 00 00 ->trade accepted to him {SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32460750 80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete 14333 ///////////////////////////////////////// E9 D7 38 03 00 00 00 01 GUID OF A 07 E2 91 03 00 00 00 01 GUID OF B A asks B to trade {CLIENT} Packet: (0x3863) CMSG_INITIATE_TRADE PacketSize = 6 TimeStamp = 14190240 67 90 E3 02 00 06 server sends back to A confirmation of the received invite {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14190989 5D 00 00 01 00 00 00 00 00 00 00 90 02 00 00 00 00 00 00 06 80 7F 0D 41 E3 03 00 00 00 29 B4 5E 2D //maybe some auto click by client on some popup {CLIENT} Packet: (0x98CA) UNKNOWN PacketSize = 0 TimeStamp = 14191005 probably the other client accepted the trade {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 31 TimeStamp = 14191301 49 00 00 02 00 00 00 AB 2A 00 00 DB 00 09 00 00 00 0A 40 80 0D 41 0A 20 84 0D 41 2C 31 E9 00 ///////////////////////////////////////// B asks A to trade {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430 5D 00 2A 01 00 00 00 AB 2A 00 00 90 02 00 00 00 00 00 01 06 30 7F 0D 41 E3 07 E2 91 03 30 95 A8 4A compressed guid of the inviter B accepts trade {CLIENT} Packet: (0x0869) UNKNOWN PacketSize = 0 TimeStamp = 14208430 server lets B know that he received the previous packet {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 32 TimeStamp = 14208851 59 00 01 02 00 00 00 00 00 00 00 16 00 00 0A 00 00 00 DD E0 85 0D 41 BC B0 7D 0D 41 67 00 00 00 ///////////////////////////////////////// */ /* we receive invite {SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430 5D 00 mask - 5 bits 2A junk 01 00 00 00 status ? AB 2A 00 00 famous contant value or 0 90 - go2 B we are asking this guy to accept our trade 02 - go3 B we are asking this guy to accept our trade 00 00 00 00 00 00 - junk ? 06 - go0 B we are asking this guy to accept our trade 80 7F 0D 41 - magic float ? E3 - go1 B we are asking this guy to accept our trade 07 E2 91 03 lowguid of the other guy junk ? 30 95 A8 4A serializer ? */ //right now trade initiator does not need this packet /* { sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 ); data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7 data << uint8( 0 ); // junk // data << ObfuscateByte( GUID_bytes[6] ); data << uint32( TRADE_STATUS_PROPOSED ); data << uint32( TRADE_ID_CONST ); //used a lot of times or 0 data << ObfuscateByte( GUID_bytes[2] ); data << ObfuscateByte( GUID_bytes[3] ); data << uint8( 0 ); // junk data << uint32( 0x00000000 ); // highguid or junk // data << ObfuscateByte( GUID_bytes[7] ); data << ObfuscateByte( GUID_bytes[0] ); data << float( 0 ); // junk data << ObfuscateByte( GUID_bytes[1] ); data << uint32( pTarget->GetLowGUID() ); // junk data << uint32( 0x00000000 ); // could be trade ID. Like A asks B, B refuses, A received back this number SendPacket( &data ); }/**/ // _player->SendTradeUpdate( 0 ); //trade target does need this packet so he can auto reply with CMSG_BEGIN_TRADE { *(uint64*)GUID_bytes = _player->GetGUID(); sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 ); data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7 data << uint8( 0 ); // junk, can send 0 also // data << ObfuscateByte( GUID_bytes[6] ); data << uint32( TRADE_STATUS_PROPOSED ); data << uint32( TRADE_ID_CONST ); //used a lot of times or 0, data << ObfuscateByte( GUID_bytes[2] ); data << ObfuscateByte( GUID_bytes[3] ); data << uint8( 0 ); // junk data << uint32( 0x00000000 ); // highguid ? trade session counter ? junk ? // data << ObfuscateByte( GUID_bytes[7] ); data << ObfuscateByte( GUID_bytes[0] ); data << float( 0 ); // junk seems to be some float sometimes data << ObfuscateByte( GUID_bytes[1] ); data << uint32( _player->GetLowGUID() ); // lowguid ? junk ? data << uint32( 0 ); // could be trade ID. Like A asks B, B refuses, A received back this number. Or it could be time, global packet serializer pTarget->m_session->SendPacket( &data ); }/**/ // pTarget->SendTradeUpdate( 0 ); }
void WorldSession::HandleChannelJoin(WorldPacket& recvPacket) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recvPacket, 1); std::string channelname, pass; uint32 channel_id; recvPacket >> channel_id; recvPacket.readBit(); // has voice recvPacket.readBit(); // zone update uint8 channelLength = recvPacket.readBits(8); uint8 passwordLength = recvPacket.readBits(8); channelname = recvPacket.ReadString(channelLength); pass = recvPacket.ReadString(passwordLength); if (sWorld.settings.gm.gmClientChannelName.size() && !stricmp(sWorld.settings.gm.gmClientChannelName.c_str(), channelname.c_str()) && !GetPermissionCount()) return; Channel* channel = channelmgr.GetCreateChannel(channelname.c_str(), _player, channel_id); if (channel == nullptr) return; channel->AttemptJoin(_player, pass.c_str()); LogDebugFlag(LF_OPCODE, "ChannelJoin %s", channelname.c_str()); }
void WorldSession::HandleSendMail(WorldPacket& recv_data) { CHECK_INWORLD_RETURN MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; std::vector< Item* > items; std::vector< Item* >::iterator itr; std::string recepient; Item* pItem; //uint32 err = MAIL_OK; recv_data >> gameobject >> recepient; recv_data >> msg.subject >> msg.body >> msg.stationery; recv_data >> unk2 >> itemcount; if (itemcount > MAIL_MAX_ITEM_SLOT || msg.body.find("%") != std::string::npos || msg.subject.find("%") != std::string::npos) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if (player == NULL) { SendMailError(MAIL_ERR_RECIPIENT_NOT_FOUND); return; } for (i = 0; i < itemcount; ++i) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID(itemguid); if (pItem == NULL || pItem->IsSoulbound() || pItem->IsConjured()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } if (pItem->IsAccountbound() && GetAccountId() != player->acct) // don't mail account-bound items to another account { WorldPacket data(SMSG_SEND_MAIL_RESULT, 16); data << uint32(0); data << uint32(0); data << uint32(MAIL_ERR_BAG_FULL); data << uint32(INV_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); SendPacket(&data); return; } items.push_back(pItem); } recv_data >> msg.money; recv_data >> msg.cod; ///\todo left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 bool interfaction = false; if (sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION) || (HasGMPermissions() && sMailSystem.MailOption(MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM))) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if (player->team != _player->GetTeam() && !interfaction) { SendMailError(MAIL_ERR_NOT_YOUR_ALLIANCE); return; } // Check if we're sending mail to ourselves if (strcmp(player->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if (msg.stationery == MAIL_STATIONERY_GM && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32)UNIXTIME; // Set up the cost int32 cost = 0; // Check for attached money if (msg.money > 0) cost += msg.money; if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_POSTAGE_COSTS) && !(GetPermissionCount() && sMailSystem.MailOption(MAIL_FLAG_NO_COST_FOR_GM))) { cost += 30; } // check that we have enough in our backpack if (!_player->HasGold(cost)) { SendMailError(MAIL_ERR_NOT_ENOUGH_MONEY); return; } // 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(NULL); pItem->SaveToDB(INVENTORY_SLOT_NOT_SET, 0, true, NULL); msg.items.push_back(pItem->GetLowGUID()); 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->DeleteMe(); } } if (msg.money != 0 || msg.cod != 0 || (!msg.items.size() && player->acct != _player->GetSession()->GetAccountId())) { if (!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModGold(-cost); // Fill in the rest of the info msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); // 30 day expiry time for unread mail if (!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.deleted_flag = false; msg.message_type = 0; msg.checked_flag = msg.body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player->guid, &msg); // Save/Update character's gold if they've received gold that is. This prevents a rollback. CharacterDatabase.Execute("UPDATE characters SET gold = %u WHERE guid = %u", _player->GetGold(), _player->m_playerInfo->guid); // Success packet :) SendMailError(MAIL_OK); }
void WorldSession::_HandleAreaTriggerOpcode(uint32 id) { sLog.outDebug("AreaTrigger: %u", id); WorldPacket data(80); AreaTrigger * pAreaTrigger = AreaTriggerStorage.LookupEntry(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(GetPermissionCount()) { sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u.", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id); } /* if we don't have an areatrigger, create one on the stack to use for gm scripts :p */ if(!pAreaTrigger) { AreaTrigger tmpTrigger; tmpTrigger.AreaTriggerID = id; ScriptSystem->OnActivateAreaTrigger(&tmpTrigger, _player); return; } /* script prerequsites */ if(ScriptSystem->OnActivateAreaTrigger(pAreaTrigger, _player) == false) return; if(pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; snprintf(lvltext, 30, "at least level %d", (int)pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); //death system check. Corpse *pCorpse = NULL; // CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->iInstanceType == MODE_HEROIC && pMapinfo->type != INSTANCE_NULL) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Heroic mode is not available for this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && GetPlayer()->InGroup() && GetPlayer()->GetGroup()->GetGroupType() != GROUP_TYPE_RAID) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && !GetPlayer()->InGroup()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_quest && !_player->HasFinishedQuest(pMapinfo->required_quest)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_item && !_player->GetItemInterface()->GetItemCount(pMapinfo->required_item, true)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetGUIDLow()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(GetPlayer()->InGroup()) { MapMgr * groupinstance = sWorldCreator.GetInstanceByGroup(GetPlayer()->GetGroup(), GetPlayer(), pMapinfo); if (groupinstance) { if(groupinstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); GetPlayer()->ResurrectPlayer(); return; } } } //if its a raid instance and corpse is inside and player is not in a group, ressurect if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } //if its a instance and player is trying to enter when corpse is on a diferent instance, repop back else if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pCorpse->GetMapId() != pAreaTrigger->Mapid) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } bool result = sWorldCreator.CheckInstanceForObject(static_cast<Object*>(GetPlayer()), pMapinfo); if(result) { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } }
void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recv_data, 16); if(!_player->isAlive()) return; uint64 guid; uint32 text_emote, unk, namelen = 1; const char* name = " "; recv_data >> text_emote; recv_data >> unk; recv_data >> guid; if(m_muted && m_muted >= (uint32)UNIXTIME) { SystemMessage("Your voice is currently muted by a moderator."); return; } if(!GetPermissionCount() && sWorld.flood_lines) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { return; } } Unit* pUnit = _player->GetMapMgr()->GetUnit(guid); if(pUnit) { if(pUnit->IsPlayer()) { name = TO< Player* >(pUnit)->GetName(); namelen = (uint32)strlen(name) + 1; } else if(pUnit->IsPet()) { name = TO< Pet* >(pUnit)->GetName().c_str(); namelen = (uint32)strlen(name) + 1; } else { Creature* p = TO< Creature* >(pUnit); name = p->GetCreatureInfo()->Name; namelen = (uint32)strlen(name) + 1; } } emoteentry* em = dbcEmoteEntry.LookupEntryForced(text_emote); if(em) { WorldPacket data(SMSG_EMOTE, 28 + namelen); sHookInterface.OnEmote(_player, (EmoteType)em->textid, pUnit); if(pUnit) CALL_SCRIPT_EVENT(pUnit, OnEmote)(_player, (EmoteType)em->textid); switch(em->textid) { case EMOTE_STATE_SLEEP: case EMOTE_STATE_SIT: case EMOTE_STATE_KNEEL: case EMOTE_STATE_DANCE: { _player->SetEmoteState(em->textid); } break; } data << (uint32)em->textid; data << (uint64)GetPlayer()->GetGUID(); GetPlayer()->SendMessageToSet(&data, true); //If player receives his own emote, his animation stops. data.Initialize(SMSG_TEXT_EMOTE); data << (uint64)GetPlayer()->GetGUID(); data << (uint32)text_emote; data << unk; data << (uint32)namelen; if(namelen > 1) data.append(name, namelen); else data << (uint8)0x00; GetPlayer()->SendMessageToSet(&data, true); #ifdef ENABLE_ACHIEVEMENTS _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, 0); #endif sQuestMgr.OnPlayerEmote(_player, text_emote, guid); } }
void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recv_data, 9); WorldPacket* data = NULL; uint32 type; int32 lang; const char* pMisc = NULL; const char* pMsg = NULL; recv_data >> type; recv_data >> lang; if(lang >= NUM_LANGUAGES) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } // Flood protection if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines != 0) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if(m_muted && m_muted >= (uint32)UNIXTIME) { SystemMessage("Your voice is currently muted by a moderator."); return; } } break; } std::string msg, to = "", channel = "", tmp; msg.reserve(256); // Process packet switch(type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_YELL: recv_data >> msg; pMsg = msg.c_str(); //g_chatFilter->ParseEscapeCodes((char*)pMsg,true); pMisc = 0; break; case CHAT_MSG_WHISPER: recv_data >> to >> msg; pMsg = msg.c_str(); pMisc = to.c_str(); break; case CHAT_MSG_CHANNEL: recv_data >> channel; recv_data >> msg; pMsg = msg.c_str(); pMisc = channel.c_str(); break; case CHAT_MSG_AFK: case CHAT_MSG_DND: break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recv_data >> msg; pMsg = msg.c_str(); break; default: LOG_ERROR("CHAT: unknown msg type %u, lang: %u", type, lang); } if(int(msg.find("|T")) > -1) { GetPlayer()->BroadcastMessage("Don't even THINK about doing that again"); return; } // HookInterface OnChat event if(pMsg && !sHookInterface.OnChat(_player, type, lang, pMsg, pMisc)) return; Channel* chn = NULL; // Main chat message processing switch(type) { case CHAT_MSG_EMOTE: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('0') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true, ! sWorld.interfaction_chat); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_SAY: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg)) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >= 0) { data = sChatHandler.FillMessageData(CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } else { if(lang > 0 && LanguageSkills[lang] && ! _player->_HasSkillLine(LanguageSkills[lang])) return; if(lang == 0 && ! CanUseCommand('c') && ! sWorld.interfaction_chat) return; data = sChatHandler.FillMessageData(CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); GetPlayer()->SendMessageToSet(data, true); } delete data; } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(sWorld.interfaction_chat && lang > 0) lang = 0; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group* pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(type, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup* sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup* sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; } break; case CHAT_MSG_GUILD: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); } break; case CHAT_MSG_OFFICER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); } break; case CHAT_MSG_YELL: { if(sWorld.interfaction_chat && lang > 0) lang = 0; if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang == 0 && sWorld.interfaction_chat) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else if(lang == 0 && !CanUseCommand('c')) { if(data != NULL) delete data; return; } else if(GetPlayer()->m_modlanguage >= 0) data = sChatHandler.FillMessageData(CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); else data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; } break; case CHAT_MSG_WHISPER: { if(lang != -1) lang = LANG_UNIVERSAL; //All whispers are universal if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } PlayerCache* playercache = objmgr.GetPlayerCache(to.c_str(), false); if(playercache == NULL) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } if(_player->GetTeamInitial() != playercache->GetUInt32Value(CACHE_PLAYER_INITIALTEAM) && !sWorld.interfaction_chat && !playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && !_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM)) { WorldPacket response(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); response << to; SendPacket(&response); playercache->DecRef(); break; } // Check that the player isn't a gm with his status on // TODO: Game Master's on retail are able to have block whispers after they close the ticket with the current packet. // When a Game Master is visible to your player it says "This player is unavailable for whisper" I need to figure out how this done. if(!HasPermissions() && playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && playercache->CountValue64(CACHE_GM_TARGETS, _player->GetGUID()) == 0) { // Build automated reply string Reply = "SYSTEM: This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, Reply.c_str(), playercache->GetGUID(), 4); SendPacket(data); delete data; playercache->DecRef(); break; } if(playercache->CountValue64(CACHE_SOCIAL_IGNORELIST, _player->GetLowGUID()) > 0) { data = sChatHandler.FillMessageData(CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; playercache->DecRef(); break; } else { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); playercache->SendPacket(data); } //Sent the to Users id as the channel, this should be fine as it's not used for whisper if(lang != -1) //DO NOT SEND if its an addon message! { data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_AFK)) { // Has AFK flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } else if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_DND)) { // Has DND flag, autorespond. std::string reason; playercache->GetStringValue(CACHE_AFK_DND_REASON, reason); data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0); SendPacket(data); delete data; } playercache->DecRef(); } break; case CHAT_MSG_CHANNEL: { if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; chn = channelmgr.GetChannel(channel.c_str(), GetPlayer()); if(chn) { //g_chatFilter->ParseEscapeCodes((char*)pMsg, (chn->m_flags & CHANNEL_PACKET_ALLOWLINKS)>0 ); chn->Say(GetPlayer(), msg.c_str(), NULL, false); } } break; case CHAT_MSG_AFK: { std::string reason = ""; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(), EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK); if(GetPlayer()->m_bg) GetPlayer()->m_bg->RemovePlayer(GetPlayer(), false); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(), &Player::SoftDisconnect, EVENT_PLAYER_SOFT_DISCONNECT, sWorld.GetKickAFKPlayerTime(), 1, 0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_DND)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); else { GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DND); } } break; case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: { if(sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_bg != NULL) { data = sChatHandler.FillMessageData(type, lang, msg.c_str(), _player->GetGUID()); _player->m_bg->DistributePacketToTeam(data, _player->GetTeam()); delete data; } } break; } }
void WorldSession::HandleSendMail(WorldPacket & recv_data ) { MailMessage msg; uint64 gameobject; uint32 unk2; uint8 itemcount; uint8 itemslot; uint8 i; uint64 itemguid; vector< Item* > items; vector< Item* >::iterator itr; string recepient; Item * pItem; //uint32 err = MAIL_OK; recv_data >> gameobject >> recepient; recv_data >> msg.subject >> msg.body >> msg.stationary; recv_data >> unk2 >> itemcount; //he simply ads ' ' after each '%' to string so that vsnprintf function would not find tokens in string char *t=(char*)msg.subject.c_str(); if( t[0] != 0 ) //if not an empty string { int ind=1; //make sure we do not have any recognizable tokens here while(t[ind]!=0 && ind<5000) { if(t[ind-1]=='%') t[ind]=' ';//just remove chars that could be interpreted ind++; } } msg.subject = t; t=(char*)msg.body.c_str(); if( t[0] != 0 ) //if not an empty string { int ind=1; while(t[ind]!=0 && ind<5000) { if(t[ind-1]=='%') t[ind]=' ';//just remove chars that could be interpreted ind++; } } msg.body = t; if( itemcount > 12 ) { //SystemMessage("Sorry, Ascent does not support sending multiple items at this time. (don't want to lose your item do you) Remove some items, and try again."); SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } for( i = 0; i < itemcount; ++i ) { recv_data >> itemslot; recv_data >> itemguid; pItem = _player->GetItemInterface()->GetItemByGUID( itemguid ); if( pItem == NULL || pItem->IsSoulbound() || pItem->HasFlag( ITEM_FIELD_FLAGS, ITEM_FLAG_CONJURED ) ) { SendMailError( MAIL_ERR_INTERNAL_ERROR ); return; } items.push_back( pItem ); } recv_data >> msg.money; recv_data >> msg.cod; // left over: (TODO- FIX ME BURLEX!) // uint32 // uint32 // uint8 // Search for the recipient PlayerInfo* player = ObjectMgr::getSingleton().GetPlayerInfoByName(recepient.c_str()); if( player == NULL ) { SendMailError( MAIL_ERR_RECIPIENT_NOT_FOUND ); return; } bool interfaction = false; if( sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION ) || (HasGMPermissions() && sMailSystem.MailOption( MAIL_FLAG_CAN_SEND_TO_OPPOSITE_FACTION_GM ) ) ) { interfaction = true; } // Check we're sending to the same faction (disable this for testing) if( player->team != _player->GetTeam() && !interfaction ) { SendMailError( MAIL_ERR_NOT_YOUR_ALLIANCE ); return; } // Check if we're sending mail to ourselves if( strcmp(player->name, _player->GetName()) == 0 && !GetPermissionCount()) { SendMailError(MAIL_ERR_CANNOT_SEND_TO_SELF); return; } if( msg.stationary == 0x3d || msg.stationary == 0x3d && !HasGMPermissions()) { SendMailError(MAIL_ERR_INTERNAL_ERROR); return; } // Instant delivery time by default. msg.delivery_time = (uint32)UNIXTIME; // 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 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( NULL ); 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->DeleteMe(); } } if(msg.money != 0 || msg.cod != 0 || !msg.items.size() && player->acct != _player->GetSession()->GetAccountId()) { if(!sMailSystem.MailOption(MAIL_FLAG_DISABLE_HOUR_DELAY_FOR_ITEMS)) msg.delivery_time += 3600; // 1hr } // take the money _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -cost); // Fill in the rest of the info msg.player_guid = player->guid; msg.sender_guid = _player->GetGUID(); // 30 day expiry time for unread mail mail if(!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) msg.expire_time = (uint32)UNIXTIME + (TIME_DAY * MAIL_DEFAULT_EXPIRATION_TIME); else msg.expire_time = 0; msg.copy_made = false; msg.read_flag = false; msg.deleted_flag = false; msg.message_type = 0; // Great, all our info is filled in. Now we can add it to the other players mailbox. sMailSystem.DeliverMessage(player->guid, &msg); // Success packet :) SendMailError(MAIL_OK); }
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); }
void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) { #ifdef FORCED_GM_TRAINEE_MODE if( CanUseCommand('k') && !HasGMPermissions() ) { GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" ); return; } #endif if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) ) { GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" ); return; } Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || !plr) { return; } packetSMSG_TRADE_STATUS data; memset( &data, 0, sizeof( data ) ); data.trade_status = TRADE_STATUS_ACCEPTED; OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); _player->mTradeStatus = TRADE_STATUS_ACCEPTED; //when both have this status we can close the deal bool bag_hack_detected = false; if(plr->mTradeStatus == TRADE_STATUS_ACCEPTED) { // Ready! uint32 ItemCount = 0; uint32 TargetItemCount = 0; Player * pTarget = plr; /* // Calculate Item Count for(uint32 Index = 0; Index < 7; ++Index) { if(_player->mTradeItems[Index] != 0) ++ItemCount; if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; }*/ // Calculate Count for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) // cebernic: checking for MAX_TRADE_TRADABLE_ITEMS items ,untradable item check via others func. { Item * pItem; // safely trade checking pItem = _player->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; bag_hack_detected = true; break; } else ++ItemCount; } pItem = pTarget->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; bag_hack_detected = true; break; } else ++TargetItemCount; } //if(_player->mTradeItems[Index] != 0) ++ItemCount; //if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; } if( (_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount || bag_hack_detected == true || (ItemCount==0 && TargetItemCount==0 && !pTarget->mTradeGold && !_player->mTradeGold) ) // ceberwow added it { // Not enough slots on one end. data.trade_status = TRADE_STATUS_CANCELLED; } else { data.trade_status = TRADE_STATUS_COMPLETE; uint64 Guid; Item * pItem; // Remove all items from the players inventory for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) { Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( _player->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || _player->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { _player->mTradeItems[Index] = NULL; } else { if(GetPermissionCount()>0) sGMLog.writefromsession(this, "traded item %s to %s", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName()); pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( pTarget->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || pTarget->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { pTarget->mTradeItems[Index] = NULL; } else { if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0) sGMLog.writefromsession(pTarget->GetSession(), "traded item %s to %s", pTarget->mTradeItems[Index]->GetProto()->Name1, _player->GetName()); pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } } // Dump all items back into the opposite players inventory for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) { pItem = _player->mTradeItems[Index]; if(pItem != 0 && pTarget) { pItem->SetOwner(pTarget); // crash fixed. if( !pTarget->m_ItemInterface->AddItemToFreeSlot(&pItem) ) { pItem->DeleteMe(); pItem = NULL; _player->mTradeItems[Index] = NULL; continue; } } pItem = pTarget->mTradeItems[Index]; if(pItem != 0 && _player) { pItem->SetOwner(_player); if( !_player->m_ItemInterface->AddItemToFreeSlot(&pItem) ) { pItem->DeleteMe(); pItem = NULL; pTarget->mTradeItems[Index] = NULL; continue; } } } // Trade Gold if(pTarget->mTradeGold && pTarget->GetGold() >= pTarget->mTradeGold ) { _player->ModGold(pTarget->mTradeGold); pTarget->ModGold(-(int64)pTarget->mTradeGold); if(GetPermissionCount()>0) sGMLog.writefromsession(this, "traded(gave) %u gold to %s", pTarget->mTradeGold, pTarget->GetName()); } if(_player->mTradeGold && _player->GetGold() >= _player->mTradeGold) { pTarget->ModGold( _player->mTradeGold); _player->ModGold( -(int64)_player->mTradeGold); if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0) sGMLog.writefromsession(pTarget->GetSession(), "traded(gave) %u gold to %s", _player->mTradeGold, _player->GetName()); } // Close Window data.trade_status = TRADE_STATUS_COMPLETE; } OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data); _player->mTradeStatus = TRADE_STATUS_COMPLETE; plr->mTradeStatus = TRADE_STATUS_COMPLETE; // Reset Trade Vars _player->ResetTradeVariables(); plr->ResetTradeVariables(); //removed by zack. Hehe, just a way to spam db with saves. Not funny // added alternative way as item saves before // Save for eachother //plr->SaveToDB(false); //_player->SaveToDB(false); } }
void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) { Player * plr = _player->GetTradeTarget(); if(_player->mTradeTarget == 0 || !plr) return; uint32 TradeStatus = TRADE_STATUS_ACCEPTED; // Tell the other player we're green. #ifdef USING_BIG_ENDIAN swap32(&TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); _player->mTradeStatus = TradeStatus; swap32(&TradeStatus); #else plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); _player->mTradeStatus = TradeStatus; #endif if(plr->mTradeStatus == TRADE_STATUS_ACCEPTED) { // Ready! uint32 ItemCount = 0; uint32 TargetItemCount = 0; Player * pTarget = plr; /* // Calculate Item Count for(uint32 Index = 0; Index < 7; ++Index) { if(_player->mTradeItems[Index] != 0) ++ItemCount; if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; }*/ // Calculate Count for(uint32 Index = 0; Index < 6; ++Index) // cebernic: checking for 6items ,untradable item check via others func. { Item * pItem; // safely trade checking pItem = _player->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && ((Container*)pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; break; } else ++ItemCount; } pItem = pTarget->mTradeItems[Index]; if( pItem ) { if( ( pItem->IsContainer() && ((Container*)pItem)->HasItems() ) || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) ) { ItemCount = 0; TargetItemCount = 0; break; } else ++TargetItemCount; } //if(_player->mTradeItems[Index] != 0) ++ItemCount; //if(pTarget->mTradeItems[Index] != 0) ++TargetItemCount; } if( (_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount || (pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount || (ItemCount==0 && TargetItemCount==0 && !pTarget->mTradeGold && !_player->mTradeGold) ) // ceberwow added it { // Not enough slots on one end. TradeStatus = TRADE_STATUS_CANCELLED; } else { TradeStatus = TRADE_STATUS_COMPLETE; uint64 Guid; Item * pItem; // Remove all items from the players inventory for(uint32 Index = 0; Index < 6; ++Index) { Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( _player->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || _player->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { _player->mTradeItems[Index] = NULL; } else { if(GetPermissionCount()>0) { sGMLog.writefromsession(this, "traded item %s to %s", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName()); } pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0; if(Guid != 0) { if( pTarget->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP || pTarget->mTradeItems[Index]->GetProto()->Bonding >= ITEM_BIND_QUEST ) { pTarget->mTradeItems[Index] = NULL; } else { pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true); } } } // Dump all items back into the opposite players inventory for(uint32 Index = 0; Index < 6; ++Index) { pItem = _player->mTradeItems[Index]; if(pItem != 0 && pTarget) { pItem->SetOwner(pTarget); // crash fixed. if( !pTarget->m_ItemInterface->AddItemToFreeSlot(pItem) ) pItem->DeleteMe(); } pItem = pTarget->mTradeItems[Index]; if(pItem != 0 && _player) { pItem->SetOwner(_player); if( !_player->m_ItemInterface->AddItemToFreeSlot(pItem) ) pItem->DeleteMe(); } } // Trade Gold if(pTarget->mTradeGold) { _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, pTarget->mTradeGold); pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pTarget->mTradeGold); } if(_player->mTradeGold) { pTarget->ModUnsigned32Value(PLAYER_FIELD_COINAGE, _player->mTradeGold); _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)_player->mTradeGold); } // Close Window TradeStatus = TRADE_STATUS_COMPLETE; } #ifdef USING_BIG_ENDIAN swap32(&TradeStatus); OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); swap32(&TradeStatus); #else OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); plr->m_session->OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus); #endif _player->mTradeStatus = TRADE_STATUS_COMPLETE; plr->mTradeStatus = TRADE_STATUS_COMPLETE; // Reset Trade Vars _player->ResetTradeVariables(); pTarget->ResetTradeVariables(); plr->mTradeTarget = 0; _player->mTradeTarget = 0; // Save for eachother plr->SaveToDB(false); _player->SaveToDB(false); } }
void WorldSession::HandleChannelJoin(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket, 1); string channelname,pass; uint32 dbc_id = 0; uint16 crap; // crap = some sort of channel type? uint32 i; Channel * chn; recvPacket >> dbc_id >> crap; recvPacket >> channelname; recvPacket >> pass; if(!stricmp(channelname.c_str(), "LookingForGroup") && !sWorld.m_lfgForNonLfg) { // make sure we have lfg dungeons for(i = 0; i < 3; ++i) { if(_player->LfgDungeonId[i] != 0) break; } if(i == 3) return; // don't join lfg } if( sWorld.GmClientChannel.size() && !stricmp(sWorld.GmClientChannel.c_str(), channelname.c_str()) && !GetPermissionCount()) return; chn = channelmgr.GetCreateChannel(channelname.c_str(), _player, dbc_id); if(chn == NULL) return; chn->AttemptJoin(_player, pass.c_str()); DEBUG_LOG("ChannelJoin", "%s", channelname.c_str()); }
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 9); WorldPacket *data; if(!_player->IsInWorld()) return; uint32 type; int32 lang; const char * pMisc = 0; const char * pMsg = 0; recv_data >> type; recv_data >> lang; if( lang >= NUM_LANGUAGES ) return; if(GetPlayer()->IsBanned()) { GetPlayer()->BroadcastMessage("You cannot do that when banned."); return; } if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines) { /* flood detection, wheeee! */ if(UNIXTIME >= floodTime) { floodLines = 0; floodTime = UNIXTIME + sWorld.flood_seconds; } if((++floodLines) > sWorld.flood_lines) { if(sWorld.flood_message) _player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME); return; } } std::stringstream irctext; irctext.rdbuf()->str(""); std::string msg; msg.reserve(256); //arghhh STFU. I'm not giving you gold or items NOOB switch(type) { case CHAT_MSG_EMOTE: case CHAT_MSG_SAY: case CHAT_MSG_YELL: case CHAT_MSG_WHISPER: case CHAT_MSG_CHANNEL: { if( m_muted && m_muted >= (uint32)UNIXTIME ) { SystemMessage("Your voice is currently muted by a moderator."); return; } }break; } switch(type) { case CHAT_MSG_EMOTE: { recv_data >> msg; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ,true ); //sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; }break; case CHAT_MSG_SAY: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->m_modlanguage >=0) { data = sChatHandler.FillMessageData( CHAT_MSG_SAY, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); GetPlayer()->SendMessageToSet( data, true ); } else { if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; data = sChatHandler.FillMessageData( CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendChatPacket(data, 1, lang, this); for(set<Player*>::iterator itr = _player->m_inRangePlayers.begin(); itr != _player->m_inRangePlayers.end(); ++itr) { (*itr)->GetSession()->SendChatPacket(data, 1, lang, this); } } //sLog.outString("[say] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Group *pGroup = _player->GetGroup(); if(pGroup == NULL) break; if(GetPlayer()->m_modlanguage >=0) data=sChatHandler.FillMessageData( type, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data=sChatHandler.FillMessageData( type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0); if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID) { // only send to that subgroup SubGroup * sgr = _player->GetGroup() ? _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0; if(sgr) { _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } else { SubGroup * sgr; for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i) { sgr = _player->GetGroup()->GetSubGroup(i); _player->GetGroup()->Lock(); for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr) { if((*itr)->m_loggedInPlayer) (*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this); } _player->GetGroup()->Unlock(); } } //sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str()); delete data; pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_GUILD: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) { break; } if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_OFFICER: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(_player->m_playerInfo->guild) _player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_YELL: { recv_data >> msg; if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_YELL, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); //SendPacket(data); //sWorld.SendZoneMessage(data, GetPlayer()->GetZoneId(), this); _player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this); delete data; //sLog.outString("[yell] %s: %s", _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=0; } break; case CHAT_MSG_WHISPER: { std::string to = "",tmp; recv_data >> to >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } Player *player = objmgr.GetPlayer(to.c_str(), false); if(!player) { data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1); *data << to; SendPacket(data); delete data; break; } // Check that the player isn't a gm with his status on if(!_player->GetSession()->GetPermissionCount() && player->bGMTagOn && player->gmTargets.count(_player) == 0) { // Send CHAT_MSG_WHISPER_INFORM packet WorldPacket *data2; data2 = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0); SendPacket(data2); delete data2; // Build automated reply string Reply = "This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message."; data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, LANG_UNIVERSAL, Reply.c_str(), player->GetGUID(), 4); SendPacket(data); delete data; break; } if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false) return; if(lang==0 && !CanUseCommand('c')) return; if( player->Social_IsIgnoring( _player->GetLowGUID() ) ) { data = sChatHandler.FillMessageData( CHAT_MSG_IGNORED, LANG_UNIVERSAL, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); SendPacket(data); delete data; } else { if(GetPlayer()->m_modlanguage >=0) data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, GetPlayer()->m_modlanguage, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); else data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, ((CanUseCommand('c') || player->GetSession()->CanUseCommand('c')) && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 ); player->GetSession()->SendPacket(data); delete data; } //Sent the to Users id as the channel, this should be fine as it's not used for wisper data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0 ); SendPacket(data); delete data; if(player->HasFlag(PLAYER_FLAGS, 0x02)) { // Has AFK flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } else if(player->HasFlag(PLAYER_FLAGS, 0x04)) { // Has DND flag, autorespond. data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0); SendPacket(data); delete data; } //sLog.outString("[whisper] %s to %s: %s", _player->GetName(), to.c_str(), msg.c_str()); pMsg=msg.c_str(); pMisc=to.c_str(); } break; case CHAT_MSG_CHANNEL: { std::string channel = ""; recv_data >> channel; recv_data >> msg; if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if (sChatHandler.ParseCommands(msg.c_str(), this) > 0) break; Channel *chn = channelmgr.GetChannel(channel.c_str(),GetPlayer()); if(chn) chn->Say(GetPlayer(),msg.c_str(), NULL, false); //sLog.outString("[%s] %s: %s", channel.c_str(), _player->GetName(), msg.c_str()); pMsg=msg.c_str(); pMisc=channel.c_str(); } break; case CHAT_MSG_AFK: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } /* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/ if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x02)) { GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.RemoveEvents(GetPlayer(),EVENT_PLAYER_SOFT_DISCONNECT); } else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x02); if(sWorld.GetKickAFKPlayerTime()) sEventMgr.AddEvent(GetPlayer(),&Player::SoftDisconnect,EVENT_PLAYER_SOFT_DISCONNECT,sWorld.GetKickAFKPlayerTime(),1,0); } } break; case CHAT_MSG_DND: { std::string reason; recv_data >> reason; GetPlayer()->SetAFKReason(reason); if(g_chatFilter->Parse(msg) == true) { SystemMessage("Your chat message was blocked by a server-side filter."); return; } if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x04)) GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x04); else { GetPlayer()->SetFlag(PLAYER_FLAGS, 0x04); } } break; default: sLog.outError("CHAT: unknown msg type %u, lang: %u", type, lang); } if(pMsg) sHookInterface.OnChat(_player, type, lang, pMsg, pMisc); }
void WorldSession::HandleChannelJoin(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket, 1); string channelname,pass; uint32 dbc_id = 0; uint16 crap; // crap = some sort of channel type? Actually it seems that this is 2 bytes and not 1 uint16 Channel * chn; recvPacket >> crap; // seems like 00 and 01 recvPacket >> dbc_id; recvPacket >> channelname; recvPacket >> pass; if(!stricmp(channelname.c_str(), "LookingForGroup") && !sWorld.m_lfgForNonLfg) { /* // make sure we have lfg dungeons for(uint32 i = 0; i < MAX_LFG_QUEUE_ID; ++i) { if(_player->LfgDungeonId[i] != 0) break; } if(i == MAX_LFG_QUEUE_ID) return; // don't join lfg */ //are we looking to any dungeons at all ? if( _player->LFG_dungeons.begin() == NULL ) return; } if( sWorld.GmClientChannel.size() && !stricmp(sWorld.GmClientChannel.c_str(), channelname.c_str()) && !GetPermissionCount()) { return; } chn = channelmgr.GetCreateChannel(channelname.c_str(), _player, dbc_id); if(chn == NULL) { return; } chn->AttemptJoin(_player, pass.c_str()); Log.Debug("ChannelJoin", "%s", channelname.c_str()); }