Fix gender exploit.
Now check that character has a valid gender (and not an invalid via packet modifications). This check works when trying to create a character or when building the character list. If gender is invalid (neither male nor female): can't create the character and can't see in the characters' list (and also can't login with it via packet modding). Signed-off-by: Anubisss <[email protected]>
This commit is contained in:
@@ -895,6 +895,9 @@ void Player::CleanupsBeforeDelete(bool finalCleanup)
|
||||
bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 /*outfitId*/)
|
||||
{
|
||||
//FIXME: outfitId not used in player creating
|
||||
// TODO: need more checks against packet modifications
|
||||
// should check that skin, face, hair* are valid via DBC per race/class
|
||||
// also do it in Player::BuildEnumData, Player::LoadFromDB
|
||||
|
||||
Object::_Create(guidlow, 0, HIGHGUID_PLAYER);
|
||||
|
||||
@@ -928,6 +931,12 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c
|
||||
|
||||
setFactionForRace(race);
|
||||
|
||||
if (!IsValidGender(gender))
|
||||
{
|
||||
sLog->outError("Player has invalid gender (%hu), can't be loaded.", gender);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 RaceClassGender = (race) | (class_ << 8) | (gender << 16);
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
|
||||
@@ -1842,6 +1851,7 @@ bool Player::BuildEnumData(QueryResult result, WorldPacket * p_data)
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
uint8 pRace = fields[2].GetUInt8();
|
||||
uint8 pClass = fields[3].GetUInt8();
|
||||
uint8 Gender = fields[4].GetUInt8();
|
||||
|
||||
PlayerInfo const *info = sObjectMgr->GetPlayerInfo(pRace, pClass);
|
||||
if (!info)
|
||||
@@ -1849,12 +1859,17 @@ bool Player::BuildEnumData(QueryResult result, WorldPacket * p_data)
|
||||
sLog->outError("Player %u has incorrect race/class pair. Don't build enum.", guid);
|
||||
return false;
|
||||
}
|
||||
else if (!IsValidGender(Gender))
|
||||
{
|
||||
sLog->outError("Player (%u) has incorrect gender (%hu), don't build enum.", guid, Gender);
|
||||
return false;
|
||||
}
|
||||
|
||||
*p_data << uint64(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
|
||||
*p_data << fields[1].GetString(); // name
|
||||
*p_data << uint8(pRace); // race
|
||||
*p_data << uint8(pClass); // class
|
||||
*p_data << uint8(fields[4].GetUInt8()); // gender
|
||||
*p_data << uint8(Gender); // gender
|
||||
|
||||
uint32 playerBytes = fields[5].GetUInt32();
|
||||
*p_data << uint8(playerBytes); // skin
|
||||
@@ -16430,11 +16445,18 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
|
||||
// overwrite possible wrong/corrupted guid
|
||||
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
|
||||
|
||||
uint8 Gender = fields[5].GetUInt8();
|
||||
if (!IsValidGender(Gender))
|
||||
{
|
||||
sLog->outError("Player (GUID: %u) has wrong gender (%hu), can't be loaded.", guid, Gender);
|
||||
return false;
|
||||
}
|
||||
|
||||
// overwrite some data fields
|
||||
uint32 bytes0 = 0;
|
||||
bytes0 |= fields[3].GetUInt8(); // race
|
||||
bytes0 |= fields[4].GetUInt8() << 8; // class
|
||||
bytes0 |= fields[5].GetUInt8() << 16; // gender
|
||||
bytes0 |= Gender << 16; // gender
|
||||
SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0);
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
|
||||
|
||||
@@ -1471,6 +1471,8 @@ class Player : public Unit, public GridObject<Player>
|
||||
static uint32 GetLevelFromDB(uint64 guid);
|
||||
static bool LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid);
|
||||
|
||||
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE ; }
|
||||
|
||||
/*********************************************************/
|
||||
/*** SAVE SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
@@ -552,7 +552,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
|
||||
Player * pNewChar = new Player(this);
|
||||
if (!pNewChar->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId))
|
||||
{
|
||||
// Player not create (race/class problem?)
|
||||
// Player not create (race/class/etc problem?)
|
||||
pNewChar->CleanupsBeforeDelete();
|
||||
delete pNewChar;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user