mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 17:54:48 +01:00
Core/RBAC: Create new permissions related to character creation
- 'Skips character creation team mask check' - 'Skips character creation class mask check' - 'Skips character creation race mask check' - 'Skips character creation reserved name check' - 'Skips character creation heroic min level check' - 'Creation of two side faction characters in same account' (Affected by global config option)
This commit is contained in:
@@ -274,7 +274,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
|
||||
WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK))
|
||||
{
|
||||
if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
|
||||
{
|
||||
@@ -283,13 +283,17 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
uint32 team = Player::TeamForRace(race_);
|
||||
switch (team)
|
||||
{
|
||||
case ALLIANCE: disabled = mask & (1 << 0); break;
|
||||
case HORDE: disabled = mask & (1 << 1); break;
|
||||
case ALLIANCE:
|
||||
disabled = mask & (1 << 0);
|
||||
break;
|
||||
case HORDE:
|
||||
disabled = mask & (1 << 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_DISABLED;
|
||||
data << uint8(CHAR_CREATE_DISABLED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
@@ -299,7 +303,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
|
||||
if (!classEntry)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_FAILED;
|
||||
data << uint8(CHAR_CREATE_FAILED);
|
||||
SendPacket(&data);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Class (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", class_, GetAccountId());
|
||||
return;
|
||||
@@ -308,7 +312,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_);
|
||||
if (!raceEntry)
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_FAILED;
|
||||
data << uint8(CHAR_CREATE_FAILED);
|
||||
SendPacket(&data);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Race (%u) not found in DBC while creating new char for account (ID: %u): wrong DBC files or cheater?", race_, GetAccountId());
|
||||
return;
|
||||
@@ -317,7 +321,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
// prevent character creating Expansion race without Expansion account
|
||||
if (raceEntry->expansion > Expansion())
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_EXPANSION;
|
||||
data << uint8(CHAR_CREATE_EXPANSION);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
@@ -326,13 +330,13 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
// prevent character creating Expansion class without Expansion account
|
||||
if (classEntry->expansion > Expansion())
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_EXPANSION_CLASS;
|
||||
data << uint8(CHAR_CREATE_EXPANSION_CLASS);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
|
||||
{
|
||||
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
|
||||
if ((1 << (race_ - 1)) & raceMaskDisabled)
|
||||
@@ -341,7 +345,10 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK))
|
||||
{
|
||||
uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
|
||||
if ((1 << (class_ - 1)) & classMaskDisabled)
|
||||
{
|
||||
@@ -354,7 +361,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
// prevent character creating with invalid name
|
||||
if (!normalizePlayerName(name))
|
||||
{
|
||||
data << (uint8)CHAR_NAME_NO_NAME;
|
||||
data << uint8(CHAR_NAME_NO_NAME);
|
||||
SendPacket(&data);
|
||||
sLog->outError(LOG_FILTER_NETWORKIO, "Account:[%d] but tried to Create character with empty [name] ", GetAccountId());
|
||||
return;
|
||||
@@ -369,29 +376,32 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(name))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(name))
|
||||
{
|
||||
data << (uint8)CHAR_NAME_RESERVED;
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
|
||||
if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT)
|
||||
if (class_ == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER))
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT;
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
|
||||
if (heroic_free_slots == 0)
|
||||
{
|
||||
data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT;
|
||||
SendPacket(&data);
|
||||
return;
|
||||
// speedup check for heroic class disabled case
|
||||
uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
|
||||
if (req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
|
||||
SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0
|
||||
@@ -482,7 +492,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
}
|
||||
}
|
||||
|
||||
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
|
||||
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
|
||||
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
||||
|
||||
_charCreateCallback.FreeResult();
|
||||
@@ -506,8 +516,9 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
bool haveSameRace = false;
|
||||
uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
|
||||
bool hasHeroicReqLevel = (heroicReqLevel == 0);
|
||||
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
|
||||
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || HasPermission(RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
|
||||
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
||||
bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER);
|
||||
|
||||
if (result)
|
||||
{
|
||||
@@ -517,7 +528,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
Field* field = result->Fetch();
|
||||
uint8 accRace = field[1].GetUInt8();
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
|
||||
if (checkHeroicReqs)
|
||||
{
|
||||
uint8 accClass = field[2].GetUInt8();
|
||||
if (accClass == CLASS_DEATH_KNIGHT)
|
||||
@@ -576,7 +587,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
if (!haveSameRace)
|
||||
haveSameRace = createInfo->Race == accRace;
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
|
||||
if (checkHeroicReqs)
|
||||
{
|
||||
uint8 acc_class = field[2].GetUInt8();
|
||||
if (acc_class == CLASS_DEATH_KNIGHT)
|
||||
@@ -605,7 +616,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
|
||||
}
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && !hasHeroicReqLevel)
|
||||
if (checkHeroicReqs && !hasHeroicReqLevel)
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CREATE, 1);
|
||||
data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
|
||||
@@ -1122,7 +1133,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
// check name limitations
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_RENAME, 1);
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
@@ -1444,7 +1455,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
// check name limitations
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1);
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
@@ -1690,7 +1701,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RACEMASK))
|
||||
{
|
||||
uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
|
||||
if ((1 << (race - 1)) & raceMaskDisabled)
|
||||
@@ -1721,7 +1732,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
// check name limitations
|
||||
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname))
|
||||
if (!HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newname))
|
||||
{
|
||||
WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1);
|
||||
data << uint8(CHAR_NAME_RESERVED);
|
||||
|
||||
Reference in New Issue
Block a user