void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { m_playerLoading = true; uint64 playerGuid = 0; DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); recv_data >> playerGuid; Player* plr = new Player(this); ASSERT(plr); plr->SetSession(this); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!plr->LoadFromDB(GUID_LOPART(playerGuid))) { m_playerLoading = false; return; } //plr->_RemoveAllItemMods(); //set a count of unread mails: QueryResult *resultMails = sDatabase.PQuery("SELECT COUNT(id) FROM `mail` WHERE `receiver` = '%u' AND `checked` = 0", GUID_LOPART(playerGuid)); if (resultMails) { Field *fieldMail = resultMails->Fetch(); plr->unReadMails = fieldMail[0].GetUInt8(); delete resultMails; } else plr->unReadMails = 0; SetPlayer(plr); WorldPacket data( SMSG_ACCOUNT_DATA_MD5, (80) ); for(int i = 0; i < 80; i++) data << uint8(0); SendPacket(&data); Player *pCurrChar = GetPlayer(); pCurrChar->LoadIgnoreList(); pCurrChar->SendFriendlist(); pCurrChar->SendIgnorelist(); sChatHandler.FillSystemMessageData(&data, this, sWorld.GetMotd()); SendPacket( &data ); DEBUG_LOG( "WORLD: Sent motd (SMSG_MESSAGECHAT)" ); if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); if(guild) { data.Initialize(SMSG_GUILD_EVENT, (2+guild->GetMOTD().size()+1)); data << (uint8)GE_MOTD; data << (uint8)1; data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; data<<pCurrChar->GetName(); data<<(uint8)0<<(uint8)0<<(uint8)0; guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member not existed guild (id: %u), removing guild membership for player.",pCurrChar->GetName(),pCurrChar->GetGUIDLow(),pCurrChar->GetGuildId()); pCurrChar->SetUInt32Value(PLAYER_GUILDID,0); pCurrChar->SetUInt32ValueInDB(PLAYER_GUILDID,0,pCurrChar->GetGUID()); } } // home bind stuff Field *fields; QueryResult *result7 = sDatabase.PQuery("SELECT COUNT(`guid`) FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); if (result7) { int cnt; fields = result7->Fetch(); cnt = fields[0].GetUInt32(); if ( cnt > 0 ) { QueryResult *result4 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `character_homebind` WHERE `guid` = '%u'", GUID_LOPART(playerGuid)); assert(result4); fields = result4->Fetch(); data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result4; } else { int plrace = GetPlayer()->getRace(); int plclass = GetPlayer()->getClass(); QueryResult *result5 = sDatabase.PQuery("SELECT `map`,`zone`,`position_x`,`position_y`,`position_z` FROM `playercreateinfo` WHERE `race` = '%u' AND `class` = '%u'", plrace, plclass); assert(result5); fields = result5->Fetch(); // store and send homebind for player sDatabase.PExecute("INSERT INTO `character_homebind` (`guid`,`map`,`zone`,`position_x`,`position_y`,`position_z`) VALUES ('%u', '%u', '%u', '%f', '%f', '%f')", GUID_LOPART(playerGuid), fields[0].GetUInt32(), fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); data.Initialize (SMSG_BINDPOINTUPDATE, 5*4); data << fields[2].GetFloat() << fields[3].GetFloat() << fields[4].GetFloat(); data << fields[0].GetUInt32(); data << fields[1].GetUInt32(); SendPacket (&data); DEBUG_LOG("Setting player home position: mapid is: %u, zoneid is %u, X is %f, Y is %f, Z is %f\n",fields[0].GetUInt32(),fields[1].GetUInt32(),fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); delete result5; } delete result7; } data.Initialize( SMSG_TUTORIAL_FLAGS, 8*32 ); for (int i = 0; i < 8; i++) data << uint32( GetPlayer()->GetTutorialInt(i) ); SendPacket(&data); //sLog.outDebug( "WORLD: Sent tutorial flags." ); GetPlayer()->SendInitialSpells(); GetPlayer()->SendInitialActionButtons(); /*if(GetPlayer()->getClass() == CLASS_HUNTER || GetPlayer()->getClass() == CLASS_ROGUE) { uint32 shiftdata=0x01; for(uint8 i=0;i<32;i++) { if ( 522753 & shiftdata ) { data.Initialize(SMSG_SET_FLAT_SPELL_MODIFIER); data << uint8(i); data << uint8(5); data << uint16(1); data << uint16(0); SendPacket(&data); } shiftdata=shiftdata<<1; } }*/ data.Initialize(SMSG_INITIALIZE_FACTIONS, (4+64*5)); data << uint32 (0x00000040); for(uint32 a=0; a<64; a++) { if(GetPlayer()->FactionIsInTheList(a)) { std::list<struct Factions>::iterator itr; for(itr = GetPlayer()->factions.begin(); itr != GetPlayer()->factions.end(); ++itr) { if(itr->ReputationListID == a) { data << uint8 (itr->Flags); data << uint32 (itr->Standing); break; } } } else { data << uint8 (0x00); data << uint32 (0x00000000); } } SendPacket(&data); GetPlayer()->UpdateHonor(); data.Initialize(SMSG_LOGIN_SETTIMESPEED, 8); time_t gameTime = sWorld.GetGameTime(); struct tm *lt = localtime(&gameTime); uint32 xmitTime = (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min; data << xmitTime; data << (uint32)0x3C888889; //(float)0.017f; SendPacket( &data ); //Show cinematic at the first time that player login if( !GetPlayer()->getCinematic() ) { GetPlayer()->setCinematic(1); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(GetPlayer()->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } QueryResult *result = sDatabase.PQuery("SELECT `guildid`,`rank` FROM `guild_member` WHERE `guid` = '%u'",pCurrChar->GetGUIDLow()); if(result) { Field *fields = result->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete result; } MapManager::Instance().GetMap(pCurrChar->GetMapId())->Add(pCurrChar); ObjectAccessor::Instance().InsertPlayer(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); if (pCurrChar->m_transport) { Transport* curTrans = pCurrChar->m_transport; pCurrChar->TeleportTo(curTrans->GetMapId(), curTrans->GetPositionX(), curTrans->GetPositionY(), curTrans->GetPositionZ(), curTrans->GetOrientation(), true, false); } sDatabase.PExecute("UPDATE `character` SET `online` = 1 WHERE `guid` = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE `account` SET `online` = 1 WHERE `id` = '%u'", GetAccountId()); plr->SetInGameTime( getMSTime() ); data.Initialize(SMSG_FRIEND_STATUS, 19); data<<uint8(FRIEND_ONLINE); data<<pCurrChar->GetGUID(); data<<uint8(1); data<<pCurrChar->GetAreaId(); data<<pCurrChar->getLevel(); data<<pCurrChar->getClass(); pCurrChar->BroadcastPacketToFriendListers(&data); // setting new speed if dead if ( pCurrChar->m_deathState == DEAD ) { pCurrChar->SetMovement(MOVE_WATER_WALK); if (pCurrChar->getRace() == RACE_NIGHTELF) { pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); } else { pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); } } pCurrChar->LoadEnchant(); pCurrChar->_LoadSpellCooldowns(); // Place charcter in world (and load zone) before some object loading pCurrChar->LoadCorpse(); pCurrChar->LoadPet(); // show time before shutdown if shudown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); result = sDatabase.PQuery("SELECT `leaderGuid` FROM `raidgroup_member` WHERE `memberGuid`='%u'", GUID_LOPART(pCurrChar->GetGUID())); if(result) { uint64 leaderGuid = MAKE_GUID((*result)[0].GetUInt32(),HIGHGUID_PLAYER); delete result; pCurrChar->groupInfo.group = objmgr.GetGroupByLeader(leaderGuid); if(pCurrChar->groupInfo.group) { pCurrChar->groupInfo.group->SendInit(this); pCurrChar->groupInfo.group->SendUpdate(); } } if(pCurrChar->isGameMaster()) SendNotification("GM mode is ON"); m_playerLoading = false; }
void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recvData) { sLog->outDebug("CMSG_ARENA_TEAM_INVITE"); uint32 arenaTeamId; // arena team id std::string invitedName; Player* player = NULL; recvData >> arenaTeamId >> invitedName; if (!invitedName.empty()) { if (!normalizePlayerName(invitedName)) return; player = sObjectAccessor->FindPlayerByName(invitedName.c_str()); } if (!player) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", invitedName, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S); return; } ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId); if (!arenaTeam) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); return; } // OK result but don't send invite if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; } if (player->GetArenaTeamId(arenaTeam->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; } if (player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, arenaTeam->GetName(), "", ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S); return; } sLog->outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), invitedName.c_str()); player->SetArenaTeamIdInvited(arenaTeam->GetId()); WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); data << arenaTeam->GetName(); player->GetSession()->SendPacket(&data); sLog->outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE"); }
void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { if (GetPlayer()->_trade) return; uint64 ID; if (!GetPlayer()->isAlive()) { SendTradeStatus(TRADE_STATUS_YOU_DEAD); return; } if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED)) { SendTradeStatus(TRADE_STATUS_YOU_STUNNED); return; } if (isLogingOut()) { SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); return; } if (GetPlayer()->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; } if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetSkyFireString(LANG_TRADE_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } recvPacket >> ID; Player* pOther = ObjectAccessor::FindPlayer(ID); if (!pOther) { SendTradeStatus(TRADE_STATUS_NO_TARGET); return; } if (pOther == GetPlayer() || pOther->_trade) { SendTradeStatus(TRADE_STATUS_BUSY); return; } if (!pOther->isAlive()) { SendTradeStatus(TRADE_STATUS_TARGET_DEAD); return; } if (pOther->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; } if (pOther->HasUnitState(UNIT_STATE_STUNNED)) { SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); return; } if (pOther->GetSession()->isLogingOut()) { SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); return; } if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendTradeStatus(TRADE_STATUS_IGNORE_YOU); return; } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam()) { SendTradeStatus(TRADE_STATUS_WRONG_FACTION); return; } if (!pOther->IsWithinDistInMap(_player, 10.0f, false)) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; } if (pOther->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetSkyFireString(LANG_TRADE_OTHER_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } // OK start trade _player->_trade = new TradeData(_player, pOther); pOther->_trade = new TradeData(pOther, _player); WorldPacket data(SMSG_TRADE_STATUS, 1+8+4+4+4+1+4+4+4); data << uint8(0); data << uint64(_player->GetGUID()); data << uint32(0); data << uint32(TRADE_STATUS_BEGIN_TRADE); data << uint32(0); data << uint8(0); data << uint32(0); data << uint32(0); data << uint32(0); pOther->GetSession()->SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = objmgr.GetPlayer(Guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if(Aura * pAura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << (uint32) pAura->GetId(); data << (uint8) 1; } } data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if(Aura * pAura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << (uint32) pAura->GetId(); data << (uint8) 1; } } data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void ArathiBasin::EventUpdateResources(uint32 Team) { static uint32 resource_fields[2] = { WORLDSTATE_AB_ALLIANCE_RESOURCES, WORLDSTATE_AB_HORDE_RESOURCES }; uint32 current_resources = m_resources[Team]; uint32 current_bases = m_capturedBases[Team]; if(current_bases>5) current_bases=5; // figure out how much resources we have to add to that team based on the number of captured bases. current_resources += (PointBonusPerUpdate[current_bases]); // did it change? if(current_resources == m_resources[Team]) return; m_mainLock.Acquire(); // check for overflow if(current_resources > RESOURCES_WINVAL) current_resources = RESOURCES_WINVAL; m_resources[Team] = current_resources; if((current_resources - m_lastHonorGainResources[Team]) >= m_resToGainBH) { m_lastHonorGainResources[Team] += m_resToGainBH; for(set< Player* >::iterator itr = m_players[Team].begin(); itr != m_players[Team].end(); itr++) { (*itr)->m_bgScore.BonusHonor += m_bonusHonor; HonorHandler::AddHonorPointsToPlayer((*itr), m_bonusHonor); } } // update the world states m_mapMgr->GetStateManager().UpdateWorldState(resource_fields[Team], current_resources); if(current_resources >= RESOURCES_WARNING_THRESHOLD && !m_nearingVictory[Team]) { m_nearingVictory[Team] = true; SendChatMessage(Team ? CHAT_MSG_BG_SYSTEM_HORDE : CHAT_MSG_BG_SYSTEM_ALLIANCE, (uint64)0, "The %s has gathered %u resources and is nearing victory!", Team ? "Horde" : "Alliance", current_resources); uint32 sound = SOUND_ALLIANCE_BGALMOSTEND - Team; PlaySoundToAll(sound); } // check for winning condition if(current_resources == RESOURCES_WINVAL) { m_ended = true; m_losingteam = (Team) ? 0 : 1; m_nextPvPUpdateTime = 0; sEventMgr.RemoveEvents(this); sEventMgr.AddEvent(TO_CBATTLEGROUND(this), &CBattleground::Close, EVENT_BATTLEGROUND_CLOSE, 120000, 1,0); SendChatMessage( CHAT_MSG_BG_SYSTEM_NEUTRAL, 0, "|cffffff00This battleground will close in 2 minutes."); for(uint32 i = 0; i < 2; i++) { for(set<Player* >::iterator itr = m_players[i].begin(); itr != m_players[i].end(); itr++) { (*itr)->Root(); if( (*itr)->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK) ) continue; if(i == m_losingteam) { (*itr)->m_bgScore.BonusHonor += m_bonusHonor; HonorHandler::AddHonorPointsToPlayer((*itr), m_bonusHonor); if((*itr)->fromrandombg) { (*itr)->m_honorToday += (*itr)->GenerateRBGReward((*itr)->getLevel(),5); HonorHandler::RecalculateHonorFields((*itr)); (*itr)->fromrandombg = false; } } else { (*itr)->m_bgScore.BonusHonor += 2*m_bonusHonor; HonorHandler::AddHonorPointsToPlayer((*itr), 2*m_bonusHonor); uint32 diff = abs((int32)(m_resources[i] - m_resources[i ? 0 : 1])); (*itr)->GetAchievementInterface()->HandleAchievementCriteriaWinBattleground( m_mapMgr->GetMapId(), diff, ((uint32)UNIXTIME - m_startTime) / 1000, TO_CBATTLEGROUND(this)); if((*itr)->fromrandombg) { Player * p = (*itr); p->AddArenaPoints(p->randombgwinner == false ? p->GenerateRBGReward(p->getLevel(),25) : p->GenerateRBGReward(p->getLevel(),0)); p->m_honorToday += p->randombgwinner == false ? p->GenerateRBGReward(p->getLevel(),30) : p->GenerateRBGReward(p->getLevel(),15); HonorHandler::RecalculateHonorFields(p); p->randombgwinner = true; p->fromrandombg = false; } } } } } UpdatePvPData(); m_mainLock.Release(); }
void WorldSession::HandleGrantLevel(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: CMSG_GRANT_LEVEL"); ObjectGuid guid; guid[2] = recvData.ReadBit(); // 18 guid[1] = recvData.ReadBit(); // 17 guid[5] = recvData.ReadBit(); // 21 guid[3] = recvData.ReadBit(); // 19 guid[7] = recvData.ReadBit(); // 23 guid[4] = recvData.ReadBit(); // 20 guid[0] = recvData.ReadBit(); // 16 guid[6] = recvData.ReadBit(); // 22 recvData.ReadByteSeq(guid[1]); // 17 recvData.ReadByteSeq(guid[4]); // 20 recvData.ReadByteSeq(guid[2]); // 18 recvData.ReadByteSeq(guid[7]); // 23 recvData.ReadByteSeq(guid[5]); // 21 recvData.ReadByteSeq(guid[3]); // 19 recvData.ReadByteSeq(guid[6]); // 22 recvData.ReadByteSeq(guid[0]); // 16 Player* target = ObjectAccessor::GetObjectInWorld(guid, _player); // check cheating uint8 levels = _player->GetGrantableLevels(); uint8 error = 0; if (!target) error = ERR_REFER_A_FRIEND_NO_TARGET; else if (levels == 0) error = ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS; else if (GetRecruiterId() != target->GetSession()->GetAccountId()) error = ERR_REFER_A_FRIEND_NOT_REFERRED_BY; else if (target->GetTeamId() != _player->GetTeamId()) error = ERR_REFER_A_FRIEND_DIFFERENT_FACTION; else if (target->getLevel() >= _player->getLevel()) error = ERR_REFER_A_FRIEND_TARGET_TOO_HIGH; else if (target->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) error = ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I; else if (target->GetGroup() != _player->GetGroup()) error = ERR_REFER_A_FRIEND_NOT_IN_GROUP; if (error) { WorldPacket data(SMSG_REFER_A_FRIEND_FAILURE, 24); data << uint32(error); if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP) data << target->GetName(); SendPacket(&data); return; } ObjectGuid oGUID = _player->GetGUID(); WorldPacket data2(SMSG_PROPOSE_LEVEL_GRANT, 8); data2.WriteBit(oGUID[6]); // 22 data2.WriteBit(oGUID[7]); // 23 data2.WriteBit(oGUID[2]); // 18 data2.WriteBit(oGUID[5]); // 21 data2.WriteBit(oGUID[3]); // 19 data2.WriteBit(oGUID[0]); // 16 data2.WriteBit(oGUID[1]); // 17 data2.WriteBit(oGUID[4]); // 20 data2.WriteByteSeq(oGUID[2]); // 18 data2.WriteByteSeq(oGUID[5]); // 21 data2.WriteByteSeq(oGUID[6]); // 22 data2.WriteByteSeq(oGUID[7]); // 23 data2.WriteByteSeq(oGUID[1]); // 17 data2.WriteByteSeq(oGUID[4]); // 20 data2.WriteByteSeq(oGUID[3]); // 19 data2.WriteByteSeq(oGUID[0]); // 16 target->GetSession()->SendPacket(&data2); }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "Received opcode CMSG_OFFER_PETITION"); // ok uint8 signs = 0; uint64 petitionguid, plguid; uint32 type, junk; Player* player; recvData >> junk; // this is not petition type! recvData >> petitionguid; // petition guid recvData >> plguid; // player guid player = ObjectAccessor::FindPlayer(plguid); if (!player) return; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); stmt->setUInt32(0, GUID_LOPART(petitionguid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) return; Field* fields = result->Fetch(); type = fields[0].GetUInt8(); TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionguid), GUID_LOPART(plguid)); if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam()) { if (type != GUILD_CHARTER_TYPE) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } if (type != GUILD_CHARTER_TYPE) { if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { // player is too low level to join an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ARENA_TEAM_TARGET_TOO_LOW_S); return; } uint8 slot = ArenaTeam::GetSlotByType(type); if (slot >= MAX_ARENA_SLOT) return; if (player->GetArenaTeamId(slot)) { // player is already in an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName().c_str(), "", ERR_ALREADY_IN_ARENA_TEAM_S); return; } if (player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName().c_str(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } } else { if (player->GetGuildId()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (player->GetGuildIdInvited()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); stmt->setUInt32(0, GUID_LOPART(petitionguid)); result = CharacterDatabase.Query(stmt); // result == NULL also correct charter without signs if (result) signs = uint8(result->GetRowCount()); WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12)); data << uint64(petitionguid); // petition guid data << uint64(_player->GetGUID()); // owner guid data << uint32(GUID_LOPART(petitionguid)); // guild guid data << uint8(signs); // sign's count for (uint8 i = 1; i <= signs; ++i) { Field* fields2 = result->Fetch(); data << uint64(MAKE_NEW_GUID(fields2[0].GetUInt32(), 0, HIGHGUID_PLAYER)); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); } player->GetSession()->SendPacket(&data); }
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER"); //recv_data.hexlike(); CHECK_PACKET_SIZE(recv_data, 4+1); uint32 ArenaTeamId; // arena team id std::string Invitedname; Player * player = NULL; recv_data >> ArenaTeamId >> Invitedname; if(!Invitedname.empty()) { if(!normalizePlayerName(Invitedname)) return; player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); } if(!player) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) { //SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S); // can't find related opcode SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName()); return; } ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); if(!arenateam) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); return; } // OK result but not send invite if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; } if(player->GetArenaTeamId(arenateam->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S); return; } if(player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } if(arenateam->GetMembersSize() >= arenateam->GetType() * 2) { // should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL // SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL); SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName()); return; } sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str()); player->SetArenaTeamIdInvited(arenateam->GetId()); WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); data << arenateam->GetName(); player->GetSession()->SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE"); }
int main() { t_win w; int c; int g = 0; int direction = 0; int index = 0; int index_2 = 0; std::srand(std::time(NULL)); initscr(); start_color(); init_color(COLOR_BLUE, 222,184, 135); //light brown color init_color(COLOR_YELLOW, 500,400, 300); init_pair(1, COLOR_YELLOW, COLOR_BLACK); init_pair(2, COLOR_BLUE, COLOR_BLACK); init_pair(5, COLOR_MAGENTA, COLOR_BLACK); init_pair(6, COLOR_GREEN, COLOR_BLACK); init_pair(7, COLOR_WHITE, COLOR_BLACK); curs_set(0); cbreak(); noecho(); nodelay(stdscr, TRUE); keypad(stdscr, TRUE); // srand(NULL); Player a; int difficulty = 0; // Enemy b; int i = 0; // int wave = 5; // int y = 0; // int next_line = 0; // int half_line = 0; // if (a.getLevel() == 0) // ARMY = 5; Enemy b[ARMY]; Fire x[SCUD]; FireEnemy p[KRR]; Background back(COLS, LINES); Enemy e[3] = { Enemy("{@@}", "/''\\", 5), Enemy("dOOb", "^/\\^", 6), Enemy("/MM\\", "\\~~/", 7)}; while (i < SCUD) { x[i].setExist(0); i++; } i = 0; while (i < KRR) { p[i].setExist(0); i++; } i = 0; // int random; ft_init(1, b, x, p, e); // while (i < ARMY) { // y = 0; // if (y < WAVE && i < ARMY) { // next_line++; // if (next_line % 2 == 0) // half_line = 5; // else // half_line = 0; // while (y < WAVE && i < ARMY) { // b[i].setPosX(15 - (next_line * 2)); // b[i].setPosY(10 * (y + 1) - half_line); // b[i].setMaxX(LINES - 3); // b[i].setMaxY((COLS - 2) - half_line); // random = std::rand() % 2; // b[i].setExist(random); // random = std::rand() % 3; // b[i].setName(e[random].getName()); // b[i].setName2(e[random].getName2()); // i++; // y++; // } // } // } index = 0; w.win = subwin(stdscr, LINES * 0.9, COLS, LINES * 0.1, 0); w.score = subwin(stdscr, LINES * 0.1, COLS, 0, 0); box(w.win, ACS_VLINE, ACS_HLINE); box(w.score, ACS_VLINE, ACS_HLINE); a.setPosX(LINES - 10); a.setPosY(COLS / 2); a.setMaxX(LINES - 1); a.setMaxY(COLS - 3); a.setScore(0); a.setLife(3); a.setLevel(0); mvwprintw(w.score, 1, 5, "SCORE : "); std::string score_display = std::to_string(a.getScore()); mvwprintw(w.score, 1, 14, score_display.c_str()); mvwprintw(w.score, 2, 5, "TIME : "); mvwprintw(w.score, 1, COLS - 15, "LIFE : "); std::string life_display = std::to_string(a.getLife()); mvwprintw(w.score, 1, COLS - 8, life_display.c_str()); mvwprintw(w.score, 2, COLS - 15, "LEVEL : "); ft_display_ship(&w, a.getPosX(), a.getPosY()); ft_display_enemy(b, &w, difficulty); // mvwprintw(w.win, a.getPosX(), a.getPosY(), "/.\\"); // wrefresh(w.win); struct timeval t; struct timezone z; long int ut = t.tv_sec * 1000 + t.tv_usec / 1000; long int ut2 = t.tv_sec * 1000 + t.tv_usec / 1000; long int ut3 = t.tv_sec * 1000 + t.tv_usec / 1000; long int ut4 = t.tv_sec * 1000 + t.tv_usec / 1000; std::string time_display = std::to_string(ut); mvwprintw(w.win, 10, 10, time_display.c_str()); // ut += 1000; std::string time2_display = std::to_string(ut); mvwprintw(w.win, 11, 10, time2_display.c_str()); wrefresh(w.win); // sleep(5); // int wave = 0; i = 10; int n_time = time(NULL); int m_time = time(NULL); time_t timer; time_t buf; time(&buf); time(&timer); int seconds = 0; while (1) { int y = 0; difficulty = (a.getLevel() + 1) * (ARMY / 10); while (y < SCUD) { i = 0; while (i < difficulty) { if (b[i].getPosY() == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } else if (b[i].getPosY() - 1 == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } else if (b[i].getPosY() + 4 == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } else if (b[i].getPosY() + 3 == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } else if (b[i].getPosY() + 2 == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } else if (b[i].getPosY() + 1 == x[y].getPosY() && b[i].getPosX() == x[y].getPosX() && b[i].getExist() == 1 && x[y].getExist() == 1) { x[y].setExist(0); b[i].setExist(0); a.setScore(a.getScore() + 10); } i++; } y++; } i = 0; while (i < KRR) { if (p[i].getPosY() == a.getPosY() && p[i].getPosX() == a.getPosX()) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 1 && p[i].getPosX() == a.getPosX()) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 2 && p[i].getPosX() == a.getPosX()) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() - 1 && p[i].getPosX() == a.getPosX() + 1) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 1 && p[i].getPosX() == a.getPosX() + 1) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 2 && p[i].getPosX() == a.getPosX() + 1) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 3 && p[i].getPosX() == a.getPosX() + 1) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } if (p[i].getPosY() == a.getPosY() + 4 && p[i].getPosX() == a.getPosX() + 1) { if (m_time < time(NULL)) { a.setLife(a.getLife() - 1); p[i].setExist(0); m_time = time(NULL); m_time += 1; } } i++; } // std::string life_display = std::to_string(a.getLife()); mvwprintw(w.score, 1, COLS - 8, "%d", a.getLife()); mvwprintw(w.score, 2, COLS - 8, "%d", a.getLevel()); time(&timer); seconds = difftime(timer, buf); mvwprintw(w.score, 2, 14, "%d", seconds); wrefresh(w.score); i = 0; int lose = 0; while (i < difficulty) { if (b[i].getPosY() == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() + 1 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() + 2 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() + 3 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() + 4 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() - 1 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosY() - 2 == a.getPosY() && b[i].getPosX() == a.getPosX() && b[i].getExist() == 1) { a.setLife(0); lose = 1; } else if (b[i].getPosX() == LINES - 5) { lose = 1; } i++; } i = 0; // while (i < ARMY) { // if () // } if (a.getLife() == 0) { lose = 1; } if (lose == 1) { ft_display_clear(&w); mvwprintw(w.win, LINES / 3, COLS / 2 - 4, "GAME OVER"); mvwprintw(w.win, LINES / 3 + 2, COLS / 2 - 12, "Try again? (Level 0) [y/n]"); wrefresh(w.win); while (1) { if ((c = getch()) != ERR) { if (c == 121) { mvwprintw(w.win, LINES / 3 + 5, COLS / 2 - 9, "Please insert credit"); wrefresh(w.win); } if (c == 110 || c == 27) { endwin(); std::exit(0); } } } } i = 0; while (i < difficulty) { if (b[i].getExist() == 1 && b[i].getPosY() == a.getPosY()) { if (n_time < time(NULL)) { p[index_2] = FireEnemy(); p[index_2].setPosX(b[i].getPosX() + 1); p[index_2].setPosY(b[i].getPosY()); p[index_2].setExist(1); n_time = time(NULL); // n_time += 2; index_2++; } } i++; } i = 0; int win_level = 1; while (i < difficulty) { if (b[i].getExist() == 1) win_level = 0; i++; } if (win_level == 1) { a.setLevel(a.getLevel() + 1); ft_display_clear(&w); mvwprintw(w.win, LINES / 3, COLS / 2 - 4, "WIN"); mvwprintw(w.win, LINES / 3 + 2, COLS / 2 - 12, "Next Level? [y/n]"); wrefresh(w.win); while (1) { if ((c = getch()) != ERR) { if (c == 121) { ft_init((a.getLevel() + 1), b, x, p, e); a.setPosX(LINES - 10); a.setPosY(COLS / 2); a.setMaxX(LINES - 1); a.setMaxY(COLS - 3); a.setLife(3); break ; } if (c == 110 || c == 27) { endwin(); std::exit(0); } } } } gettimeofday(&t, &z); if (ut3 + 2000 < t.tv_sec * 1000 + t.tv_usec / 1000) { ut3 = t.tv_sec * 1000 + t.tv_usec / 1000; g++; if (g == 40) g = 0; } if (ut4 + 10 < t.tv_sec * 1000 + t.tv_usec / 1000) { ut4 = t.tv_sec * 1000 + t.tv_usec / 1000; // back.move(); ft_display_clear(&w); // ft_display_planet(&w, g); ft_display_planet(&w, g); box(w.win, ACS_VLINE, ACS_HLINE); back.refresh(); ft_display_enemy(b, &w, difficulty); ft_display_fire(x, &w); ft_display_fire_enemy(p, &w); ft_display_ship(&w, a.getPosX(), a.getPosY()); wrefresh(w.win); } if (ut + 400 - ((a.getLevel() + 1) * 100) < t.tv_sec * 1000 + t.tv_usec / 1000) { ut = t.tv_sec * 1000 + t.tv_usec / 1000; ft_move_right_enemy(b, &direction, a.getLevel() + 1); // wclear(w.win); box(w.win, ACS_VLINE, ACS_HLINE); // back.refresh(); ft_display_enemy(b, &w, difficulty); ft_display_fire(x, &w); ft_display_ship(&w, a.getPosX(), a.getPosY()); // g++; std::string score_display = std::to_string(a.getScore()); mvwprintw(w.score, 1, 14, score_display.c_str()); wrefresh(w.score); wrefresh(w.win); } if (ut2 + 150 < t.tv_sec * 1000 + t.tv_usec / 1000) { ut2 = t.tv_sec * 1000 + t.tv_usec / 1000; i = 0; back.move(); while (i < SCUD) { x[i].setPosX(x[i].getPosX() - 1); i++; } i = 0; while (i < KRR) { p[i].setPosX(p[i].getPosX() + 1); i++; } box(w.win, ACS_VLINE, ACS_HLINE); // back.refresh(); ft_display_enemy(b, &w, difficulty); ft_display_fire(x, &w); ft_display_ship(&w, a.getPosX(), a.getPosY()); wrefresh(w.win); } if ((c = getch()) != ERR) { if (c == 27) { endwin(); std::exit(0); } if (c == KEY_LEFT) { if (a.getPosY() > 2) a.setPosY(a.getPosY() - 3); } if (c == KEY_RIGHT) { if (a.getPosY() < a.getMaxY()) a.setPosY(a.getPosY() + 3); } if (c == KEY_UP) { if (a.getPosX() - 5 > 0) a.setPosX(a.getPosX() - 2); } if (c == KEY_DOWN) { if (a.getPosX() + 5 < a.getMaxX()) a.setPosX(a.getPosX() + 2); } if (c == 32) { if (index == 199) index = 0; x[index] = Fire(); x[index].setPosX(a.getPosX() - 1); x[index].setPosY(a.getPosY() + 1); x[index].setExist(1); index++; } // wrefresh(w.win); c = 0; } } return 0; }
void WorldSession::HandleGroupInviteOpcode(WorldPacket& recv_data) { ObjectGuid guid; recv_data.read_skip<uint32>(); // cross-realm party related recv_data.read_skip<uint32>(); // roles mask? recv_data.ReadGuidMask<2, 7>(guid); uint32 realmLength = recv_data.ReadBits(9); recv_data.ReadGuidMask<3>(guid); uint32 nameLength = recv_data.ReadBits(10); recv_data.ReadGuidMask<5, 4, 6, 0, 1>(guid); recv_data.ReadGuidBytes<4, 7, 6>(guid); std::string membername = recv_data.ReadString(nameLength); std::string realmname = recv_data.ReadString(realmLength); // attempt add selected player // cheating if (!normalizePlayerName(membername)) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } Player* player = sObjectMgr.GetPlayer(membername.c_str()); // no player if (!player) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetSocial()->HasIgnore(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); if (group && group->isRaidGroup() && !player->GetAllowLowLevelRaid() && (player->getLevel() < sWorld.getConfig(CONFIG_UINT32_MIN_LEVEL_FOR_RAID))) { SendPartyResult(PARTY_OP_INVITE, "", ERR_RAID_DISALLOWED_BY_LEVEL); return; } // player already invited if (player->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); return; } Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); // player already in another group if (group2) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); // tell the player that they were invited but it failed as they were already in a group player->GetSession()->SendGroupInvite(player, true); return; } if (group) { // not have permissions for invite if (!group->IsLeader(GetPlayer()->GetObjectGuid()) && !group->IsAssistant(GetPlayer()->GetObjectGuid())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { group = new Group; // new group: if can't add then delete if (!group->AddLeaderInvite(GetPlayer())) { delete group; return; } if (!group->AddInvite(player)) { delete group; return; } } else { // already existing group: if can't add then just leave if (!group->AddInvite(player)) { return; } } player->GetSession()->SendGroupInvite(_player); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_AURAS | GROUP_UPDATE_FLAG_PHASE; if (pet) mask1 = 0x7FEFFEFF; // full mask & ~(GROUP_UPDATE_FLAG_VEHICLE_SEAT | GROUP_UPDATE_FLAG_UNK) Powers powerType = player->GetPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; uint16 iCoordZ = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); iCoordZ = player->GetPositionZ(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; iCoordZ = loc.coord_z; } else { // unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordZ); // GROUP_UPDATE_FLAG_POSITION data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->GetPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint8(1); // GROUP_UPDATE_FLAG_PET_AURAS data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint32(0); // GROUP_UPDATE_FLAG_PET_AURAS } if (player->GetTransportInfo()) // GROUP_UPDATE_FLAG_VEHICLE_SEAT data << uint32(((Unit*)player->GetTransportInfo()->GetTransport())->GetVehicleInfo()->GetVehicleEntry()->m_seatID[player->GetTransportInfo()->GetTransportSeat()]); data << uint32(8); // GROUP_UPDATE_FLAG_PHASE data << uint32(0); // GROUP_UPDATE_FLAG_PHASE data << uint8(0); // GROUP_UPDATE_FLAG_PHASE SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; data << uint8(0); // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder data << uint32(64); // how many bits client reads from auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << (uint32) aurApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; data << uint8(0); // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder data << uint32(64); // how many bits client reads from auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * auraApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << (uint32) auraApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_AURAS data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS data << (uint32) 0; } SendPacket(&data); }
void LfgMgr::SendLfgList( Player* plr, uint32 Dungeon ) { if( plr == NULL ) return; if( Dungeon >= MAX_DUNGEONS ) return; LfgPlayerList::iterator itr; GroupMembersSet::iterator it2; uint32 count = 0; Player * pl; uint32 i; uint64 tguid; SubGroup * sgrp; m_lock.Acquire(); WorldPacket data(MSG_LOOKING_FOR_GROUP, ((m_lookingForGroup[Dungeon].size() + m_lookingForMore[Dungeon].size()) * 20) + 20); data << LfgDungeonTypes[Dungeon]; data << Dungeon; data << uint32(m_lookingForGroup[Dungeon].size()); data << uint32(m_lookingForGroup[Dungeon].size()); for(itr = m_lookingForGroup[Dungeon].begin(); itr != m_lookingForGroup[Dungeon].end(); ++itr) { pl = *itr; if(pl->GetTeam() != plr->GetTeam() || pl == plr) continue; ++count; data << pl->GetNewGUID(); data << pl->getLevel(); data << pl->GetZoneId(); data << uint8(0); // 1=LFG? for(i = 0; i < MAX_LFG_QUEUE_ID; ++i) data << pl->LfgDungeonId[i] << uint8(0) << pl->LfgType[i]; data << pl->Lfgcomment; // LFG members are never in parties. data << uint32(0); } for(itr = m_lookingForMore[Dungeon].begin(); itr != m_lookingForMore[Dungeon].end(); ++itr) { pl = *itr; if(pl->GetTeam() != plr->GetTeam() || pl == plr) continue; ++count; data << pl->GetNewGUID(); data << pl->getLevel(); data << pl->GetZoneId(); data << uint8(1); // 1=LFM? for(i = 0; i < MAX_LFG_QUEUE_ID; ++i) data << pl->LfgDungeonId[i] << uint8(0) << pl->LfgType[i]; data << pl->Lfgcomment; if(pl->GetGroup() && pl->GetGroup()->GetGroupType() == GROUP_TYPE_PARTY) { pl->GetGroup()->Lock(); sgrp = pl->GetGroup()->GetSubGroup(0); data << uint32(sgrp->GetMemberCount() - 1); for(it2 = sgrp->GetGroupMembersBegin(); it2 != sgrp->GetGroupMembersEnd(); ++it2) { if((*it2)->m_loggedInPlayer) data << (*it2)->m_loggedInPlayer->GetNewGUID(); else { tguid = (*it2)->guid; FastGUIDPack(data, tguid); } } pl->GetGroup()->Unlock(); } else data << uint32(0); } m_lock.Release(); //*(uint32*)(data.contents()[8]) = count; //*(uint32*)(data.contents()[12]) = count; data.put(8, count); data.put(12, count); plr->GetSession()->SendPacket(&data); }
bool Guild::AddMember(ObjectGuid plGuid, uint32 plRank) { Player* pl = sObjectMgr.GetPlayer(plGuid); if (pl) { if (pl->GetGuildId() != 0) return false; } else { if (Player::GetGuildIdFromDB(plGuid) != 0) // player already in guild return false; } // remove all player signs from another petitions // this will be prevent attempt joining player to many guilds and corrupt guild data integrity Player::RemovePetitionsAndSigns(plGuid); uint32 lowguid = plGuid.GetCounter(); // fill player data MemberSlot newmember; newmember.guid = plGuid; if (pl) { newmember.accountId = pl->GetSession()->GetAccountId(); newmember.Name = pl->GetName(); newmember.Level = pl->getLevel(); newmember.Class = pl->getClass(); newmember.ZoneId = pl->GetZoneId(); } else { // 0 1 2 3 4 QueryResult* result = CharacterDatabase.PQuery("SELECT name,level,class,zone,account FROM characters WHERE guid = '%u'", lowguid); if (!result) return false; // player doesn't exist Field* fields = result->Fetch(); newmember.Name = fields[0].GetCppString(); newmember.Level = fields[1].GetUInt8(); newmember.Class = fields[2].GetUInt8(); newmember.ZoneId = fields[3].GetUInt32(); newmember.accountId = fields[4].GetInt32(); delete result; if (newmember.Level < 1 || newmember.Level > STRONG_MAX_LEVEL || !((1 << (newmember.Class - 1)) & CLASSMASK_ALL_PLAYABLE)) { sLog.outError("%s has a broken data in field `characters` table, cannot add him to guild.", plGuid.GetString().c_str()); return false; } } newmember.RankId = plRank; newmember.OFFnote = (std::string)""; newmember.Pnote = (std::string)""; newmember.LogoutTime = time(NULL); members[lowguid] = newmember; std::string dbPnote = newmember.Pnote; std::string dbOFFnote = newmember.OFFnote; CharacterDatabase.escape_string(dbPnote); CharacterDatabase.escape_string(dbOFFnote); CharacterDatabase.PExecute("INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')", m_Id, lowguid, newmember.RankId, dbPnote.c_str(), dbOFFnote.c_str()); // If player not in game data in data field will be loaded from guild tables, no need to update it!! if (pl) { pl->SetInGuild(m_Id); pl->SetRank(newmember.RankId); pl->SetGuildIdInvited(0); } UpdateAccountsNumber(); // used by eluna sEluna->OnAddMember(this, pl, newmember.RankId); return true; }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2); data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets uint16 online_status = GetPlayer()->IsReferAFriendLinked(player) ? (MEMBER_STATUS_ONLINE | MEMBER_STATUS_RAF) : MEMBER_STATUS_ONLINE; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(online_status); // member's online status data << uint16(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint16(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { // unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) { auramask |= (uint64(1) << i); data << uint16(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint16(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint16(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) { petauramask |= (uint64(1) << i); data << uint16(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recvData >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auraMask = 0; size_t maskPos = data.wpos(); data << uint64(auraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); uint64 petAuraMask = 0; maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); SendPacket(&data); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { ObjectGuid playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(playerGuid, holder)) { KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries m_playerLoading = false; return; } SetPlayer(pCurrChar); WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); data.Initialize(SMSG_ACCOUNT_DATA_TIMES, 128); for (int i = 0; i < 32; ++i) data << uint32(0); SendPacket(&data); // Send MOTD (1.12.1 not have SMSG_MOTD, so do it in another way) { uint32 linecount = 0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; std::string motd; pos = 0; while ((nextpos = str_motd.find('@', pos)) != std::string::npos) { if (nextpos != pos) { ChatHandler(pCurrChar).PSendSysMessage("%s", str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage("%s", str_motd.substr(pos).c_str()); ++linecount; } DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); } // QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow()); QueryResult* resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); if (resultGuild) { Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); delete resultGuild; } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } if (pCurrChar->GetGuildId() != 0) { Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); if (guild) { data.Initialize(SMSG_GUILD_EVENT, (1 + 1 + guild->GetMOTD().size() + 1)); data << uint8(GE_MOTD); data << uint8(1); data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG("WORLD: Sent guild-motd (SMSG_GUILD_EVENT)"); guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } else { // remove wrong guild data sLog.outError("Player %s (GUID: %u) marked as member of nonexistent guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } if (!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); // Show cinematic at the first time that player login if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } uint32 miscRequirement = 0; AreaLockStatus lockStatus = AREA_LOCKSTATUS_OK; if (AreaTrigger const* at = sObjectMgr.GetMapEntranceTrigger(pCurrChar->GetMapId())) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); else { // Some basic checks in case of a map without areatrigger MapEntry const* mapEntry = sMapStore.LookupEntry(pCurrChar->GetMapId()); if (!mapEntry) lockStatus = AREA_LOCKSTATUS_UNKNOWN_ERROR; } if (lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->GetMap()->Add(pCurrChar)) { // normal delayed teleport protection not applied (and this correct) for this case (Player object just created) AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); if (!at || lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation())) pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); // DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); pCurrChar->SendInitialPacketsAfterAddToMap(); static SqlStatementID updChars; static SqlStatementID updAccount; SqlStatement stmt = CharacterDatabase.CreateStatement(updChars, "UPDATE characters SET online = 1 WHERE guid = ?"); stmt.PExecute(pCurrChar->GetGUIDLow()); stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET active_realm_id = ? WHERE id = ?"); stmt.PExecute(realmID, GetAccountId()); pCurrChar->SetInGameTime(WorldTimer::getMSTime()); // announce group about member online (must be after add to player list to receive announce to self) if (Group* group = pCurrChar->GetGroup()) group->SendUpdate(); // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { // not blizz like, we must correctly save and load player instead... if (pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetWaterWalk(true); } pCurrChar->ContinueTaxiFlight(); // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if (sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING)) pCurrChar->SetFFAPvP(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); // Apply at_login requests if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); SendNotification(LANG_RESET_TALENTS); // we can use SMSG_TALENTS_INVOLUNTARILY_RESET here } if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); // show time before shutdown if shutdown planned. if (sWorld.IsShutdowning()) sWorld.ShutdownMsg(true, pCurrChar); if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if (pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); if (!pCurrChar->isGMVisible()) { SendNotification(LANG_INVISIBLE_INVISIBLE); SpellEntry const* invisibleAuraInfo = sSpellStore.LookupEntry(sWorld.getConfig(CONFIG_UINT32_GM_INVISIBLE_AURA)); if (invisibleAuraInfo && IsSpellAppliesAura(invisibleAuraInfo)) pCurrChar->CastSpell(pCurrChar, invisibleAuraInfo, true); } std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if (!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); m_playerLoading = false; if (sWorld.getConfig(CONFIG_BOOL_WORLD_LOGN_ON)) { sWorld.SendWorldText(20001, pCurrChar->GetName(), pCurrChar->getLevel()); } delete holder; }
void WorldSession::HandleSendMail(WorldPacket & recv_data) { uint64 mailbox, unk3; std::string receiver, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; recv_data >> mailbox; recv_data >> receiver; recv_data >> subject; recv_data >> body; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 uint8 items_count; recv_data >> items_count; // attached items count if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recv_data.rfinish(); // set to end to avoid warnings spam return; } uint64 itemGUIDs[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { recv_data.read_skip<uint8>(); // item slot in mail, not used recv_data >> itemGUIDs[i]; } recv_data >> money >> COD; // money and cod recv_data >> unk3; // const 0 recv_data >> unk4; // const 0 // packet read complete, now do check if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; if (receiver.empty()) return; Player* player = _player; if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } uint64 rc = 0; if (normalizePlayerName(receiver)) rc = sObjectMgr->GetPlayerGUIDByName(receiver); if (!rc) { sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); if (player->GetGUID() == rc) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client uint32 reqmoney = cost + money; if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receive = ObjectAccessor::FindPlayer(rc); uint32 rc_team = 0; uint8 mails_count = 0; //do not allow to send to one player more than 100 mails uint8 receiveLevel = 0; if (receive) { rc_team = receive->GetTeam(); mails_count = receive->GetMailSize(); receiveLevel = receive->getLevel(); } else { rc_team = sObjectMgr->GetPlayerTeamByGUID(rc); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); stmt->setUInt32(0, GUID_LOPART(rc)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); mails_count = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); stmt->setUInt32(0, GUID_LOPART(rc)); result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); receiveLevel = fields[0].GetUInt8(); } } //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mails_count > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... or all items are account bound bool accountBound = items_count ? true : false; for (uint8 i = 0; i < items_count; ++i) { Item* item = player->GetItemByGuid(itemGUIDs[i]); if (item) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity())) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } if (receiveLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(rc); Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { if (!itemGUIDs[i]) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = player->GetItemByGuid(itemGUIDs[i]); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; } if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS); return; } items[i] = item; } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int32(reqmoney)); player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (items_count > 0 || money > 0) { if (items_count > 0) { for (uint8 i = 0; i < items_count; ++i) { Item* item = items[i]; if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory item->SetOwnerGUID(rc); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player->GetSession()->GetAccountId() != rc_account; } if (money > 0 && !AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list draft .AddMoney(money) .AddCOD(COD) .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { uint32 type; uint32 lang; recvData >> type; recvData >> lang; if (type >= MAX_CHAT_MSG_TYPE) { TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type); recvData.rfinish(); return; } if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } Player* sender = GetPlayer(); //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang); // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetMiscValue() == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); recvData.rfinish(); return; } } if (lang == LANG_ADDON) { // LANG_ADDON is only valid for the following message types switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_GUILD: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_WHISPER: // check if addon messages are disabled if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) { recvData.rfinish(); return; } break; default: TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); recvData.rfinish(); return; } } // LANG_ADDON should not be changed nor be affected by flood control else { // send in universal language if player in .gmon mode (ignore spell effects) if (sender->IsGameMaster()) lang = LANG_UNIVERSAL; else { Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetMiscValue(); else if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; } } } if (!sender->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); recvData.rfinish(); // Prevent warnings return; } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) sender->UpdateSpeakTime(); } if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); recvData.rfinish(); return; } std::string to, channel, msg; bool ignoreChecks = false; switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recvData >> msg; break; case CHAT_MSG_WHISPER: recvData >> to; recvData >> msg; break; case CHAT_MSG_CHANNEL: recvData >> channel; recvData >> msg; break; case CHAT_MSG_AFK: case CHAT_MSG_DND: recvData >> msg; ignoreChecks = true; break; } if (!ignoreChecks) { if (msg.empty()) return; if (ChatHandler(this).ParseCommands(msg.c_str())) return; if (lang != LANG_ADDON) { // Strip invisible characters for non-addon messages if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) stripLineInvisibleChars(msg); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) { TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), msg.c_str()); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) KickPlayer(); return; } } } if (sender->isGMChat() && sWorld->getBoolConfig(CONFIG_GM_BLUE_CHAT_ENABLE)) msg = "|cff2998ff" + msg + "|r"; switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); return; } if (type == CHAT_MSG_SAY) sender->Say(msg, Language(lang)); else if (type == CHAT_MSG_EMOTE) sender->TextEmote(msg); else if (type == CHAT_MSG_YELL) sender->Yell(msg, Language(lang)); } break; case CHAT_MSG_WHISPER: { if (!normalizePlayerName(to)) { SendPlayerNotFoundNotice(to); break; } Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; } if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ)); return; } if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendWrongFactionNotice(); return; } if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster()) { SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str()); return; } // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to // We also do that if a player is under the required level for whispers. if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) || (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, Language(lang), receiver); } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: { // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = sender->GetGroup(); if (!group || group->isBGGroup()) return; } if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); } break; case CHAT_MSG_GUILD: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_OFFICER: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_RAID: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup()) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID())) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: { //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: { // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);; group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)); return; } } if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam())) { if (Channel* chn = cMgr->GetChannel(channel, sender)) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); if (chn->IsLFG()) { uint32 lenght = 0; for (uint32 i=0; i < msg.length(); i++, lenght++) { if ((int)msg.c_str() [ i ] & 128) i++; } uint32 cost = lenght * sWorld->getIntConfig(CONFIG_LFG_COST); if (sender->GetMoney() < cost) { ChatHandler(sender->GetSession()).PSendSysMessage(LANG_NOT_ENOUGHT_MONEY); break; } sender->ModifyMoney(-(int32)cost); } chn->Say(sender->GetGUID(), msg.c_str(), lang); } } } break; case CHAT_MSG_AFK: { if (!sender->IsInCombat()) { if (sender->isAFK()) // Already AFK { if (msg.empty()) sender->ToggleAFK(); // Remove AFK else sender->autoReplyMsg = msg; // Update message } else // New AFK mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; if (sender->isDND()) sender->ToggleDND(); sender->ToggleAFK(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); } break; } case CHAT_MSG_DND: { if (sender->isDND()) // Already DND { if (msg.empty()) sender->ToggleDND(); // Remove DND else sender->autoReplyMsg = msg; // Update message } else // New DND mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; if (sender->isAFK()) sender->ToggleAFK(); sender->ToggleDND(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); break; } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } }
void GameGraphic::initStaticBackground(BoardBatch& staticBoardBatch, float lowX, float lowY, Player& player) { const float squareSize = TetrisData::getInstance().getTetrisSquareSize(); const float borderSize = TetrisData::getInstance().getTetrisBorderSize(); const TetrisBoard& tetrisBoard = player.getTetrisBoard(); const int columns = tetrisBoard.getColumns(); const int rows = tetrisBoard.getRows(); const float middleDistance = 5; const float rightDistance = 5; const float infoSize = squareSize * 5; const float boardWidth = squareSize * columns; width_ = squareSize * columns + infoSize + borderSize * 2 + middleDistance + rightDistance; height_ = squareSize * (rows - 2) + borderSize * 2; // Draw the player area. float x = lowX + borderSize; float y = lowY * 0.5f + borderSize; staticBoardBatch.addRectangle( x, y, boardWidth + infoSize + middleDistance + rightDistance, squareSize * (rows - 2), TetrisData::getInstance().getPlayerAreaColor()); // Draw the outer square. x = lowX + borderSize; y = lowY + borderSize; staticBoardBatch.addRectangle( x, y, squareSize * columns, squareSize * (rows - 2), TetrisData::getInstance().getOuterSquareColor()); // Draw the inner squares. for (int row = 0; row < rows - 2; ++row) { for (int column = 0; column < columns; ++column) { x = lowX + borderSize + squareSize * column + squareSize * 0.1f; y = lowY + borderSize + squareSize * row + squareSize * 0.1f; staticBoardBatch.addRectangle( x, y, squareSize * 0.8f, squareSize * 0.8f, TetrisData::getInstance().getInnerSquareColor()); } } // Draw the block start area. x = lowX + borderSize; y = lowY + borderSize + squareSize * (rows - 4); staticBoardBatch.addRectangle( x, y, squareSize * columns, squareSize * 2, TetrisData::getInstance().getStartAreaColor()); // Draw the preview block area. x = lowX + borderSize + boardWidth + middleDistance; y = lowY + borderSize + squareSize * (rows - 4) - (squareSize * 5 + middleDistance); staticBoardBatch.addRectangle( x, y, infoSize, infoSize, TetrisData::getInstance().getStartAreaColor()); nextBlock_ = DrawBlock(Block(tetrisBoard.getNextBlockType(), 0, 0), tetrisBoard.getRows(), squareSize, x + squareSize * 2.5f, y + squareSize * 2.5f, true); mw::Font font = TetrisData::getInstance().getDefaultFont(30); name_ = DrawText(player.getName(), font, x, y + squareSize * 5, 8.f); level_ = player.getLevel(); textLevel_ = DrawText("Level " + std::to_string(level_), font, x, y - 20, 8.f); points_ = player.getPoints(); textPoints_ = DrawText("Points " + std::to_string(points_), font, x, y - 20 - 12, 8.f); clearedRows_ = player.getClearedRows(); textClearedRows_ = DrawText("Rows " + std::to_string(clearedRows_), font, x, y - 20 - 12 * 2, 8.f); const mw::Color borderColor = TetrisData::getInstance().getBorderColor(); // Add border. // Left-up corner. x = lowX; y = lowY + height_ - borderSize; staticBoardBatch.addSquare( x, y, borderSize, borderColor); // Right-up corner. x = lowX + width_ - borderSize; y = lowY + height_ - borderSize; staticBoardBatch.addSquare( x, y, borderSize, borderColor); // Left-down corner. x = lowX; y = lowY; staticBoardBatch.addSquare( x, y, borderSize, borderColor); // Right-down corner. x = lowX + width_ - borderSize; y = lowY; staticBoardBatch.addSquare( x, y, borderSize, borderColor); // Up. x = lowX + borderSize; y = lowY + height_ - borderSize; staticBoardBatch.addRectangle( x, y, width_ - 2 * borderSize, borderSize, borderColor); // Down. x = lowX + borderSize; y = lowY; staticBoardBatch.addRectangle( x, y, width_ - 2 * borderSize, borderSize, borderColor); // Left. x = lowX; y = lowY + borderSize; staticBoardBatch.addRectangle( x, y, borderSize, height_ - 2 * borderSize, borderColor); // Right. x = lowX + width_ - borderSize; y = lowY + borderSize; staticBoardBatch.addRectangle( x, y, borderSize, height_ - 2 * borderSize, borderColor); rows_.clear(); currentBlock_ = DrawBlock(tetrisBoard.getBlock(), tetrisBoard.getRows(), squareSize, lowX + borderSize, lowY + borderSize, false); // Add rows to represent the board. // Add free rows to represent potential rows, e.g. the board receives external rows. for (int row = 0; row < rows; ++row) { auto drawRow = std::make_shared<DrawRow>(row, tetrisBoard, squareSize, lowX + borderSize, lowY + borderSize); auto freeRow = std::make_shared<DrawRow>(*drawRow); freeRow->clear(); // Make all elements to only contain blocktype empty squares. rows_.push_back(drawRow); freeRows_.push_back(freeRow); } middleText_ = DrawText(lowX + borderSize + squareSize * columns * 0.5f, lowY + height_ * 0.5f); }
//show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, target_name)) { target = sObjectMgr->GetPlayerByLowGUID(parseGUID); target_guid = parseGUID; } else if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accId = 0; uint32 money = 0; uint32 total_player_time = 0; uint8 level = 0; uint32 latency = 0; uint8 race; uint8 Class; int64 muteTime = 0; int64 banTime = -1; uint32 mapId; uint32 areaId; uint32 phase = 0; // get additional information from Player object if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); level = target->getLevel(); latency = target->GetSession()->GetLatency(); race = target->getRace(); Class = target->getClass(); muteTime = target->GetSession()->m_muteTime; mapId = target->GetMapId(); areaId = target->GetAreaId(); phase = target->GetPhaseMask(); } // get additional information from DB else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; // 0 1 2 3 4 5 6 7 QueryResult result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class, map, zone FROM characters " "WHERE guid = '%u'", GUID_LOPART(target_guid)); if (!result) return false; Field* fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); level = fields[1].GetUInt32(); money = fields[2].GetUInt32(); accId = fields[3].GetUInt32(); race = fields[4].GetUInt8(); Class = fields[5].GetUInt8(); mapId = fields[6].GetUInt16(); areaId = fields[7].GetUInt16(); } std::string username = GetTrinityString(LANG_ERROR); std::string email = GetTrinityString(LANG_ERROR); std::string last_ip = GetTrinityString(LANG_ERROR); uint32 security = 0; std::string last_login = GetTrinityString(LANG_ERROR); QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime " "FROM account a " "LEFT JOIN account_access aa " "ON (a.id = aa.id) " "WHERE a.id = '%u'", accId); if (result) { Field* fields = result->Fetch(); username = fields[0].GetString(); security = fields[1].GetUInt32(); email = fields[2].GetString(); muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; if (!m_session || m_session->GetSecurity() >= AccountTypes(security)) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); } else { last_ip = "-"; last_login = "******"; } } std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency); std::string bannedby = "unknown"; std::string banreason = ""; if (QueryResult result2 = LoginDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned " "WHERE id = '%u' AND active ORDER BY bandate ASC LIMIT 1", accId)) { Field* fields = result2->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } else if (QueryResult result3 = CharacterDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned " "WHERE guid = '%u' AND active ORDER BY bandate ASC LIMIT 1", GUID_LOPART(target_guid))) { Field* fields = result3->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } if (muteTime > 0) PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); if (banTime >= 0) PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); std::string race_s, Class_s; switch (race) { case RACE_HUMAN: race_s = "Human"; break; case RACE_ORC: race_s = "Orc"; break; case RACE_DWARF: race_s = "Dwarf"; break; case RACE_NIGHTELF: race_s = "Night Elf"; break; case RACE_UNDEAD_PLAYER: race_s = "Undead"; break; case RACE_TAUREN: race_s = "Tauren"; break; case RACE_GNOME: race_s = "Gnome"; break; case RACE_TROLL: race_s = "Troll"; break; case RACE_BLOODELF: race_s = "Blood Elf"; break; case RACE_DRAENEI: race_s = "Draenei"; break; } switch (Class) { case CLASS_WARRIOR: Class_s = "Warrior"; break; case CLASS_PALADIN: Class_s = "Paladin"; break; case CLASS_HUNTER: Class_s = "Hunter"; break; case CLASS_ROGUE: Class_s = "Rogue"; break; case CLASS_PRIEST: Class_s = "Priest"; break; case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break; case CLASS_SHAMAN: Class_s = "Shaman"; break; case CLASS_MAGE: Class_s = "Mage"; break; case CLASS_WARLOCK: Class_s = "Warlock"; break; case CLASS_DRUID: Class_s = "Druid"; break; } std::string timeStr = secsToTimeString(total_player_time, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp); // Add map, zone, subzone and phase to output int locale = GetSessionDbcLocale(); std::string areaName = "<unknown>"; std::string zoneName = ""; MapEntry const* map = sMapStore.LookupEntry(mapId); AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { areaName = area->area_name[locale]; AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } if (target) { if (!zoneName.empty()) PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); else PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "<unknown>", phase); } else PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); return true; }
void WorldSession::SendLfgSearchResults(LfgType type, uint32 entry) { WorldPacket data(SMSG_LFG_SEARCH_RESULTS); data << uint32(type); // type data << uint32(entry); // entry from LFGDungeons.dbc uint8 isGuidsPresent = 0; data << uint8(isGuidsPresent); if (isGuidsPresent) { uint32 guids_count = 0; data << uint32(guids_count); for (uint32 i = 0; i < guids_count; ++i) { data << uint64(0); // player/group guid } } uint32 groups_count = 1; data << uint32(groups_count); // groups count data << uint32(groups_count); // groups count (total?) for (uint32 i = 0; i < groups_count; ++i) { data << uint64(1); // group guid uint32 flags = 0x92; data << uint32(flags); // flags if (flags & 0x2) { data << uint8(0); // comment string, max len 256 } if (flags & 0x10) { for (uint32 j = 0; j < 3; ++j) data << uint8(0); // roles } if (flags & 0x80) { data << uint64(0); // instance guid data << uint32(0); // completed encounters } } // TODO: Guard Player map HashMapHolder<Player>::MapType const& players = sObjectAccessor.GetPlayers(); uint32 playersSize = players.size(); data << uint32(playersSize); // players count data << uint32(playersSize); // players count (total?) for (HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter) { Player* plr = iter->second; if (!plr || plr->GetTeam() != _player->GetTeam()) continue; if (!plr->IsInWorld()) continue; data << plr->GetObjectGuid(); // guid uint32 flags = 0xFF; data << uint32(flags); // flags if (flags & 0x1) { data << uint8(plr->getLevel()); data << uint8(plr->getClass()); data << uint8(plr->getRace()); for (uint32 i = 0; i < 3; ++i) data << uint8(0); // talent spec x/x/x data << uint32(0); // armor data << uint32(0); // spd/heal data << uint32(0); // spd/heal data << uint32(0); // HasteMelee data << uint32(0); // HasteRanged data << uint32(0); // HasteSpell data << float(0); // MP5 data << float(0); // MP5 Combat data << uint32(0); // AttackPower data << uint32(0); // Agility data << uint32(0); // Health data << uint32(0); // Mana data << uint32(0); // Unk1 data << float(0); // Unk2 data << uint32(0); // Defence data << uint32(0); // Dodge data << uint32(0); // Block data << uint32(0); // Parry data << uint32(0); // Crit data << uint32(0); // Expertise } if (flags & 0x2) data << ""; // comment if (flags & 0x4) data << uint8(0); // group leader if (flags & 0x8) data << uint64(1); // group guid if (flags & 0x10) data << uint8(0); // roles if (flags & 0x20) data << uint32(plr->GetZoneId()); // areaid if (flags & 0x40) data << uint8(0); // status if (flags & 0x80) { data << uint64(0); // instance guid data << uint32(0); // completed encounters } } SendPacket(&data); }
void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { ObjectGuid guid; guid[0] = recvPacket.ReadBit(); guid[3] = recvPacket.ReadBit(); guid[5] = recvPacket.ReadBit(); guid[1] = recvPacket.ReadBit(); guid[4] = recvPacket.ReadBit(); guid[6] = recvPacket.ReadBit(); guid[7] = recvPacket.ReadBit(); guid[2] = recvPacket.ReadBit(); recvPacket.ReadByteSeq(guid[7]); recvPacket.ReadByteSeq(guid[4]); recvPacket.ReadByteSeq(guid[3]); recvPacket.ReadByteSeq(guid[5]); recvPacket.ReadByteSeq(guid[1]); recvPacket.ReadByteSeq(guid[2]); recvPacket.ReadByteSeq(guid[6]); recvPacket.ReadByteSeq(guid[0]); if (GetPlayer()->m_trade) return; TradeStatusInfo info; if (!GetPlayer()->IsAlive()) { info.Status = TRADE_STATUS_YOU_DEAD; SendTradeStatus(info); return; } if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED)) { info.Status = TRADE_STATUS_YOU_STUNNED; SendTradeStatus(info); return; } if (isLogingOut()) { info.Status = TRADE_STATUS_YOU_LOGOUT; SendTradeStatus(info); return; } if (GetPlayer()->IsInFlight()) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_TRADE_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } Player* pOther = ObjectAccessor::FindPlayer(guid); if (!pOther) { info.Status = TRADE_STATUS_NO_TARGET; SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther->m_trade) { info.Status = TRADE_STATUS_BUSY; SendTradeStatus(info); return; } if (!pOther->IsAlive()) { info.Status = TRADE_STATUS_TARGET_DEAD; SendTradeStatus(info); return; } if (pOther->IsInFlight()) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (pOther->HasUnitState(UNIT_STATE_STUNNED)) { info.Status = TRADE_STATUS_TARGET_STUNNED; SendTradeStatus(info); return; } if (pOther->GetSession()->isLogingOut()) { info.Status = TRADE_STATUS_TARGET_LOGOUT; SendTradeStatus(info); return; } if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { info.Status = TRADE_STATUS_IGNORE_YOU; SendTradeStatus(info); return; } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam()) { info.Status = TRADE_STATUS_WRONG_FACTION; SendTradeStatus(info); return; } if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false)) { info.Status = TRADE_STATUS_TARGET_TO_FAR; SendTradeStatus(info); return; } if (pOther->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_TRADE_OTHER_REQ), sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ)); return; } // OK start trade _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); info.Status = TRADE_STATUS_BEGIN_TRADE; info.TraderGuid = _player->GetGUID(); pOther->GetSession()->SendTradeStatus(info); }
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data) { /* {CLIENT} Packet: (0xEF7D) CMSG_ARENA_TEAM_INVITE PacketSize = 10 TimeStamp = 22824147 AA 69 74 00 55 64 72 65 61 00 */ WorldPacket data(SMSG_ARENA_TEAM_INVITE, 40); string player_name; uint32 teamId; recv_data >> teamId >> player_name; ArenaTeam * pTeam = objmgr.GetArenaTeamById(teamId); if( !pTeam ) { return; } if(!pTeam->HasMember(GetPlayer()->GetLowGUID())) { GetPlayer()->SoftDisconnect(); return; } Player * plr = objmgr.GetPlayer(player_name.c_str(), false); if(plr == NULL) { SystemMessage("Player `%s` is non-existent or not online.", player_name.c_str()); return; } if(pTeam->m_leader != _player->GetLowGUID()) { SystemMessage("You are not the captain of this arena team."); return; } if( plr->getLevel() < PLAYER_ARENA_MIN_LEVEL ) { SystemMessage( "Player must be level %u to join an arena team.", PLAYER_ARENA_MIN_LEVEL ); return; } if(plr->m_arenaTeams[pTeam->m_type] != NULL) { SystemMessage("That player is already in an arena team of this type."); return; } if(plr->m_arenateaminviteguid != 0) { SystemMessage("That player is already invited to an arena team"); return; } if(plr->GetTeam() != _player->GetTeam() && !HasGMPermissions()) { SystemMessage("That player is a member of a different faction."); return; } plr->m_arenateaminviteguid = _player->m_arenaTeams[pTeam->m_type]->m_id; data << _player->GetName(); data << _player->m_arenaTeams[pTeam->m_type]->m_name; plr->GetSession()->SendPacket(&data); }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) { DEBUG_LOG("Received opcode CMSG_OFFER_PETITION"); // ok //recv_data.hexlike(); ObjectGuid petitionGuid; ObjectGuid playerGuid; uint32 junk; recv_data >> junk; // this is not petition type! recv_data >> petitionGuid; // petition guid recv_data >> playerGuid; // player guid Player *player = ObjectAccessor::FindPlayer(playerGuid); if (!player) return; /// Get petition type and check QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter()); if (!result) return; Field *fields = result->Fetch(); uint32 type = fields[0].GetUInt32(); delete result; DEBUG_LOG("OFFER PETITION: type %u petition %s to %s", type, petitionGuid.GetString().c_str(), playerGuid.GetString().c_str()); if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() ) { if(type != 9) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_NOT_ALLIED); return; } if(type != 9) { if(player->getLevel() < sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)) { // player is too low level to join an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S); return; } if (!IsArenaTypeValid(ArenaType(type))) return; uint8 slot = ArenaTeam::GetSlotByType(ArenaType(type)); if(slot >= MAX_ARENA_SLOT) return; if(player->GetArenaTeamId(slot)) { // player is already in an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; } if(player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } } else { if(player->GetGuildId()) { SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_IN_GUILD_S); return; } if(player->GetGuildIdInvited()) { SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_INVITED_TO_GUILD_S); return; } } /// Get petition signs count uint8 signs = 0; result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter()); // result==NULL also correct charter without signs if(result) signs = (uint8)result->GetRowCount(); /// Send response WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12)); data << ObjectGuid(petitionGuid); // petition guid data << ObjectGuid(_player->GetObjectGuid()); // owner guid data << uint32(petitionGuid.GetCounter()); // guild guid (in mangos always same as low part of petition guid) data << uint8(signs); // sign's count for(uint8 i = 1; i <= signs; ++i) { Field *fields2 = result->Fetch(); ObjectGuid signerGuid = ObjectGuid(HIGHGUID_PLAYER, fields2[0].GetUInt32()); data << ObjectGuid(signerGuid); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); } delete result; player->GetSession()->SendPacket(&data); }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox; uint64 money, COD; std::string receiverName, subject, body; uint32 bodyLength, subjectLength, receiverLength; uint32 unk1, unk2; uint8 itemCount; recvData >> unk1 >> unk2; // both unknown recvData >> COD >> money; // money and cod mailbox[0] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); bodyLength = recvData.ReadBits(11); mailbox[3] = recvData.ReadBit(); receiverLength = recvData.ReadBits(9); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); itemCount = recvData.ReadBits(5); // attached items count if (itemCount > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recvData.rfinish(); // set to end to avoid warnings spam return; } ObjectGuid itemGuids[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < itemCount; ++i) { itemGuids[i][1] = recvData.ReadBit(); itemGuids[i][7] = recvData.ReadBit(); itemGuids[i][2] = recvData.ReadBit(); itemGuids[i][5] = recvData.ReadBit(); itemGuids[i][0] = recvData.ReadBit(); itemGuids[i][6] = recvData.ReadBit(); itemGuids[i][3] = recvData.ReadBit(); itemGuids[i][4] = recvData.ReadBit(); } subjectLength = recvData.ReadBits(9); mailbox[2] = recvData.ReadBit(); for (uint8 i = 0; i < itemCount; ++i) { recvData.read_skip<uint8>(); // item slot in mail, not used recvData.ReadByteSeq(itemGuids[i][3]); recvData.ReadByteSeq(itemGuids[i][0]); recvData.ReadByteSeq(itemGuids[i][2]); recvData.ReadByteSeq(itemGuids[i][1]); recvData.ReadByteSeq(itemGuids[i][6]); recvData.ReadByteSeq(itemGuids[i][5]); recvData.ReadByteSeq(itemGuids[i][7]); recvData.ReadByteSeq(itemGuids[i][4]); } recvData.ReadByteSeq(mailbox[1]); body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[0]); subject = recvData.ReadString(subjectLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[4]); receiverName = recvData.ReadString(receiverLength); // packet read complete, now do check if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; if (receiverName.empty()) return; Player* player = _player; if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } uint64 receiverGuid = 0; if (normalizePlayerName(receiverName)) receiverGuid = sObjectMgr->GetPlayerGUIDByName(receiverName); if (!receiverGuid) { TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: not existed!) with subject %s " "and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s " "includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = itemCount ? 30 * itemCount : 30; // price hardcoded in client uint64 reqmoney = cost + money; if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); uint32 receiverTeam = 0; uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; if (receiver) { receiverTeam = receiver->GetTeam(); mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); } else { receiverTeam = sObjectMgr->GetPlayerTeamByGUID(receiverGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); stmt->setUInt32(0, GUID_LOPART(receiverGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); mailsCount = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); stmt->setUInt32(0, GUID_LOPART(receiverGuid)); result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); receiverLevel = fields[0].GetUInt8(); } receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mailsCount > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... or all items are account bound bool accountBound = itemCount ? true : false; for (uint8 i = 0; i < itemCount; ++i) { if (Item* item = player->GetItemByGuid(itemGuids[i])) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < itemCount; ++i) { if (!itemGuids[i]) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = player->GetItemByGuid(itemGuids[i]); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); return; } if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_EXPIRATION)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_DYNAMIC_FLAGS, ITEM_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_DESTROY_NONEMPTY_BAG); return; } items[i] = item; } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int64(reqmoney)); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (itemCount > 0 || money > 0) { bool log = HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); if (itemCount > 0) { for (uint8 i = 0; i < itemCount; ++i) { Item* item = items[i]; if (log) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail item: %s (Entry: %u Count: %u) " "to player: %s (GUID: %u) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory item->SetOwnerGUID(receiverGuid); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId; } if (log && money > 0) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: " UI64FMTD " to player: %s (GUID: %u) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), money, receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // Mail sent between guild members arrives instantly if they have the guild perk "Guild Mail" if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (guild->GetLevel() >= 17 && guild->IsMember(receiverGuid)) deliver_delay = 0; // will delete item or place to receiver mail list draft .AddMoney(money) .AddCOD(COD) .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandleWhoOpcode( WorldPacket & recv_data ) { DEBUG_LOG( "WORLD: Recvd CMSG_WHO Message" ); //recv_data.hexlike(); uint32 clientcount = 0; uint32 level_min, level_max, racemask, classmask, zones_count, str_count; uint32 zoneids[10]; // 10 is client limit std::string player_name, guild_name; recv_data >> level_min; // maximal player level, default 0 recv_data >> level_max; // minimal player level, default 100 (MAX_LEVEL) recv_data >> player_name; // player name, case sensitive... recv_data >> guild_name; // guild name, case sensitive... recv_data >> racemask; // race mask recv_data >> classmask; // class mask recv_data >> zones_count; // zones count, client limit=10 (2.0.10) if(zones_count > 10) return; // can't be received from real client or broken packet for(uint32 i = 0; i < zones_count; ++i) { uint32 temp; recv_data >> temp; // zone id, 0 if zone is unknown... zoneids[i] = temp; DEBUG_LOG("Zone %u: %u", i, zoneids[i]); } recv_data >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10) if(str_count > 4) return; // can't be received from real client or broken packet DEBUG_LOG("Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count); std::wstring str[4]; // 4 is client limit for(uint32 i = 0; i < str_count; ++i) { std::string temp; recv_data >> temp; // user entered string, it used as universal search pattern(guild+player name)? if(!Utf8toWStr(temp,str[i])) continue; wstrToLower(str[i]); DEBUG_LOG("String %u: %s", i, temp.c_str()); } std::wstring wplayer_name; std::wstring wguild_name; if(!(Utf8toWStr(player_name, wplayer_name) && Utf8toWStr(guild_name, wguild_name))) return; wstrToLower(wplayer_name); wstrToLower(wguild_name); // client send in case not set max level value 100 but mangos support 255 max level, // update it to show GMs with characters after 100 level if(level_max >= MAX_LEVEL) level_max = STRONG_MAX_LEVEL; Team team = _player->GetTeam(); AccountTypes security = GetSecurity(); bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_WHO_LIST); AccountTypes gmLevelInWhoList = (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_WHO_LIST); WorldPacket data( SMSG_WHO, 50 ); // guess size data << uint32(clientcount); // clientcount place holder, listed count data << uint32(clientcount); // clientcount place holder, online count // TODO: Guard Player map HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers(); for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { Player* pl = itr->second; if (security == SEC_PLAYER) { // player can see member of other team only if CONFIG_BOOL_ALLOW_TWO_SIDE_WHO_LIST if (pl->GetTeam() != team && !allowTwoSideWhoList ) continue; // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST if (pl->GetSession()->GetSecurity() > gmLevelInWhoList) continue; } // do not process players which are not in world if (!pl->IsInWorld()) continue; // check if target is globally visible for player if (!pl->IsVisibleGloballyFor(_player)) continue; // check if target's level is in level range uint32 lvl = pl->getLevel(); if (lvl < level_min || lvl > level_max) continue; // check if class matches classmask uint32 class_ = pl->getClass(); if (!(classmask & (1 << class_))) continue; // check if race matches racemask uint32 race = pl->getRace(); if (!(racemask & (1 << race))) continue; uint32 pzoneid = pl->GetZoneId(); uint8 gender = pl->getGender(); bool z_show = true; for (uint32 i = 0; i < zones_count; ++i) { if(zoneids[i] == pzoneid) { z_show = true; break; } z_show = false; } if (!z_show) continue; std::string pname = pl->GetName(); std::wstring wpname; if(!Utf8toWStr(pname,wpname)) continue; wstrToLower(wpname); if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos)) continue; std::string gname = sGuildMgr.GetGuildNameById(pl->GetGuildId()); std::wstring wgname; if (!Utf8toWStr(gname,wgname)) continue; wstrToLower(wgname); if (!(wguild_name.empty() || wgname.find(wguild_name) != std::wstring::npos)) continue; std::string aname; if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(pzoneid)) aname = areaEntry->area_name[GetSessionDbcLocale()]; bool s_show = true; for (uint32 i = 0; i < str_count; ++i) { if (!str[i].empty()) { if (wgname.find(str[i]) != std::wstring::npos || wpname.find(str[i]) != std::wstring::npos || Utf8FitTo(aname, str[i]) ) { s_show = true; break; } s_show = false; } } if (!s_show) continue; data << pname; // player name data << gname; // guild name data << uint32(lvl); // player level data << uint32(class_); // player class data << uint32(race); // player race data << uint8(gender); // player gender data << uint32(pzoneid); // player zone id // 50 is maximum player count sent to client if ((++clientcount) == 50) break; } uint32 count = m.size(); data.put( 0, clientcount ); // insert right count, listed count data.put( 4, count > 50 ? count : clientcount ); // insert right count, online count SendPacket(&data); DEBUG_LOG( "WORLD: Send SMSG_WHO Message" ); }
//show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accId = 0; uint64 money = 0; uint32 total_player_time = 0; uint8 level = 0; uint32 latency = 0; uint8 race; uint8 Class; int64 muteTime = 0; int64 banTime = -1; // get additional information from Player object if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); level = target->getLevel(); latency = target->GetSession()->GetLatency(); race = target->getRace(); Class = target->getClass(); muteTime = target->GetSession()->m_muteTime; } // get additional information from DB else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; // 0 1 2 3 4 5 QueryResult result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid)); if (!result) return false; Field *fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); level = fields[1].GetUInt32(); money = fields[2].GetUInt64(); accId = fields[3].GetUInt32(); race = fields[4].GetUInt8(); Class = fields[5].GetUInt8(); } std::string username = GetDarkCoreString(LANG_ERROR); std::string email = GetDarkCoreString(LANG_ERROR); std::string last_ip = GetDarkCoreString(LANG_ERROR); uint32 security = 0; std::string last_login = GetDarkCoreString(LANG_ERROR); QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime " "FROM account a " "LEFT JOIN account_access aa " "ON (a.id = aa.id) " "WHERE a.id = '%u'", accId); if (result) { Field* fields = result->Fetch(); username = fields[0].GetString(); security = fields[1].GetUInt32(); email = fields[2].GetString(); muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; if (!m_session || m_session->GetSecurity() >= AccountTypes(security)) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); } else { last_ip = "-"; last_login = "******"; } } std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetDarkCoreString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency); if (QueryResult result = LoginDatabase.PQuery("SELECT unbandate, bandate = unbandate FROM account_banned WHERE id = '%u' AND active ORDER BY bandate ASC LIMIT 1", accId)) { Field * fields = result->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); } else if (QueryResult result = CharacterDatabase.PQuery("SELECT unbandate, bandate = unbandate FROM character_banned WHERE guid = '%u' AND active ORDER BY bandate ASC LIMIT 1", GUID_LOPART(target_guid))) { Field * fields = result->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); } muteTime = muteTime - time(NULL); if (muteTime > 0 || banTime >= 0) PSendSysMessage(LANG_PINFO_MUTE_BAN, muteTime > 0 ? secsToTimeString(muteTime, true).c_str() : "---", !banTime ? "perm." : (banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "---")); std::string race_s, Class_s; switch(race) { case RACE_HUMAN: race_s = "Human"; break; case RACE_ORC: race_s = "Orc"; break; case RACE_DWARF: race_s = "Dwarf"; break; case RACE_NIGHTELF: race_s = "Night Elf"; break; case RACE_UNDEAD_PLAYER: race_s = "Undead"; break; case RACE_TAUREN: race_s = "Tauren"; break; case RACE_GNOME: race_s = "Gnome"; break; case RACE_TROLL: race_s = "Troll"; break; case RACE_BLOODELF: race_s = "Blood Elf"; break; case RACE_DRAENEI: race_s = "Draenei"; break; case RACE_WORGEN: race_s = "Worgen"; break; case RACE_GOBLIN: race_s = "Goblin"; break; } switch(Class) { case CLASS_WARRIOR: Class_s = "Warrior"; break; case CLASS_PALADIN: Class_s = "Paladin"; break; case CLASS_HUNTER: Class_s = "Hunter"; break; case CLASS_ROGUE: Class_s = "Rogue"; break; case CLASS_PRIEST: Class_s = "Priest"; break; case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break; case CLASS_SHAMAN: Class_s = "Shaman"; break; case CLASS_MAGE: Class_s = "Mage"; break; case CLASS_WARLOCK: Class_s = "Warlock"; break; case CLASS_DRUID: Class_s = "Druid"; break; } std::string timeStr = secsToTimeString(total_player_time, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp); return true; }
//npc tame handling static bool HandleNpcTameCommand (ChatHandler* handler, const char* /*args*/) { Creature *creatureTarget = handler->getSelectedCreature(); if (!creatureTarget || creatureTarget->isPet()) { handler->PSendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } Player *player = handler->GetSession()->GetPlayer(); if (player->GetPetGUID()) { handler->SendSysMessage(LANG_YOU_ALREADY_HAVE_PET); handler->SetSentErrorMessage(true); return false; } CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); if (!cInfo->isTameable(player->CanTameExoticPets())) { handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); handler->SetSentErrorMessage(true); return false; } // Everything looks OK, create new pet Pet* pet = player->CreateTamedPetFrom(creatureTarget); if (!pet) { handler->PSendSysMessage(LANG_CREATURE_NON_TAMEABLE, cInfo->Entry); handler->SetSentErrorMessage(true); return false; } // place pet before player float x, y, z; player->GetClosePoint(x, y, z, creatureTarget->GetObjectSize(), CONTACT_DISTANCE); pet->Relocate(x, y, z, M_PI - player->GetOrientation()); // set pet to defensive mode by default (some classes can't control controlled pets in fact). pet->SetReactState(REACT_DEFENSIVE); // calculate proper level uint8 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); // add to world pet->GetMap()->Add(pet->ToCreature()); // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); // caster have pet now player->SetMinion(pet, true, PET_SLOT_UNK_SLOT); pet->SavePetToDB(PET_SLOT_ACTUAL_PET_SLOT); player->PetSpellInitialize(); return true; }
void WorldSession::HandleSendMail(WorldPackets::Mail::SendMail& packet) { if (packet.Info.Attachments.size() > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); return; } if (!CanOpenMailBox(packet.Info.Mailbox)) return; if (packet.Info.Target.empty()) return; Player* player = _player; if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } ObjectGuid receiverGuid; if (normalizePlayerName(packet.Info.Target)) receiverGuid = ObjectMgr::GetPlayerGUIDByName(packet.Info.Target); if (!receiverGuid) { TC_LOG_INFO("network", "Player %s is sending mail to %s (GUID: not existing!) with subject %s " "and body %s includes " SZFMTD " items, " SI64FMTD " copper and " SI64FMTD " COD copper with StationeryID = %d", GetPlayerInfo().c_str(), packet.Info.Target.c_str(), packet.Info.Subject.c_str(), packet.Info.Body.c_str(), packet.Info.Attachments.size(), packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } if (packet.Info.SendMoney < 0) { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); TC_LOG_WARN("cheat", "Player %s attempted to send mail to %s (%s) with negative money value (SendMoney: " SI64FMTD ")", GetPlayerInfo().c_str(), packet.Info.Target.c_str(), receiverGuid.ToString().c_str(), packet.Info.SendMoney); return; } if (packet.Info.Cod < 0) { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); TC_LOG_WARN("cheat", "Player %s attempted to send mail to %s (%s) with negative COD value (Cod: " SI64FMTD ")", GetPlayerInfo().c_str(), packet.Info.Target.c_str(), receiverGuid.ToString().c_str(), packet.Info.Cod); return; } TC_LOG_INFO("network", "Player %s is sending mail to %s (%s) with subject %s and body %s " "includes " SZFMTD " items, " SI64FMTD " copper and " SI64FMTD " COD copper with StationeryID = %d", GetPlayerInfo().c_str(), packet.Info.Target.c_str(), receiverGuid.ToString().c_str(), packet.Info.Subject.c_str(), packet.Info.Body.c_str(), packet.Info.Attachments.size(), packet.Info.SendMoney, packet.Info.Cod, packet.Info.StationeryID); if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = !packet.Info.Attachments.empty() ? 30 * packet.Info.Attachments.size() : 30; // price hardcoded in client int64 reqmoney = cost + packet.Info.SendMoney; // Check for overflow if (reqmoney < packet.Info.SendMoney) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid); uint32 receiverTeam = 0; uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; uint32 receiverBnetAccountId = 0; if (receiver) { receiverTeam = receiver->GetTeam(); mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); receiverBnetAccountId = receiver->GetSession()->GetBattlenetAccountId(); } else { receiverTeam = ObjectMgr::GetPlayerTeamByGUID(receiverGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); stmt->setUInt64(0, receiverGuid.GetCounter()); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); mailsCount = fields[0].GetUInt64(); } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_LEVEL); stmt->setUInt64(0, receiverGuid.GetCounter()); result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); receiverLevel = fields[0].GetUInt8(); } receiverAccountId = ObjectMgr::GetPlayerAccountIdByGUID(receiverGuid); receiverBnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(receiverAccountId); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mailsCount > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... or all items are account bound bool accountBound = !packet.Info.Attachments.empty(); for (auto const& att : packet.Info.Attachments) { if (Item* item = player->GetItemByGuid(att.ItemGUID)) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->GetFlags() & ITEM_FLAG_IS_BOUND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } std::vector<Item*> items; for (auto const& att : packet.Info.Attachments) { if (att.ItemGUID.IsEmpty()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = player->GetItemByGuid(att.ItemGUID); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { if (!item->IsBattlenetAccountBound() || !player->GetSession()->GetBattlenetAccountId() || player->GetSession()->GetBattlenetAccountId() != receiverBnetAccountId) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); return; } } if (item->GetTemplate()->GetFlags() & ITEM_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (packet.Info.Cod && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_DESTROY_NONEMPTY_BAG); return; } items.push_back(item); } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-reqmoney); player->UpdateCriteria(CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(packet.Info.Subject, packet.Info.Body); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (!packet.Info.Attachments.empty() || packet.Info.SendMoney > 0) { bool log = HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); if (!packet.Info.Attachments.empty()) { for (auto const& item : items) { if (log) { sLog->outCommand(GetAccountId(), "GM %s (%s) (Account: %u) mail item: %s (Entry: %u Count: %u) " "to: %s (%s) (Account: %u)", GetPlayerName().c_str(), _player->GetGUID().ToString().c_str(), GetAccountId(), item->GetTemplate()->GetDefaultLocaleName(), item->GetEntry(), item->GetCount(), packet.Info.Target.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory item->SetOwnerGUID(receiverGuid); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player->GetSession()->GetAccountId() != receiverAccountId; } if (log && packet.Info.SendMoney > 0) { sLog->outCommand(GetAccountId(), "GM %s (%s) (Account: %u) mail money: " SI64FMTD " to: %s (%s) (Account: %u)", GetPlayerName().c_str(), _player->GetGUID().ToString().c_str(), GetAccountId(), packet.Info.SendMoney, packet.Info.Target.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // Mail sent between guild members arrives instantly if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (guild->IsMember(receiverGuid)) deliver_delay = 0; // don't ask for COD if there are no items if (packet.Info.Attachments.empty()) packet.Info.Cod = 0; // will delete item or place to receiver mail list draft .AddMoney(packet.Info.SendMoney) .AddCOD(packet.Info.Cod) .SendMailTo(trans, MailReceiver(receiver, receiverGuid.GetCounter()), MailSender(player), packet.Info.Body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }