void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) { std::string name; Player *oldLeader = GetPlayer(); Guild *guild; //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER"); recvPacket >> name; if(!normalizePlayerName(name)) return; guild = objmgr.GetGuildById(oldLeader->GetGuildId()); if (!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } if( oldLeader->GetGUID() != guild->GetLeader()) { SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); return; } uint64 newLeaderGUID; MemberSlot* slot = guild->GetMemberSlot(name, newLeaderGUID); if (!slot) { SendGuildCommandResult(GUILD_INVITE_S, name, GUILD_PLAYER_NOT_IN_GUILD_S); return; } guild->SetLeader(newLeaderGUID); guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER); WorldPacket data(SMSG_GUILD_EVENT, (2+20)); // guess size data << (uint8)GE_LEADER_CHANGED; data << (uint8)2; // strings count data << oldLeader->GetName(); data << name.c_str(); guild->BroadcastPacket(&data); //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); }
void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) { DEBUG_LOG("WORLD: Received CMSG_GUILD_LEADER"); std::string name = recvPacket.ReadString(recvPacket.ReadBits(7)); Player* oldLeader = GetPlayer(); if (!normalizePlayerName(name)) return; Guild* guild = sGuildMgr.GetGuildById(oldLeader->GetGuildId()); if (!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD); return; } if (oldLeader->GetObjectGuid() != guild->GetLeaderGuid()) { SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS); return; } MemberSlot* oldSlot = guild->GetMemberSlot(oldLeader->GetObjectGuid()); if (!oldSlot) { SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS); return; } MemberSlot* slot = guild->GetMemberSlot(name); if (!slot) { SendGuildCommandResult(GUILD_INVITE_S, name, ERR_GUILD_PLAYER_NOT_IN_GUILD_S); return; } if (slot->guid == oldLeader->GetObjectGuid()) return; guild->SetLeader(slot->guid); // NOTE: GR_OFFICER might not actually be officer rank oldSlot->ChangeRank(GR_OFFICER); guild->BroadcastEvent(GE_LEADER_CHANGED, oldLeader->GetName(), name.c_str()); }
void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) { Player* player = ObjectAccessor::FindPlayer(guid); if (!player) return; CalendarInviteStore const& eventInviteeList = _invites[calendarEvent.GetEventId()]; WorldPacket data(SMSG_CALENDAR_SEND_EVENT, 60 + eventInviteeList.size() * 32); data << uint8(sendType); data.appendPackGUID(calendarEvent.GetCreatorGUID()); data << uint64(calendarEvent.GetEventId()); data << calendarEvent.GetTitle(); data << calendarEvent.GetDescription(); data << uint8(calendarEvent.GetType()); data << uint8(CALENDAR_REPEAT_NEVER); // repeatable data << uint32(CALENDAR_MAX_INVITES); data << int32(calendarEvent.GetDungeonId()); data << uint32(calendarEvent.GetFlags()); data.AppendPackedTime(calendarEvent.GetEventTime()); data.AppendPackedTime(calendarEvent.GetTimeZoneTime()); Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId()); data << uint64(guild ? guild->GetGUID() : 0); data << uint32(eventInviteeList.size()); for (CalendarInviteStore::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr) { CalendarInvite const* calendarInvite = (*itr); uint64 inviteeGuid = calendarInvite->GetInviteeGUID(); Player* invitee = ObjectAccessor::FindPlayer(inviteeGuid); uint8 inviteeLevel = invitee ? invitee->getLevel() : Player::GetLevelFromDB(inviteeGuid); uint32 inviteeGuildId = invitee ? invitee->GetGuildId() : Player::GetGuildIdFromDB(inviteeGuid); data.appendPackGUID(inviteeGuid); data << uint8(inviteeLevel); data << uint8(calendarInvite->GetStatus()); data << uint8(calendarInvite->GetRank()); data << uint8(calendarEvent.IsGuildEvent() && calendarEvent.GetGuildId() == inviteeGuildId); data << uint64(calendarInvite->GetInviteId()); data.AppendPackedTime(calendarInvite->GetStatusTime()); data << calendarInvite->GetText(); } player->SendDirectMessage(&data); }
static bool HandleGHCommand(ChatHandler* handler, const char* args) { Player *chr = handler->GetSession()->GetPlayer(); if(chr->isInFlight()) { handler->PSendSysMessage(LANG_YOU_IN_FLIGHT); //SetSentErrorMessage(true); return false; } if(chr->isInCombat()) { handler->PSendSysMessage(LANG_YOU_IN_COMBAT); //SetSentErrorMessage(true); return false; } if (chr->GetGuildId() == 0) { return false; } QueryResult result; result = CharacterDatabase.PQuery("SELECT `x`, `y`, `z`, `map` FROM `guildhouses` WHERE `guildId` = %u", chr->GetGuildId()); if(!result) { handler->PSendSysMessage("GH Port"); return false; } float x, y, z; uint32 map; Field *fields = result->Fetch(); x = fields[0].GetFloat(); y = fields[1].GetFloat(); z = fields[2].GetFloat(); map = fields[3].GetUInt32(); chr->SaveRecallPosition(); chr->TeleportTo(map, x, y, z, 0); chr->SaveToDB(); return true; }
static bool HandleGuildUninviteCommand(ChatHandler* handler, char const* args) { Player* target; uint64 targetGuid; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) return false; uint32 guildId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(targetGuid); if (!guildId) return false; Guild* targetGuild = sGuildMgr->GetGuildById(guildId); if (!targetGuild) return false; targetGuild->DeleteMember(targetGuid, false, true); return true; }
static bool HandleGuildUninviteCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid targetGuid; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) return false; ObjectGuid::LowType guildId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(targetGuid); if (!guildId) return false; Guild* targetGuild = sGuildMgr->GetGuildById(guildId); if (!targetGuild) return false; SQLTransaction trans(nullptr); targetGuild->DeleteMember(trans, targetGuid, false, true, true); return true; }
bool ChatHandler::HandleCreateGuildCommand(const char* args) { WorldPacket data; Guild *guild; Player * player; std::string lname,gname; if (!*args) return false; lname = strtok((char*)args, " "); gname = strtok(NULL, " "); if(!gname.c_str()) { FillSystemMessageData(&data, m_session, fmtstring("You need to insert a Guild Name!")); m_session->SendPacket(&data); return true; } player = ObjectAccessor::Instance().FindPlayerByName(lname.c_str()); if(!player) { FillSystemMessageData(&data, m_session, fmtstring("Player not found!")); m_session->SendPacket(&data); return true; } if(!player->GetGuildId()) { guild = new Guild; guild->create(player->GetGUID(),gname); objmgr.AddGuild(guild); } else { FillSystemMessageData(&data, m_session, fmtstring("Player already have a guild!")); m_session->SendPacket(&data); } return true; }
void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) { sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER"); std::string name; recvPacket >> name; Player *oldLeader = GetPlayer(); if(!normalizePlayerName(name)) return; Guild *guild = sObjectMgr.GetGuildById(oldLeader->GetGuildId()); if (!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_PLAYER_NOT_IN_GUILD); return; } if (oldLeader->GetGUID() != guild->GetLeader()) { SendGuildCommandResult(GUILD_INVITE_S, "", ERR_GUILD_PERMISSIONS); return; } uint64 newLeaderGUID; MemberSlot* slot = guild->GetMemberSlot(name, newLeaderGUID); if (!slot) { SendGuildCommandResult(GUILD_INVITE_S, name, ERR_GUILD_PLAYER_NOT_IN_GUILD_S); return; } guild->SetLeader(newLeaderGUID); guild->ChangeRank(oldLeader->GetGUID(), GR_OFFICER); guild->BroadcastEvent(GE_LEADER_CHANGED, 0, 2, oldLeader->GetName(), name, ""); }
void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) { Guild *guild; Player *player = GetPlayer(); sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT"); guild = sObjectMgr.GetGuildById(player->GetGuildIdInvited()); if(!guild || player->GetGuildId()) return; // not let enemies sign guild charter if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(guild->GetLeader())) return; if(!guild->AddMember(GetPlayer()->GetGUID(),guild->GetLowestRank())) return; // Put record into guild log guild->LogGuildEvent(GUILD_EVENT_LOG_JOIN_GUILD, GetPlayer()->GetGUIDLow(), 0, 0); guild->BroadcastEvent(GE_JOINED, player->GetGUID(), 1, player->GetName(), "", ""); }
/** \brief GM command level 3 - Create a guild. * * This command allows a GM (level 3) to create a guild. * * The "args" parameter contains the name of the guild leader * and then the name of the guild. * */ static bool HandleGuildCreateCommand(ChatHandler* handler, char const* args) { if (!*args) return false; // if not guild name only (in "") then player name Player* target; if (!handler->extractPlayerTarget(*args != '"' ? (char*)args : NULL, &target)) return false; char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args; if (!tailStr) return false; char* guildStr = handler->extractQuotedArg(tailStr); if (!guildStr) return false; std::string guildName = guildStr; if (target->GetGuildId()) { handler->SendSysMessage(LANG_PLAYER_IN_GUILD); return true; } Guild* guild = new Guild; if (!guild->Create(target, guildName)) { delete guild; handler->SendSysMessage(LANG_GUILD_NOT_CREATED); handler->SetSentErrorMessage(true); return false; } sGuildMgr->AddGuild(guild); return true; }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) { sLog->outDebug(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(); sLog->outDebug(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::HandleInviteToGuild(WorldPacket & recv_data) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recv_data, 1); std::string inviteeName; recv_data >> inviteeName; Player* plyr = objmgr.GetPlayer(inviteeName.c_str() , false); Guild* pGuild = _player->m_playerInfo->guild; if(!plyr) { Guild::SendGuildCommandResult(this, GUILD_INVITE_S, inviteeName.c_str(), GUILD_PLAYER_NOT_FOUND); return; } else if(!pGuild) { Guild::SendGuildCommandResult(this, GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } if(plyr->GetGuildId()) { Guild::SendGuildCommandResult(this, GUILD_INVITE_S, plyr->GetName(), ALREADY_IN_GUILD); return; } else if(plyr->GetGuildInvitersGuid()) { Guild::SendGuildCommandResult(this, GUILD_INVITE_S, plyr->GetName(), ALREADY_INVITED_TO_GUILD); return; } else if(!_player->m_playerInfo->guildRank->CanPerformCommand(GR_RIGHT_INVITE)) { Guild::SendGuildCommandResult(this, GUILD_INVITE_S, "", GUILD_PERMISSIONS); return; } else if(plyr->GetTeam() != _player->GetTeam() && _player->GetSession()->GetPermissionCount() == 0 && !sWorld.interfaction_guild) { Guild::SendGuildCommandResult(this, GUILD_INVITE_S, "", GUILD_NOT_ALLIED); return; } pGuild->getLock().Acquire(); uint32 memberCount = pGuild->GetNumMembers(); pGuild->getLock().Release(); if( memberCount >= MAX_GUILD_MEMBERS ){ SystemMessage( "Your guild is full." ); return; } Guild::SendGuildCommandResult(this, GUILD_INVITE_S, inviteeName.c_str(), GUILD_U_HAVE_INVITED); //41 WorldPacket data(SMSG_GUILD_INVITE, 100); data << _player->GetName(); data << pGuild->GetGuildName(); plyr->GetSession()->SendPacket(&data); plyr->SetGuildInvitersGuid(_player->GetLowGUID()); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { ObjectGuid playerGuid = holder->GetGuid(); Player* pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); SetPlayer(pCurrChar); m_playerLoading = true; SetOnline(); // "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; sLog.outError("HandlePlayerLogin> LoadFromDB failed to load %s, AccountId = %u", pCurrChar->GetGuidStr().c_str(), GetAccountId()); WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1); data << (uint8)CHAR_LOGIN_NO_CHARACTER; SendPacket(data, true); return; } 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 Spam records SendExpectedSpamRecords(); SendMotd(pCurrChar); // 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->UpdatePlayerOnlineStatus(pCurrChar); // 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, TRIGGERED_OLD_TRIGGERED); // 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, TRIGGERED_OLD_TRIGGERED); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetWaterWalk(true); } pCurrChar->TaxiFlightResume(); // 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->SetPvPFreeForAll(true); if (pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->UpdatePvPContested(true); // 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_RESET_TAXINODES)) { pCurrChar->InitTaxiNodes(); pCurrChar->RemoveAtLoginFlag(AT_LOGIN_RESET_TAXINODES, true); SendNotification("Your taxi nodes have been reset."); } 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 = sSpellTemplate.LookupEntry<SpellEntry>(sWorld.getConfig(CONFIG_UINT32_GM_INVISIBLE_AURA)); if (invisibleAuraInfo && IsSpellAppliesAura(invisibleAuraInfo)) pCurrChar->CastSpell(pCurrChar, invisibleAuraInfo, TRIGGERED_OLD_TRIGGERED); } 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; delete holder; }
void Channel::Join(ObjectGuid p, const char* pass) { WorldPacket data; if (IsOn(p)) { if (!IsConstant()) // non send error message for built-in channels { MakePlayerAlreadyMember(&data, p); SendToOne(&data, p); } return; } if (IsBanned(p)) { MakeBanned(&data); SendToOne(&data, p); return; } if (m_password.length() > 0 && strcmp(pass, m_password.c_str())) { MakeWrongPassword(&data); SendToOne(&data, p); return; } Player* plr = sObjectMgr.GetPlayer(p); if (plr) { if (HasFlag(CHANNEL_FLAG_LFG) && sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER) { MakeNotInLfg(&data); SendToOne(&data, p); return; } if (plr->GetGuildId() && (GetFlags() == 0x38)) return; plr->JoinedChannel(this); } if (m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_BOOL_SILENTLY_GM_JOIN_TO_CHANNEL))) { MakeJoined(&data, p); SendToAll(&data); } data.clear(); PlayerInfo& pinfo = m_players[p]; pinfo.player = p; pinfo.flags = 0; MakeYouJoined(&data); SendToOne(&data, p); sIRC.Handle_WoW_Channel(m_name, sObjectMgr.GetPlayer(p), CHANNEL_JOIN); JoinNotify(p); // if no owner first logged will become if (!IsConstant() && !m_ownerGuid) { SetOwner(p, (m_players.size() > 1 ? true : false)); m_players[p].SetModerator(true); } }
void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); uint64 guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (GUID_HIPART(guid)) { case HIGHGUID_GAMEOBJECT: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HIGHGUID_CORPSE: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HIGHGUID_ITEM: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); if (Guild* guild = sGuildMgr->GetGuildById((*i)->GetGuildId())) if (uint32 guildGold = CalculatePct(goldPerPlayer, (*i)->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); data << uint8(playersNear.size() <= 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." (*i)->GetSession()->SendPacket(&data); } } else { player->ModifyMoney(loot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (uint32 guildGold = CalculatePct(loot->gold, player->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); data << uint8(1); // "You loot..." SendPacket(&data); } #ifdef ELUNA sHookMgr->OnLootMoney(player, loot->gold); #endif loot->gold = 0; // Delete the money loot record from the DB if (loot->containerID > 0) loot->DeleteLootMoneyFromContainerItemDB(); // Delete container if empty if (loot->isLooted() && IS_ITEM_GUID(guid)) player->GetSession()->DoLootRelease(guid); } }
void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) { uint64 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(GUID_LOPART(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); pCurrChar->SendDungeonDifficulty(false); WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); data << pCurrChar->GetPositionY(); data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); // load player specific part before send times LoadAccountData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA),PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos, nextpos-pos); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); 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 non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } 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<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); // Increment online members of the guild guild->IncOnlineMemberCount(); } 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->SetInGuild(0); } } data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); data << uint32(0); data << uint32(0); SendPacket(&data); if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); pCurrChar->SendInitialPacketsBeforeAddToMap(); //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) { if (cEntry->CinematicSequence) pCurrChar->SendCinematicStart(cEntry->CinematicSequence); else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET active_realm_id = %d WHERE id = '%u'", realmID, GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), 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, 0);// 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, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) pCurrChar->SetMovement(MOVE_WATER_WALK); } pCurrChar->ContinueTaxiFlight(); // reset for all pets before pet loading if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) Pet::resetTalentsForAllPetsOf(pCurrChar); // 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->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); 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); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state SendNotification(LANG_RESET_TALENTS); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); 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; delete holder; }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_OFFER_PETITION"); // ok uint8 playerCount = 0; ObjectGuid petitionGuid, playerGuid; uint32 type; Player* player; recvData.read_skip<uint32>(); playerGuid[4] = recvData.ReadBit(); playerGuid[1] = recvData.ReadBit(); petitionGuid[2] = recvData.ReadBit(); playerGuid[6] = recvData.ReadBit(); petitionGuid[1] = recvData.ReadBit(); playerGuid[2] = recvData.ReadBit(); petitionGuid[4] = recvData.ReadBit(); playerGuid[3] = recvData.ReadBit(); playerGuid[7] = recvData.ReadBit(); petitionGuid[0] = recvData.ReadBit(); petitionGuid[6] = recvData.ReadBit(); playerGuid[5] = recvData.ReadBit(); playerGuid[0] = recvData.ReadBit(); petitionGuid[3] = recvData.ReadBit(); petitionGuid[5] = recvData.ReadBit(); petitionGuid[7] = recvData.ReadBit(); recvData.ReadByteSeq(playerGuid[7]); recvData.ReadByteSeq(petitionGuid[1]); recvData.ReadByteSeq(petitionGuid[4]); recvData.ReadByteSeq(petitionGuid[2]); recvData.ReadByteSeq(playerGuid[6]); recvData.ReadByteSeq(petitionGuid[3]); recvData.ReadByteSeq(petitionGuid[0]); recvData.ReadByteSeq(petitionGuid[5]); recvData.ReadByteSeq(playerGuid[0]); recvData.ReadByteSeq(playerGuid[2]); recvData.ReadByteSeq(playerGuid[5]); recvData.ReadByteSeq(playerGuid[3]); recvData.ReadByteSeq(playerGuid[4]); recvData.ReadByteSeq(petitionGuid[7]); recvData.ReadByteSeq(playerGuid[1]); recvData.ReadByteSeq(petitionGuid[6]); player = ObjectAccessor::FindPlayer(playerGuid); 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(); sLog->outDebug(LOG_FILTER_NETWORKIO, "OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionGuid), GUID_LOPART(playerGuid)); 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_CREATE_S, 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(), "", 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(), "", 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()) { Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (player->GetGuildIdInvited()) { Guild::SendCommandResult(this, GUILD_INVITE_S, 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) playerCount = uint8(result->GetRowCount()); ObjectGuid* playerGuids = new ObjectGuid[playerCount]; for (uint8 i = 0; i < playerCount; ++i) { Field* fields2 = result->Fetch(); uint32 lowGuid = fields2[0].GetUInt32(); playerGuids[i] = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER); result->NextRow(); } WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (9 + 9 + 3 + 4 + playerCount * (9 + 4))); data.WriteBit(playerGuid[1]); data.WriteBit(petitionGuid[3]); data.WriteBit(playerGuid[3]); data.WriteBit(petitionGuid[4]); data.WriteBit(petitionGuid[0]); data.WriteBit(playerGuid[7]); data.WriteBit(playerGuid[5]); data.WriteBit(petitionGuid[1]); data.WriteBit(petitionGuid[5]); data.WriteBit(petitionGuid[7]); data.WriteBit(playerGuid[0]); data.WriteBit(playerGuid[6]); data.WriteBit(petitionGuid[6]); data.WriteBit(playerGuid[2]); data.WriteBit(playerGuid[4]); data.WriteBits(playerCount, 21); for (int i = 0; i < playerCount; i++) { data.WriteBit(playerGuids[i][2]); data.WriteBit(playerGuids[i][0]); data.WriteBit(playerGuids[i][4]); data.WriteBit(playerGuids[i][7]); data.WriteBit(playerGuids[i][5]); data.WriteBit(playerGuids[i][1]); data.WriteBit(playerGuids[i][6]); data.WriteBit(playerGuids[i][3]); } data.WriteBit(petitionGuid[2]); data.FlushBits(); for (int i = 0; i < playerCount; i++) { data.WriteByteSeq(playerGuids[i][6]); data.WriteByteSeq(playerGuids[i][0]); data.WriteByteSeq(playerGuids[i][1]); data.WriteByteSeq(playerGuids[i][3]); data.WriteByteSeq(playerGuids[i][2]); data.WriteByteSeq(playerGuids[i][5]); data.WriteByteSeq(playerGuids[i][7]); data.WriteByteSeq(playerGuids[i][4]); data << uint32(1); // Choice ??? Blizzard also stores declined players ??? } data.WriteByteSeq(petitionGuid[6]); data.WriteByteSeq(petitionGuid[5]); data.WriteByteSeq(petitionGuid[4]); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(petitionGuid[1]); data << uint32(GUID_LOPART(petitionGuid)); // guildID data.WriteByteSeq(petitionGuid[2]); data.WriteByteSeq(petitionGuid[3]); data.WriteByteSeq(petitionGuid[7]); data.WriteByteSeq(playerGuid[5]); data.WriteByteSeq(playerGuid[6]); data.WriteByteSeq(playerGuid[3]); data.WriteByteSeq(playerGuid[7]); data.WriteByteSeq(playerGuid[1]); data.WriteByteSeq(playerGuid[0]); data.WriteByteSeq(petitionGuid[0]); data.WriteByteSeq(playerGuid[2]); delete[] playerGuids; player->GetSession()->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); pCurrChar->SendDungeonDifficulty(false); 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); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos, nextpos-pos); ++linecount; } pos = nextpos + 1; } if (pos < str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); 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->DisplayGuildBankTabsInfo(this); 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); } if (!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) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); //DEBUG_LOG("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); 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->SetMovement(MOVE_WATER_WALK); } 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; delete holder; }
void WorldSession::HandleLootMoneyOpcode(WorldPackets::Loot::LootMoney& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY"); Player* player = GetPlayer(); ObjectGuid guid = player->GetLootGUID(); if (!guid) return; Loot* loot = NULL; bool shareMoney = true; switch (guid.GetHigh()) { case HighGuid::GameObject: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); // do not check distance for GO if player is the owner of it (ex. fishing bobber) if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player, INTERACTION_DISTANCE)))) loot = &go->loot; break; } case HighGuid::Corpse: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &bones->loot; shareMoney = false; } break; } case HighGuid::Item: { if (Item* item = player->GetItemByGuid(guid)) { loot = &item->loot; shareMoney = false; } break; } case HighGuid::Creature: case HighGuid::Vehicle: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE)) { loot = &creature->loot; if (creature->IsAlive()) shareMoney = false; } else player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); break; } default: return; // unlootable type } if (loot) { loot->NotifyMoneyRemoved(); if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player { Group* group = player->GetGroup(); std::vector<Player*> playersNear; for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) continue; if (player->IsWithinDistInMap(member, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false)) playersNear.push_back(member); } uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size())); for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); if (Guild* guild = sGuildMgr->GetGuildById((*i)->GetGuildId())) if (uint32 guildGold = CalculatePct(goldPerPlayer, (*i)->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPackets::Loot::LootMoneyNotify packet; packet.Money = goldPerPlayer; packet.SoleLooter = playersNear.size() <= 1 ? true : false; (*i)->SendDirectMessage(packet.Write()); } } else { player->ModifyMoney(loot->gold); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) if (uint32 guildGold = CalculatePct(loot->gold, player->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT))) guild->HandleMemberDepositMoney(this, guildGold, true); WorldPackets::Loot::LootMoneyNotify packet; packet.Money = loot->gold; packet.SoleLooter = true; // "You loot..." SendPacket(packet.Write()); } loot->gold = 0; // Delete the money loot record from the DB if (!loot->containerID.IsEmpty()) loot->DeleteLootMoneyFromContainerItemDB(); // Delete container if empty if (loot->isLooted() && guid.IsItem()) player->GetSession()->DoLootRelease(guid); } }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox; uint64 money, COD; std::string receiver, subject, body; uint32 bodyLength, subjectLength, receiverLength; uint32 unk1, unk2; recvData >> COD >> money; // money and cod recvData >> unk1; recvData >> unk2; // Stationery? subjectLength = recvData.ReadBits(9); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); mailbox[0] = recvData.ReadBit(); bodyLength = recvData.ReadBits(12); mailbox[2] = recvData.ReadBit(); receiverLength = recvData.ReadBits(7); mailbox[1] = recvData.ReadBit(); uint8 items_count = recvData.ReadBits(5); // attached items count if (items_count > 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; } mailbox[6] = recvData.ReadBit(); ObjectGuid itemGUIDs[MAX_MAIL_ITEMS]; uint8 bitOrder[8] = {3, 7, 0, 2, 6, 5, 1, 4}; for (uint8 i = 0; i < items_count; ++i) recvData.ReadBitInOrder(itemGUIDs[i], bitOrder); mailbox[4] = recvData.ReadBit(); mailbox[3] = recvData.ReadBit(); recvData.FlushBits(); recvData.ReadByteSeq(mailbox[7]); for (uint8 i = 0; i < items_count; ++i) { recvData.ReadByteSeq(itemGUIDs[i][3]); recvData.ReadByteSeq(itemGUIDs[i][1]); recvData.ReadByteSeq(itemGUIDs[i][0]); recvData.ReadByteSeq(itemGUIDs[i][7]); recvData.ReadByteSeq(itemGUIDs[i][6]); recvData.read_skip<uint8>(); // item slot in mail, not used recvData.ReadByteSeq(itemGUIDs[i][4]); recvData.ReadByteSeq(itemGUIDs[i][5]); recvData.ReadByteSeq(itemGUIDs[i][2]); } recvData.ReadByteSeq(mailbox[3]); body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[4]); subject = recvData.ReadString(subjectLength); recvData.ReadByteSeq(mailbox[1]); receiver = recvData.ReadString(receiverLength); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[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, " UI64FMTD " copper and " UI64FMTD " 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, " UI64FMTD " copper and " UI64FMTD " 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 uint64 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 if (receive) { rc_team = receive->GetTeam(); mails_count = receive->GetMailSize(); } //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; } } } // We have remove mysql query for check team of offline players // On pandashan, it's will work anyway because of interfaction /*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; }*/ 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_NOT_SAME_ACCOUNT); 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_DESTROY_NONEMPTY_BAG); return; } items[i] = item; } // Check for spamming if (!UpdateAntispamCount()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); SendNotification(GetTrinityString(LANG_ANTISPAM_ERROR)); return; } // Check for special symbols if (!checkMailText(subject) || !checkMailText(body)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); return; } 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 (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(), "", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName(), rc_account, "", 0, receiver.c_str(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName().c_str(), 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)) { //TODO: charcter guid sLog->outCommand(GetAccountId(), "", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName(), rc_account, "", 0, receiver.c_str(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); } } // Guild Mail if (receive && receive->GetGuildId() && player->GetGuildId()) if (player->HasAura(83951) && (player->GetGuildId() == receive->GetGuildId())) needItemDelay = false; // 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::HandlePlayerLogin(LoginQueryHolder* holder) { /* Store the player's GUID for later reference */ ObjectGuid playerGuid = holder->GetGuid(); /* Create a new instance of the player object */ Player* pCurrChar = new Player(this); /* Initialize a motion generator */ pCurrChar->GetMotionMaster()->Initialize(); /* Account ID is validated in LoadFromDB (prevents cheaters logging in to characters not on their account) */ if (!pCurrChar->LoadFromDB(playerGuid, holder)) /// Could not load character from database, cancel login { /* Disconnect the game client */ KickPlayer(); /* Remove references to avoid dangling pointers */ delete pCurrChar; delete holder; /* Checked in WorldSession::Update */ m_playerLoading = false; return; } /* Validation check completely, assign player to WorldSession::_player for later use */ 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); /* 1.12.1 does not have SMSG_MOTD, so we send a server message */ /* Used for counting number of newlines in MOTD */ uint32 linecount = 0; /* The MOTD itself */ std::string str_motd = sWorld.GetMotd(); /* Used for tracking our position within the MOTD while iterating through it */ std::string::size_type pos = 0, nextpos; /* Find the next occurance of @ in the string * This is how newlines are represented */ while ((nextpos = str_motd.find('@', pos)) != std::string::npos) { /* If these are not equal, it means a '@' was found * These are used to represent newlines in the string * It is set by the code above here */ if (nextpos != pos) { /* Send the player a system message containing the substring from pos to nextpos - pos */ ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos, nextpos - pos).c_str()); ++linecount; } pos = nextpos + 1; } /* There are no more newlines in our MOTD, so we send whatever is left */ if (pos < str_motd.length()) { ChatHandler(pCurrChar).PSendSysMessage(str_motd.substr(pos).c_str()); } DEBUG_LOG("WORLD: Sent motd (SMSG_MOTD)"); /* Attempt to load guild for player */ if (QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD)) { /* We're in a guild, so set the player's guild data to represent that */ Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt32()); /* Avoid dangling pointers */ delete resultGuild; } /* Player thinks they have a guild, but it isn't in the database. Clear that information */ else if (pCurrChar->GetGuildId()) { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } /* Player is in a guild * TODO: Can we move this code into the block above? Not sure why it's down here */ if (pCurrChar->GetGuildId() != 0) { /* Get guild based on what we set the player's guild to above */ Guild* guild = sGuildMgr.GetGuildById(pCurrChar->GetGuildId()); /* More checks to see if they're in a guild? I'm sure this is redundant */ if (guild) { /* Build MOTD packet and send it to the player */ 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)"); /* Let everyone in the guild know you've just signed in */ guild->BroadcastEvent(GE_SIGNED_ON, pCurrChar->GetObjectGuid(), pCurrChar->GetName()); } /* If the player is not in a guild */ else { 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()); /* Set guild to 0 (again) */ pCurrChar->SetInGuild(0); } } /* Don't let the player get stuck logging in with no corpse */ if (!pCurrChar->IsAlive()) { pCurrChar->SendCorpseReclaimDelay(true); } /* Sends information required before the player can be added to the map * TODO: See if we can send information about game objects here (prevent alt+f4 through object) */ pCurrChar->SendInitialPacketsBeforeAddToMap(); /* If it's the player's first login, send a cinematic */ if (!pCurrChar->getCinematic()) { pCurrChar->setCinematic(1); /* Set the start location to the player's racial starting point */ 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; } } /* This code is run if we can not add the player to the map for some reason */ if (lockStatus != AREA_LOCKSTATUS_OK || !pCurrChar->GetMap()->Add(pCurrChar)) { /* Attempt to find an areatrigger to teleport the player for us */ AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId()); if (at) { lockStatus = pCurrChar->GetAreaTriggerLockStatus(at, miscRequirement); } /* We couldn't find an areatrigger to teleport, so just move the player back to their home bind */ 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 %i", pCurrChar->GetName(), pCurrChar->GetMapId()); /* send the player's social lists */ pCurrChar->GetSocial()->SendFriendList(); pCurrChar->GetSocial()->SendIgnoreList(); /* Send packets that must be sent only after player is added to the map */ pCurrChar->SendInitialPacketsAfterAddToMap(); /* Mark player as online in the database */ 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()); /* Sync player's in-game time with server time */ pCurrChar->SetInGameTime(WorldTimer::getMSTime()); /* Send logon notification to player's group * This is sent after player is added to the world so that player receives it too */ if (Group* group = pCurrChar->GetGroup()) { group->SendUpdate(); } /* Inform player's friends that player has come online */ sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetObjectGuid(), true); /* Load the player's corpse if it exists, or resurrect the player if not */ pCurrChar->LoadCorpse(); /* If the player is dead, we need to set them as a ghost and increase movespeed */ if (pCurrChar->m_deathState != ALIVE) { /* If player is a night elf, wisp racial should be applied */ 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) } /* Apply ghost spell to player */ pCurrChar->CastSpell(pCurrChar, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) /* Allow player to walk on water */ pCurrChar->SetWaterWalk(true); } /* If player is on a taxi, continue their flight */ pCurrChar->ContinueTaxiFlight(); /* Load pet if player has one * If the player is dead or on a taxi, the pet will be remembered as a temporary summon */ pCurrChar->LoadPet(); /* If we're running an FFA PvP realm and the player isn't a GM, mark them as PvP flagged */ 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 onLogon requests (such as talent resets) */ 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 } /* We've done what we need to, remove the flag */ if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) { pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); } /* If the server is shutting down, show shutdown time remaining */ if (sWorld.IsShutdowning()) { sWorld.ShutdownMsg(true, pCurrChar); } /* If player should have all taxi paths, give them to the player */ if (sWorld.getConfig(CONFIG_BOOL_ALL_TAXI_PATHS)) { pCurrChar->SetTaxiCheater(true); } /* Send GM notifications */ 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()); /* Make player stand up if they're not already stood up and not stunned */ if (!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) { pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); } m_playerLoading = false; /* Used for movement */ m_clientTimeDelay = 0; /* Used for looting */ pCurrChar->lastTimeLooted = time(NULL); delete holder; }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox; uint64 money, COD; std::string receiverName, subject, body; uint32 bodyLength, subjectLength, receiverLength; uint32 unk1, unk2; recvData >> unk1; recvData >> unk2; // Stationery? recvData >> COD >> money; // money and cod bodyLength = recvData.ReadBits(12); subjectLength = recvData.ReadBits(9); uint8 items_count = recvData.ReadBits(5); // attached items count if (items_count > 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; } mailbox[0] = recvData.ReadBit(); ObjectGuid itemGUIDs[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { itemGUIDs[i][2] = recvData.ReadBit(); itemGUIDs[i][6] = recvData.ReadBit(); itemGUIDs[i][3] = recvData.ReadBit(); itemGUIDs[i][7] = recvData.ReadBit(); itemGUIDs[i][1] = recvData.ReadBit(); itemGUIDs[i][0] = recvData.ReadBit(); itemGUIDs[i][4] = recvData.ReadBit(); itemGUIDs[i][5] = recvData.ReadBit(); } mailbox[3] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); receiverLength = recvData.ReadBits(7); mailbox[2] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); recvData.ReadByteSeq(mailbox[4]); for (uint8 i = 0; i < items_count; ++i) { recvData.ReadByteSeq(itemGUIDs[i][6]); recvData.ReadByteSeq(itemGUIDs[i][1]); recvData.ReadByteSeq(itemGUIDs[i][7]); recvData.ReadByteSeq(itemGUIDs[i][2]); recvData.read_skip<uint8>(); // item slot in mail, not used recvData.ReadByteSeq(itemGUIDs[i][3]); recvData.ReadByteSeq(itemGUIDs[i][0]); recvData.ReadByteSeq(itemGUIDs[i][4]); recvData.ReadByteSeq(itemGUIDs[i][5]); } recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); subject = recvData.ReadString(subjectLength); receiverName = recvData.ReadString(receiverLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[0]); body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[1]); // 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(), items_count, 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(), items_count, money, COD, unk1, unk2); if (player->GetGUID() == receiverGuid) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = items_count ? 30 * items_count : 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 = items_count ? true : false; for (uint8 i = 0; i < items_count; ++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 < 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() != 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 (items_count > 0 || money > 0) { bool log = HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE); if (items_count > 0) { for (uint8 i = 0; i < items_count; ++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); }
// Lists all recruits for a guild - Misses times void WorldSession::HandleGuildFinderGetRecruits(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_GET_RECRUITS"); uint32 unkTime = 0; recvPacket >> unkTime; Player* player = GetPlayer(); if (!player->GetGuildId()) return; std::vector<MembershipRequest> recruitsList = sGuildFinderMgr->GetAllMembershipRequestsForGuild(player->GetGuildId()); uint32 recruitCount = recruitsList.size(); ByteBuffer dataBuffer; WorldPacket data(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED); data << uint32(time(NULL)); // Unk time data.WriteBits(recruitCount, 18); for (std::vector<MembershipRequest>::const_iterator itr = recruitsList.begin(); itr != recruitsList.end(); ++itr) { MembershipRequest request = *itr; ObjectGuid playerGuid(MAKE_NEW_GUID(request.GetPlayerGUID(), 0, HIGHGUID_PLAYER)); uint8 _class, _level = 0; std::string name; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_NAME_QUERY_SIMPLE); stmt->setUInt32(0, request.GetPlayerGUID()); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { //name, race, gender, class, level Field* fields = result->Fetch(); name = fields[0].GetString(); _class = fields[3].GetUInt8(); _level = fields[4].GetUInt8(); } data.WriteBits(request.GetComment().size(), 10); data.WriteBitSeq<6, 3, 1, 4, 0, 5, 2>(playerGuid); data.WriteBits(name.size(), 6); data.WriteBitSeq<7>(playerGuid); dataBuffer << uint32(_class); dataBuffer << uint32(_level); dataBuffer << uint32(0); dataBuffer << uint32(time(NULL) <= request.GetExpiryTime()); dataBuffer << uint32(request.GetAvailability()); dataBuffer.WriteByteSeq<7>(playerGuid); dataBuffer << uint32(time(NULL) - request.GetSubmitTime()); // Time in seconds since application submitted. if (name.size() > 0) dataBuffer.append(name.c_str(), name.size()); dataBuffer.WriteByteSeq<6>(playerGuid); if (name.size() > 0) dataBuffer.append(name.c_str(), name.size()); dataBuffer << uint32(request.GetClassRoles()); dataBuffer.WriteByteSeq<1>(playerGuid); dataBuffer << uint32(request.GetInterests()); dataBuffer << uint32(request.GetExpiryTime() - time(NULL)); // TIme in seconds until application expires. dataBuffer.WriteByteSeq<2, 5, 0, 4, 3>(playerGuid); } data.FlushBits(); data.append(dataBuffer); player->SendDirectMessage(&data); }
void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) { sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE"); std::string Invitedname, plname; Player * player = NULL; recvPacket >> Invitedname; if(normalizePlayerName(Invitedname)) player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); if(!player) { SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_PLAYER_NOT_FOUND); return; } Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } // OK result but not send invite if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; // not let enemies sign guild charter if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) { SendGuildCommandResult(GUILD_INVITE_S, Invitedname, GUILD_NOT_ALLIED); return; } if(player->GetGuildId()) { plname = player->GetName(); SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_IN_GUILD); return; } if(player->GetGuildIdInvited()) { plname = player->GetName(); SendGuildCommandResult(GUILD_INVITE_S, plname, ALREADY_INVITED_TO_GUILD); return; } if(!guild->HasRankRight(GetPlayer()->GetRank(), GR_RIGHT_INVITE)) { SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); return; } sLog.outDebug("Player %s Invited %s to Join his Guild", GetPlayer()->GetName(), Invitedname.c_str()); player->SetGuildIdInvited(GetPlayer()->GetGuildId()); // Put record into guildlog guild->LogGuildEvent(GUILD_EVENT_LOG_INVITE_PLAYER, GetPlayer()->GetGUIDLow(), player->GetGUIDLow(), 0); WorldPacket data(SMSG_GUILD_INVITE, (8+10)); // guess size data << GetPlayer()->GetName(); data << guild->GetName(); player->GetSession()->SendPacket(&data); sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)"); }
void WorldSession::HandleWhoOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_WHO"); // recv_data.hexlike(); 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); uint32 matchcount = 0; uint32 displaycount = 0; WorldPacket data(SMSG_WHO, 50); // guess size data << uint32(matchcount); // placeholder, count of players matching criteria data << uint32(displaycount); // placeholder, count of players displayed // 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; // 49 is maximum player count sent to client ++matchcount; if (matchcount > 49) continue; ++displaycount; 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 } data.put(0, displaycount); // insert right count, count displayed data.put(4, matchcount); // insert right count, count of matches SendPacket(&data); DEBUG_LOG("WORLD: Send SMSG_WHO Message"); }
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 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(GUID_LOPART(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); pCurrChar->SendDungeonDifficulty(false); 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); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { if (nextpos != pos) { data << str_motd.substr(pos,nextpos-pos); ++linecount; } pos = nextpos+1; } if (pos<str_motd.length()) { data << str_motd.substr(pos); ++linecount; } data.put(0, linecount); SendPacket( &data ); 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 non existed membership { pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } 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<<pCurrChar->GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); // Increment online members of the guild guild->IncOnlineMemberCount(); } 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->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); ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); if(rEntry) { data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); data << uint32(rEntry->startmovie); SendPacket( &data ); } } if (!pCurrChar->GetMap()->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->GetSocial()->SendSocialList(); pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), 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, 0);// 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, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); //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->SetMovement(MOVE_WATER_WALK); } if(uint32 sourceNode = pCurrChar->m_taxi.GetTaxiSource()) { sLog.outDebug( "WORLD: Restart character %u taxi flight", pCurrChar->GetGUIDLow() ); uint32 MountId = objmgr.GetTaxiMount(sourceNode, pCurrChar->GetTeam()); uint32 path = pCurrChar->m_taxi.GetCurrentTaxiPath(); // search appropriate start path node uint32 startNode = 0; TaxiPathNodeList const& nodeList = sTaxiPathNodesByPath[path]; float distPrev = MAP_SIZE*MAP_SIZE; float distNext = (nodeList[0].x-pCurrChar->GetPositionX())*(nodeList[0].x-pCurrChar->GetPositionX())+ (nodeList[0].y-pCurrChar->GetPositionY())*(nodeList[0].y-pCurrChar->GetPositionY())+ (nodeList[0].z-pCurrChar->GetPositionZ())*(nodeList[0].z-pCurrChar->GetPositionZ()); for(uint32 i = 1; i < nodeList.size(); ++i) { TaxiPathNode const& node = nodeList[i]; TaxiPathNode const& prevNode = nodeList[i-1]; // skip nodes at another map if(node.mapid != pCurrChar->GetMapId()) continue; distPrev = distNext; distNext = (node.x-pCurrChar->GetPositionX())*(node.x-pCurrChar->GetPositionX())+ (node.y-pCurrChar->GetPositionY())*(node.y-pCurrChar->GetPositionY())+ (node.z-pCurrChar->GetPositionZ())*(node.z-pCurrChar->GetPositionZ()); float distNodes = (node.x-prevNode.x)*(node.x-prevNode.x)+ (node.y-prevNode.y)*(node.y-prevNode.y)+ (node.z-prevNode.z)*(node.z-prevNode.z); if(distNext + distPrev < distNodes) { startNode = i; break; } } SendDoFlight( MountId, path, startNode ); } // Load pet if any and player is alive and not in taxi flight if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0) 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->SetFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP); 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); } // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); 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()); m_playerLoading = false; delete holder; }
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==nullptr 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::HandleOfferPetitionOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data, 4+8+8); sLog.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok //recv_data.hexlike(); uint8 signs = 0; uint64 petitionguid, plguid; uint32 type, junk; Player *player; recv_data >> junk; // this is not petition type! recv_data >> petitionguid; // petition guid recv_data >> plguid; // player guid player = ObjectAccessor::FindPlayer(plguid); if (!player) return; QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); if (!result) return; Field *fields = result->Fetch(); type = fields[0].GetUInt32(); delete result; sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionguid), GUID_LOPART(plguid)); if (!sWorld.getConfig(CONFIG_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, "", GUILD_NOT_ALLIED); return; } if(type != 9) { if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) { // player is too low level to join an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName(), "", ERR_ARENA_TEAM_PLAYER_TO_LOW); 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(), "", 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(), ALREADY_IN_GUILD); return; } if(player->GetGuildIdInvited()) { SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ALREADY_INVITED_TO_GUILD); return; } } result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); // result==NULL also correct charter without signs if(result) signs = result->GetRowCount(); WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12)); data << petitionguid; // petition guid data << _player->GetGUID(); // owner guid data << GUID_LOPART(petitionguid); // guild guid (in mangos always same as GUID_LOPART(petition guid) data << signs; // sign's count for(uint8 i = 1; i <= signs; i++) { Field *fields = result->Fetch(); uint64 plguid = fields[0].GetUInt64(); data << plguid; // Player GUID data << (uint32)0; // there 0 ... result->NextRow(); } delete result; player->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, can not 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 #ifdef ENABLE_ELUNA sEluna->OnAddMember(this, pl, newmember.RankId); #endif /* ENABLE_ELUNA */ return true; }
bool Guild::AddMember(uint64 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); // fill player data MemberSlot newmember; if (pl) { newmember.Name = pl->GetName(); newmember.Level = pl->getLevel(); newmember.Class = pl->getClass(); newmember.ZoneId = pl->GetZoneId(); } else { // 0 1 2 3 QueryResult *result = CharacterDatabase.PQuery("SELECT name,level,class,zone FROM characters WHERE guid = '%u'", GUID_LOPART(plGuid)); 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(); delete result; if (newmember.Level < 1 || newmember.Level > STRONG_MAX_LEVEL || newmember.Class < CLASS_WARRIOR || newmember.Class >= MAX_CLASSES) { sLog.outError("Player (GUID: %u) has a broken data in field `characters` table, cannot add him to guild.",GUID_LOPART(plGuid)); return false; } } newmember.RankId = plRank; newmember.OFFnote = (std::string)""; newmember.Pnote = (std::string)""; newmember.LogoutTime = time(NULL); members[GUID_LOPART(plGuid)] = 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, GUID_LOPART(plGuid), 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); } return true; }