void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_RENAME"); ObjectGuid petitionGuid; uint32 type; uint8 nameLen; std::string newName; nameLen = recvData.ReadBits(7); recvData.ReadGuidMask(petitionGuid, 7, 4, 6, 2, 0, 5, 3, 1); recvData.ReadGuidBytes(petitionGuid, 4, 1, 7); newName = recvData.ReadString(nameLen); recvData.ReadGuidBytes(petitionGuid, 0, 3, 2, 6, 5); Item* item = _player->GetItemByGuid(petitionGuid); if (!item) return; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); type = fields[0].GetUInt8(); } else { TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid)); return; } if (sGuildMgr->GetGuildByName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, newName); return; } if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, newName); return; } stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME); stmt->setString(0, newName); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); CharacterDatabase.Execute(stmt); TC_LOG_DEBUG("network", "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str()); WorldPacket data(SMSG_PETITION_RENAME_RESULT, (9 + 1 + newName.size())); data.WriteBits(newName.length(), 7); data.WriteGuidMask(petitionGuid, 0, 3, 4, 2, 6, 5, 7, 1); data.WriteGuidBytes(petitionGuid, 4, 3, 6, 0, 5, 2, 1, 7); data.WriteString(newName); SendPacket(&data); }
DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, std::string name, uint32 guid) { uint32 charcount = AccountMgr::GetCharactersCount(account); if (charcount >= 10) return DUMP_TOO_MANY_CHARS; FILE* fin = fopen(file.c_str(), "r"); if (!fin) return DUMP_FILE_OPEN_ERROR; char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20]; // make sure the same guid doesn't already exist and is safe to use bool incHighest = true; if (guid != 0 && guid < sObjectMgr->_hiCharGuid) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_GUID); stmt->setUInt32(0, guid); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) guid = sObjectMgr->_hiCharGuid; // use first free if exists else incHighest = false; } else guid = sObjectMgr->_hiCharGuid; // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) name = ""; if (ObjectMgr::CheckPlayerName(name, true) == CHAR_NAME_SUCCESS) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) name = ""; // use the one from the dump } else name = ""; // name encoded or empty snprintf(newguid, 20, "%u", guid); snprintf(chraccount, 20, "%u", account); snprintf(newpetid, 20, "%u", sObjectMgr->GeneratePetNumber()); snprintf(lastpetid, 20, "%s", ""); std::map<uint32, uint32> items; std::map<uint32, uint32> mails; char buf[32000] = ""; typedef std::map<uint32, uint32> PetIds; // old->new petid relation typedef PetIds::value_type PetIdsPair; PetIds petids; uint8 gender = GENDER_NONE; uint8 race = RACE_NONE; uint8 playerClass = 0; uint8 level = 1; SQLTransaction trans = CharacterDatabase.BeginTransaction(); while (!feof(fin)) { if (!fgets(buf, 32000, fin)) { if (feof(fin)) break; ROLLBACK(DUMP_FILE_BROKEN); } std::string line; line.assign(buf); // skip empty strings size_t nw_pos = line.find_first_not_of(" \t\n\r\7"); if (nw_pos == std::string::npos) continue; // skip logfile-side dump start notice, the important notes and dump end notices if ((line.substr(nw_pos, 16) == "== START DUMP ==") || (line.substr(nw_pos, 15) == "IMPORTANT NOTE:") || (line.substr(nw_pos, 14) == "== END DUMP ==")) continue; // add required_ check /* if (line.substr(nw_pos, 41) == "UPDATE character_db_version SET required_") { if (!CharacterDatabase.Execute(line.c_str())) ROLLBACK(DUMP_FILE_BROKEN); continue; } */ // determine table name and load type std::string tn = gettablename(line); if (tn.empty()) { sLog->outError(LOG_FILTER_GENERAL, "LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str()); ROLLBACK(DUMP_FILE_BROKEN); } DumpTableType type = DumpTableType(0); uint8 i; for (i = 0; i < DUMP_TABLE_COUNT; ++i) { if (tn == dumpTables[i].name) { type = dumpTables[i].type; break; } } if (i == DUMP_TABLE_COUNT) { sLog->outError(LOG_FILTER_GENERAL, "LoadPlayerDump: Unknown table: '%s'!", tn.c_str()); ROLLBACK(DUMP_FILE_BROKEN); } // change the data to server values switch (type) { case DTT_CHARACTER: { if (!changenth(line, 1, newguid)) // characters.guid update ROLLBACK(DUMP_FILE_BROKEN); if (!changenth(line, 2, chraccount)) // characters.account update ROLLBACK(DUMP_FILE_BROKEN); race = uint8(atol(getnth(line, 4).c_str())); playerClass = uint8(atol(getnth(line, 5).c_str())); gender = uint8(atol(getnth(line, 6).c_str())); level = uint8(atol(getnth(line, 7).c_str())); if (name == "") { // check if the original name already exists name = getnth(line, 3); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) if (!changenth(line, 37, "1")) // characters.at_login set to "rename on login" ROLLBACK(DUMP_FILE_BROKEN); } else if (!changenth(line, 3, name.c_str())) // characters.name ROLLBACK(DUMP_FILE_BROKEN); const char null[5] = "NULL"; if (!changenth(line, 69, null)) // characters.deleteInfos_Account ROLLBACK(DUMP_FILE_BROKEN); if (!changenth(line, 70, null)) // characters.deleteInfos_Name ROLLBACK(DUMP_FILE_BROKEN); if (!changenth(line, 71, null)) // characters.deleteDate ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_CHAR_TABLE: { if (!changenth(line, 1, newguid)) // character_*.guid update ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_EQSET_TABLE: { if (!changenth(line, 1, newguid)) ROLLBACK(DUMP_FILE_BROKEN); // character_equipmentsets.guid char newSetGuid[24]; snprintf(newSetGuid, 24, UI64FMTD, sObjectMgr->GenerateEquipmentSetGuid()); if (!changenth(line, 2, newSetGuid)) ROLLBACK(DUMP_FILE_BROKEN); // character_equipmentsets.setguid break; } case DTT_INVENTORY: { if (!changenth(line, 1, newguid)) // character_inventory.guid update ROLLBACK(DUMP_FILE_BROKEN); if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid, true)) ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.bag update if (!changeGuid(line, 4, items, sObjectMgr->_hiItemGuid)) ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.item update break; } case DTT_MAIL: // mail { if (!changeGuid(line, 1, mails, sObjectMgr->_mailId)) ROLLBACK(DUMP_FILE_BROKEN); // mail.id update if (!changenth(line, 6, newguid)) // mail.receiver update ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_MAIL_ITEM: // mail_items { if (!changeGuid(line, 1, mails, sObjectMgr->_mailId)) ROLLBACK(DUMP_FILE_BROKEN); // mail_items.id if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid)) ROLLBACK(DUMP_FILE_BROKEN); // mail_items.item_guid if (!changenth(line, 3, newguid)) // mail_items.receiver ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM: { // item, owner, data field:item, owner guid if (!changeGuid(line, 1, items, sObjectMgr->_hiItemGuid)) ROLLBACK(DUMP_FILE_BROKEN); // item_instance.guid update if (!changenth(line, 3, newguid)) // item_instance.owner_guid update ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM_GIFT: { if (!changenth(line, 1, newguid)) // character_gifts.guid update ROLLBACK(DUMP_FILE_BROKEN); if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid)) ROLLBACK(DUMP_FILE_BROKEN); // character_gifts.item_guid update break; } case DTT_PET: { //store a map of old pet id to new inserted pet id for use by type 5 tables snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); if (*lastpetid == '\0') snprintf(lastpetid, 20, "%s", currpetid); if (strcmp(lastpetid, currpetid) != 0) { snprintf(newpetid, 20, "%d", sObjectMgr->GeneratePetNumber()); snprintf(lastpetid, 20, "%s", currpetid); } std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid)); if (petids_iter == petids.end()) { petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid))); } if (!changenth(line, 1, newpetid)) // character_pet.id update ROLLBACK(DUMP_FILE_BROKEN); if (!changenth(line, 3, newguid)) // character_pet.owner update ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown { snprintf(currpetid, 20, "%s", getnth(line, 1).c_str()); // lookup currpetid and match to new inserted pet id std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid)); if (petids_iter == petids.end()) // couldn't find new inserted id ROLLBACK(DUMP_FILE_BROKEN); snprintf(newpetid, 20, "%d", petids_iter->second); if (!changenth(line, 1, newpetid)) ROLLBACK(DUMP_FILE_BROKEN); break; } default: sLog->outError(LOG_FILTER_GENERAL, "Unknown dump table type: %u", type); break; } fixNULLfields(line); trans->Append(line.c_str()); } CharacterDatabase.CommitTransaction(trans); // in case of name conflict player has to rename at login anyway sWorld->AddCharacterNameData(guid, name, gender, race, playerClass, level); sObjectMgr->_hiItemGuid += items.size(); sObjectMgr->_mailId += mails.size(); if (incHighest) ++sObjectMgr->_hiCharGuid; fclose(fin); return DUMP_SUCCESS; }
void WorldSession::HandlePetRename(WorldPacket & recvData) { ;//sLog->outDetail("HandlePetRename. CMSG_PET_RENAME"); uint64 petguid; uint8 isdeclined; std::string name; DeclinedName declinedname; recvData >> petguid; recvData >> name; recvData >> isdeclined; Pet* pet = ObjectAccessor::FindPet(petguid); // check it! if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) || pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo()) return; PetNameInvalidReason res = ObjectMgr::CheckPetName(name); if (res != PET_NAME_SUCCESS) { SendPetNameInvalid(res, name, NULL); return; } if (sObjectMgr->IsReservedName(name)) { SendPetNameInvalid(PET_NAME_RESERVED, name, NULL); return; } pet->SetName(name); Unit* owner = pet->GetOwner(); if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED); if (isdeclined) { for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { recvData >> declinedname.name[i]; } std::wstring wname; Utf8toWStr(name, wname); if (!ObjectMgr::CheckDeclinedNames(wname, declinedname)) { SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname); return; } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (isdeclined) { if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED)) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME); stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME); stmt->setUInt32(0, _player->GetGUIDLow()); for (uint8 i = 0; i < 5; i++) stmt->setString(i+1, declinedname.name[i]); trans->Append(stmt); } } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME); stmt->setString(0, name); stmt->setUInt32(1, _player->GetGUIDLow()); stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped }
void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recvData) { ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_BUY"); uint64 guidNPC; uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client std::string name; recvData >> guidNPC; // NPC GUID recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint64>(); // 0 recvData >> name; // name recvData.read_skip<std::string>(); // some string recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint16>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 recvData.read_skip<uint32>(); // 0 for (int i = 0; i < 10; ++i) recvData.read_skip<std::string>(); recvData >> clientIndex; // index recvData.read_skip<uint32>(); // 0 ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str()); // prevent cheating Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guidNPC, UNIT_NPC_FLAG_PETITIONER); if (!creature) { ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC)); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); uint32 charterid = 0; uint32 cost = 0; uint32 type = 0; if (creature->IsTabardDesigner()) { // if tabard designer, then trying to buy a guild charter. // do not let if already in guild. if (_player->GetGuildId()) return; charterid = GUILD_CHARTER; cost = GUILD_CHARTER_COST; type = GUILD_CHARTER_TYPE; } else { // TODO: find correct opcode if (_player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { SendNotification(LANG_ARENA_ONE_TOOLOW, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)); return; } switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case) { case 1: charterid = ARENA_TEAM_CHARTER_2v2; cost = ARENA_TEAM_CHARTER_2v2_COST; type = ARENA_TEAM_CHARTER_2v2_TYPE; break; case 2: charterid = ARENA_TEAM_CHARTER_3v3; cost = ARENA_TEAM_CHARTER_3v3_COST; type = ARENA_TEAM_CHARTER_3v3_TYPE; break; case 3: charterid = ARENA_TEAM_CHARTER_5v5; cost = ARENA_TEAM_CHARTER_5v5_COST; type = ARENA_TEAM_CHARTER_5v5_TYPE; break; default: ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "unknown selection at buy arena petition: %u", clientIndex); return; } if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); return; } } if (type == GUILD_CHARTER_TYPE) { if (sGuildMgr->GetGuildByName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, name); return; } } else { if (sArenaTeamMgr->GetArenaTeamByName(name)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); return; } if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID); return; } } ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid); if (!pProto) { _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); return; } if (!_player->HasEnoughMoney(cost)) { //player hasn't got enough money _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0); return; } ItemPosCountVec dest; InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, NULL, NULL, charterid); return; } _player->ModifyMoney(-(int32)cost); Item* charter = _player->StoreNewItem(dest, charterid, true); if (!charter) return; charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow()); // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item) charter->SetState(ITEM_CHANGED, _player); _player->SendNewItem(charter, 1, true, false); // a petition is invalid, if both the owner and the type matches // we checked above, if this player is in an arenateam, so this must be // datacorruption Petition const* petition = sPetitionMgr->GetPetitionByOwnerWithType(_player->GetGUIDLow(), type); ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); CharacterDatabase.EscapeString(name); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (petition) { trans->PAppend("DELETE FROM petition WHERE petitionguid = %u", petition->petitionGuid); trans->PAppend("DELETE FROM petition_sign WHERE petitionguid = %u", petition->petitionGuid); // xinef: clear petition store sPetitionMgr->RemovePetition(petition->petitionGuid); } // xinef: petition pointer is invalid from now on PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION); stmt->setUInt32(0, _player->GetGUIDLow()); stmt->setUInt32(1, charter->GetGUIDLow()); stmt->setString(2, name); stmt->setUInt8(3, uint8(type)); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); // xinef: fill petition store sPetitionMgr->AddPetition(charter->GetGUIDLow(), _player->GetGUIDLow(), name, uint8(type)); }
static bool HandleWpModifyCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: add del text emote spell waittime move char* show_str = strtok((char*)args, " "); if (!show_str) { return false; } std::string show = show_str; // Check // Remember: "show" must also be the name of a column! if ((show != "delay") && (show != "action") && (show != "action_chance") && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd") ) { return false; } // Next arg is: <PATHID> <WPNUM> <ARGUMENT> char* arg_str = NULL; // Did user provide a GUID // or did the user select a creature? // -> variable lowguid is filled with the GUID of the NPC uint32 pathid = 0; uint32 point = 0; uint32 wpGuid = 0; Creature* target = handler->getSelectedCreature(); if (!target || target->GetEntry() != VISUAL_WAYPOINT) { handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r"); return false; } // The visual waypoint wpGuid = target->GetGUIDLow(); // User did select a visual waypoint? // Check the creature PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID); stmt->setUInt32(0, wpGuid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow()); // Select waypoint number from database // Since we compare float values, we have to deal with // some difficulties. // Here we search for all waypoints that only differ in one from 1 thousand // (0.001) - There is no other way to compare C++ floats with mySQL floats // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html std::string maxDiff = "0.01"; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS); stmt->setFloat(0, target->GetPositionX()); stmt->setString(1, maxDiff); stmt->setFloat(2, target->GetPositionY()); stmt->setString(3, maxDiff); stmt->setFloat(4, target->GetPositionZ()); stmt->setString(5, maxDiff); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); return true; } } do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); point = fields[1].GetUInt32(); } while (result->NextRow()); // We have the waypoint number and the GUID of the "master npc" // Text is enclosed in "<>", all other arguments not arg_str = strtok((char*)NULL, " "); // Check for argument if (show != "del" && show != "move" && arg_str == NULL) { handler->PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str); return false; } if (show == "del") { handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid); if (wpGuid != 0) if (Creature* wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wpCreature->CombatStop(); wpCreature->DeleteFromDB(); wpCreature->AddObjectToRemoveList(); } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POINT); stmt->setUInt32(0, pathid); stmt->setUInt32(1, point); WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_REMOVED); return true; } // del if (show == "move") { handler->PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid); Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); { // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints if (wpGuid != 0) { if (Creature* wpCreature = map->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wpCreature->CombatStop(); wpCreature->DeleteFromDB(); wpCreature->AddObjectToRemoveList(); } // re-create Creature* wpCreature2 = new Creature; if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; wpCreature2 = NULL; return false; } wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); /// @todo Should we first use "Create" then use "LoadFromDB"? if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; wpCreature2 = NULL; return false; } //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2); } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_POSITION); stmt->setFloat(0, chr->GetPositionX()); stmt->setFloat(1, chr->GetPositionY()); stmt->setFloat(2, chr->GetPositionZ()); stmt->setUInt32(3, pathid); stmt->setUInt32(4, point); WorldDatabase.Execute(stmt); handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); } return true; } // move const char *text = arg_str; if (text == 0) { // show_str check for present in list of correct values, no sql injection possible WorldDatabase.PExecute("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'", show_str, pathid, point); // Query can't be a prepared statement } else { // show_str check for present in list of correct values, no sql injection possible std::string text2 = text; WorldDatabase.EscapeString(text2); WorldDatabase.PExecute("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'", show_str, text2.c_str(), pathid, point); // Query can't be a prepared statement } handler->PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); return true; }
static bool HandleAddDisables(ChatHandler* handler, char const* args, uint8 disableType) { char* entryStr = strtok((char*)args, " "); if (!entryStr || !atoi(entryStr)) return false; char* flagsStr = strtok(NULL, " "); uint8 flags = flagsStr ? uint8(atoi(flagsStr)) : 0; char* commentStr = strtok(NULL, ""); if (!commentStr) return false; std::string disableComment = commentStr; uint32 entry = uint32(atoi(entryStr)); std::string disableTypeStr = ""; switch (disableType) { case DISABLE_TYPE_SPELL: { if (!sSpellMgr->GetSpellInfo(entry)) { handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "spell"; break; } case DISABLE_TYPE_QUEST: { if (!sObjectMgr->GetQuestTemplate(entry)) { handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "quest"; break; } case DISABLE_TYPE_MAP: { if (!sMapStore.LookupEntry(entry)) { handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "map"; break; } case DISABLE_TYPE_BATTLEGROUND: { if (!sBattlemasterListStore.LookupEntry(entry)) { handler->PSendSysMessage(LANG_COMMAND_NO_BATTLEGROUND_FOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "battleground"; break; } case DISABLE_TYPE_ACHIEVEMENT_CRITERIA: { if (!sAchievementMgr->GetAchievementCriteria(entry)) { handler->PSendSysMessage(LANG_COMMAND_NO_ACHIEVEMENT_CRITERIA_FOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "achievement criteria"; break; } case DISABLE_TYPE_OUTDOORPVP: { if (entry > MAX_OUTDOORPVP_TYPES) { handler->PSendSysMessage(LANG_COMMAND_NO_OUTDOOR_PVP_FORUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "outdoorpvp"; break; } case DISABLE_TYPE_VMAP: { if (!sMapStore.LookupEntry(entry)) { handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "vmap"; break; } case DISABLE_TYPE_MMAP: { if (!sMapStore.LookupEntry(entry)) { handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); handler->SetSentErrorMessage(true); return false; } disableTypeStr = "mmap"; break; } default: break; } PreparedStatement* stmt = NULL; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); stmt->setUInt8(1, disableType); PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { handler->PSendSysMessage("This %s (Id: %u) is already disabled.", disableTypeStr.c_str(), entry); handler->SetSentErrorMessage(true); return false; } stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_DISABLES); stmt->setUInt32(0, entry); stmt->setUInt8(1, disableType); stmt->setUInt16(2, flags); stmt->setString(3, disableComment); WorldDatabase.Execute(stmt); handler->PSendSysMessage("Add Disabled %s (Id: %u) for reason %s", disableTypeStr.c_str(), entry, disableComment.c_str()); return true; }
void Item::SaveToDB(SQLTransaction& trans) { bool isInTransaction = !(trans.null()); if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); uint32 guid = GetGUIDLow(); switch (uState) { case ITEM_NEW: case ITEM_CHANGED: { uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(uState == ITEM_NEW ? CHAR_REP_ITEM_INSTANCE : CHAR_UPD_ITEM_INSTANCE); stmt->setUInt32( index, GetEntry()); stmt->setUInt32(++index, GUID_LOPART(GetOwnerGUID())); stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_CREATOR))); stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_GIFTCREATOR))); stmt->setUInt32(++index, GetCount()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURATION)); std::ostringstream ssSpells; for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) ssSpells << GetSpellCharges(i) << ' '; stmt->setString(++index, ssSpells.str()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_FLAGS)); std::ostringstream ssEnchants; for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i) { ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' '; ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' '; } stmt->setString(++index, ssEnchants.str()); stmt->setInt16 (++index, GetItemRandomPropertyId()); stmt->setUInt16(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)); stmt->setString(++index, m_text); stmt->setUInt32(++index, guid); trans->Append(stmt); if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER); stmt->setUInt32(0, GUID_LOPART(GetOwnerGUID())); stmt->setUInt32(1, guid); trans->Append(stmt); } break; } case ITEM_REMOVED: { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); stmt->setUInt32(0, guid); trans->Append(stmt); if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); stmt->setUInt32(0, guid); trans->Append(stmt); } if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); // Delete the items if this is a container if (!loot.isLooted()) ItemContainerDeleteLootMoneyAndLootItemsFromDB(); delete this; return; } case ITEM_UNCHANGED: break; } SetState(ITEM_UNCHANGED); if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); }
// Realm List command handler bool AuthSocket::_HandleRealmList() { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "Entering _HandleRealmList"); #endif if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) // No SQL injection (prepared statement) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError("'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); ACE_INET_Addr clientAddr; socket().peer().get_remote_addr(clientAddr); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { const Realm &realm = i->second; // don't work with realms which not compatible with the client bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild)); // No SQL injection. id of realm is controlled by the database. uint32 flag = realm.flag; RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild); if (!okBuild) { if (!buildInfo) continue; flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for } if (!buildInfo) flag &= ~REALM_FLAG_SPECIFYBUILD; std::string name = i->first; if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { std::ostringstream ss; ss << name << " (" << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << ')'; name = ss.str(); } // We don't need the port number from which client connects with but the realm's port clientAddr.set_port_number(realm.ExternalAddress.get_port_number()); uint8 lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; uint8 AmountOfCharacters = 0; stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM); stmt->setUInt32(0, realm.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); pkt << realm.icon; // realm type if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients pkt << lock; // if 1, then realm locked pkt << uint8(flag); // RealmFlags pkt << name; pkt << GetAddressString(GetAddressForClient(realm, clientAddr)); pkt << realm.populationLevel; pkt << AmountOfCharacters; pkt << realm.timezone; // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients pkt << uint8(realm.m_ID); else pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { pkt << uint8(buildInfo->MajorVersion); pkt << uint8(buildInfo->MinorVersion); pkt << uint8(buildInfo->BugfixVersion); pkt << uint16(buildInfo->Build); } ++RealmListSize; } if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients { pkt << uint8(0x10); pkt << uint8(0x00); } else // 1.12.1 and 1.12.2 clients { pkt << uint8(0x00); pkt << uint8(0x02); } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << uint32(0); if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients RealmListSizeBuffer << uint16(RealmListSize); else RealmListSizeBuffer << uint32(RealmListSize); ByteBuffer hdr; hdr << uint8(REALM_LIST); hdr << uint16(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
// Realm List command handler bool AuthSocket::_HandleRealmList() { sLog->outDebug(LOG_FILTER_AUTHSERVER, "Entering _HandleRealmList"); if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) // No SQL injection (prepared statement) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError(LOG_FILTER_AUTHSERVER, "'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client if ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild != _build) continue; else if ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) continue; uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); else AmountOfCharacters = 0; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; // realm type if ( _expversion & POST_BC_EXP_FLAG ) // only 2.x and 3.x clients pkt << lock; // if 1, then realm locked pkt << uint8(i->second.flag); // RealmFlags pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients pkt << (uint8)0x2C; // unk, may be realm number/id? else pkt << (uint8)0x0; // 1.12.1 and 1.12.2 clients if (i->second.flag & REALM_FLAG_SPECIFYBUILD) { // TODO: Make this customizable pkt << uint8(3); pkt << uint8(3); pkt << uint8(5); pkt << uint16(12340); } ++RealmListSize; } if ( _expversion & POST_BC_EXP_FLAG ) // 2.x and 3.x clients { pkt << (uint8)0x10; pkt << (uint8)0x00; } else // 1.12.1 and 1.12.2 clients { pkt << (uint8)0x00; pkt << (uint8)0x02; } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << (uint32)0; if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients RealmListSizeBuffer << (uint16)RealmListSize; else RealmListSizeBuffer << (uint32)RealmListSize; ByteBuffer hdr; hdr << (uint8) REALM_LIST; hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
// Logon Challenge command handler bool AuthSocket::_HandleLogonChallenge() { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "Entering _HandleLogonChallenge"); #endif if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; ///- Session is closed unless overriden _status = STATUS_CLOSED; // pussywizard: logon flood protection: { TRINITY_GUARD(ACE_Thread_Mutex, LastLoginAttemptMutex); std::string ipaddr = socket().getRemoteAddress(); uint32 currTime = time(NULL); std::map<std::string, uint32>::iterator itr = LastLoginAttemptTimeForIP.find(ipaddr); if (itr != LastLoginAttemptTimeForIP.end() && itr->second >= currTime) { ByteBuffer pkt; pkt << uint8(AUTH_LOGON_CHALLENGE); pkt << uint8(0x00); pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); socket().send((char const*)pkt.contents(), pkt.size()); return true; } if (LastLoginAttemptCleanTime+60 < currTime) { LastLoginAttemptTimeForIP.clear(); LastLoginAttemptCleanTime = currTime; } else LastLoginAttemptTimeForIP[ipaddr] = currTime; } // Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); EndianConvertPtr<uint16>(&buf[0]); uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] got header, body is %#04x bytes", remaining); #endif if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; //No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // Read the remaining of the packet socket().recv((char *)&buf[4], remaining); #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] got full packet, %#04x bytes", ch->size); sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); #endif // BigEndian code, nop in little endian case // size already converted EndianConvertPtr<uint32>(&ch->gamename[0]); EndianConvert(ch->build); EndianConvertPtr<uint32>(&ch->platform[0]); EndianConvertPtr<uint32>(&ch->os[0]); EndianConvertPtr<uint32>(&ch->country[0]); EndianConvert(ch->timezone_bias); EndianConvert(ch->ip); ByteBuffer pkt; _login = (const char*)ch->I; _build = ch->build; _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); _os = (const char*)ch->os; if (_os.size() > 4) return false; // Restore string order as its byte order is reversed std::reverse(_os.begin(), _os.end()); pkt << uint8(AUTH_LOGON_CHALLENGE); pkt << uint8(0x00); // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); std::string const& ip_address = socket().getRemoteAddress(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); stmt->setString(0, ip_address); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) { pkt << uint8(WOW_FAIL_BANNED); #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] Banned ip tries to login!",socket().getRemoteAddress().c_str(), socket().getRemotePort()); #endif } else { // Get the account details from the account table // No SQL injection (prepared statement) stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGONCHALLENGE); stmt->setString(0, _login); PreparedQueryResult res2 = LoginDatabase.Query(stmt); if (res2) { Field* fields = res2->Fetch(); // If the IP is 'locked', check that the player comes indeed from the correct IP address bool locked = false; if (fields[2].GetUInt8() == 1) // if ip is locked { sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString()); sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Player address is '%s'", ip_address.c_str()); if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) { sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account IP differs"); pkt << uint8(WOW_FAIL_LOCKED_ENFORCED); locked = true; } else sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account IP matches"); } else { sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); std::string accountCountry = fields[3].GetString(); if (accountCountry.empty() || accountCountry == "00") sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account '%s' is not locked to country", _login.c_str()); else if (!accountCountry.empty()) { uint32 ip = inet_addr(ip_address.c_str()); EndianConvertReverse(ip); stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); stmt->setUInt32(0, ip); if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt)) { std::string loginCountry = (*sessionCountryQuery)[0].GetString(); sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _login.c_str(), accountCountry.c_str(), loginCountry.c_str()); if (loginCountry != accountCountry) { sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account country differs."); pkt << uint8(WOW_FAIL_UNLOCKABLE_LOCK); locked = true; } else sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] Account country matches"); } else sLog->outDebug(LOG_FILTER_NETWORKIO, "[AuthChallenge] IP2NATION Table empty"); } } if (!locked) { //set expired bans to inactive LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); // If the account is banned, reject the logon attempt stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED); stmt->setUInt32(0, fields[1].GetUInt32()); PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) { if ((*banresult)[0].GetUInt32() == (*banresult)[1].GetUInt32()) { pkt << uint8(WOW_FAIL_BANNED); sLog->outDebug(LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] Banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ()); } else { pkt << uint8(WOW_FAIL_SUSPENDED); sLog->outDebug(LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ()); } } else { // Get the password from the account table, upper it, and make the SRP6 calculation std::string rI = fields[0].GetString(); // Don't calculate (v, s) if there are already some in the database std::string databaseV = fields[6].GetString(); std::string databaseS = fields[7].GetString(); #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); #endif // multiply with 2 since bytes are stored as hexstring if (databaseV.size() != s_BYTE_SIZE * 2 || databaseS.size() != s_BYTE_SIZE * 2) _SetVSFields(rI); else { s.SetHexStr(databaseS.c_str()); v.SetHexStr(databaseV.c_str()); } b.SetRand(19 * 8); BigNumber gmod = g.ModExp(b, N); B = ((v * 3) + gmod) % N; ASSERT(gmod.GetNumBytes() <= 32); BigNumber unk3; unk3.SetRand(16 * 8); // Fill the response packet with the result if (AuthHelper::IsAcceptedClientBuild(_build)) pkt << uint8(WOW_SUCCESS); else pkt << uint8(WOW_FAIL_VERSION_INVALID); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32).get(), 32); // 32 bytes pkt << uint8(1); pkt.append(g.AsByteArray().get(), 1); pkt << uint8(32); pkt.append(N.AsByteArray(32).get(), 32); pkt.append(s.AsByteArray().get(), s.GetNumBytes()); // 32 bytes pkt.append(unk3.AsByteArray(16).get(), 16); uint8 securityFlags = 0; pkt << uint8(securityFlags); // security flags (0x0...0x04) if (securityFlags & 0x01) // PIN input { pkt << uint32(0); pkt << uint64(0) << uint64(0); // 16 bytes hash? } if (securityFlags & 0x02) // Matrix input { pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint64(0); } if (securityFlags & 0x04) // Security token input pkt << uint8(1); uint8 secLevel = fields[5].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; _localizationName.resize(4); for (int i = 0; i < 4; ++i) _localizationName[i] = ch->country[4-i-1]; #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug( LOG_FILTER_NETWORKIO, "'%s:%d' [AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName) ); #endif ///- All good, await client's proof _status = STATUS_LOGON_PROOF; } } } else //no account pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); } socket().send((char const*)pkt.contents(), pkt.size()); return true; }
// Reconnect Challenge command handler bool AuthSocket::_HandleReconnectChallenge() { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "Entering _HandleReconnectChallenge"); #endif if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; // Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); EndianConvertPtr<uint16>(&buf[0]); uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "[ReconnectChallenge] got header, body is %#04x bytes", remaining); #endif if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; ///- Session is closed unless overriden _status = STATUS_CLOSED; // No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // Read the remaining of the packet socket().recv((char *)&buf[4], remaining); #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "[ReconnectChallenge] got full packet, %#04x bytes", ch->size); sLog->outDebug(LOG_FILTER_NETWORKIO, "[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); #endif _login = (const char*)ch->I; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SESSIONKEY); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); // Stop if the account is not found if (!result) { sLog->outError("'%s:%d' [ERROR] user %s tried to login and we cannot find his session key in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str()); socket().shutdown(); return false; } // Reinitialize build, expansion and the account securitylevel _build = ch->build; _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); _os = (const char*)ch->os; if (_os.size() > 4) return false; // Restore string order as its byte order is reversed std::reverse(_os.begin(), _os.end()); Field* fields = result->Fetch(); uint8 secLevel = fields[2].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; K.SetHexStr ((*result)[0].GetCString()); ///- All good, await client's proof _status = STATUS_RECON_PROOF; // Sending response ByteBuffer pkt; pkt << uint8(AUTH_RECONNECT_CHALLENGE); pkt << uint8(0x00); _reconnectProof.SetRand(16 * 8); pkt.append(_reconnectProof.AsByteArray(16).get(), 16); // 16 bytes random pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros socket().send((char const*)pkt.contents(), pkt.size()); return true; }
static bool HandleBanListIPCommand(ChatHandler* handler, char const* args) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS); LoginDatabase.Execute(stmt); char* filterStr = strtok((char*)args, " "); std::string filter = filterStr ? filterStr : ""; LoginDatabase.EscapeString(filter); PreparedQueryResult result; if (filter.empty()) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL); result = LoginDatabase.Query(stmt); } else { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP); stmt->setString(0, filter); result = LoginDatabase.Query(stmt); } if (!result) { handler->PSendSysMessage(LANG_BANLIST_NOIP); return true; } handler->PSendSysMessage(LANG_BANLIST_MATCHINGIP); // Chat short output if (handler->GetSession()) { do { Field* fields = result->Fetch(); handler->PSendSysMessage("%s", fields[0].GetCString()); } while (result->NextRow()); } // Console wide output else { handler->SendSysMessage(LANG_BANLIST_IPS); handler->SendSysMessage(" ==============================================================================="); handler->SendSysMessage(LANG_BANLIST_IPS_HEADER); do { handler->SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); time_t timeBan = time_t(fields[1].GetUInt32()); tm* tmBan = localtime(&timeBan); if (fields[1].GetUInt32() == fields[2].GetUInt32()) { handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, fields[3].GetCString(), fields[4].GetCString()); } else { time_t timeUnban = time_t(fields[2].GetUInt32()); tm* tmUnban = localtime(&timeUnban); handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", fields[0].GetCString(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min, fields[3].GetCString(), fields[4].GetCString()); } } while (result->NextRow()); handler->SendSysMessage(" ==============================================================================="); } return true; }
static bool HandleBanListCharacterCommand(ChatHandler* handler, char const* args) { if (!*args) return false; char* filterStr = strtok((char*)args, " "); if (!filterStr) return false; std::string filter(filterStr); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME_FILTER); stmt->setString(0, filter); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_BANLIST_NOCHARACTER); return true; } handler->PSendSysMessage(LANG_BANLIST_MATCHINGCHARACTER); // Chat short output if (handler->GetSession()) { do { Field* fields = result->Fetch(); PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANNED_NAME); stmt2->setUInt32(0, fields[0].GetUInt32()); PreparedQueryResult banResult = CharacterDatabase.Query(stmt2); if (banResult) handler->PSendSysMessage("%s", (*banResult)[0].GetCString()); } while (result->NextRow()); } // Console wide output else { handler->SendSysMessage(LANG_BANLIST_CHARACTERS); handler->SendSysMessage(" =============================================================================== "); handler->SendSysMessage(LANG_BANLIST_CHARACTERS_HEADER); do { handler->SendSysMessage("-------------------------------------------------------------------------------"); Field* fields = result->Fetch(); std::string char_name = fields[1].GetString(); PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANINFO_LIST); stmt2->setUInt32(0, fields[0].GetUInt32()); PreparedQueryResult banInfo = CharacterDatabase.Query(stmt2); if (banInfo) { Field* banFields = banInfo->Fetch(); do { time_t timeBan = time_t(banFields[0].GetUInt32()); tm* tmBan = localtime(&timeBan); if (banFields[0].GetUInt32() == banFields[1].GetUInt32()) { handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, banFields[2].GetCString(), banFields[3].GetCString()); } else { time_t timeUnban = time_t(banFields[1].GetUInt32()); tm* tmUnban = localtime(&timeUnban); handler->PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", char_name.c_str(), tmBan->tm_year%100, tmBan->tm_mon+1, tmBan->tm_mday, tmBan->tm_hour, tmBan->tm_min, tmUnban->tm_year%100, tmUnban->tm_mon+1, tmUnban->tm_mday, tmUnban->tm_hour, tmUnban->tm_min, banFields[2].GetCString(), banFields[3].GetCString()); } } while (banInfo->NextRow()); } } while (result->NextRow()); handler->SendSysMessage(" =============================================================================== "); } return true; }
void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY"); ObjectGuid guid; recvData.ReadGuidMask(guid, 5, 2, 3); uint8 nameLength = recvData.ReadBits(7); recvData.ReadGuidMask(guid, 4, 1, 7, 0, 6); std::string name = recvData.ReadString(nameLength); recvData.ReadGuidBytes(guid, 1, 7, 4, 6, 0, 5, 2, 3); TC_LOG_DEBUG("network", "Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guid), name.c_str()); // prevent cheating Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_PETITIONER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guid)); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); uint32 charterid = 0; uint32 cost = 0; uint32 type = 0; // if tabard designer, then trying to buy a guild charter. // do not let if already in guild. if (_player->GetGuildId()) return; charterid = GUILD_CHARTER; cost = GUILD_CHARTER_COST; type = GUILD_CHARTER_TYPE; if (sGuildMgr->GetGuildByName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, name); return; } ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid); if (!pProto) { _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); return; } if (!_player->HasEnoughMoney(uint64(cost))) { //player hasn't got enough money _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0); return; } ItemPosCountVec dest; InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount); if (msg != EQUIP_ERR_OK) { _player->SendEquipError(msg, NULL, NULL, charterid); return; } _player->ModifyMoney(-(int32)cost); Item* charter = _player->StoreNewItem(dest, charterid, true); if (!charter) return; //I think this has changed charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow()); // ITEM_FIELD_ENCHANTMENT is guild/arenateam id // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item) charter->SetState(ITEM_CHANGED, _player); _player->SendNewItem(charter, 1, true, false); // a petition is invalid, if both the owner and the type matches // we checked above, if this player is in an arenateam, so this must be // datacorruption PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_BY_OWNER); stmt->setUInt32(0, _player->GetGUIDLow()); stmt->setUInt8(1, type); PreparedQueryResult result = CharacterDatabase.Query(stmt); std::ostringstream ssInvalidPetitionGUIDs; if (result) { do { Field* fields = result->Fetch(); ssInvalidPetitionGUIDs << '\'' << fields[0].GetUInt32() << "', "; } while (result->NextRow()); } // delete petitions with the same guid as this one ssInvalidPetitionGUIDs << '\'' << charter->GetGUIDLow() << '\''; //Probably DB Charter Petitions has changed too TC_LOG_DEBUG("network", "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); CharacterDatabase.EscapeString(name); SQLTransaction trans = CharacterDatabase.BeginTransaction(); trans->PAppend("DELETE FROM petition WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION); stmt->setUInt32(0, _player->GetGUIDLow()); stmt->setUInt32(1, charter->GetGUIDLow()); stmt->setString(2, name); stmt->setUInt8(3, uint8(type)); //Type no needed anymore trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); uint64 petitionGuid; uint32 type; std::string newName; recvData >> petitionGuid; // guid recvData >> newName; // new name Item* item = _player->GetItemByGuid(petitionGuid); if (!item) return; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); type = fields[0].GetUInt8(); } else { TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid)); return; } if (type == GUILD_CHARTER_TYPE) { if (sGuildMgr->GetGuildByName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, newName); return; } if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, newName); return; } } else { if (sArenaTeamMgr->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; } } stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME); stmt->setString(0, newName); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); CharacterDatabase.Execute(stmt); TC_LOG_DEBUG("network", "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str()); WorldPacket data(MSG_PETITION_RENAME, (8+newName.size()+1)); data << uint64(petitionGuid); data << newName; SendPacket(&data); }
// Logon Proof command handler bool AuthSession::HandleLogonProof() { TC_LOG_DEBUG("server.authserver", "Entering _HandleLogonProof"); _status = STATUS_CLOSED; // Read the packet sAuthLogonProof_C *logonProof = reinterpret_cast<sAuthLogonProof_C*>(GetReadBuffer().GetReadPointer()); // If the client has no valid version if (_expversion == NO_VALID_EXP_FLAG) { // Check if we have the appropriate patch on the disk TC_LOG_DEBUG("network", "Client with invalid version, patching is not implemented"); return false; } // Continue the SRP6 calculation based on data received from the client BigNumber A; A.SetBinary(logonProof->A, 32); // SRP safeguard: abort if A == 0 if ((A % N).IsZero()) return false; SHA1Hash sha; sha.UpdateBigNumbers(&A, &B, nullptr); sha.Finalize(); BigNumber u; u.SetBinary(sha.GetDigest(), 20); BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); uint8 t[32]; uint8 t1[16]; uint8 vK[40]; memcpy(t, S.AsByteArray(32).get(), 32); for (int i = 0; i < 16; ++i) t1[i] = t[i * 2]; sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) vK[i * 2] = sha.GetDigest()[i]; for (int i = 0; i < 16; ++i) t1[i] = t[i * 2 + 1]; sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) vK[i * 2 + 1] = sha.GetDigest()[i]; K.SetBinary(vK, 40); uint8 hash[20]; sha.Initialize(); sha.UpdateBigNumbers(&N, nullptr); sha.Finalize(); memcpy(hash, sha.GetDigest(), 20); sha.Initialize(); sha.UpdateBigNumbers(&g, nullptr); sha.Finalize(); for (int i = 0; i < 20; ++i) hash[i] ^= sha.GetDigest()[i]; BigNumber t3; t3.SetBinary(hash, 20); sha.Initialize(); sha.UpdateData(_accountInfo.Login); sha.Finalize(); uint8 t4[SHA_DIGEST_LENGTH]; memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); sha.Initialize(); sha.UpdateBigNumbers(&t3, nullptr); sha.UpdateData(t4, SHA_DIGEST_LENGTH); sha.UpdateBigNumbers(&s, &A, &B, &K, nullptr); sha.Finalize(); BigNumber M; M.SetBinary(sha.GetDigest(), sha.GetLength()); // Check if SRP6 results match (password is correct), else send an error if (!memcmp(M.AsByteArray(sha.GetLength()).get(), logonProof->M1, 20)) { // Check auth token if ((logonProof->securityFlags & 0x04) || !_tokenKey.empty()) { uint8 size = *(GetReadBuffer().GetReadPointer() + sizeof(sAuthLogonProof_C)); std::string token(reinterpret_cast<char*>(GetReadBuffer().GetReadPointer() + sizeof(sAuthLogonProof_C) + sizeof(size)), size); GetReadBuffer().ReadCompleted(sizeof(size) + size); uint32 validToken = TOTP::GenerateToken(_tokenKey.c_str()); _tokenKey.clear(); uint32 incomingToken = atoi(token.c_str()); if (validToken != incomingToken) { ByteBuffer packet; packet << uint8(AUTH_LOGON_PROOF); packet << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); packet << uint8(3); packet << uint8(0); SendPacket(packet); return true; } } TC_LOG_DEBUG("server.authserver", "'%s:%d' User '%s' successfully authenticated", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); // Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF); stmt->setString(0, K.AsHexStr()); stmt->setString(1, GetRemoteIpAddress().to_string()); stmt->setUInt32(2, GetLocaleByName(_localizationName)); stmt->setString(3, _os); stmt->setString(4, _accountInfo.Login); LoginDatabase.DirectExecute(stmt); // Finish SRP6 and send the final result to the client sha.Initialize(); sha.UpdateBigNumbers(&A, &M, &K, nullptr); sha.Finalize(); ByteBuffer packet; if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.AccountFlags = 0x00800000; // 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) proof.SurveyId = 0; proof.unk3 = 0; packet.resize(sizeof(proof)); std::memcpy(packet.contents(), &proof, sizeof(proof)); } else { sAuthLogonProof_S_Old proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; packet.resize(sizeof(proof)); std::memcpy(packet.contents(), &proof, sizeof(proof)); } SendPacket(packet); _status = STATUS_AUTHED; } else { ByteBuffer packet; packet << uint8(AUTH_LOGON_PROOF); packet << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); packet << uint8(3); packet << uint8(0); SendPacket(packet); TC_LOG_INFO("server.authserver.hack", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str()); uint32 MaxWrongPassCount = sConfigMgr->GetIntDefault("WrongPass.MaxCount", 0); // We can not include the failed account login hook. However, this is a workaround to still log this. if (sConfigMgr->GetBoolDefault("WrongPass.Logging", false)) { PreparedStatement* logstmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FALP_IP_LOGGING); logstmt->setUInt32(0, _accountInfo.Id); logstmt->setString(1, GetRemoteIpAddress().to_string()); logstmt->setString(2, "Logged on failed AccountLogin due wrong password"); LoginDatabase.Execute(logstmt); } if (MaxWrongPassCount > 0) { //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_FAILEDLOGINS); stmt->setString(0, _accountInfo.Login); LoginDatabase.Execute(stmt); if (++_accountInfo.FailedLogins >= MaxWrongPassCount) { uint32 WrongPassBanTime = sConfigMgr->GetIntDefault("WrongPass.BanTime", 600); bool WrongPassBanType = sConfigMgr->GetBoolDefault("WrongPass.BanType", false); if (WrongPassBanType) { stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED); stmt->setUInt32(0, _accountInfo.Id); stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, _accountInfo.FailedLogins); } else { stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED); stmt->setString(0, GetRemoteIpAddress().to_string()); stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); TC_LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] IP got banned for '%u' seconds because account %s failed to authenticate '%u' times", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), WrongPassBanTime, _accountInfo.Login.c_str(), _accountInfo.FailedLogins); } } } } return true; }
Channel::Channel(std::string const& name, uint32 channelId, uint32 channelDBId, TeamId teamId, bool announce): _announce(announce), _ownership(true), _IsSaved(false), _flags(0), _channelId(channelId), _teamId(teamId), _ownerGUID(0), _name(name), _channelDBId(channelDBId), _password("") { // set special flags if built-in channel if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channelId)) // check whether it's a built-in channel { _announce = false; // no join/leave announces _ownership = false; // no ownership handout _flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels if (ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel _flags |= CHANNEL_FLAG_TRADE; if (ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels _flags |= CHANNEL_FLAG_CITY; if (ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel _flags |= CHANNEL_FLAG_LFG; else // for all other channels _flags |= CHANNEL_FLAG_NOT_LFG; } else // it's custom channel { _flags |= CHANNEL_FLAG_CUSTOM; // pussywizard: _channelRights = ChannelMgr::GetChannelRightsFor(_name); if (_channelRights.flags & CHANNEL_RIGHT_FORCE_NO_ANNOUNCEMENTS) _announce = false; if (_channelRights.flags & CHANNEL_RIGHT_FORCE_ANNOUNCEMENTS) _announce = true; if (_channelRights.flags & CHANNEL_RIGHT_NO_OWNERSHIP) _ownership = false; if (_channelRights.flags & CHANNEL_RIGHT_DONT_PRESERVE) return; _IsSaved = true; // Xinef: loading if (channelDBId > 0) return; // If storing custom channels in the db is enabled either load or save the channel if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS)) { _channelDBId = ++ChannelMgr::_channelIdMax; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL); stmt->setUInt32(0, _channelDBId); stmt->setString(1, name); stmt->setUInt32(2, _teamId); stmt->setUInt8(3, _announce); CharacterDatabase.Execute(stmt); } } }
// Logon Challenge command handler bool AuthSocket::_HandleLogonChallenge() { sLog->outStaticDebug("Entering _HandleLogonChallenge"); if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; ///- Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); #if TRINITY_ENDIAN == TRINITY_BIGENDIAN EndianConvert(*((uint16*)(buf[0]))); #endif uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; sLog->outStaticDebug("[AuthChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; //No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // Read the remaining of the packet socket().recv((char *)&buf[4], remaining); sLog->outStaticDebug("[AuthChallenge] got full packet, %#04x bytes", ch->size); sLog->outStaticDebug("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); // BigEndian code, nop in little endian case // size already converted #if TRINITY_ENDIAN == TRINITY_BIGENDIAN EndianConvert(*((uint32*)(&ch->gamename[0]))); EndianConvert(ch->build); EndianConvert(*((uint32*)(&ch->platform[0]))); EndianConvert(*((uint32*)(&ch->os[0]))); EndianConvert(*((uint32*)(&ch->country[0]))); EndianConvert(ch->timezone_bias); EndianConvert(ch->ip); #endif ByteBuffer pkt; _login = (const char*)ch->I; _build = ch->build; _expversion = (AuthHelper::IsPostWotLKAcceptedClientBuild(_build) ? POST_WOTLK_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDIPBANS)); const std::string& ip_address = socket().get_remote_address(); PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_IPBANNED); stmt->setString(0, ip_address); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) { pkt << (uint8)WOW_FAIL_BANNED; sLog->outBasic("[AuthChallenge] Banned ip %s tried to login!", ip_address.c_str()); } else { // Get the account details from the account table // No SQL injection (prepared statement) stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_LOGONCHALLENGE); stmt->setString(0, _login); PreparedQueryResult res2 = LoginDatabase.Query(stmt); if (res2) { Field* fields = res2->Fetch(); // If the IP is 'locked', check that the player comes indeed from the correct IP address bool locked = false; if (fields[2].GetUInt8() == 1) // if ip is locked { sLog->outStaticDebug("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString()); sLog->outStaticDebug("[AuthChallenge] Player address is '%s'", ip_address.c_str()); if (strcmp(fields[3].GetCString(), ip_address.c_str())) { sLog->outStaticDebug("[AuthChallenge] Account IP differs"); pkt << (uint8) WOW_FAIL_SUSPENDED; locked = true; } else sLog->outStaticDebug("[AuthChallenge] Account IP matches"); } else sLog->outStaticDebug("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); if (!locked) { //set expired bans to inactive LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDACCBANS)); // If the account is banned, reject the logon attempt stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCBANNED); stmt->setUInt32(0, fields[1].GetUInt32()); PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) { if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) { pkt << (uint8) WOW_FAIL_BANNED; sLog->outBasic("[AuthChallenge] Banned account %s tried to login!", _login.c_str()); } else { pkt << (uint8) WOW_FAIL_SUSPENDED; sLog->outBasic("[AuthChallenge] Temporarily banned account %s tried to login!", _login.c_str()); } } else { // Get the password from the account table, upper it, and make the SRP6 calculation std::string rI = fields[0].GetString(); // Don't calculate (v, s) if there are already some in the database std::string databaseV = fields[5].GetString(); std::string databaseS = fields[6].GetString(); sLog->outDebug(LOG_FILTER_NETWORKIO, "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); // multiply with 2, since bytes are stored as hexstring if (databaseV.size() != s_BYTE_SIZE * 2 || databaseS.size() != s_BYTE_SIZE * 2) _SetVSFields(rI); else { s.SetHexStr(databaseS.c_str()); v.SetHexStr(databaseV.c_str()); } b.SetRand(19 * 8); BigNumber gmod = g.ModExp(b, N); B = ((v * 3) + gmod) % N; ASSERT(gmod.GetNumBytes() <= 32); BigNumber unk3; unk3.SetRand(16 * 8); // Fill the response packet with the result pkt << uint8(WOW_SUCCESS); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32), 32); // 32 bytes pkt << uint8(1); pkt.append(g.AsByteArray(), 1); pkt << uint8(32); pkt.append(N.AsByteArray(32), 32); pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes pkt.append(unk3.AsByteArray(16), 16); uint8 securityFlags = 0; pkt << uint8(securityFlags); // security flags (0x0...0x04) if (securityFlags & 0x01) // PIN input { pkt << uint32(0); pkt << uint64(0) << uint64(0); // 16 bytes hash? } if (securityFlags & 0x02) // Matrix input { pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint64(0); } if (securityFlags & 0x04) // Security token input pkt << uint8(1); uint8 secLevel = fields[4].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; _localizationName.resize(4); for (int i = 0; i < 4; ++i) _localizationName[i] = ch->country[4-i-1]; sLog->outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)); } } } else //no account pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT; } socket().send((char const*)pkt.contents(), pkt.size()); return true; }
void WorldSession::HandlePetRename(WorldPacket& recvData) { TC_LOG_DEBUG("network.opcode", "WORLD: Received CMSG_PET_RENAME"); ObjectGuid petguid; uint8 isdeclined; std::string name; DeclinedName declinedname; recvData >> petguid; recvData >> name; recvData >> isdeclined; Pet* pet = ObjectAccessor::GetPet(*_player, petguid); // check it! if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType() != HUNTER_PET || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED) || pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo()) return; PetNameInvalidReason res = ObjectMgr::CheckPetName(name, GetSessionDbcLocale()); if (res != PET_NAME_SUCCESS) { SendPetNameInvalid(res, name, nullptr); return; } if (sObjectMgr->IsReservedName(name)) { SendPetNameInvalid(PET_NAME_RESERVED, name, nullptr); return; } pet->SetName(name); if (pet->GetOwner()->GetGroup()) pet->GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED); if (isdeclined) { for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { recvData >> declinedname.name[i]; } std::wstring wname; if (!Utf8toWStr(name, wname)) return; if (!ObjectMgr::CheckDeclinedNames(wname, declinedname)) { SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname); return; } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (isdeclined) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME); stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME); stmt->setUInt32(0, _player->GetGUID().GetCounter()); for (uint8 i = 0; i < 5; i++) stmt->setString(i + 1, declinedname.name[i]); trans->Append(stmt); } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME); stmt->setString(0, name); stmt->setUInt32(1, _player->GetGUID().GetCounter()); stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped }
// Logon Proof command handler bool AuthSocket::_HandleLogonProof() { sLog->outStaticDebug("Entering _HandleLogonProof"); // Read the packet sAuthLogonProof_C lp; if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) return false; // If the client has no valid version if (_expversion == NO_VALID_EXP_FLAG) { // Check if we have the appropriate patch on the disk sLog->outDebug(LOG_FILTER_NETWORKIO, "Client with invalid version, patching is not implemented"); socket().shutdown(); return true; } // Continue the SRP6 calculation based on data received from the client BigNumber A; A.SetBinary(lp.A, 32); // SRP safeguard: abort if A == 0 if (A.isZero()) { socket().shutdown(); return true; } SHA1Hash sha; sha.UpdateBigNumbers(&A, &B, NULL); sha.Finalize(); BigNumber u; u.SetBinary(sha.GetDigest(), 20); BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); uint8 t[32]; uint8 t1[16]; uint8 vK[40]; memcpy(t, S.AsByteArray(32), 32); for (int i = 0; i < 16; ++i) t1[i] = t[i * 2]; sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) vK[i * 2] = sha.GetDigest()[i]; for (int i = 0; i < 16; ++i) t1[i] = t[i * 2 + 1]; sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) vK[i * 2 + 1] = sha.GetDigest()[i]; K.SetBinary(vK, 40); uint8 hash[20]; sha.Initialize(); sha.UpdateBigNumbers(&N, NULL); sha.Finalize(); memcpy(hash, sha.GetDigest(), 20); sha.Initialize(); sha.UpdateBigNumbers(&g, NULL); sha.Finalize(); for (int i = 0; i < 20; ++i) hash[i] ^= sha.GetDigest()[i]; BigNumber t3; t3.SetBinary(hash, 20); sha.Initialize(); sha.UpdateData(_login); sha.Finalize(); uint8 t4[SHA_DIGEST_LENGTH]; memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); sha.Initialize(); sha.UpdateBigNumbers(&t3, NULL); sha.UpdateData(t4, SHA_DIGEST_LENGTH); sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); sha.Finalize(); BigNumber M; M.SetBinary(sha.GetDigest(), 20); // Check if SRP6 results match (password is correct), else send an error if (!memcmp(M.AsByteArray(), lp.M1, 20)) { sLog->outBasic("User '%s' successfully authenticated", _login.c_str()); // Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket const char* K_hex = K.AsHexStr(); PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_LOGONPROOF); stmt->setString(0, K_hex); stmt->setString(1, socket().get_remote_address().c_str()); stmt->setUInt32(2, GetLocaleByName(_localizationName)); stmt->setString(3, _login); LoginDatabase.Execute(stmt); OPENSSL_free((void*)K_hex); // Finish SRP6 and send the final result to the client sha.Initialize(); sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) { sAuthLogonProof_S proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk1 = 0x00800000; proof.unk2 = 0x00; proof.unk3 = 0x00; socket().send((char *)&proof, sizeof(proof)); } else { sAuthLogonProof_S_Old proof; memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; proof.unk2 = 0x00; socket().send((char *)&proof, sizeof(proof)); } _authed = true; } else { char data[4] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 }; socket().send(data, sizeof(data)); sLog->outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); uint32 MaxWrongPassCount = sConfig->GetIntDefault("WrongPass.MaxCount", 0); if (MaxWrongPassCount > 0) { // Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_FAILEDLOGINS); stmt->setString(0, _login); LoginDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_FAILEDLOGINS); stmt->setString(0, _login); if (PreparedQueryResult loginfail = LoginDatabase.Query(stmt)) { uint32 failed_logins = (*loginfail)[1].GetUInt32(); if (failed_logins >= MaxWrongPassCount) { uint32 WrongPassBanTime = sConfig->GetIntDefault("WrongPass.BanTime", 600); bool WrongPassBanType = sConfig->GetBoolDefault("WrongPass.BanType", false); if (WrongPassBanType) { uint32 acc_id = (*loginfail)[0].GetUInt32(); stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_ACCAUTOBANNED); stmt->setUInt32(0, acc_id); stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); sLog->outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", _login.c_str(), WrongPassBanTime, failed_logins); } else { stmt = LoginDatabase.GetPreparedStatement(LOGIN_SET_IPAUTOBANNED); stmt->setString(0, socket().get_remote_address()); stmt->setUInt32(1, WrongPassBanTime); LoginDatabase.Execute(stmt); sLog->outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", socket().get_remote_address().c_str(), WrongPassBanTime, _login.c_str(), failed_logins); } } } } } return true; }
void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recvData) { ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_RENAME"); // ok uint64 petitionGuid; std::string newName; recvData >> petitionGuid; // guid recvData >> newName; // new name Item* item = _player->GetItemByGuid(petitionGuid); if (!item) return; Petition const* petition = sPetitionMgr->GetPetition(GUID_LOPART(petitionGuid)); if (!petition) { ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid)); return; } if (petition->petitionType == GUILD_CHARTER_TYPE) { if (sGuildMgr->GetGuildByName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, newName); return; } if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_INVALID, newName); return; } } else { if (sArenaTeamMgr->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; } } PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME); stmt->setString(0, newName); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); CharacterDatabase.Execute(stmt); // xinef: update petition container const_cast<Petition*>(petition)->petitionName = newName; ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str()); WorldPacket data(MSG_PETITION_RENAME, (8+newName.size()+1)); data << uint64(petitionGuid); data << newName; SendPacket(&data); }
// Reconnect Challenge command handler bool AuthSocket::_HandleReconnectChallenge() { sLog->outStaticDebug("Entering _HandleReconnectChallenge"); if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; // Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); #if TRINITY_ENDIAN == TRINITY_BIGENDIAN EndianConvert(*((uint16*)(buf[0]))); #endif //TRINITY_ENDIAN uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; sLog->outStaticDebug("[ReconnectChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; // No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // Read the remaining of the packet socket().recv((char *)&buf[4], remaining); sLog->outStaticDebug("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); sLog->outStaticDebug("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); _login = (const char*)ch->I; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_SESSIONKEY); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); // Stop if the account is not found if (!result) { sLog->outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); socket().shutdown(); return false; } // Reinitialize build, expansion and the account securitylevel _build = ch->build; _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); Field* fields = result->Fetch(); uint8 secLevel = fields[2].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; K.SetHexStr ((*result)[0].GetCString()); // Sending response ByteBuffer pkt; pkt << (uint8)AUTH_RECONNECT_CHALLENGE; pkt << (uint8)0x00; _reconnectProof.SetRand(16 * 8); pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random pkt << (uint64)0x00 << (uint64)0x00; // 16 bytes zeros socket().send((char const*)pkt.contents(), pkt.size()); return true; }
void Item::SaveToDB(SQLTransaction& trans) { uint32 guid = GetGUIDLow(); switch (uState) { case ITEM_NEW: case ITEM_CHANGED: { uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(uState == ITEM_NEW ? CHAR_ADD_ITEM_INSTANCE : CHAR_UPDATE_ITEM_INSTANCE); stmt->setUInt32( index, GetEntry()); stmt->setUInt32(++index, GUID_LOPART(GetOwnerGUID())); stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_CREATOR))); stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_GIFTCREATOR))); stmt->setUInt32(++index, GetCount()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURATION)); std::ostringstream ssSpells; for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) ssSpells << GetSpellCharges(i) << " "; stmt->setString(++index, ssSpells.str()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_FLAGS)); std::ostringstream ssEnchants; for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i) { ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << " "; ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << " "; ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << " "; } stmt->setString(++index, ssEnchants.str()); stmt->setInt32 (++index, GetItemRandomPropertyId()); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)); stmt->setString(++index, m_text); stmt->setUInt32(++index, guid); trans->Append(stmt); if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GIFT_OWNER); stmt->setUInt32(0, GUID_LOPART(GetOwnerGUID())); stmt->setUInt32(1, guid); trans->Append(stmt); } break; } case ITEM_REMOVED: { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); stmt->setUInt32(0, guid); trans->Append(stmt); if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); stmt->setUInt32(0, guid); trans->Append(stmt); } delete this; return; } case ITEM_UNCHANGED: break; } SetState(ITEM_UNCHANGED); }
// Realm List command handler bool AuthSocket::_HandleRealmList() { sLog->outStaticDebug("Entering _HandleRealmList"); if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) // No SQL injection (prepared statement) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCIDBYNAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError("[ERROR] user %s tried to login and we cannot find him in the database.", _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) { if (i->second.gamebuild != _build) { sLog->outStaticDebug("Realm not added because of not correct build : %u != %u", i->second.gamebuild, _build); continue; } } else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) continue; uint8 AmountOfCharacters; // No SQL injection. id of realm is controlled by the database. stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_NUMCHARSONREALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); else AmountOfCharacters = 0; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; if (_expversion & (POST_BC_EXP_FLAG | POST_WOTLK_EXP_FLAG)) pkt << lock; pkt << i->second.color; pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; if (_expversion & (POST_BC_EXP_FLAG | POST_WOTLK_EXP_FLAG)) pkt << (uint8) 0x2C; else pkt << (uint8) 0x0; ++RealmListSize; } if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) { pkt << (uint8) 0x10; pkt << (uint8) 0x00; } else { pkt << (uint8) 0x00; pkt << (uint8) 0x02; } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << (uint32)0; if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) RealmListSizeBuffer << (uint16)RealmListSize; else RealmListSizeBuffer << (uint32)RealmListSize; ByteBuffer hdr; hdr << (uint8) REALM_LIST; hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) : m_announce(true), m_ownership(true), m_name(name), m_password(""), m_flags(0), m_channelId(channel_id), m_ownerGUID(0), m_Team(Team) { m_IsSaved = false; // set special flags if built-in channel if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channel_id)) // check whether it's a built-in channel { m_announce = false; // no join/leave announces m_ownership = false; // no ownership handout m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels if (ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel m_flags |= CHANNEL_FLAG_TRADE; if (ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels m_flags |= CHANNEL_FLAG_CITY; if (ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel m_flags |= CHANNEL_FLAG_LFG; else // for all other channels m_flags |= CHANNEL_FLAG_NOT_LFG; } else // it's custom channel { channel_id = 0; m_flags |= CHANNEL_FLAG_CUSTOM; // If storing custom channels in the db is enabled either load or save the channel if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS)) { PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_CHANNEL); stmt->setString(0, name); stmt->setUInt32(1, m_Team); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) //load { Field *fields = result->Fetch(); m_announce = fields[0].GetBool(); m_ownership = fields[1].GetBool(); m_password = fields[2].GetString(); const char* db_BannedList = fields[3].GetCString(); if (db_BannedList) { Tokens tokens(db_BannedList, ' '); Tokens::iterator iter; for (iter = tokens.begin(); iter != tokens.end(); ++iter) { uint64 banned_guid = atol(*iter); if (banned_guid) { sLog->outDebug(LOG_FILTER_CHATSYS, "Channel(%s) loaded banned guid:" UI64FMTD "", name.c_str(), banned_guid); banned.insert(banned_guid); } } } } else // save { stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHANNEL); stmt->setString(0, name); stmt->setUInt32(1, m_Team); CharacterDatabase.Execute(stmt); sLog->outDebug(LOG_FILTER_CHATSYS, "Channel(%s) saved in database", name.c_str()); } m_IsSaved = true; } } }
void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, MailSender const& sender, MailCheckMask checked, uint32 deliver_delay) { Player* pReceiver = receiver.GetPlayer(); // can be NULL Player* pSender = sObjectMgr->GetPlayerByLowGUID(sender.GetSenderId()); if (pReceiver) prepareItems(pReceiver, trans); // generate mail template items uint32 mailId = sObjectMgr->GenerateMailID(); time_t deliver_time = time(NULL) + deliver_delay; //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour uint32 expire_delay; // auction mail without any items and money if (sender.GetMailMessageType() == MAIL_AUCTION && m_items.empty() && !m_money) expire_delay = sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY); // mail from battlemaster (rewardmarks) should last only one day else if (sender.GetMailMessageType() == MAIL_CREATURE && sBattlegroundMgr->GetBattleMasterBG(sender.GetSenderId()) != BATTLEGROUND_TYPE_NONE) expire_delay = DAY; // default case: expire time if COD 3 days, if no COD 30 days (or 90 days if sender is a game master) else if (m_COD) expire_delay = 3 * DAY; else expire_delay = pSender && pSender->isGameMaster() ? 90 * DAY : 30 * DAY; time_t expire_time = deliver_time + expire_delay; // Add to DB uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL); stmt->setUInt32( index, mailId); stmt->setUInt8 (++index, uint8(sender.GetMailMessageType())); stmt->setInt8 (++index, int8(sender.GetStationery())); stmt->setUInt16(++index, GetMailTemplateId()); stmt->setUInt32(++index, sender.GetSenderId()); stmt->setUInt32(++index, receiver.GetPlayerGUIDLow()); stmt->setString(++index, GetSubject()); stmt->setString(++index, GetBody()); stmt->setBool (++index, !m_items.empty()); stmt->setUInt64(++index, uint64(expire_time)); stmt->setUInt64(++index, uint64(deliver_time)); stmt->setUInt32(++index, m_money); stmt->setUInt32(++index, m_COD); stmt->setUInt8 (++index, uint8(checked)); trans->Append(stmt); for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) { Item* pItem = mailItemIter->second; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL_ITEM); stmt->setUInt32(0, mailId); stmt->setUInt32(1, pItem->GetGUIDLow()); stmt->setUInt32(2, receiver.GetPlayerGUIDLow()); trans->Append(stmt); } // For online receiver update in game mail status and data if (pReceiver) { pReceiver->AddNewMailDeliverTime(deliver_time); if (pReceiver->IsMailsLoaded()) { Mail* m = new Mail; m->messageID = mailId; m->mailTemplateId = GetMailTemplateId(); m->subject = GetSubject(); m->body = GetBody(); m->money = GetMoney(); m->COD = GetCOD(); for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) { Item* item = mailItemIter->second; m->AddItem(item->GetGUIDLow(), item->GetEntry()); } m->messageType = sender.GetMailMessageType(); m->stationery = sender.GetStationery(); m->sender = sender.GetSenderId(); m->receiver = receiver.GetPlayerGUIDLow(); m->expire_time = expire_time; m->deliver_time = deliver_time; m->checked = checked; m->state = MAIL_STATE_UNCHANGED; pReceiver->AddMail(m); // to insert new mail to beginning of maillist if (!m_items.empty()) { for (MailItemMap::iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) pReceiver->AddMItem(mailItemIter->second); } } else if (!m_items.empty()) { SQLTransaction temp = SQLTransaction(NULL); deleteIncludedItems(temp); } } else if (!m_items.empty()) { SQLTransaction temp = SQLTransaction(NULL); deleteIncludedItems(temp); } }
void WorldSession::HandleCalendarEventInvite(WorldPackets::Calendar::CalendarEventInvite& calendarEventInvite) { ObjectGuid playerGuid = _player->GetGUID(); ObjectGuid inviteeGuid; uint32 inviteeTeam = 0; ObjectGuid::LowType inviteeGuildId = UI64LIT(0); if (Player* player = ObjectAccessor::FindConnectedPlayerByName(calendarEventInvite.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, calendarEventInvite.Name); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); inviteeGuid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64()); 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, calendarEventInvite.Name.c_str()); return; } } if (!calendarEventInvite.Creating) { if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(calendarEventInvite.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; } CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEventInvite.EventID, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); } else sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID); } else { if (calendarEventInvite.IsSignUp && inviteeGuildId == _player->GetGuildId()) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); return; } CalendarInvite invite(sCalendarMgr->GetFreeInviteId(), NULL, inviteeGuid, playerGuid, CALENDAR_DEFAULT_RESPONSE_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->SendCalendarEventInvite(invite); } }
//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, 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::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); } }
void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) { TC_LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE"); uint64 playerGuid = _player->GetGUID(); uint64 eventId; uint64 inviteId; std::string name; uint16 length; bool isPreInvite; bool isGuildEvent; uint64 inviteeGuid = 0; uint32 inviteeTeam = 0; uint32 inviteeGuildId = 0; recvData >> eventId >> inviteId; isPreInvite = recvData.ReadBit(); length = recvData.ReadBits(9); isGuildEvent = recvData.ReadBit(); name = recvData.ReadString(length); if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str())) { // 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 = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); 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 = " UI64FMTD " AND friend = " UI64FMTD, inviteeGuid, playerGuid)) { 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->GetEventTime() < time(NULL)) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_PASSED); return; } // DEFAULT_STATUS_TIME is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, DEFAULT_STATUS_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); } else sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID); } else { // DEFAULT_STATUS_TIME is 01/01/2000 00:00:00 - default response time CalendarInvite invite(0, 0, inviteeGuid, playerGuid, DEFAULT_STATUS_TIME, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->SendCalendarEventInvite(invite); } }