bool ChatHandler::HandlePlayerbotCommand(char* args) { if (sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_DISABLE)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (NULL, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid.IsEmpty() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sObjectMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } QueryResult *resultchar = CharacterDatabase.PQuery("SELECT COUNT(*) FROM characters WHERE online = '1' AND account = '%u'", accountId); if (resultchar) { Field *fields = resultchar->Fetch(); int acctcharcount = fields[0].GetUInt32(); int maxnum = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_MAXBOTS); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (acctcharcount > maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)", maxnum); SetSentErrorMessage(true); delete resultchar; return false; } delete resultchar; } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level,name FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); int maxlvl = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_RESTRICTLEVEL); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->AddPlayerBot(guid); PSendSysMessage("Bot added successfully."); } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); } else if (cmdStr == "co" || cmdStr == "combatorder") { Unit *target = NULL; char *orderChar = strtok(NULL, " "); if (!orderChar) { PSendSysMessage("|cffff0000Syntax error:|cffffffff .bot co <botName> <order=reset|tank|assist|heal|protect> [targetPlayer]"); SetSentErrorMessage(true); return false; } std::string orderStr = orderChar; if (orderStr == "protect" || orderStr == "assist") { char *targetChar = strtok(NULL, " "); ObjectGuid targetGuid = m_session->GetPlayer()->GetSelectionGuid(); if (!targetChar && targetGuid.IsEmpty()) { PSendSysMessage("|cffff0000Combat orders protect and assist expect a target either by selection or by giving target player in command string!"); SetSentErrorMessage(true); return false; } if (targetChar) { std::string targetStr = targetChar; targetGuid = sObjectMgr.GetPlayerGuidByName(targetStr.c_str()); } target = ObjectAccessor::GetUnit(*m_session->GetPlayer(), targetGuid); if (!target) { PSendSysMessage("|cffff0000Invalid target for combat order protect or assist!"); SetSentErrorMessage(true); return false; } } if (mgr->GetPlayerBot(guid) == NULL) { PSendSysMessage("|cffff0000Bot can not receive combat order because bot does not exist in world."); SetSentErrorMessage(true); return false; } mgr->GetPlayerBot(guid)->GetPlayerbotAI()->SetCombatOrderByStr(orderStr, target); } return true; }
/** * Handles the Packet sent by the client when sending a mail. * * This methods takes the packet sent by the client and performs the following actions: * - Checks whether the mail is valid: i.e. can he send the selected items, * does he have enough money, etc. * - Creates a MailDraft and adds the needed items, money, cost data. * - Sends the mail. * * Depending on the outcome of the checks performed the player will recieve a different * MailResponseResult. * * @see MailResponseResult * @see SendMailResult() * * @param recv_data the WorldPacket containing the data sent by the client. */ void WorldSession::HandleSendMail(WorldPacket & recv_data ) { ObjectGuid mailboxGuid; ObjectGuid itemGuid; uint64 unk3; std::string receiver, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; recv_data >> mailboxGuid; recv_data >> receiver; recv_data >> subject; recv_data >> body; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 recv_data >> itemGuid; recv_data >> money >> COD; // money and cod recv_data >> unk3; // const 0 recv_data >> unk4; // const 0 // packet read complete, now do check if (!CheckMailBox(mailboxGuid)) return; if (receiver.empty()) return; Player* pl = _player; ObjectGuid rc; if (normalizePlayerName(receiver)) rc = sObjectMgr.GetPlayerGuidByName(receiver); if (!rc) { DETAIL_LOG("%s is sending mail to %s (GUID: nonexistent!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), receiver.c_str(), subject.c_str(), body.c_str(), itemGuid ? 1 : 0, money, COD, unk1, unk2); pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } DETAIL_LOG("%s is sending mail to %s with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), rc.GetString().c_str(), subject.c_str(), body.c_str(), itemGuid ? 1 : 0, money, COD, unk1, unk2); if (pl->GetObjectGuid() == rc) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 reqmoney = money + 30; if (pl->GetMoney() < reqmoney) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player *receive = sObjectMgr.GetPlayer(rc); Team rc_team; 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(); } else { rc_team = sObjectMgr.GetPlayerTeamByGUID(rc); if (QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", rc.GetCounter())) { Field *fields = result->Fetch(); mails_count = fields[0].GetUInt32(); delete result; } } // 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) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // check the receiver's Faction... if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(rc); Item* item = NULL; if (itemGuid) { item = pl->GetItemByGuid(itemGuid); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if(!item) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded()) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if ((item->GetProto()->Flags & ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } } pl->SendMailResult(0, MAIL_SEND, MAIL_OK); pl->ModifyMoney( -int32(reqmoney) ); bool needItemDelay = false; MailDraft draft(subject, body); if (itemGuid || money > 0) { uint32 rc_account = 0; if(receive) rc_account = receive->GetSession()->GetAccountId(); else rc_account = sObjectMgr.GetPlayerAccountIdByGUID(rc); if (item) { if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), item->GetProto()->Name1, item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); } //CharacterDatabase.PExecute("INSERT INTO character_destroyedItem VALUES ( %I64u, %u, %u, %u, CURRENT_TIMESTAMP )", _player->GetGUID(), item->GetEntry(), item->GetCount(), 1); pl->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(); // deletes item from character's inventory item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", rc.GetCounter(), item->GetGUIDLow()); CharacterDatabase.CommitTransaction(); draft.AddItem(item); // if item send to character at another account, then apply item delivery delay needItemDelay = pl->GetSession()->GetAccountId() != rc_account; } if (money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_UINT32_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list draft .SetMoney(money) .SetCOD(COD) .SendMailTo(MailReceiver(receive, rc), pl, body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); }
void WorldSession::HandleCharCustomizeOpcode(WorldPacket& recv_data) { ObjectGuid guid; std::string newname; recv_data >> guid; recv_data >> newname; uint8 gender, skin, face, hairStyle, hairColor, facialHair; recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face; QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", guid.GetCounter()); if (!result) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_CREATE_ERROR); SendPacket( &data ); return; } Field *fields = result->Fetch(); uint32 at_loginFlags = fields[0].GetUInt32(); delete result; if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_CREATE_ERROR); SendPacket( &data ); return; } // prevent character rename to invalid name if (!normalizePlayerName(newname)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_NAME_NO_NAME); SendPacket( &data ); return; } uint8 res = ObjectMgr::CheckPlayerName(newname,true); if (res != CHAR_NAME_SUCCESS) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(res); SendPacket( &data ); return; } // check name limitations if (GetSecurity() == SEC_PLAYER && sObjectMgr.IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_NAME_RESERVED); SendPacket(&data); return; } // character with this name already exist ObjectGuid newguid = sAccountMgr.GetPlayerGuidByName(newname); if (newguid && newguid != guid) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket(&data); return; } CharacterDatabase.escape_string(newname); Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), guid.GetCounter()); std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s), Character %s customized to: %s", GetAccountId(), IP_str.c_str(), guid.GetString().c_str(), newname.c_str()); WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + (newname.size() + 1) + 6); data << uint8(RESPONSE_SUCCESS); data << ObjectGuid(guid); data << newname; data << uint8(gender); data << uint8(skin); data << uint8(face); data << uint8(hairStyle); data << uint8(hairColor); data << uint8(facialHair); SendPacket(&data); }
bool Group::_setAssistantFlag(ObjectGuid guid, const bool& state) { member_witerator slot = _getMemberWSlot(guid); if (slot == m_memberSlots.end()) return false; slot->assistant = state; if (!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET assistant='%u' WHERE memberGuid='%u'", (state == true) ? 1 : 0, guid.GetCounter()); return true; }
bool LoginQueryHolder::Initialize() { SetSize(MAX_PLAYER_LOGIN_QUERY); bool res = true; // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags," "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost," "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path," "honor_highest_rank, honor_standing, stored_honor_rating, stored_dishonorable_kills, stored_honorable_kills," "watchedFaction, drunk," "health, power1, power2, power3, power4, power5, exploredZones, equipmentCache, ammoId, actionBars FROM characters WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM character_aura WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHONORCP, "SELECT victim_type,victim,honor,date,type FROM character_honor_cp WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADITEMLOOT, "SELECT guid,itemid,amount,property FROM item_loot WHERE owner_guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags FROM character_social WHERE guid = '%u' LIMIT 255", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS, "SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBGDATA, "SELECT instance_id, team, join_x, join_y, join_z, join_o, join_map FROM character_battleground_data WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILS, "SELECT id,messageType,sender,receiver,subject,itemTextId,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId,has_items FROM mail WHERE receiver = '%u' ORDER BY id DESC", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS, "SELECT data, mail_id, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE receiver = '%u'", m_guid.GetCounter()); return res; }
void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recv_data) { DEBUG_LOG("Received opcode CMSG_TURN_IN_PETITION"); // ok // recv_data.hexlike(); ObjectGuid petitionGuid; recv_data >> petitionGuid; DEBUG_LOG("Petition %s turned in by %s", petitionGuid.GetString().c_str(), _player->GetGuidStr().c_str()); /// Collect petition info data ObjectGuid ownerGuid; uint32 type; std::string name; // data QueryResult* result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter()); if (result) { Field* fields = result->Fetch(); ownerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); name = fields[1].GetCppString(); type = fields[2].GetUInt32(); delete result; } else { sLog.outError("CMSG_TURN_IN_PETITION: petition table not have data for guid %u!", petitionGuid.GetCounter()); return; } if (type == 9) { if (_player->GetGuildId()) { WorldPacket data(SMSG_TURN_IN_PETITION_RESULTS, 4); data << uint32(PETITION_TURN_ALREADY_IN_GUILD); // already in guild _player->GetSession()->SendPacket(&data); return; } } else { if (!IsArenaTypeValid(ArenaType(type))) return; uint8 slot = ArenaTeam::GetSlotByType(ArenaType(type)); if (slot >= MAX_ARENA_SLOT) return; if (_player->GetArenaTeamId(slot)) { // data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); // data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild //_player->GetSession()->SendPacket(&data); SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); return; } } if (_player->GetObjectGuid() != ownerGuid) return; // signs result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter()); uint8 signs = result ? (uint8)result->GetRowCount() : 0; uint32 count = type == 9 ? sWorld.getConfig(CONFIG_UINT32_MIN_PETITION_SIGNS) : type - 1; if (signs < count) { WorldPacket data(SMSG_TURN_IN_PETITION_RESULTS, 4); data << uint32(PETITION_TURN_NEED_MORE_SIGNATURES); // need more signatures... SendPacket(&data); delete result; return; } if (type == 9) { if (sGuildMgr.GetGuildByName(name)) { SendGuildCommandResult(GUILD_CREATE_S, name, ERR_GUILD_NAME_EXISTS_S); delete result; return; } } else { if (sObjectMgr.GetArenaTeamByName(name)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); delete result; return; } } // and at last charter item check Item* item = _player->GetItemByGuid(petitionGuid); if (!item) { delete result; return; } // OK! // delete charter item _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); if (type == 9) // create guild { Guild* guild = new Guild; if (!guild->Create(_player, name)) { delete guild; delete result; return; } // register guild and add guildmaster sGuildMgr.AddGuild(guild); // add members for (uint8 i = 0; i < signs; ++i) { Field* fields = result->Fetch(); ObjectGuid signGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); if (!signGuid) continue; guild->AddMember(signGuid, guild->GetLowestRank()); result->NextRow(); } } else // or arena team { ArenaTeam* at = new ArenaTeam; if (!at->Create(_player->GetObjectGuid(), ArenaType(type), name)) { sLog.outError("PetitionsHandler: arena team create failed."); delete at; delete result; return; } uint32 icon, iconcolor, border, bordercolor, backgroud; recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor; at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor); // register team and add captain sObjectMgr.AddArenaTeam(at); DEBUG_LOG("PetitonsHandler: arena team added to objmrg"); // add members for (uint8 i = 0; i < signs; ++i) { Field* fields = result->Fetch(); ObjectGuid memberGUID = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); if (!memberGUID) continue; DEBUG_LOG("PetitionsHandler: adding arena member %s", memberGUID.GetString().c_str()); at->AddMember(memberGUID); result->NextRow(); } } delete result; CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter()); CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter()); CharacterDatabase.CommitTransaction(); // created DEBUG_LOG("TURN IN PETITION %s", petitionGuid.GetString().c_str()); WorldPacket data(SMSG_TURN_IN_PETITION_RESULTS, 4); data << uint32(PETITION_TURN_OK); SendPacket(&data); }
// this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket& recv_data) { DEBUG_LOG("WORLD: HandleAuctionSellItem"); ObjectGuid auctioneerGuid; uint32 etime, bid, buyout, itemCount; GuidVector guids; std::vector<uint32> stackSizes; recv_data >> auctioneerGuid; recv_data >> itemCount; if (itemCount > MAX_BAG_SIZE * 5) { recv_data.rpos(recv_data.wpos()); // should not happen return; } guids.resize(itemCount); stackSizes.resize(itemCount); for (uint32 i = 0; i < itemCount; ++i) { recv_data >> guids[i]; // item guid recv_data >> stackSizes[i]; // stack size } recv_data >> bid; recv_data >> buyout; recv_data >> etime; if (!bid || !etime) return; // check for cheaters Player* pl = GetPlayer(); AuctionHouseEntry const* auctionHouseEntry = GetCheckedAuctionHouseForAuctioneer(auctioneerGuid); if (!auctionHouseEntry) return; // always return pointer AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry); // client send time in minutes, convert to common used sec time etime *= MINUTE; // client understand only 3 auction time switch (etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } for (uint32 i = 0; i < itemCount; ++i) { ObjectGuid itemGuid = guids[i]; if (!itemGuid) continue; uint32 stackSize = stackSizes[i]; Item* it = pl->GetItemByGuid(itemGuid); // do not allow to sell already auctioned items if (sAuctionMgr.GetAItem(itemGuid.GetCounter())) { sLog.outError("AuctionError, %s is sending %s, but item is already in another auction", pl->GetGuidStr().c_str(), itemGuid.GetString().c_str()); SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); continue; } // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) if (!it) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); continue; } if (!it->CanBeTraded()) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); continue; } if ((it->GetProto()->Flags & ITEM_FLAG_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); continue; } // check money for deposit uint32 deposit = AuctionHouseMgr::GetAuctionDeposit(auctionHouseEntry, etime, it); if (pl->GetMoney() < deposit) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_NOT_ENOUGH_MONEY); continue; } if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); } if (stackSize == 0) stackSize = 1; if (stackSize > it->GetMaxStackCount()) // too big stack size stackSize = it->GetMaxStackCount(); if (!pl->HasItemCount(it->GetEntry(), stackSize)) // not enough items continue; Item* newItem = it->CloneItem(stackSize); pl->DestroyItemCount(it, stackSize, true); pl->ModifyMoney(-int32(deposit)); AuctionEntry* AH = auctionHouse->AddAuction(auctionHouseEntry, newItem, etime, bid, buyout, deposit, pl); DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, etime, auctionHouseEntry->houseId); SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } }
// this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { DEBUG_LOG("WORLD: HandleAuctionSellItem"); ObjectGuid auctioneerGuid; uint32 etime, bid, buyout, itemCount; std::vector<ObjectGuid> guids; std::vector<uint32> stackSizes; recv_data >> auctioneerGuid; recv_data >> itemCount; if(itemCount > MAX_BAG_SIZE * 5) { recv_data.rpos(recv_data.wpos()); // should not happen return; } guids.resize(itemCount); stackSizes.resize(itemCount); for(uint32 i = 0; i < itemCount; ++i) { recv_data >> guids[i]; // item guid recv_data >> stackSizes[i]; // stack size } recv_data >> bid; recv_data >> buyout; recv_data >> etime; if (!bid || !etime) return; // check for cheaters Player *pl = GetPlayer(); AuctionHouseEntry const* auctionHouseEntry = GetCheckedAuctionHouseForAuctioneer(auctioneerGuid); if (!auctionHouseEntry) return; // always return pointer AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry); // client send time in minutes, convert to common used sec time etime *= MINUTE; // client understand only 3 auction time switch(etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); for(uint32 i = 0; i < itemCount; ++i) { ObjectGuid itemGuid = guids[i]; if(itemGuid.IsEmpty()) continue; uint32 stackSize = stackSizes[i]; Item *it = pl->GetItemByGuid(itemGuid); // do not allow to sell already auctioned items if (sAuctionMgr.GetAItem(itemGuid.GetCounter())) { sLog.outError("AuctionError, %s is sending %s, but item is already in another auction", pl->GetGuidStr().c_str(), itemGuid.GetString().c_str()); SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); continue; } // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) if(!it) { SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); continue; } if(!it->CanBeTraded()) { SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); continue; } if ((it->GetProto()->Flags & ITEM_FLAG_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_CANNOT_TRADE_THAT); continue; } // check money for deposit uint32 deposit = AuctionHouseMgr::GetAuctionDeposit( auctionHouseEntry, etime, it ); if ( pl->GetMoney() < deposit ) { SendAuctionCommandResult(NULL, AUCTION_STARTED, AUCTION_ERR_NOT_ENOUGH_MONEY); continue; } if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE) ) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); } if(stackSize == 0) stackSize = 1; if(stackSize > it->GetMaxStackCount()) // too big stack size stackSize = it->GetMaxStackCount(); if(!pl->HasItemCount(it->GetEntry(), stackSize)) // not enough items continue; Item *newItem = it->CloneItem(stackSize, pl); pl->DestroyItemCount(it, stackSize, true); pl->ModifyMoney( -int32(deposit) ); uint32 auction_time = uint32(etime * sWorld.getConfig(CONFIG_FLOAT_RATE_AUCTION_TIME)); AuctionEntry *AH = new AuctionEntry; AH->Id = sObjectMgr.GenerateAuctionID(); AH->itemGuidLow = newItem->GetObjectGuid().GetCounter(); AH->itemTemplate = newItem->GetEntry(); AH->owner = pl->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expireTime = time(NULL) + auction_time; AH->moneyDeliveryTime = 0; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, auction_time, AH->GetHouseId()); auctionHouse->AddAuction(AH); sAuctionMgr.AddAItem(newItem); CharacterDatabase.BeginTransaction(); newItem->SaveToDB(); AH->SaveToDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); if (sIRC.BOTMASK & 1024) sIRC.AHFunc(it->GetEntry(), it->GetProto()->Name1, pl->GetName()); SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } }
void WorldSession::HandleCharDeleteOpcode(WorldPacket& recv_data) { ObjectGuid guid; recv_data >> guid; // can't delete loaded character if (sObjectMgr.GetPlayer(guid)) return; uint32 accountId = 0; std::string name; // is guild leader if (sGuildMgr.GetGuildByLeader(guid)) { WorldPacket data(SMSG_CHAR_DELETE, 1); data << (uint8)CHAR_DELETE_FAILED_GUILD_LEADER; SendPacket(&data); return; } // is arena team captain if (sObjectMgr.GetArenaTeamByCaptain(guid)) { WorldPacket data(SMSG_CHAR_DELETE, 1); data << (uint8)CHAR_DELETE_FAILED_ARENA_CAPTAIN; SendPacket(&data); return; } uint32 lowguid = guid.GetCounter(); QueryResult* result = CharacterDatabase.PQuery("SELECT account,name FROM characters WHERE guid='%u'", lowguid); if (result) { Field* fields = result->Fetch(); accountId = fields[0].GetUInt32(); name = fields[1].GetCppString(); delete result; } // prevent deleting other players' characters using cheating tools if (accountId != GetAccountId()) return; std::string IP_str = GetRemoteAddress(); BASIC_LOG("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), lowguid); sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), lowguid); if (sLog.IsOutCharDump()) // optimize GetPlayerDump call { std::string dump = PlayerDumpWriter().GetDump(lowguid); sLog.outCharDump(dump.c_str(), GetAccountId(), lowguid, name.c_str()); } Player::DeleteFromDB(guid, GetAccountId()); WorldPacket data(SMSG_CHAR_DELETE, 1); data << (uint8)CHAR_DELETE_SUCCESS; SendPacket(&data); }
void Guild::SetLeader(ObjectGuid guid) { MemberSlot* slot = GetMemberSlot(guid); if (!slot) { return; } m_LeaderGuid = guid; slot->ChangeRank(GR_GUILDMASTER); CharacterDatabase.PExecute("UPDATE guild SET leaderguid='%u' WHERE guildid='%u'", guid.GetCounter(), m_Id); }
/** * Remove character from guild * * @param guid Character that removed from guild * @param isDisbanding Flag set if function called from Guild::Disband, so not need update DB in per-member mode only or leader update * * @return true, if guild need to be disband and erase (no members or can't setup leader) */ bool Guild::DelMember(ObjectGuid guid, bool isDisbanding) { uint32 lowguid = guid.GetCounter(); // guild master can be deleted when loading guild and guid doesn't exist in characters table // or when he is removed from guild by gm command if (m_LeaderGuid == guid && !isDisbanding) { MemberSlot* oldLeader = NULL; MemberSlot* best = NULL; ObjectGuid newLeaderGUID; for (Guild::MemberList::iterator i = members.begin(); i != members.end(); ++i) { if (i->first == lowguid) { oldLeader = &(i->second); continue; } if (!best || best->RankId > i->second.RankId) { best = &(i->second); newLeaderGUID = ObjectGuid(HIGHGUID_PLAYER, i->first); } } if (!best) { return true; } SetLeader(newLeaderGUID); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (Player* newLeader = sObjectMgr.GetPlayer(newLeaderGUID)) { newLeader->SetRank(GR_GUILDMASTER); } // when leader non-exist (at guild load with deleted leader only) not send broadcasts if (oldLeader) { BroadcastEvent(GE_LEADER_CHANGED, oldLeader->Name.c_str(), best->Name.c_str()); BroadcastEvent(GE_LEFT, guid, oldLeader->Name.c_str()); } } members.erase(lowguid); Player* player = sObjectMgr.GetPlayer(guid); // If player not online data in data field will be loaded from guild tabs no need to update it !! if (player) { player->SetInGuild(0); player->SetRank(0); } CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guid = '%u'", lowguid); if (!isDisbanding) { UpdateAccountsNumber(); } // Used by Eluna #ifdef ENABLE_ELUNA sEluna->OnRemoveMember(this, player, isDisbanding); // IsKicked not a part of Mangos, implement? #endif /* ENABLE_ELUNA */ return members.empty(); }
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 ChatHandler::HandlePlayerbotCommand(char* args) { if (sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_DISABLE)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (NULL, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sAccountMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sAccountMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { if (!sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_SHAREDBOTS)) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } QueryResult *resultsocial = CharacterDatabase.PQuery("SELECT COUNT(*) FROM character_social s, characters c WHERE s.guid=c.guid AND c.online = 0 AND flags & 1 AND s.note " _LIKE_ " " _CONCAT3_ ("'%%'","'shared'","'%%'")" AND s.friend = '%u' AND s.guid = '%llu'", m_session->GetPlayer()->GetGUIDLow(), guid.GetRawValue()); if (resultsocial) { Field *fields = resultsocial->Fetch(); if (fields[0].GetUInt32() == 0 && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You may only add bots from the same account or a friend's character that contains 'shared' in the notes on their friend list while not online."); SetSentErrorMessage(true); delete resultsocial; return false; } } delete resultsocial; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } if (!(m_session->GetSecurity() > SEC_PLAYER)) { int maxnum = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_MAXBOTS); int charcount = m_session->GetPlayer()->GetPlayerbotMgr()->GetBotCount(); if (charcount >= maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)",maxnum); SetSentErrorMessage(true); return false; } } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level, name, race FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); uint32 race = fields[2].GetUInt32(); Team master_team = m_session->GetPlayer()->GetTeam(); Team bot_team = HORDE; if (RACEMASK_ALLIANCE & (1 << (race-1))) bot_team = ALLIANCE; int maxlvl = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_RESTRICTLEVEL); int minlvl = sWorld.getConfig(CONFIG_UINT32_PLAYERBOT_MINBOTLEVEL); if (!(m_session->GetSecurity() > SEC_PLAYER)) { if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } if (charlvl < minlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too low.(Current Min:lvl |cffffffff%u)", fields[1].GetString(), minlvl); SetSentErrorMessage(true); delete resultlvl; return false; } if (!sWorld.getConfig(CONFIG_BOOL_PLAYERBOT_ALLOW_SUMMON_OPPOSITE_FACTION) && bot_team != master_team) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it is from opposite faction.", fields[1].GetString()); SetSentErrorMessage(true); delete resultlvl; return false; } } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid) || sObjectMgr.GetPlayer(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->AddPlayerBot(guid); PSendSysMessage("Bot added successfully."); ++mgr->m_botCount; } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); --mgr->m_botCount; } else if (cmdStr == "co" || cmdStr == "combatorder") { Unit *target = NULL; char *orderChar = strtok(NULL, " "); if (!orderChar) { PSendSysMessage("|cffff0000Syntax error:|cffffffff .bot co <botName> <order=reset|tank|assist|heal|protect> [targetPlayer]"); SetSentErrorMessage(true); return false; } std::string orderStr = orderChar; if (orderStr == "protect" || orderStr == "assist") { char *targetChar = strtok(NULL, " "); ObjectGuid targetGuid = m_session->GetPlayer()->GetSelectionGuid(); if (!targetChar && targetGuid.IsEmpty()) { PSendSysMessage("|cffff0000Combat orders protect and assist expect a target either by selection or by giving target player in command string!"); SetSentErrorMessage(true); return false; } if (targetChar) { std::string targetStr = targetChar; ObjectGuid targ_guid = sAccountMgr.GetPlayerGuidByName(targetStr.c_str()); targetGuid.Set(targ_guid.GetRawValue()); } target = ObjectAccessor::GetUnit(*m_session->GetPlayer(), targetGuid); if (!target) { PSendSysMessage("|cffff0000Invalid target for combat order protect or assist!"); SetSentErrorMessage(true); return false; } } if (mgr->GetPlayerBot(guid) == NULL) { PSendSysMessage("|cffff0000Bot can not receive combat order because bot does not exist in world."); SetSentErrorMessage(true); return false; } mgr->GetPlayerBot(guid)->GetPlayerbotAI()->SetCombatOrderByStr(orderStr, target); } return true; }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox, unk3; std::string receiverName, subject, body; uint32 stationery, package, money, COD; uint8 unk4; uint8 items_count; recvData >> mailbox >> receiverName >> subject >> body >> stationery // stationery? >> package // 0x00000000 >> items_count; // 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; } ObjectGuid itemGUIDs[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { recvData.read_skip<uint8>(); // item slot in mail, not used recvData >> itemGUIDs[i]; } recvData >> money >> COD; // money and cod recvData >> unk3; // const 0 recvData >> unk4; // const 0 // packet read complete, now do check if (!CanOpenMailBox(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; } ObjectGuid receiverGuid; if (normalizePlayerName(receiverName)) receiverGuid = sCharacterCache->GetCharacterGuidByName(receiverName); if (!receiverGuid) { TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: non-existing!) with subject %s " "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUID().GetCounter(), receiverName.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, stationery, package); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } TC_LOG_INFO("network", "Player %u is sending mail to %s (%s) with subject %s and body %s " "including %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUID().GetCounter(), receiverName.c_str(), receiverGuid.ToString().c_str(), subject.c_str(), body.c_str(), items_count, money, COD, stationery, package); 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 uint32 reqmoney = cost + money; // Check for overflow if (reqmoney < money) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid); uint32 receiverTeam = 0; uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; if (receiver) { receiverTeam = receiver->GetTeam(); mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); } else { if (CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByGuid(receiverGuid)) { receiverTeam = Player::TeamForRace(characterInfo->Race); receiverLevel = characterInfo->Level; receiverAccountId = characterInfo->AccountId; } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT); stmt->setUInt32(0, receiverGuid.GetCounter()); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); mailsCount = fields[0].GetUInt64(); } } // 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_FLAG_IS_BOUND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && player->GetTeam() != receiverTeam && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_MAIL)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } if (receiverLevel < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_RECEIVER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } 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_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; } if ((item->GetTemplate()->Flags & ITEM_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_FIELD_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS); return; } items[i] = item; } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int32(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: %s (%s) (Account: %u)", GetPlayerName().c_str(), GetGUIDLow(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiverName.c_str(), receiverGuid.ToString().c_str(), 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: %u to: %s (%s) (Account: %u)", GetPlayerName().c_str(), GetGUIDLow(), GetAccountId(), money, receiverName.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // don't ask for COD if there are no items if (items_count == 0) COD = 0; // will delete item or place to receiver mail list draft .AddMoney(money) .AddCOD(COD) .SendMailTo(trans, MailReceiver(receiver, receiverGuid.GetCounter()), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandlePetitionSignOpcode(WorldPacket& recv_data) { DEBUG_LOG("Received opcode CMSG_PETITION_SIGN"); // ok // recv_data.hexlike(); Field* fields; ObjectGuid petitionGuid; uint8 unk; recv_data >> petitionGuid; // petition guid recv_data >> unk; uint32 petitionLowGuid = petitionGuid.GetCounter(); QueryResult* result = CharacterDatabase.PQuery( "SELECT ownerguid, " " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, " " type " "FROM petition WHERE petitionguid = '%u'", petitionLowGuid, petitionLowGuid); if (!result) { sLog.outError("any petition on server..."); return; } fields = result->Fetch(); uint32 ownerLowGuid = fields[0].GetUInt32(); ObjectGuid ownerGuid = ObjectGuid(HIGHGUID_PLAYER, ownerLowGuid); uint8 signs = fields[1].GetUInt8(); uint32 type = fields[2].GetUInt32(); delete result; if (ownerGuid == _player->GetObjectGuid()) return; // not let enemies sign guild charter if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr.GetPlayerTeamByGUID(ownerGuid)) { 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)) { 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)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; } if (_player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } } 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; } } if (++signs > type) // client signs maximum return; // client doesn't allow to sign petition two times by one character, but not check sign by another character from same account // not allow sign another player from already sign player account result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), petitionLowGuid); if (result) { delete result; WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4)); data << ObjectGuid(petitionGuid); data << ObjectGuid(_player->GetObjectGuid()); data << uint32(PETITION_SIGN_ALREADY_SIGNED); // close at signer side SendPacket(&data); // update for owner if online if (Player* owner = sObjectMgr.GetPlayer(ownerGuid)) owner->GetSession()->SendPacket(&data); return; } CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", ownerLowGuid, petitionLowGuid, _player->GetGUIDLow(), GetAccountId()); DEBUG_LOG("PETITION SIGN: %s by %s", petitionGuid.GetString().c_str(), _player->GetGuidStr().c_str()); WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4)); data << ObjectGuid(petitionGuid); data << ObjectGuid(_player->GetObjectGuid()); data << uint32(PETITION_SIGN_OK); // close at signer side SendPacket(&data); // update signs count on charter, required testing... // Item *item = _player->GetItemByGuid(petitionguid)); // if(item) // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs); // update for owner if online if (Player* owner = sObjectMgr.GetPlayer(ownerGuid)) owner->GetSession()->SendPacket(&data); }
void WorldSession::HandleSetPlayerDeclinedNamesOpcode(WorldPacket& recv_data) { ObjectGuid guid; recv_data >> guid; // not accept declined names for unsupported languages std::string name; if (!sObjectMgr.GetPlayerNameByGUID(guid, name)) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } std::wstring wname; if (!Utf8toWStr(name, wname)) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } std::string name2; DeclinedName declinedname; recv_data >> name2; if (name2 != name) // character have different name { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { recv_data >> declinedname.name[i]; if (!normalizePlayerName(declinedname.name[i])) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } } if (!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0), declinedname)) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(1); data << ObjectGuid(guid); SendPacket(&data); return; } for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) CharacterDatabase.escape_string(declinedname.name[i]); CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", guid.GetCounter()); CharacterDatabase.PExecute("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')", guid.GetCounter(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); CharacterDatabase.CommitTransaction(); WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4 + 8); data << uint32(0); // OK data << ObjectGuid(guid); SendPacket(&data); sWorld.InvalidatePlayerDataToAllClient(guid); }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recv_data) { DEBUG_LOG("Received opcode CMSG_OFFER_PETITION"); // ok // recv_data.hexlike(); ObjectGuid petitionGuid; ObjectGuid playerGuid; uint32 junk; recv_data >> junk; // this is not petition type! recv_data >> petitionGuid; // petition guid recv_data >> playerGuid; // player guid Player* player = ObjectAccessor::FindPlayer(playerGuid); if (!player) return; /// Get petition type and check QueryResult* result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter()); if (!result) return; Field* fields = result->Fetch(); uint32 type = fields[0].GetUInt32(); delete result; DEBUG_LOG("OFFER PETITION: type %u petition %s to %s", type, petitionGuid.GetString().c_str(), playerGuid.GetString().c_str()); if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam()) { if (type != 9) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else SendGuildCommandResult(GUILD_CREATE_S, "", ERR_GUILD_NOT_ALLIED); return; } if (type != 9) { if (player->getLevel() < sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)) { // player is too low level to join an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_TARGET_TOO_LOW_S); return; } if (!IsArenaTypeValid(ArenaType(type))) return; uint8 slot = ArenaTeam::GetSlotByType(ArenaType(type)); if (slot >= MAX_ARENA_SLOT) return; if (player->GetArenaTeamId(slot)) { // player is already in an arena team SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; } if (player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } } else { if (player->GetGuildId()) { SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_IN_GUILD_S); return; } if (player->GetGuildIdInvited()) { SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ERR_ALREADY_INVITED_TO_GUILD_S); return; } } /// Get petition signs count uint8 signs = 0; result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionGuid.GetCounter()); // result==NULL also correct charter without signs if (result) signs = (uint8)result->GetRowCount(); /// Send response WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12)); data << ObjectGuid(petitionGuid); // petition guid data << ObjectGuid(_player->GetObjectGuid()); // owner guid data << uint32(petitionGuid.GetCounter()); // guild guid (in mangos always same as low part of petition guid) data << uint8(signs); // sign's count for (uint8 i = 1; i <= signs; ++i) { Field* fields2 = result->Fetch(); ObjectGuid signerGuid = ObjectGuid(HIGHGUID_PLAYER, fields2[0].GetUInt32()); data << ObjectGuid(signerGuid); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); } delete result; player->GetSession()->SendPacket(&data); }
std::string IRCCmd::GetCharNameFromGUID(ObjectGuid guid) { QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%d'", guid.GetCounter()); if(result) { std::string name = (*result)[0].GetCppString(); delete result; return name; } return ""; }
// this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket& recv_data) { DEBUG_LOG("WORLD: HandleAuctionSellItem"); ObjectGuid auctioneerGuid; ObjectGuid itemGuid; uint32 etime, bid, buyout; recv_data >> auctioneerGuid; recv_data >> itemGuid; recv_data >> bid; recv_data >> buyout; recv_data >> etime; if (!bid || !etime) return; // check for cheaters Player* pl = GetPlayer(); AuctionHouseEntry const* auctionHouseEntry = GetCheckedAuctionHouseForAuctioneer(auctioneerGuid); if (!auctionHouseEntry) return; // always return pointer AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(auctionHouseEntry); // client send time in minutes, convert to common used sec time etime *= MINUTE; // client understand only 3 auction time switch (etime) { case 1*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: case 12*MIN_AUCTION_TIME: break; default: return; } // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); if (!itemGuid) return; Item* it = pl->GetItemByGuid(itemGuid); // do not allow to sell already auctioned items if (sAuctionMgr.GetAItem(itemGuid.GetCounter())) { sLog.outError("AuctionError, %s is sending %s, but item is already in another auction", pl->GetGuidStr().c_str(), itemGuid.GetString().c_str()); SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); return; } // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) if (!it) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); return; } if (!it->CanBeTraded()) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); return; } if ((it->GetProto()->Flags & ITEM_FLAG_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_INVENTORY, EQUIP_ERR_ITEM_NOT_FOUND); return; } // check money for deposit uint32 deposit = AuctionHouseMgr::GetAuctionDeposit(auctionHouseEntry, etime, it); if (pl->GetMoney() < deposit) { SendAuctionCommandResult(nullptr, AUCTION_STARTED, AUCTION_ERR_NOT_ENOUGH_MONEY); return; } if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); } pl->ModifyMoney(-int32(deposit)); AuctionEntry* AH = auctionHouse->AddAuction(auctionHouseEntry, it, etime, bid, buyout, deposit, pl); DETAIL_LOG("selling %s to auctioneer %s with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", itemGuid.GetString().c_str(), auctioneerGuid.GetString().c_str(), bid, buyout, etime, auctionHouseEntry->houseId); SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK); }
void LFGMgr::Join(Player* player) { // LfgDungeonSet* dungeons = NULL; if (!sWorld.getConfig(CONFIG_BOOL_LFG_ENABLE) && !sWorld.getConfig(CONFIG_BOOL_LFR_ENABLE)) return; ObjectGuid guid; Group* group = player->GetGroup(); if (group) { if (player->GetObjectGuid() != group->GetLeaderGuid()) { player->GetSession()->SendLfgJoinResult(ERR_LFG_NO_SLOTS_PLAYER); return; } else guid = group->GetObjectGuid(); } else guid = player->GetObjectGuid(); if (guid.IsEmpty()) return; LFGType type = player->GetLFGState()->GetType(); if (type == LFG_TYPE_NONE) { DEBUG_LOG("LFGMgr::Join: %u trying to join without dungeon type. Aborting.", guid.GetCounter()); player->GetSession()->SendLfgJoinResult(ERR_LFG_INVALID_SLOT); return; } else if (group && type == LFG_TYPE_RAID && !group->isRaidGroup()) { DEBUG_LOG("LFGMgr::Join: %u trying to join to raid finder, but group is not raid. Aborting.", guid.GetCounter()); player->GetSession()->SendLfgJoinResult(ERR_LFG_MISMATCHED_SLOTS); return; } else if (group && type != LFG_TYPE_RAID && group->isRaidGroup()) { DEBUG_LOG("LFGMgr::Join: %u trying to join to dungeon finder, but group is raid. Aborting.", guid.GetCounter()); player->GetSession()->SendLfgJoinResult(ERR_LFG_MISMATCHED_SLOTS); return; } LFGQueueInfoMap::iterator queue = (guid.IsGroup() ? m_groupQueueInfoMap[type].find(guid) : m_queueInfoMap[type].find(guid)); LFGJoinResult result = ERR_LFG_OK; if (queue != (guid.IsGroup() ? m_groupQueueInfoMap[type].end() : m_queueInfoMap[type].end())) { DEBUG_LOG("LFGMgr::Join: %u trying to join but is already in queue!", guid.GetCounter()); result = ERR_LFG_NO_LFG_OBJECT; player->GetSession()->SendLfgJoinResult(result); _Leave(guid); _LeaveGroup(guid); return; } result = guid.IsGroup() ? GetGroupJoinResult(group) : GetPlayerJoinResult(player); if (result != ERR_LFG_OK) // Someone can't join. Clear all stuf { DEBUG_LOG("LFGMgr::Join: %u joining with %u members. result: %u", guid.GetCounter(), group ? group->GetMembersCount() : 1, result); player->GetLFGState()->Clear(); player->GetSession()->SendLfgJoinResult(result); player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_ROLECHECK_FAILED, type); return; } if (!guid.IsGroup() && player->GetLFGState()->GetRoles() == LFG_ROLE_MASK_NONE) { sLog.outError("LFGMgr::Join: %u has no roles", guid.GetCounter()); } // Joining process if (guid.IsGroup()) { for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { if (Player* player = itr->getSource()) _Leave(player->GetObjectGuid()); } _LeaveGroup(guid, type); _JoinGroup(guid, type); } else { _Leave(guid, type); _Join(guid, type); } player->GetLFGState()->SetState((type == LFG_TYPE_RAID) ? LFG_STATE_LFR : LFG_STATE_LFG); player->GetSession()->SendLfgJoinResult(ERR_LFG_OK, 0); if (group) player->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_JOIN_PROPOSAL, type); else player->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_JOIN_PROPOSAL, type); if(sWorld.getConfig(CONFIG_BOOL_RESTRICTED_LFG_CHANNEL)) player->JoinLFGChannel(); }
bool Group::_setMembersGroup(ObjectGuid guid, uint8 group) { member_witerator slot = _getMemberWSlot(guid); if (slot == m_memberSlots.end()) return false; slot->group = group; SubGroupCounterIncrease(group); if (!isBGGroup()) CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, guid.GetCounter()); return true; }
//this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) { ObjectGuid auctioneer; uint64 bid, buyout; uint32 itemsCount, etime; recvData >> auctioneer; recvData >> itemsCount; ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot uint32 count[MAX_AUCTION_ITEMS]; memset(count, 0, sizeof(count)); if (itemsCount > MAX_AUCTION_ITEMS) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); recvData.rfinish(); return; } for (uint32 i = 0; i < itemsCount; ++i) { recvData >> itemGUIDs[i]; recvData >> count[i]; if (!itemGUIDs[i] || !count[i] || count[i] > 1000) { recvData.rfinish(); return; } } recvData >> bid; recvData >> buyout; recvData >> etime; if (!bid || !etime) return; if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow()); SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) not found or you can't interact with him.", auctioneer.ToString().c_str()); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); if (!auctionHouseEntry) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (%s) has wrong faction.", auctioneer.ToString().c_str()); return; } etime *= MINUTE; switch (etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); Item* items[MAX_AUCTION_ITEMS]; uint32 finalCount = 0; uint32 itemEntry = 0; for (uint32 i = 0; i < itemsCount; ++i) { Item* item = _player->GetItemByGuid(itemGUIDs[i]); if (!item) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_ITEM_NOT_FOUND); return; } if (itemEntry == 0) itemEntry = item->GetTemplate()->ItemId; if (sAuctionMgr->GetAItem(item->GetGUIDLow()) || !item->CanBeTraded() || item->IsNotEmptyBag() || item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) || item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } items[i] = item; finalCount += count[i]; } if (!finalCount) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } // check if there are 2 identical guids, in this case user is most likely cheating for (uint32 i = 0; i < itemsCount - 1; ++i) { for (uint32 j = i + 1; j < itemsCount; ++j) { if (itemGUIDs[i] == itemGUIDs[j]) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } } for (uint32 i = 0; i < itemsCount; ++i) { Item* item = items[i]; if (item->GetMaxStackCount() < finalCount) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } Item* item = items[0]; uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME)); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount); if (!_player->HasEnoughMoney((uint64)deposit)) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY); return; } AuctionEntry* AH = new AuctionEntry(); if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD else AH->auctioneer = auctioneer.GetCounter(); // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[0]) { if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = item->GetGUIDLow(); AH->itemEntry = item->GetEntry(); AH->itemCount = item->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(trans); item->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size { Item* newItem = item->CloneItem(finalCount, _player); if (!newItem) { TC_LOG_ERROR("network", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry()); SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); delete AH; return; } if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = newItem->GetGUIDLow(); AH->itemEntry = newItem->GetEntry(); AH->itemCount = newItem->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); for (uint32 j = 0; j < itemsCount; ++j) { Item* item2 = items[j]; // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2->GetCount() == count[j]) { _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->DeleteFromInventoryDB(trans); item2->DeleteFromDB(trans); CharacterDatabase.CommitTransaction(trans); delete item2; } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { item2->SetCount(item2->GetCount() - count[j]); item2->SetState(ITEM_CHANGED, _player); _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]); item2->SendUpdateToPlayer(_player); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->SaveToDB(trans); CharacterDatabase.CommitTransaction(trans); } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); newItem->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } _player->ModifyMoney(-int32(deposit)); }
void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) { TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE"); ObjectGuid playerGuid = _player->GetGUID(); uint64 eventId; uint64 inviteId; std::string name; bool isPreInvite; bool isGuildEvent; ObjectGuid inviteeGuid; uint32 inviteeTeam = 0; uint32 inviteeGuildId = 0; recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent; if (Player* player = ObjectAccessor::FindConnectedPlayerByName(name)) { // Invitee is online inviteeGuid = player->GetGUID(); inviteeTeam = player->GetTeam(); inviteeGuildId = player->GetGuildId(); } else { // Invitee offline, get data from database PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME); stmt->setString(0, name); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); inviteeGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); inviteeTeam = Player::TeamForRace(fields[1].GetUInt8()); inviteeGuildId = Player::GetGuildIdFromDB(inviteeGuid); } } if (!inviteeGuid) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND); return; } if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR)) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED); return; } if (QueryResult result = CharacterDatabase.PQuery("SELECT flags FROM character_social WHERE guid = %u AND friend = %u", inviteeGuid.GetCounter(), playerGuid.GetCounter())) { Field* fields = result->Fetch(); if (fields[0].GetUInt8() & SOCIAL_FLAG_IGNORED) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str()); return; } } if (!isPreInvite) { if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) { if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId) { // we can't invite guild members to guild events sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); return; } // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); } else sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID); } else { if (isGuildEvent && inviteeGuildId == _player->GetGuildId()) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); return; } // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite invite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->SendCalendarEventInvite(invite); } }
/** * Handles the Packet sent by the client when sending a mail. * * This methods takes the packet sent by the client and performs the following actions: * - Checks whether the mail is valid: i.e. can he send the selected items, * does he have enough money, etc. * - Creates a MailDraft and adds the needed items, money, cost data. * - Sends the mail. * * Depending on the outcome of the checks performed the player will recieve a different * MailResponseResult. * * @see MailResponseResult * @see SendMailResult() * * @param recv_data the WorldPacket containing the data sent by the client. */ void WorldSession::HandleSendMail(WorldPacket& recv_data) { sLog.outError("WORLD: CMSG_SEND_MAIL"); ObjectGuid mailboxGuid; uint64 money, COD; std::string receiver, subject, body; uint8 receiverLen, subjectLen, bodyLen; uint32 unk1, unk2; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 recv_data >> money >> COD; // money and cod bodyLen = recv_data.ReadBits(12); subjectLen = recv_data.ReadBits(9); uint8 items_count = recv_data.ReadBits(5); // attached items count if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recv_data.rfinish(); // set to end to avoid warnings spam return; } recv_data.ReadGuidMask<0>(mailboxGuid); ObjectGuid itemGuids[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) recv_data.ReadGuidMask<2, 6, 3, 7, 1, 0, 4, 5>(itemGuids[i]); recv_data.ReadGuidMask<3, 4>(mailboxGuid); receiverLen = recv_data.ReadBits(7); recv_data.ReadGuidMask<2, 6, 1, 7, 5>(mailboxGuid); recv_data.ReadGuidBytes<4>(mailboxGuid); for (uint8 i = 0; i < items_count; ++i) { recv_data.ReadGuidBytes<6, 1, 7, 2>(itemGuids[i]); recv_data.read_skip<uint8>(); // item slot in mail, not used recv_data.ReadGuidBytes<3, 0, 4, 5>(itemGuids[i]); } recv_data.ReadGuidBytes<7, 3, 6, 5>(mailboxGuid); subject = recv_data.ReadString(subjectLen); receiver = recv_data.ReadString(receiverLen); recv_data.ReadGuidBytes<2, 0>(mailboxGuid); body = recv_data.ReadString(bodyLen); recv_data.ReadGuidBytes<1>(mailboxGuid); DEBUG_LOG("WORLD: CMSG_SEND_MAIL receiver '%s' subject '%s' body '%s' mailbox " UI64FMTD " money " UI64FMTD " COD " UI64FMTD " unkt1 %u unk2 %u", receiver.c_str(), subject.c_str(), body.c_str(), mailboxGuid.GetRawValue(), money, COD, unk1, unk2); // packet read complete, now do check if (!CheckMailBox(mailboxGuid)) return; if (receiver.empty()) return; Player* pl = _player; ObjectGuid rc; if (normalizePlayerName(receiver)) rc = sAccountMgr.GetPlayerGuidByName(receiver); if (!rc) { DEBUG_LOG("%s is sending mail to %s (GUID: nonexistent!) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } DEBUG_LOG("%s is sending mail to %s with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGuidStr().c_str(), rc.GetString().c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); if (pl->GetObjectGuid() == rc) { pl->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 (pl->GetMoney() < reqmoney) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receive = sObjectMgr.GetPlayer(rc); Team rc_team; 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(); } else { rc_team = sAccountMgr.GetPlayerTeamByGUID(rc); if (QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", rc.GetCounter())) { Field* fields = result->Fetch(); mails_count = fields[0].GetUInt32(); delete result; } } // 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) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // check the receiver's Faction... if (!sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sAccountMgr.GetPlayerAccountIdByGUID(rc); Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { if (!itemGuids[i].IsItem()) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = pl->GetItemByGuid(itemGuids[i]); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; } if ((item->GetProto()->Flags & ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } items[i] = item; } pl->SendMailResult(0, MAIL_SEND, MAIL_OK); pl->ModifyMoney(-int64(reqmoney)); pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); if (items_count > 0 || money > 0) { if (items_count > 0) { for (uint8 i = 0; i < items_count; ++i) { Item* item = items[i]; if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), item->GetProto()->Name1, item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable pl->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(); // deletes item from character's inventory item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", rc.GetCounter(), item->GetGUIDLow()); CharacterDatabase.CommitTransaction(); draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = pl->GetSession()->GetAccountId() != rc_account; } if (money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail money: " UI64FMTD " to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_UINT32_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list draft .SetMoney(money) .SetCOD(COD) .SendMailTo(MailReceiver(receive, rc), pl, body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); }
//rename characters static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid targetGuid; std::string targetName; if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; char const* newNameStr = strtok(NULL, " "); if (newNameStr) { std::string playerOldName; std::string newName = newNameStr; if (target) { // check online security if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; playerOldName = target->GetName(); } else { // check offline security if (handler->HasLowerSecurity(NULL, targetGuid)) return false; ObjectMgr::GetPlayerNameByGUID(targetGuid, playerOldName); } if (!normalizePlayerName(newName)) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } if (ObjectMgr::CheckPlayerName(newName, target ? target->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale(), true) != CHAR_NAME_SUCCESS) { handler->SendSysMessage(LANG_BAD_VALUE); handler->SetSentErrorMessage(true); return false; } if (WorldSession* session = handler->GetSession()) { if (!session->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName)) { handler->SendSysMessage(LANG_RESERVED_NAME); handler->SetSentErrorMessage(true); return false; } } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, newName); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { handler->PSendSysMessage(LANG_RENAME_PLAYER_ALREADY_EXISTS, newName.c_str()); handler->SetSentErrorMessage(true); return false; } // Remove declined name from db stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME); stmt->setUInt64(0, targetGuid.GetCounter()); CharacterDatabase.Execute(stmt); if (target) { target->SetName(newName); if (WorldSession* session = target->GetSession()) session->KickPlayer(); } else { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME_BY_GUID); stmt->setString(0, newName); stmt->setUInt64(1, targetGuid.GetCounter()); CharacterDatabase.Execute(stmt); } sWorld->UpdateCharacterInfo(targetGuid, newName); handler->PSendSysMessage(LANG_RENAME_PLAYER_WITH_NEW_NAME, playerOldName.c_str(), newName.c_str()); if (WorldSession* session = handler->GetSession()) { if (Player* player = session->GetPlayer()) sLog->outCommand(session->GetAccountId(), "GM %s (Account: %u) forced rename %s to player %s (Account: %u)", player->GetName().c_str(), session->GetAccountId(), newName.c_str(), playerOldName.c_str(), ObjectMgr::GetPlayerAccountIdByGUID(targetGuid)); } else sLog->outCommand(0, "CONSOLE forced rename '%s' to '%s' (%s)", playerOldName.c_str(), newName.c_str(), targetGuid.ToString().c_str()); } else { if (target) { // check online security if (handler->HasLowerSecurity(target, ObjectGuid::Empty)) return false; handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_RENAME); } else { // check offline security if (handler->HasLowerSecurity(NULL, targetGuid)) return false; std::string oldNameLink = handler->playerLink(targetName); handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), targetGuid.ToString().c_str()); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); stmt->setUInt64(1, targetGuid.GetCounter()); CharacterDatabase.Execute(stmt); } } return true; }
void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid) { uint32 petitionLowGuid = petitionguid.GetCounter(); ObjectGuid ownerGuid; uint32 type; std::string name = "NO_NAME_FOR_GUID"; uint8 signs = 0; QueryResult* result = CharacterDatabase.PQuery( "SELECT ownerguid, name, " " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, " " type " "FROM petition WHERE petitionguid = '%u'", petitionLowGuid, petitionLowGuid); if (result) { Field* fields = result->Fetch(); ownerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); name = fields[1].GetCppString(); signs = fields[2].GetUInt8(); type = fields[3].GetUInt32(); delete result; } else { DEBUG_LOG("CMSG_PETITION_QUERY failed for petition (GUID: %u)", petitionLowGuid); return; } WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + name.size() + 1 + 1 + 4 * 13 + 2)); data << uint32(petitionLowGuid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid) data << ObjectGuid(ownerGuid); // charter owner guid data << name; // name (guild/arena team) data << uint8(0); // 1 if (type == 9) { data << uint32(9); data << uint32(9); data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition } else { data << uint32(type - 1); data << uint32(type - 1); data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition } data << uint32(0); // 5 data << uint32(0); // 6 data << uint32(0); // 7 data << uint32(0); // 8 data << uint16(0); // 9 2 bytes field data << uint32(0); // 10 data << uint32(0); // 11 data << uint32(0); // 13 count of next strings? data << uint32(0); // 14 if (type == 9) data << uint32(0); // 15 0 - guild, 1 - arena team else data << uint32(1); SendPacket(&data); }
bool LoginQueryHolder::Initialize() { SetSize(MAX_PLAYER_LOGIN_QUERY); bool res = true; // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags," "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost," "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty," "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," "health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, extend, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM character_aura WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4,itemcount5,itemcount6 FROM character_queststatus WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS, "SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADWEEKLYQUESTSTATUS, "SELECT quest FROM character_queststatus_weekly WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMONTHLYQUESTSTATUS, "SELECT quest FROM character_queststatus_monthly WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,text,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADITEMLOOT, "SELECT guid,itemid,amount,suffix,property FROM item_loot WHERE owner_guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT spec,button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS, "SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = '%u' ORDER BY setindex", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBGDATA, "SELECT instance_id, team, join_x, join_y, join_z, join_o, join_map, taxi_start, taxi_end, mount_spell FROM character_battleground_data WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA, "SELECT type, time, data FROM character_account_data WHERE guid='%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILS, "SELECT id,messageType,sender,receiver,subject,body,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId,has_items FROM mail WHERE receiver = '%u' ORDER BY id DESC", m_guid.GetCounter()); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS, "SELECT data, text, mail_id, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE receiver = '%u'", m_guid.GetCounter()); return res; }
void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recv_data) { DEBUG_LOG("Received opcode MSG_PETITION_RENAME"); // ok // recv_data.hexlike(); ObjectGuid petitionGuid; uint32 type; std::string newname; recv_data >> petitionGuid; // guid recv_data >> newname; // new name Item* item = _player->GetItemByGuid(petitionGuid); if (!item) return; QueryResult* result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionGuid.GetCounter()); if (result) { Field* fields = result->Fetch(); type = fields[0].GetUInt32(); delete result; } else { DEBUG_LOG("CMSG_PETITION_QUERY failed for petition: %s", petitionGuid.GetString().c_str()); return; } if (type == 9) { if (sGuildMgr.GetGuildByName(newname)) { SendGuildCommandResult(GUILD_CREATE_S, newname, ERR_GUILD_NAME_EXISTS_S); return; } if (sObjectMgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname)) { SendGuildCommandResult(GUILD_CREATE_S, newname, ERR_GUILD_NAME_INVALID); return; } } else { if (sObjectMgr.GetArenaTeamByName(newname)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S); return; } if (sObjectMgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID); return; } } std::string db_newname = newname; CharacterDatabase.escape_string(db_newname); CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'", db_newname.c_str(), petitionGuid.GetCounter()); DEBUG_LOG("Petition %s renamed to '%s'", petitionGuid.GetString().c_str(), newname.c_str()); WorldPacket data(MSG_PETITION_RENAME, (8 + newname.size() + 1)); data << ObjectGuid(petitionGuid); data << newname; SendPacket(&data); }
bool ChatHandler::HandlePlayerbotCommand(char* args) { if (!(m_session->GetSecurity() > SEC_PLAYER)) if (botConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) { PSendSysMessage("|cffff0000Playerbot system is currently disabled!"); SetSentErrorMessage(true); return false; } if (!m_session) { PSendSysMessage("|cffff0000You may only add bots from an active session"); SetSentErrorMessage(true); return false; } if (!*args) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } char *cmd = strtok ((char *) args, " "); char *charname = strtok (nullptr, " "); if (!cmd || !charname) { PSendSysMessage("|cffff0000usage: add PLAYERNAME or remove PLAYERNAME"); SetSentErrorMessage(true); return false; } std::string cmdStr = cmd; std::string charnameStr = charname; if (!normalizePlayerName(charnameStr)) return false; ObjectGuid guid = sObjectMgr.GetPlayerGuidByName(charnameStr.c_str()); if (guid == ObjectGuid() || (guid == m_session->GetPlayer()->GetObjectGuid())) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } uint32 accountId = sObjectMgr.GetPlayerAccountIdByGUID(guid); if (accountId != m_session->GetAccountId()) { PSendSysMessage("|cffff0000You may only add bots from the same account."); SetSentErrorMessage(true); return false; } // create the playerbot manager if it doesn't already exist PlayerbotMgr* mgr = m_session->GetPlayer()->GetPlayerbotMgr(); if (!mgr) { mgr = new PlayerbotMgr(m_session->GetPlayer()); m_session->GetPlayer()->SetPlayerbotMgr(mgr); } QueryResult *resultchar = CharacterDatabase.PQuery("SELECT COUNT(*) FROM characters WHERE online = '1' AND account = '%u'", m_session->GetAccountId()); if (resultchar) { Field *fields = resultchar->Fetch(); int acctcharcount = fields[0].GetUInt32(); int maxnum = botConfig.GetIntDefault("PlayerbotAI.MaxNumBots", 9); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (acctcharcount > maxnum && (cmdStr == "add" || cmdStr == "login")) { PSendSysMessage("|cffff0000You cannot summon anymore bots.(Current Max: |cffffffff%u)", maxnum); SetSentErrorMessage(true); delete resultchar; return false; } delete resultchar; } QueryResult *resultlvl = CharacterDatabase.PQuery("SELECT level,name FROM characters WHERE guid = '%u'", guid.GetCounter()); if (resultlvl) { Field *fields = resultlvl->Fetch(); int charlvl = fields[0].GetUInt32(); int maxlvl = botConfig.GetIntDefault("PlayerbotAI.RestrictBotLevel", 80); if (!(m_session->GetSecurity() > SEC_PLAYER)) if (charlvl > maxlvl) { PSendSysMessage("|cffff0000You cannot summon |cffffffff[%s]|cffff0000, it's level is too high.(Current Max:lvl |cffffffff%u)", fields[1].GetString(), maxlvl); SetSentErrorMessage(true); delete resultlvl; return false; } delete resultlvl; } // end of gmconfig patch if (cmdStr == "add" || cmdStr == "login") { if (mgr->GetPlayerBot(guid)) { PSendSysMessage("Bot already exists in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", guid.GetCounter()); mgr->LoginPlayerBot(guid); PSendSysMessage("Bot added successfully."); } else if (cmdStr == "remove" || cmdStr == "logout") { if (!mgr->GetPlayerBot(guid)) { PSendSysMessage("|cffff0000Bot can not be removed because bot does not exist in world."); SetSentErrorMessage(true); return false; } CharacterDatabase.DirectPExecute("UPDATE characters SET online = 0 WHERE guid = '%u'", guid.GetCounter()); mgr->LogoutPlayerBot(guid); PSendSysMessage("Bot removed successfully."); } return true; }
static bool HandleGroupListCommand(ChatHandler* handler, char const* args) { // Get ALL the variables! Player* playerTarget; uint32 phase = 0; ObjectGuid guidTarget; std::string nameTarget; std::string zoneName; const char* onlineState = ""; // Parse the guid to uint32... ObjectGuid parseGUID(HighGuid::Player, uint32(atoul(args))); // ... and try to extract a player out of it. if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) { playerTarget = ObjectAccessor::FindPlayer(parseGUID); guidTarget = parseGUID; } // If not, we return false and end right away. else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) return false; // Next, we need a group. So we define a group variable. Group* groupTarget = NULL; // We try to extract a group from an online player. if (playerTarget) groupTarget = playerTarget->GetGroup(); // If not, we extract it from the SQL. if (!groupTarget) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); stmt->setUInt32(0, guidTarget.GetCounter()); PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); if (resultGroup) groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32()); } // If both fails, players simply has no party. Return false. if (!groupTarget) { handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); handler->SetSentErrorMessage(true); return false; } // We get the group members after successfully detecting a group. Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); // To avoid a cluster f**k, namely trying multiple queries to simply get a group member count... handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party"), members.size()); // ... we simply move the group type and member count print after retrieving the slots and simply output it's size. // While rather dirty codestyle-wise, it saves space (if only a little). For each member, we look several informations up. for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { // Define temporary variable slot to iterator. Group::MemberSlot const& slot = *itr; // Check for given flag and assign it to that iterator std::string flags; if (slot.flags & MEMBER_FLAG_ASSISTANT) flags = "Assistant"; if (slot.flags & MEMBER_FLAG_MAINTANK) { if (!flags.empty()) flags.append(", "); flags.append("MainTank"); } if (slot.flags & MEMBER_FLAG_MAINASSIST) { if (!flags.empty()) flags.append(", "); flags.append("MainAssist"); } if (flags.empty()) flags = "None"; // Check if iterator is online. If is... Player* p = ObjectAccessor::FindPlayer((*itr).guid); if (p) { // ... than, it prints information like "is online", where he is, etc... onlineState = "online"; phase = (!p->IsGameMaster() ? p->GetPhaseMask() : -1); uint32 locale = handler->GetSessionDbcLocale(); AreaTableEntry const* area = GetAreaEntryByAreaID(p->GetAreaId()); if (area) { AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } } else { // ... else, everything is set to offline or neutral values. zoneName = "<ERROR>"; onlineState = "Offline"; phase = 0; } // Now we can print those informations for every single member of each group! handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, zoneName.c_str(), phase, slot.guid.GetCounter(), flags.c_str(), lfg::GetRolesString(slot.roles).c_str()); } // And finish after every iterator is done. return true; }