diff --git a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.cpp b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.cpp index 5bbd291c3..91a2d4e8c 100644 --- a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.cpp +++ b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.cpp @@ -78,6 +78,7 @@ namespace CuiLoginManagerNamespace bool s_canCreateRegularCharacter = false; bool s_canCreateJedi = false; bool s_canSkipTutorial = false; + bool s_isAdmin = false; UdpSock * pingSocket = 0; @@ -440,7 +441,9 @@ void CuiLoginManager::receiveLoginClusterStatus (const LoginClusterStatus & lcs) info.isFull = data.m_status == LoginClusterStatusData::S_full; info.onlinePlayerLimit = data.m_onlinePlayerLimit; info.onlineFreeTrialLimit = data.m_onlineFreeTrialLimit; - info.notRecommended = data.m_dontRecommend; + info.notRecommended = data.m_dontRecommend; + info.isAdmin = data.m_isAdmin; + info.isSecret = data.m_isSecret; #if PRODUCTION == 0 std::map::const_iterator iterFind = s_clusterOverrideHostInfo.find(data.m_clusterId); @@ -504,6 +507,8 @@ void CuiLoginManager::receiveLoginClusterStatus (const LoginClusterStatus & lcs) info.up = false; info.loading = false; info.locked = false; + info.isAdmin = false; + info.isSecret = false; info.restricted = false; info.isFull = false; info.onlinePlayerLimit = 0; @@ -589,6 +594,7 @@ void CuiLoginManager::receiveClientPermissionsMessage (const ClientPermissionsMe s_canCreateRegularCharacter = cpm.getCanCreateRegularCharacter(); s_canCreateJedi = cpm.getCanCreateJediCharacter(); s_canSkipTutorial = cpm.getCanSkipTutorial(); + s_isAdmin = cpm.getIsAdmin(); Transceivers::clusterConnection.emitMessage (cpm.getCanLogin ()); if (!cpm.getCanLogin ()) @@ -956,6 +962,13 @@ bool CuiLoginManager::canSkipTutorial() //---------------------------------------------------------------------- +bool CuiLoginManager::isAdmin() +{ + return s_isAdmin; +} + +//---------------------------------------------------------------------- + bool CuiLoginManager::hasUnoccupiedJediSlot() { return (s_stationIdNumberJediSlot > s_stationIdNumberJediSlotCharacter); diff --git a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.h b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.h index d16058214..88639647b 100644 --- a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.h +++ b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManager.h @@ -72,6 +72,7 @@ public: static bool canCreateRegularCharacter (); static bool canCreateJedi (); static bool canSkipTutorial (); + static bool isAdmin (); static bool hasUnoccupiedJediSlot (); static void characterChangedUnlocked (const std::string & clusterName, const NetworkId & id); static void characterChangedNormal (const std::string & clusterName, const NetworkId & id); diff --git a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManagerClusterInfo.h b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManagerClusterInfo.h index 9cc36bab5..89c5b0b7b 100644 --- a/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManagerClusterInfo.h +++ b/src/engine/client/library/clientUserInterface/src/shared/core/CuiLoginManagerClusterInfo.h @@ -43,6 +43,8 @@ public: std::string branch; uint32 version; bool netVersionMatch; + bool isAdmin; // see LoginClusterStatus.h + bool isSecret; // see LoginClusterStatus.h Ping & getPing (); const Ping & getPing () const; diff --git a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.cpp b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.cpp index 8e3c0aea3..7d4652f5a 100644 --- a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.cpp +++ b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.cpp @@ -10,17 +10,19 @@ // ====================================================================== -ClientPermissionsMessage::ClientPermissionsMessage(bool canLogin, bool canCreateRegularCharacter, bool canCreateJediCharacter, bool canSkipTutorial) : +ClientPermissionsMessage::ClientPermissionsMessage(bool canLogin, bool canCreateRegularCharacter, bool canCreateJediCharacter, bool canSkipTutorial, bool isAdmin) : GameNetworkMessage("ClientPermissionsMessage"), m_canLogin(canLogin), m_canCreateRegularCharacter(canCreateRegularCharacter), m_canCreateJediCharacter(canCreateJediCharacter), - m_canSkipTutorial(canSkipTutorial) + m_canSkipTutorial(canSkipTutorial), + m_isAdmin(isAdmin) { addVariable(m_canLogin); addVariable(m_canCreateRegularCharacter); addVariable(m_canCreateJediCharacter); addVariable(m_canSkipTutorial); + addVariable(m_isAdmin); } //----------------------------------------------------------------------- @@ -30,12 +32,14 @@ ClientPermissionsMessage::ClientPermissionsMessage(Archive::ReadIterator & sourc m_canLogin(), m_canCreateRegularCharacter(), m_canCreateJediCharacter(), - m_canSkipTutorial() + m_canSkipTutorial(), + m_isAdmin() { addVariable(m_canLogin); addVariable(m_canCreateRegularCharacter); addVariable(m_canCreateJediCharacter); addVariable(m_canSkipTutorial); + addVariable(m_isAdmin); unpack(source); } diff --git a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.h b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.h index fb6f70437..76c6b127f 100644 --- a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.h +++ b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/ClientPermissionsMessage.h @@ -24,7 +24,7 @@ class ClientPermissionsMessage : public GameNetworkMessage { public: - ClientPermissionsMessage(bool canLogin, bool canCreateRegularCharacter, bool canCreateJediCharacter, bool canSkipTutorial); + ClientPermissionsMessage(bool canLogin, bool canCreateRegularCharacter, bool canCreateJediCharacter, bool canSkipTutorial, bool isAdmin); explicit ClientPermissionsMessage(Archive::ReadIterator & source); virtual ~ClientPermissionsMessage(); @@ -33,12 +33,14 @@ class ClientPermissionsMessage : public GameNetworkMessage bool getCanCreateRegularCharacter() const; bool getCanCreateJediCharacter() const; bool getCanSkipTutorial() const; + bool getIsAdmin() const; private: Archive::AutoVariable m_canLogin; Archive::AutoVariable m_canCreateRegularCharacter; Archive::AutoVariable m_canCreateJediCharacter; Archive::AutoVariable m_canSkipTutorial; + Archive::AutoVariable m_isAdmin; ClientPermissionsMessage(); ClientPermissionsMessage(const ClientPermissionsMessage&); @@ -73,6 +75,13 @@ inline bool ClientPermissionsMessage::getCanSkipTutorial() const return m_canSkipTutorial.get(); } +// ---------------------------------------------------------------------- + +inline bool ClientPermissionsMessage::getIsAdmin() const +{ + return m_isAdmin.get(); +} + // ====================================================================== #endif // _INCLUDED_ClientCentralMessages_H diff --git a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientLoginServer/LoginClusterStatus.h b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientLoginServer/LoginClusterStatus.h index 6c0741320..fe9e255a3 100644 --- a/src/engine/shared/library/sharedNetworkMessages/src/shared/clientLoginServer/LoginClusterStatus.h +++ b/src/engine/shared/library/sharedNetworkMessages/src/shared/clientLoginServer/LoginClusterStatus.h @@ -31,6 +31,17 @@ struct LoginClusterStatus_ClusterData bool m_dontRecommend; uint32 m_onlinePlayerLimit; uint32 m_onlineFreeTrialLimit; + + // This flag tells the client that the account which requested the cluster information + // is considered an admin by the server (in Admin Account Table). This enables connection + // to locked clusters and viewing secret clusters. We don't need to worry about this flag + // being manipulated because the Connection Server verifies admin permissions after the fact. + // This flag merely unblocks client-side user interface elements for locked/secret clusters. + // We also send this flag in the ClientPermissionsMessage header for character creation. + bool m_isAdmin; + // Flag so we can append (Secret) in Client (for admins) + bool m_isSecret; + }; /** @@ -85,6 +96,8 @@ namespace Archive get(source,c.m_dontRecommend); get(source,c.m_onlinePlayerLimit); get(source,c.m_onlineFreeTrialLimit); + get(source,c.m_isAdmin); + get(source,c.m_isSecret); } inline void put(ByteStream & target, const LoginClusterStatus_ClusterData &c) @@ -101,6 +114,8 @@ namespace Archive put(target,c.m_dontRecommend); put(target,c.m_onlinePlayerLimit); put(target,c.m_onlineFreeTrialLimit); + put(target,c.m_isAdmin); + put(target,c.m_isSecret); } } diff --git a/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiAvatarSelection.cpp b/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiAvatarSelection.cpp index 40e882bc2..a4f6838ef 100644 --- a/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiAvatarSelection.cpp +++ b/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiAvatarSelection.cpp @@ -503,7 +503,17 @@ void SwgCuiAvatarSelection::addAvatar (const CuiLoginManagerAvatarInfo & avatarI if (clusterInfo->loading) statusDisplayStr = CuiStringIdsServer::server_loading.localize (); else if (clusterInfo->locked) - statusDisplayStr = CuiStringIdsServer::server_locked.localize (); + { + if(clusterInfo->isAdmin) + { + Unicode::String lockedFlag = L"\\#00ff00 (God Mode)"; + statusDisplayStr = CuiStringIdsServer::server_locked.localize() + lockedFlag; + } + else + { + statusDisplayStr = CuiStringIdsServer::server_locked.localize(); + } + } else if (clusterInfo->restricted) statusDisplayStr = CuiStringIdsServer::server_restricted.localize (); else if (clusterInfo->isFull) @@ -513,10 +523,14 @@ void SwgCuiAvatarSelection::addAvatar (const CuiLoginManagerAvatarInfo & avatarI } else statusDisplayStr = CuiStringIdsServer::server_offline.localize (); + if(clusterInfo->isAdmin && clusterInfo->isSecret) + { + Unicode::String secretFlag = L"\\#ff00ff (Secret)"; + statusDisplayStr += secretFlag; + } } -#if PRODUCTION != 1 - if (clusterInfo && !clusterInfo->branch.empty()) + if (clusterInfo && !clusterInfo->branch.empty() && clusterInfo->isAdmin) { static const Unicode::String::value_type *s_colorRed = L"\\#ff0000"; static const Unicode::String::value_type *s_colorGreen = L"\\#00ff00"; @@ -555,7 +569,6 @@ void SwgCuiAvatarSelection::addAvatar (const CuiLoginManagerAvatarInfo & avatarI planetDisplayName = color + planetDisplayName; statusDisplayStr = color + statusDisplayStr; } -#endif UIData * const d = model->AppendCell (0, narrowName.c_str (), avatarDisplayName); d->SetPropertyNarrow (Properties::AvatarNetworkId, avatarInfo.networkId.getValueString ()); @@ -1227,7 +1240,7 @@ bool SwgCuiAvatarSelection::getCurrentlySelectedAvatar (bool checkCluster) CuiMessageBox::createInfoBox (CuiStringIdsServer::server_connection_loading.localize ()); return false; } - else if (clusterInfo->locked) + else if (clusterInfo->locked && !clusterInfo->isAdmin) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_connection_locked.localize ()); return false; @@ -1242,7 +1255,7 @@ bool SwgCuiAvatarSelection::getCurrentlySelectedAvatar (bool checkCluster) return false; } */ - else if (clusterInfo->isFull && !ConfigClientGame::getAllowConnectWhenFull() && !autoConnectOk()) + else if (clusterInfo->isFull && !clusterInfo->isAdmin && !autoConnectOk()) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_cluster_full.localize ()); return false; diff --git a/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiClusterSelection.cpp b/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiClusterSelection.cpp index 129b25c8a..4dacd1e34 100644 --- a/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiClusterSelection.cpp +++ b/src/game/client/library/swgClientUserInterface/src/shared/page/SwgCuiClusterSelection.cpp @@ -375,9 +375,9 @@ void SwgCuiClusterSelection::refreshList () const std::string clientBranch(Branch().getBranchName()); - for (CuiLoginManager::ClusterInfoVector::const_iterator it = civ.begin (); it != civ.end (); ++it) + for (CuiLoginManager::ClusterInfoVector::const_iterator it = civ.begin(); it != civ.end(); ++it) { - const CuiLoginManagerClusterInfo & clusterInfo = *it; + const CuiLoginManagerClusterInfo& clusterInfo = *it; #if PRODUCTION == 1 if (clusterInfo.disableCharacterCreation) @@ -386,8 +386,9 @@ void SwgCuiClusterSelection::refreshList () Unicode::String name(Unicode::narrowToWide(clusterInfo.name)); -#if PRODUCTION != 1 - Unicode::String color = s_colorRed; // red is the default color + if (clusterInfo.isAdmin) + { + Unicode::String color = s_colorRed; // red is the default color if (!clusterInfo.branch.empty()) { @@ -413,9 +414,9 @@ void SwgCuiClusterSelection::refreshList () } char buffer[64]; - name = color + name + L" [" + Unicode::narrowToWide(clusterInfo.branch) + L"." + Unicode::narrowToWide(_itoa(clusterInfo.version, buffer, 10)) + L"]"; + name = color + name + L" [" + Unicode::narrowToWide(clusterInfo.branch) + L"." + Unicode::narrowToWide(_itoa(clusterInfo.version, buffer, 10)) + L"]"; } -#endif + } UIData * const dataCells [C_numColumns] = { @@ -500,7 +501,15 @@ void SwgCuiClusterSelection::updateServerStatus () } else if (clusterInfo.locked) { - statusStr = CuiStringIdsServer::server_locked.localize (); + if (clusterInfo.isAdmin) + { + Unicode::String lockedFlag = L"\\#00ff00 (God Mode)"; + statusStr = CuiStringIdsServer::server_locked.localize() + lockedFlag; + } + else + { + statusStr = CuiStringIdsServer::server_locked.localize(); + } statusSortStr.push_back ('3'); } else if (clusterInfo.isFull) @@ -527,6 +536,11 @@ void SwgCuiClusterSelection::updateServerStatus () statusStr = CuiStringIdsServer::server_offline.localize (); statusSortStr.push_back ('6'); } + if(clusterInfo.isAdmin && clusterInfo.isSecret) + { + Unicode::String secretFlag = L"\\#ff00ff (Secret)"; + statusStr += secretFlag; + } m_model->SetValueAtText (visualRow, C_online, statusStr); m_model->SetSortKeyAtString (visualRow, C_online, statusSortStr); @@ -727,15 +741,15 @@ void SwgCuiClusterSelection::OnButtonPressed(UIWidget *context) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_connection_loading.localize ()); } - else if (clusterInfo->locked) + else if (clusterInfo->locked && !clusterInfo->isAdmin) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_connection_locked.localize ()); } - else if (clusterInfo->restricted) + else if (clusterInfo->restricted && !clusterInfo->isAdmin) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_connection_restricted.localize ()); } - else if (clusterInfo->isFull && !ConfigClientGame::getAllowConnectWhenFull()) + else if (clusterInfo->isFull && !clusterInfo->isAdmin) { CuiMessageBox::createInfoBox (CuiStringIdsServer::server_cluster_full.localize ()); }