From 250dee5be948e96bac656cb72e580026d39105cd Mon Sep 17 00:00:00 2001 From: Meltie2013 Date: Fri, 29 Oct 2021 08:32:19 -0500 Subject: [PATCH] feat(Core): implement world availability option (#8755) --- src/server/game/Handlers/CharacterHandler.cpp | 20 ++++++++++++------- src/server/game/World/IWorld.h | 1 + src/server/game/World/World.cpp | 3 +++ src/server/shared/SharedDefines.h | 13 ++++++++++++ src/server/worldserver/worldserver.conf.dist | 9 +++++++++ 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 1c9308d3e..2807097d5 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -665,17 +665,23 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) { - if (PlayerLoading() || GetPlayer() != nullptr) - { - LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId()); - KickPlayer("WorldSession::HandlePlayerLoginOpcode Another client logging in"); - return; - } - m_playerLoading = true; ObjectGuid playerGuid; recvData >> playerGuid; + if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer()) + { + // limit player interaction with the world + if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED)) + { + WorldPacket data(SMSG_CHARACTER_LOGIN_FAILED, 1); + // see LoginFailureReason enum for more reasons + data << uint8(LoginFailureReason::NoWorld); + SendPacket(&data); + return; + } + } + if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid)) { LOG_ERROR("network", "Account (%u) can't login with that character (%s).", GetAccountId(), playerGuid.ToString().c_str()); diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index fc080d96e..b404541e6 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -170,6 +170,7 @@ enum WorldBoolConfigs CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID, CONFIG_SET_BOP_ITEM_TRADEABLE, CONFIG_ALLOW_LOGGING_IP_ADDRESSES_IN_DATABASE, + CONFIG_REALM_LOGIN_ENABLED, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d776ed3f1..884620d85 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1436,6 +1436,9 @@ void World::LoadConfigSettings(bool reload) LOG_ERROR("server.loading", "LFG.KickPreventionTimer can't be higher than 15 minutes."); } + // Realm Availability + m_bool_configs[CONFIG_REALM_LOGIN_ENABLED] = sConfigMgr->GetOption("World.RealmAvailability", false); + // call ScriptMgr if we're reloading the configuration sScriptMgr->OnAfterConfigLoad(reload); } diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 521416fa4..9a2e019d1 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3597,6 +3597,19 @@ enum ServerProcessTypes NUM_SERVER_PROCESS_TYPES }; +// Login Failure Reasons +enum class LoginFailureReason : uint8 +{ + Failed = 0, + NoWorld = 1, + DuplicateCharacter = 2, + NoInstances = 3, + Disabled = 4, + NoCharacter = 5, + LockedForTransfer = 6, + LockedByBilling = 7 +}; + namespace Acore::Impl { struct AC_SHARED_API CurrentServerProcessHolder diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 7a524d420..b335ce738 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3587,6 +3587,15 @@ LFG.MaxKickCount = 2 LFG.KickPreventionTimer = 900 +# +# World.RealmAvailability +# Description: If enabled, players will enter the realm normally. +# Character creation will still be possible even when realm is disabled. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +World.RealmAvailability = 1 + # ###################################################################################################