Core/Misc: fixed a scenario when character factionchange create unexpected results, also moved packet generating code into unique methods

(Packet structure not verificated to 6.0.2)
This commit is contained in:
joschiwald
2014-10-19 16:18:54 +02:00
parent 5b08387792
commit 53725517a0
12 changed files with 432 additions and 426 deletions
+16 -5
View File
@@ -474,12 +474,23 @@ struct MovementInfo
class WorldLocation : public Position
{
public:
explicit WorldLocation(uint32 _mapid = MAPID_INVALID, float _x = 0, float _y = 0, float _z = 0, float _o = 0)
: m_mapId(_mapid) { Relocate(_x, _y, _z, _o); }
WorldLocation(const WorldLocation &loc) : Position(loc) { WorldRelocate(loc); }
explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f)
: Position(_x, _y, _z, _o), m_mapId(_mapId) { }
void WorldRelocate(const WorldLocation &loc)
{ m_mapId = loc.GetMapId(); Relocate(loc); }
WorldLocation(WorldLocation const& loc)
: Position(loc), m_mapId(loc.GetMapId()) { }
void WorldRelocate(WorldLocation const& loc)
{
m_mapId = loc.GetMapId();
Relocate(loc);
}
void WorldRelocate(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f)
{
m_mapId = _mapId;
Relocate(_x, _y, _z, _o);
}
WorldLocation GetWorldLocation() const
{
+15 -15
View File
@@ -20468,19 +20468,19 @@ void Player::SendAttackSwingNotInRange()
GetSession()->SendPacket(&data);
}
void Player::SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid)
void Player::SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_POSITION);
stmt->setFloat(0, x);
stmt->setFloat(1, y);
stmt->setFloat(2, z);
stmt->setFloat(3, o);
stmt->setUInt16(4, uint16(mapid));
stmt->setUInt16(5, uint16(zone));
stmt->setFloat(0, loc.GetPositionX());
stmt->setFloat(1, loc.GetPositionY());
stmt->setFloat(2, loc.GetPositionZ());
stmt->setFloat(3, loc.GetOrientation());
stmt->setUInt16(4, uint16(loc.GetMapId()));
stmt->setUInt16(5, zoneId);
stmt->setUInt32(6, guid.GetCounter());
CharacterDatabase.Execute(stmt);
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 value)
@@ -20494,10 +20494,10 @@ void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 va
Tokenizer[index] = buf;
}
void Player::Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
void Player::Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2);
stmt->setUInt32(0, guid.GetCounter());
stmt->setUInt32(0, customizeInfo->Guid.GetCounter());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
@@ -20507,16 +20507,16 @@ void Player::Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, ui
uint32 playerBytes2 = fields[0].GetUInt32();
playerBytes2 &= ~0xFF;
playerBytes2 |= facialHair;
playerBytes2 |= customizeInfo->FacialHair;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES);
stmt->setUInt8(0, gender);
stmt->setUInt32(1, skin | (face << 8) | (hairStyle << 16) | (hairColor << 24));
stmt->setUInt8(0, customizeInfo->Gender);
stmt->setUInt32(1, customizeInfo->Skin | (customizeInfo->Face << 8) | (customizeInfo->HairStyle << 16) | (customizeInfo->HairColor << 24));
stmt->setUInt32(2, playerBytes2);
stmt->setUInt32(3, guid.GetCounter());
stmt->setUInt32(3, customizeInfo->Guid.GetCounter());
CharacterDatabase.Execute(stmt);
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
void Player::SendAttackSwingDeadTarget()
+5 -3
View File
@@ -56,6 +56,8 @@ class PlayerSocial;
class SpellCastTargets;
class UpdateMask;
struct CharacterCustomizeInfo;
typedef std::deque<Mail*> PlayerMails;
#define PLAYER_MAX_SKILLS 128
@@ -1694,8 +1696,8 @@ class Player : public Unit, public GridObject<Player>
static void SetUInt32ValueInArray(Tokenizer& data, uint16 index, uint32 value);
static void SetFloatValueInArray(Tokenizer& data, uint16 index, float value);
static void Customize(ObjectGuid guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid);
static void Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans);
static void SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans);
static void DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRealmChars = true, bool deleteFinally = false);
static void DeleteOldCharacters();
@@ -1936,7 +1938,7 @@ class Player : public Unit, public GridObject<Player>
void SetContestedPvPTimer(uint32 newTime) {m_contestedPvPTimer = newTime;}
void ResetContestedPvP();
/** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/
/// @todo: maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler
DuelInfo* duel;
void UpdateDuelFlag(time_t currTime);
void CheckDuelDistance(time_t currTime);
+9 -12
View File
@@ -1662,7 +1662,7 @@ void ObjectMgr::LoadCreatures()
spawnMasks[i] |= (1 << k);
_creatureDataStore.rehash(result->GetRowCount());
uint32 count = 0;
do
{
Field* fields = result->Fetch();
@@ -1800,12 +1800,10 @@ void ObjectMgr::LoadCreatures()
// Add to grid if not managed by the game event or pool system
if (gameEvent == 0 && PoolId == 0)
AddCreatureToGrid(guid, &data);
}
while (result->NextRow());
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u creatures in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " creatures in %u ms", _creatureDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::AddCreatureToGrid(uint32 guid, CreatureData const* data)
@@ -1976,8 +1974,6 @@ void ObjectMgr::LoadGameobjects()
{
uint32 oldMSTime = getMSTime();
uint32 count = 0;
// 0 1 2 3 4 5 6
QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
// 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -2000,6 +1996,7 @@ void ObjectMgr::LoadGameobjects()
spawnMasks[i] |= (1 << k);
_gameObjectDataStore.rehash(result->GetRowCount());
do
{
Field* fields = result->Fetch();
@@ -2137,10 +2134,10 @@ void ObjectMgr::LoadGameobjects()
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
AddGameobjectToGrid(guid, &data);
++count;
} while (result->NextRow());
}
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %lu gameobjects in %u ms", (unsigned long)_gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " gameobjects in %u ms", _gameObjectDataStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::AddGameobjectToGrid(uint32 guid, GameObjectData const* data)
@@ -7688,7 +7685,7 @@ bool isValidString(const std::wstring& wstr, uint32 strictMask, bool numericOrSp
return false;
}
uint8 ObjectMgr::CheckPlayerName(const std::string& name, bool create)
ResponseCodes ObjectMgr::CheckPlayerName(const std::string& name, bool create)
{
std::wstring wname;
if (!Utf8toWStr(name, wname))
+1 -1
View File
@@ -1234,7 +1234,7 @@ class ObjectMgr
bool IsReservedName(std::string const& name) const;
// name with valid structure and symbols
static uint8 CheckPlayerName(std::string const& name, bool create = false);
static ResponseCodes CheckPlayerName(std::string const& name, bool create = false);
static PetNameInvalidReason CheckPetName(std::string const& name);
static bool IsValidCharterName(std::string const& name);
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -581,7 +581,7 @@ void WorldSession::LogoutPlayer(bool save)
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
_player->CleanupsBeforeDelete();
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d",
GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel());
sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false);
@@ -1077,10 +1077,11 @@ void WorldSession::ProcessQueryCallbacks()
//- HandleCharRenameOpcode
if (_charRenameCallback.IsReady())
{
std::string param = _charRenameCallback.GetParam();
_charRenameCallback.GetResult(result);
HandleChangePlayerNameOpcodeCallBack(result, param);
_charRenameCallback.FreeResult();
CharacterRenameInfo* renameInfo = _charRenameCallback.GetParam();
HandleChangePlayerNameOpcodeCallBack(result, renameInfo);
delete renameInfo;
_charRenameCallback.Reset();
}
//- HandleCharAddIgnoreOpcode
+68 -21
View File
@@ -100,10 +100,18 @@ struct AccountData
enum PartyOperation
{
PARTY_OP_INVITE = 0,
PARTY_OP_INVITE = 0,
PARTY_OP_UNINVITE = 1,
PARTY_OP_LEAVE = 2,
PARTY_OP_SWAP = 4
PARTY_OP_LEAVE = 2,
PARTY_OP_SWAP = 4
};
enum BarberShopResult
{
BARBER_SHOP_RESULT_SUCCESS = 0,
BARBER_SHOP_RESULT_NO_MONEY = 1,
BARBER_SHOP_RESULT_NOT_ON_CHAIR = 2,
BARBER_SHOP_RESULT_NO_MONEY_2 = 3
};
enum BFLeaveReason
@@ -131,6 +139,12 @@ enum CharterTypes
ARENA_TEAM_CHARTER_5v5_TYPE = 5,
};
enum DeclinedNameResult
{
DECLINED_NAMES_RESULT_SUCCESS = 0,
DECLINED_NAMES_RESULT_ERROR = 1
};
#define DB2_REPLY_SPARSE 2442913102
#define DB2_REPLY_ITEM 1344507586
@@ -183,26 +197,52 @@ class CharacterCreateInfo
friend class Player;
protected:
CharacterCreateInfo(std::string const& name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId,
WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair),
OutfitId(outfitId), Data(std::move(data)), CharCount(0)
{ }
/// User specified variables
std::string Name;
uint8 Race;
uint8 Class;
uint8 Gender;
uint8 Skin;
uint8 Face;
uint8 HairStyle;
uint8 HairColor;
uint8 FacialHair;
uint8 OutfitId;
WorldPacket Data;
uint8 Race = 0;
uint8 Class = 0;
uint8 Gender = GENDER_NONE;
uint8 Skin = 0;
uint8 Face = 0;
uint8 HairStyle = 0;
uint8 HairColor = 0;
uint8 FacialHair = 0;
uint8 OutfitId = 0;
/// Server side data
uint8 CharCount;
uint8 CharCount = 0;
};
struct CharacterRenameInfo
{
friend class WorldSession;
protected:
ObjectGuid Guid;
std::string Name;
};
struct CharacterCustomizeInfo : public CharacterRenameInfo
{
friend class Player;
friend class WorldSession;
protected:
uint8 Gender = GENDER_NONE;
uint8 Skin = 0;
uint8 Face = 0;
uint8 HairStyle = 0;
uint8 HairColor = 0;
uint8 FacialHair = 0;
};
struct CharacterFactionChangeInfo : public CharacterCustomizeInfo
{
friend class Player;
friend class WorldSession;
protected:
uint8 Race = 0;
};
struct PacketCounter
@@ -420,6 +460,13 @@ class WorldSession
void HandleRandomizeCharNameOpcode(WorldPacket& recvData);
void HandleReorderCharacters(WorldPacket& recvData);
void HandleOpeningCinematic(WorldPacket& recvData);
void SendCharCreate(ResponseCodes result);
void SendCharDelete(ResponseCodes result);
void SendCharRename(ResponseCodes result, CharacterRenameInfo const& renameInfo);
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const& customizeInfo);
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const& factionChangeInfo);
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid);
void SendBarberShopResult(BarberShopResult result);
// played time
void HandlePlayedTime(WorldPacket& recvPacket);
@@ -789,7 +836,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recvData);
void HandleCharRenameOpcode(WorldPacket& recvData);
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string const& newName);
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, CharacterRenameInfo const* renameInfo);
void HandleSetPlayerDeclinedNames(WorldPacket& recvData);
void HandleTotemDestroyed(WorldPacket& recvData);
@@ -990,7 +1037,7 @@ class WorldSession
PreparedQueryResultFuture _charEnumCallback;
PreparedQueryResultFuture _addIgnoreCallback;
PreparedQueryResultFuture _stablePetCallback;
QueryCallback<PreparedQueryResult, std::string> _charRenameCallback;
QueryCallback<PreparedQueryResult, CharacterRenameInfo*> _charRenameCallback;
QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
+1 -1
View File
@@ -132,7 +132,7 @@ public:
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
if (handler->GetSession())
{
TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s (Email: '%s')",
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) created Account %s (Email: '%s')",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(),
accountName, email.c_str());
@@ -87,7 +87,7 @@ public:
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
if (handler->GetSession())
{
TC_LOG_INFO("entities.player.character", "Battle.net account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s",
TC_LOG_INFO("entities.player.character", "Battle.net account: %u (IP: %s) Character:[%s] (GUID: %u) created Account %s",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(),
accountName);
+4 -3
View File
@@ -511,13 +511,14 @@ public:
handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE));
// in point where GM stay
Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(),
SQLTransaction dummy;
Player::SavePositionInDB(WorldLocation(handler->GetSession()->GetPlayer()->GetMapId(),
handler->GetSession()->GetPlayer()->GetPositionX(),
handler->GetSession()->GetPlayer()->GetPositionY(),
handler->GetSession()->GetPlayer()->GetPositionZ(),
handler->GetSession()->GetPlayer()->GetOrientation(),
handler->GetSession()->GetPlayer()->GetOrientation()),
handler->GetSession()->GetPlayer()->GetZoneId(),
targetGuid);
targetGuid, dummy);
}
return true;
+7 -7
View File
@@ -141,13 +141,11 @@ public:
if (resultDB)
{
Field* fieldsDB = resultDB->Fetch();
uint32 mapId = fieldsDB[0].GetUInt16();
WorldLocation loc(fieldsDB[0].GetUInt16(), fieldsDB[2].GetFloat(), fieldsDB[3].GetFloat(), fieldsDB[4].GetFloat(), 0.0f);
uint32 zoneId = fieldsDB[1].GetUInt16();
float posX = fieldsDB[2].GetFloat();
float posY = fieldsDB[3].GetFloat();
float posZ = fieldsDB[4].GetFloat();
Player::SavePositionInDB(mapId, posX, posY, posZ, 0, zoneId, target_guid);
SQLTransaction dummy;
Player::SavePositionInDB(loc, zoneId, target_guid, dummy);
}
}
@@ -203,8 +201,10 @@ public:
std::string nameLink = handler->playerLink(target_name);
handler->PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE), tele->name.c_str());
Player::SavePositionInDB(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation,
sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid);
SQLTransaction dummy;
Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation),
sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy);
}
return true;