diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 30a90f23b..a77d17998 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -924,35 +924,10 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) uint64 guid; std::string newname; - std::string oldname; - - CHECK_PACKET_SIZE(recv_data, 8+1); recv_data >> guid; recv_data >> newname; - QueryResult *result = CharacterDatabase.PQuery("SELECT at_login, name FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); - if (!result) - { - WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_CREATE_ERROR); - SendPacket( &data ); - return; - } - - Field *fields = result->Fetch(); - uint32 at_loginFlags = fields[0].GetUInt32(); - oldname = fields[1].GetCppString(); - delete result; - - if (!(at_loginFlags & AT_LOGIN_RENAME)) - { - WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_CREATE_ERROR); - SendPacket( &data ); - return; - } - // prevent character rename to invalid name if(!normalizePlayerName(newname)) { @@ -962,7 +937,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) return; } - if(!ObjectMgr::IsValidName(newname,true)) + if(!ObjectMgr::IsValidName(newname, true)) { WorldPacket data(SMSG_CHAR_RENAME, 1); data << uint8(CHAR_NAME_INVALID_CHARACTER); @@ -979,34 +954,58 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) return; } - if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist - { - WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_CREATE_NAME_IN_USE); - SendPacket( &data ); - return; - } - - if(newname == oldname) // checked by client - { - WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_NAME_FAILURE); - SendPacket( &data ); - return; - } - CharacterDatabase.escape_string(newname); - CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), GUID_LOPART(guid)); - CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); - std::string IP_str = GetRemoteAddress(); - sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), IP_str.c_str(), oldname.c_str(), GUID_LOPART(guid), newname.c_str()); + CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack, GUID_LOPART(guid), newname, "SELECT guid, at_login, name FROM characters WHERE guid = '%u' XOR name = '%s'", GUID_LOPART(guid), newname.c_str()); +} - WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1)); +void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname) +{ + WorldSession * session = sWorld.FindSession(accountId); + if(!session) + return; + + if (!result || result->GetRowCount() != 1) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << uint8(CHAR_CREATE_ERROR); + session->SendPacket( &data ); + return; + } + + Field *fields = result->Fetch(); + uint32 guidLow = fields[0].GetUInt32(); + uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); + uint32 at_loginFlags = fields[1].GetUInt32(); + std::string oldname = fields[2].GetCppString(); + delete result; + if(oldname == newname) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << uint8(CHAR_CREATE_ERROR); + session->SendPacket( &data ); + return; + } + + // we have to check character at_login_flag & AT_LOGIN_RENAME also (fake packets hehe) + if (!(at_loginFlags & AT_LOGIN_RENAME)) + { + WorldPacket data(SMSG_CHAR_RENAME, 1); + data << uint8(CHAR_CREATE_ERROR); + session->SendPacket( &data ); + return; + } + + CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow); + CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow); + + sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress(), oldname.c_str(), guidLow, newname.c_str()); + + WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1)); data << uint8(RESPONSE_SUCCESS); data << uint64(guid); data << newname; - SendPacket(&data); + session->SendPacket(&data); } void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 6d4777800..27ff8c291 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -3137,7 +3137,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) } }while(result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned - WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'"); + WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if( hasError ) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 3100bbe53..32ab12bfa 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4575,7 +4575,7 @@ bool ChatHandler::HandleResetAllCommand(const char * args) return false; } - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin); HashMapHolder::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); for(HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) itr->second->SetAtLoginFlag(atLogin); diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index aa5009a9a..21e8cf553 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -104,7 +104,7 @@ class MANGOS_DLL_SPEC WorldSession Player* GetPlayer() const { return _player; } char const* GetPlayerName() const; void SetSecurity(uint32 security) { _security = security; } - std::string& GetRemoteAddress() { return m_Address; } + std::string const& GetRemoteAddress() { return m_Address; } void SetPlayer(Player *plr) { _player = plr; } uint8 Expansion() const { return m_expansion; } @@ -563,6 +563,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleSetActionBar(WorldPacket& recv_data); void HandleChangePlayerNameOpcode(WorldPacket& recv_data); + static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname); void HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data); void HandleTotemDestroy(WorldPacket& recv_data); diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 1b6929267..f5ef907bb 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -459,7 +459,7 @@ void Master::clearOnlineAccounts() "AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID); - CharacterDatabase.Execute("UPDATE characters SET online = 0"); + CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0"); } /// Handle termination signals diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 756f31327..2d7234568 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "6905" + #define REVISION_NR "6908" #endif // __REVISION_NR_H__