diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 32 | ||||
-rw-r--r-- | src/Bindings/ManualBindings_RankManager.cpp | 318 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 30 | ||||
-rw-r--r-- | src/Entities/Player.h | 13 | ||||
-rw-r--r-- | src/RankManager.cpp | 379 | ||||
-rw-r--r-- | src/RankManager.h | 43 |
6 files changed, 772 insertions, 43 deletions
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 253d57297..c4b12aa84 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2125,6 +2125,37 @@ static int tolua_cPlayer_GetPermissions(lua_State * tolua_S) +static int tolua_cPlayer_GetRestrictions(lua_State * tolua_S) +{ + // Function signature: cPlayer:GetRestrictions() -> {restrictions-array} + + // Check the params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cPlayer") || + !L.CheckParamEnd (2) + ) + { + return 0; + } + + // Get the params: + cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, nullptr); + if (self == nullptr) + { + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + return 0; + } + + // Push the permissions: + L.Push(self->GetRestrictions()); + return 1; +} + + + + + static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) { // Function signature: cPlayer:OpenWindow(Window) @@ -3756,6 +3787,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cPlayer"); tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions); + tolua_function(tolua_S, "GetRestrictions", tolua_cPlayer_GetRestrictions); tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches); tolua_endmodule(tolua_S); diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index fa1b88b6a..c9f187fc6 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -100,6 +100,35 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) +/** Binds cRankManager::AddRestrictionToGroup */ +static int tolua_cRankManager_AddRestrictionToGroup(lua_State * L) +{ + // Function signature: + // cRankManager:AddRestrictionToGroup(Permission, GroupName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Read the params: + AString GroupName, Permission; + S.GetStackValues(2, Permission, GroupName); + + // Add the group to the rank: + S.Push(cRoot::Get()->GetRankManager()->AddRestrictionToGroup(Permission, GroupName)); + return 1; +} + + + + + /** Binds cRankManager::AddRank */ static int tolua_cRankManager_AddRank(lua_State * L) { @@ -204,6 +233,60 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) +/** Binds cRankManager::GetAllPermissions */ +static int tolua_cRankManager_GetAllRestrictions(lua_State * L) +{ + // Function signature: + // cRankManager:GetAllRestrictions() -> arraytable of Permissions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllRestrictions(); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + +/** Binds cRankManager::GetAllPermissionsRestrictions */ +static int tolua_cRankManager_GetAllPermissionsRestrictions(lua_State * L) +{ + // Function signature: + // cRankManager:GetAllPermissionsRestrictions() -> arraytable of Permissions and Restrictions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamEnd(2) + ) + { + return 0; + } + + // Get the permissions: + AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllPermissionsRestrictions(); + + // Push the results: + S.Push(Permissions); + return 1; +} + + + + + /** Binds cRankManager::GetAllPlayerUUIDs */ static int tolua_cRankManager_GetAllPlayerUUIDs(lua_State * L) { @@ -314,6 +397,38 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) +/** Binds cRankManager::GetGroupRestrictions */ +static int tolua_cRankManager_GetGroupRestrictions(lua_State * L) +{ + // Function signature: + // cRankManager:GetGroupRestrictions(GroupName) -> arraytable of restrictions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString GroupName; + S.GetStackValue(2, GroupName); + + // Get the restrictions: + AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetGroupRestrictions(GroupName); + + // Push the results: + S.Push(Restrictions); + return 1; +} + + + + + /** Binds cRankManager::GetPlayerGroups */ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) { @@ -416,6 +531,38 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) +/** Binds cRankManager::GetPlayerRestrictions */ +static int tolua_cRankManager_GetPlayerRestrictions(lua_State * L) +{ + // Function signature: + // cRankManager:GetPlayerRestrictions(PlayerUUID) -> arraytable of restrictions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString PlayerUUID; + S.GetStackValue(2, PlayerUUID); + + // Get the permissions: + AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetPlayerRestrictions(PlayerUUID); + + // Push the results: + S.Push(Restrictions); + return 1; +} + + + + + /** Binds cRankManager::GetPlayerRankName */ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) { @@ -544,6 +691,38 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) +/** Binds cRankManager::GetRankRestrictions */ +static int tolua_cRankManager_GetRankRestrictions(lua_State * L) +{ + // Function signature: + // cRankManager:GetRankRestrictions(RankName) -> arraytable of restrictions + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2) || + !S.CheckParamEnd(3) + ) + { + return 0; + } + + // Get the params: + AString RankName; + S.GetStackValue(2, RankName); + + // Get the permissions: + AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetRankRestrictions(RankName); + + // Push the results: + S.Push(Restrictions); + return 1; +} + + + + + /** Binds cRankManager::GetRankVisuals */ static int tolua_cRankManager_GetRankVisuals(lua_State * L) { @@ -679,6 +858,38 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) +/** Binds cRankManager::IsRestrictionInGroup */ +static int tolua_cRankManager_IsRestrictionInGroup(lua_State * L) +{ + // Function signature: + // cRankManager:IsRestrictionInGroup(Restriction, GroupName) -> bool + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, Restriction; + S.GetStackValues(2, Restriction, GroupName); + + // Get the response: + bool res = cRoot::Get()->GetRankManager()->IsRestrictionInGroup(Restriction, GroupName); + + // Push the result: + S.Push(res); + return 1; +} + + + + + /** Binds cRankManager::IsPlayerRankSet */ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) { @@ -821,7 +1032,7 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) AString GroupName, Permission; S.GetStackValues(2, Permission, GroupName); - // Remove the group: + // Remove the permission: cRoot::Get()->GetRankManager()->RemovePermissionFromGroup(Permission, GroupName); return 0; } @@ -830,6 +1041,35 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) +/** Binds cRankManager::RemoveRestrictionFromGroup */ +static int tolua_cRankManager_RemoveRestrictionFromGroup(lua_State * L) +{ + // Function signature: + // cRankManager:RemoveRestrictionFromGroup(Restriction, GroupName) + + cLuaState S(L); + if ( + !S.CheckParamUserTable(1, "cRankManager") || + !S.CheckParamString(2, 3) || + !S.CheckParamEnd(4) + ) + { + return 0; + } + + // Get the params: + AString GroupName, Restriction; + S.GetStackValues(2, Restriction, GroupName); + + // Remove the restriction: + cRoot::Get()->GetRankManager()->RemoveRestrictionFromGroup(Restriction, GroupName); + return 0; +} + + + + + /** Binds cRankManager::RemovePlayerRank */ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) { @@ -1048,40 +1288,48 @@ void ManualBindings::BindRankManager(lua_State * tolua_S) // Fill in the functions (alpha-sorted): tolua_beginmodule(tolua_S, "cRankManager"); - tolua_function(tolua_S, "AddGroup", tolua_cRankManager_AddGroup); - tolua_function(tolua_S, "AddGroupToRank", tolua_cRankManager_AddGroupToRank); - tolua_function(tolua_S, "AddPermissionToGroup", tolua_cRankManager_AddPermissionToGroup); - tolua_function(tolua_S, "AddRank", tolua_cRankManager_AddRank); - tolua_function(tolua_S, "ClearPlayerRanks", tolua_cRankManager_ClearPlayerRanks); - tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); - tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); - tolua_function(tolua_S, "GetAllPlayerUUIDs", tolua_cRankManager_GetAllPlayerUUIDs); - tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); - tolua_function(tolua_S, "GetDefaultRank", tolua_cRankManager_GetDefaultRank); - tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); - tolua_function(tolua_S, "GetPlayerGroups", tolua_cRankManager_GetPlayerGroups); - tolua_function(tolua_S, "GetPlayerMsgVisuals", tolua_cRankManager_GetPlayerMsgVisuals); - tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); - tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); - tolua_function(tolua_S, "GetPlayerName", tolua_cRankManager_GetPlayerName); - tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); - tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); - tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); - tolua_function(tolua_S, "GroupExists", tolua_cRankManager_GroupExists); - tolua_function(tolua_S, "IsGroupInRank", tolua_cRankManager_IsGroupInRank); - tolua_function(tolua_S, "IsPermissionInGroup", tolua_cRankManager_IsPermissionInGroup); - tolua_function(tolua_S, "IsPlayerRankSet", tolua_cRankManager_IsPlayerRankSet); - tolua_function(tolua_S, "RankExists", tolua_cRankManager_RankExists); - tolua_function(tolua_S, "RemoveGroup", tolua_cRankManager_RemoveGroup); - tolua_function(tolua_S, "RemoveGroupFromRank", tolua_cRankManager_RemoveGroupFromRank); - tolua_function(tolua_S, "RemovePermissionFromGroup", tolua_cRankManager_RemovePermissionFromGroup); - tolua_function(tolua_S, "RemovePlayerRank", tolua_cRankManager_RemovePlayerRank); - tolua_function(tolua_S, "RemoveRank", tolua_cRankManager_RemoveRank); - tolua_function(tolua_S, "RenameGroup", tolua_cRankManager_RenameGroup); - tolua_function(tolua_S, "RenameRank", tolua_cRankManager_RenameRank); - tolua_function(tolua_S, "SetDefaultRank", tolua_cRankManager_SetDefaultRank); - tolua_function(tolua_S, "SetPlayerRank", tolua_cRankManager_SetPlayerRank); - tolua_function(tolua_S, "SetRankVisuals", tolua_cRankManager_SetRankVisuals); + tolua_function(tolua_S, "AddGroup", tolua_cRankManager_AddGroup); + tolua_function(tolua_S, "AddGroupToRank", tolua_cRankManager_AddGroupToRank); + tolua_function(tolua_S, "AddPermissionToGroup", tolua_cRankManager_AddPermissionToGroup); + tolua_function(tolua_S, "AddRestrictionToGroup", tolua_cRankManager_AddRestrictionToGroup); + tolua_function(tolua_S, "AddRank", tolua_cRankManager_AddRank); + tolua_function(tolua_S, "ClearPlayerRanks", tolua_cRankManager_ClearPlayerRanks); + tolua_function(tolua_S, "GetAllGroups", tolua_cRankManager_GetAllGroups); + tolua_function(tolua_S, "GetAllPermissions", tolua_cRankManager_GetAllPermissions); + tolua_function(tolua_S, "GetAllRestrictions", tolua_cRankManager_GetAllRestrictions); + tolua_function(tolua_S, "GetAllPermissionsRestrictions", tolua_cRankManager_GetAllPermissionsRestrictions); + tolua_function(tolua_S, "GetAllPlayerUUIDs", tolua_cRankManager_GetAllPlayerUUIDs); + tolua_function(tolua_S, "GetAllRanks", tolua_cRankManager_GetAllRanks); + tolua_function(tolua_S, "GetDefaultRank", tolua_cRankManager_GetDefaultRank); + tolua_function(tolua_S, "GetGroupPermissions", tolua_cRankManager_GetGroupPermissions); + tolua_function(tolua_S, "GetGroupRestrictions", tolua_cRankManager_GetGroupRestrictions); + tolua_function(tolua_S, "GetPlayerGroups", tolua_cRankManager_GetPlayerGroups); + tolua_function(tolua_S, "GetPlayerMsgVisuals", tolua_cRankManager_GetPlayerMsgVisuals); + tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerPermissions); + tolua_function(tolua_S, "GetPlayerPermissions", tolua_cRankManager_GetPlayerRestrictions); + tolua_function(tolua_S, "GetPlayerRankName", tolua_cRankManager_GetPlayerRankName); + tolua_function(tolua_S, "GetPlayerName", tolua_cRankManager_GetPlayerName); + tolua_function(tolua_S, "GetRankGroups", tolua_cRankManager_GetRankGroups); + tolua_function(tolua_S, "GetRankPermissions", tolua_cRankManager_GetRankPermissions); + tolua_function(tolua_S, "GetRankRestrictions", tolua_cRankManager_GetRankRestrictions); + tolua_function(tolua_S, "GetRankVisuals", tolua_cRankManager_GetRankVisuals); + tolua_function(tolua_S, "GroupExists", tolua_cRankManager_GroupExists); + tolua_function(tolua_S, "IsGroupInRank", tolua_cRankManager_IsGroupInRank); + tolua_function(tolua_S, "IsPermissionInGroup", tolua_cRankManager_IsPermissionInGroup); + tolua_function(tolua_S, "IsRestrictionInGroup", tolua_cRankManager_IsRestrictionInGroup); + tolua_function(tolua_S, "IsPlayerRankSet", tolua_cRankManager_IsPlayerRankSet); + tolua_function(tolua_S, "RankExists", tolua_cRankManager_RankExists); + tolua_function(tolua_S, "RemoveGroup", tolua_cRankManager_RemoveGroup); + tolua_function(tolua_S, "RemoveGroupFromRank", tolua_cRankManager_RemoveGroupFromRank); + tolua_function(tolua_S, "RemovePermissionFromGroup", tolua_cRankManager_RemovePermissionFromGroup); + tolua_function(tolua_S, "RemoveRestrictionFromGroup", tolua_cRankManager_RemoveRestrictionFromGroup); + tolua_function(tolua_S, "RemovePlayerRank", tolua_cRankManager_RemovePlayerRank); + tolua_function(tolua_S, "RemoveRank", tolua_cRankManager_RemoveRank); + tolua_function(tolua_S, "RenameGroup", tolua_cRankManager_RenameGroup); + tolua_function(tolua_S, "RenameRank", tolua_cRankManager_RenameRank); + tolua_function(tolua_S, "SetDefaultRank", tolua_cRankManager_SetDefaultRank); + tolua_function(tolua_S, "SetPlayerRank", tolua_cRankManager_SetPlayerRank); + tolua_function(tolua_S, "SetRankVisuals", tolua_cRankManager_SetRankVisuals); tolua_endmodule(tolua_S); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 2549a8481..7f625f5d4 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1414,14 +1414,23 @@ bool cPlayer::HasPermission(const AString & a_Permission) AStringVector Split = StringSplit(a_Permission, "."); + // Iterate over all restrictions; if any matches, then return failure: + for (auto & Restriction: m_SplitRestrictions) + { + if (PermissionMatches(Split, Restriction)) + { + return false; + } + } // for Restriction - m_SplitRestrictions[] + // Iterate over all granted permissions; if any matches, then return success: - for (AStringVectorVector::const_iterator itr = m_SplitPermissions.begin(), end = m_SplitPermissions.end(); itr != end; ++itr) + for (auto & Permission: m_SplitPermissions) { - if (PermissionMatches(Split, *itr)) + if (PermissionMatches(Split, Permission)) { return true; } - } // for itr - m_SplitPermissions[] + } // for Permission - m_SplitPermissions[] // No granted permission matches return false; @@ -2169,15 +2178,24 @@ void cPlayer::LoadRank(void) RankMgr->UpdatePlayerName(m_UUID, m_PlayerName); } m_Permissions = RankMgr->GetPlayerPermissions(m_UUID); + m_Restrictions = RankMgr->GetPlayerRestrictions(m_UUID); RankMgr->GetRankVisuals(m_Rank, m_MsgPrefix, m_MsgSuffix, m_MsgNameColorCode); // Break up the individual permissions on each dot, into m_SplitPermissions: m_SplitPermissions.clear(); m_SplitPermissions.reserve(m_Permissions.size()); - for (AStringVector::const_iterator itr = m_Permissions.begin(), end = m_Permissions.end(); itr != end; ++itr) + for (auto & Permission: m_Permissions) + { + m_SplitPermissions.push_back(StringSplit(Permission, ".")); + } // for Permission - m_Permissions[] + + // Break up the individual restrictions on each dot, into m_SplitRestrictions: + m_SplitRestrictions.clear(); + m_SplitRestrictions.reserve(m_Restrictions.size()); + for (auto & Restriction: m_Restrictions) { - m_SplitPermissions.push_back(StringSplit(*itr, ".")); - } // for itr - m_Permissions[] + m_SplitRestrictions.push_back(StringSplit(Restriction, ".")); + } // for itr - m_Restrictions[] } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 3dae58dc1..8cce4e202 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -254,7 +254,10 @@ public: static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template); // Exported in ManualBindings with AString params /** Returns all the permissions that the player has assigned to them. */ - const AStringVector & GetPermissions(void) { return m_Permissions; } // Exported in ManualBindings.cpp + const AStringVector & GetPermissions(void) const { return m_Permissions; } // Exported in ManualBindings.cpp + + /** Returns all the restrictions that the player has assigned to them. */ + const AStringVector & GetRestrictions(void) const { return m_Restrictions; } // Exported in ManualBindings.cpp // tolua_begin @@ -500,10 +503,18 @@ protected: /** All the permissions that this player has, based on their rank. */ AStringVector m_Permissions; + /** All the restrictions that this player has, based on their rank. */ + AStringVector m_Restrictions; + /** All the permissions that this player has, based on their rank, split into individual dot-delimited parts. This is used mainly by the HasPermission() function to optimize the lookup. */ AStringVectorVector m_SplitPermissions; + /** All the restrictions that this player has, based on their rank, split into individual dot-delimited parts. + This is used mainly by the HasPermission() function to optimize the lookup. */ + AStringVectorVector m_SplitRestrictions; + + // Message visuals: AString m_MsgPrefix, m_MsgSuffix; AString m_MsgNameColorCode; diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 451de88e7..54fef5ce7 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -414,6 +414,7 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) m_DB.exec("CREATE TABLE IF NOT EXISTS PermGroup (PermGroupID INTEGER PRIMARY KEY, Name)"); m_DB.exec("CREATE TABLE IF NOT EXISTS RankPermGroup (RankID INTEGER, PermGroupID INTEGER)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (PermGroupID INTEGER, Permission)"); + m_DB.exec("CREATE TABLE IF NOT EXISTS RestrictionItem (PermGroupID INTEGER, Permission)"); m_DB.exec("CREATE TABLE IF NOT EXISTS DefaultRank (RankID INTEGER)"); m_IsInitialized = true; @@ -571,6 +572,20 @@ AStringVector cRankManager::GetPlayerPermissions(const AString & a_PlayerUUID) +AStringVector cRankManager::GetPlayerRestrictions(const AString & a_PlayerUUID) +{ + AString Rank = GetPlayerRankName(a_PlayerUUID); + if (Rank.empty()) + { + Rank = m_DefaultRank; + } + return GetRankRestrictions(Rank); +} + + + + + AStringVector cRankManager::GetRankGroups(const AString & a_RankName) { ASSERT(m_IsInitialized); @@ -632,6 +647,36 @@ AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) +AStringVector cRankManager::GetGroupRestrictions(const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, + "SELECT RestrictionItem.Permission FROM RestrictionItem " + "LEFT JOIN PermGroup ON PermGroup.PermGroupID = RestrictionItem.PermGroupID " + "WHERE PermGroup.Name = ?" + ); + stmt.bind(1, a_GroupName); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get group restrictions from DB: %s", __FUNCTION__, ex.what()); + } + return res; +} + + + + + AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) { ASSERT(m_IsInitialized); @@ -663,6 +708,37 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) +AStringVector cRankManager::GetRankRestrictions(const AString & a_RankName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, + "SELECT RestrictionItem.Permission FROM RestrictionItem " + "LEFT JOIN RankPermGroup ON RankPermGroup.PermGroupID = RestrictionItem.PermGroupID " + "LEFT JOIN Rank ON Rank.RankID = RankPermGroup.RankID " + "WHERE Rank.Name = ?" + ); + stmt.bind(1, a_RankName); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get rank restrictions from DB: %s", __FUNCTION__, ex.what()); + } + return res; +} + + + + + AStringVector cRankManager::GetAllPlayerUUIDs(void) { ASSERT(m_IsInitialized); @@ -764,6 +840,46 @@ AStringVector cRankManager::GetAllPermissions(void) +AStringVector cRankManager::GetAllRestrictions(void) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + AStringVector res; + try + { + SQLite::Statement stmt(m_DB, "SELECT DISTINCT(Permission) FROM RestrictionItem"); + while (stmt.executeStep()) + { + res.push_back(stmt.getColumn(0).getText()); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to get restrictions from DB: %s", __FUNCTION__, ex.what()); + } + return res; +} + + + + + +AStringVector cRankManager::GetAllPermissionsRestrictions(void) +{ + AStringVector Permissions = GetAllPermissions(); + AStringVector Restrictions = GetAllRestrictions(); + for (auto & restriction: Restrictions) + { + Permissions.push_back(restriction); + } + return Permissions; +} + + + + + bool cRankManager::GetPlayerMsgVisuals( const AString & a_PlayerUUID, AString & a_MsgPrefix, @@ -1063,6 +1179,73 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr +bool cRankManager::AddRestrictionToGroup(const AString & a_Restriction, const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + // Get the group's ID: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such group (%s), aborting.", __FUNCTION__, a_GroupName.c_str()); + return false; + } + GroupID = stmt.getColumn(0).getInt(); + } + + // Check if the restriction is already present: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM RestrictionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, a_Restriction); + if (!stmt.executeStep()) + { + LOGWARNING("%s: Failed to check binding between restriction %s and group %s, aborting.", __FUNCTION__, a_Restriction.c_str(), a_GroupName.c_str()); + return false; + } + if (stmt.getColumn(0).getInt() > 0) + { + LOGD("%s: Restriction %s is already present in group %s, skipping and returning success.", + __FUNCTION__, a_Restriction.c_str(), a_GroupName.c_str() + ); + return true; + } + } + + // Add the restriction: + { + SQLite::Statement stmt(m_DB, "INSERT INTO RestrictionItem (Permission, PermGroupID) VALUES (?, ?)"); + stmt.bind(1, a_Restriction); + stmt.bind(2, GroupID); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add restriction %s to group %s, aborting.", __FUNCTION__, a_Restriction.c_str(), a_GroupName.c_str()); + return false; + } + } + + // Adding succeeded: + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add restriction %s to group %s: %s", + __FUNCTION__, a_Restriction.c_str(), a_GroupName.c_str(), ex.what() + ); + } + return false; +} + + + + + bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName) { ASSERT(m_IsInitialized); @@ -1133,6 +1316,76 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co +bool cRankManager::AddRestrictionsToGroup(const AStringVector & a_Restrictions, const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + // Get the group's ID: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGWARNING("%s: No such group (%s), aborting.", __FUNCTION__, a_GroupName.c_str()); + return false; + } + GroupID = stmt.getColumn(0).getInt(); + } + + for (auto itr = a_Restrictions.cbegin(), end = a_Restrictions.cend(); itr != end; ++itr) + { + // Check if the restriction is already present: + { + SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM RestrictionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, *itr); + if (!stmt.executeStep()) + { + LOGWARNING("%s: Failed to check binding between restriction %s and group %s, aborting.", __FUNCTION__, itr->c_str(), a_GroupName.c_str()); + return false; + } + if (stmt.getColumn(0).getInt() > 0) + { + LOGD("%s: Restriction %s is already present in group %s, skipping and returning success.", + __FUNCTION__, itr->c_str(), a_GroupName.c_str() + ); + continue; + } + } + + // Add the permission: + { + SQLite::Statement stmt(m_DB, "INSERT INTO RestrictionItem (Permission, PermGroupID) VALUES (?, ?)"); + stmt.bind(1, *itr); + stmt.bind(2, GroupID); + if (stmt.exec() <= 0) + { + LOGWARNING("%s: Failed to add restriction %s to group %s, skipping.", __FUNCTION__, itr->c_str(), a_GroupName.c_str()); + continue; + } + } + } // for itr - a_Restrictions[] + + // Adding succeeded: + return true; + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to add restrictions to group %s: %s", + __FUNCTION__, a_GroupName.c_str(), ex.what() + ); + } + return false; +} + + + + + void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName) { ASSERT(m_IsInitialized); @@ -1362,6 +1615,46 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const +void cRankManager::RemoveRestrictionFromGroup(const AString & a_Restriction, const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + // Get the ID of the group: + int GroupID; + { + SQLite::Statement stmt(m_DB, "SELECT PermGroupID FROM PermGroup WHERE Name = ?"); + stmt.bind(1, a_GroupName); + if (!stmt.executeStep()) + { + LOGINFO("%s: Group %s was not found, skipping.", __FUNCTION__, a_GroupName.c_str()); + return; + } + GroupID = stmt.getColumn(0).getInt(); + } + + // Remove the permission from the group: + { + SQLite::Statement stmt(m_DB, "DELETE FROM RestrictionItem WHERE PermGroupID = ? AND Permission = ?"); + stmt.bind(1, GroupID); + stmt.bind(2, a_Restriction); + stmt.exec(); + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to remove restriction %s from group %s in DB: %s", + __FUNCTION__, a_Restriction.c_str(), a_GroupName.c_str(), ex.what() + ); + } +} + + + + + bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewName) { ASSERT(m_IsInitialized); @@ -1744,6 +2037,37 @@ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AStri +bool cRankManager::IsRestrictionInGroup(const AString & a_Restriction, const AString & a_GroupName) +{ + ASSERT(m_IsInitialized); + cCSLock Lock(m_CS); + + try + { + SQLite::Statement stmt(m_DB, + "SELECT * FROM RestrictionItem " + "LEFT JOIN PermGroup ON PermGroup.PermGroupID = RestrictionItem.PermGroupID " + "WHERE RestrictionItem.Permission = ? AND PermGroup.Name = ?" + ); + stmt.bind(1, a_Restriction); + stmt.bind(2, a_GroupName); + if (stmt.executeStep()) + { + // The restriction is in the group + return true; + } + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + + void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID) { ASSERT(m_IsInitialized); @@ -1936,3 +2260,58 @@ void cRankManager::CreateDefaults(void) +bool cRankManager::DoesColumnExist(const char * a_TableName, const char * a_ColumnName) +{ + try + { + SQLite::Statement stmt(m_DB, Printf("PRAGMA table_info(%s)", a_TableName)); + while (stmt.executeStep()) // Iterate over all table's columns + { + int NumColumns = stmt.getColumnCount(); + for (int i = 0; i < NumColumns; i++) // Iterate over all reply's columns (table column's metadata) + { + auto column = stmt.getColumn(i); + if (strcmp(column.getName(), "name") == 0) + { + if (NoCaseCompare(column.getText(), a_ColumnName) == 0) + { + // Colun found + return true; + } + } + } // for i - stmt.getColumns() + } // while (stmt.executeStep()) + } + catch (const SQLite::Exception & ex) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, ex.what()); + } + return false; +} + + + + + +void cRankManager::CreateColumnIfNotExists(const char * a_TableName, const char * a_ColumnName, const char * a_ColumnType) +{ + // If the column already exists, bail out: + if (DoesColumnExist(a_TableName, a_ColumnName)) + { + return; + } + + // Add the column: + try + { + m_DB.exec(Printf("ALTER TABLE %s ADD COLUMN %s %s", a_TableName, a_ColumnName, a_ColumnType)); + } + catch (const SQLite::Exception & exc) + { + LOGWARNING("%s: Failed to query DB: %s", __FUNCTION__, exc.what()); + } +} + + + + diff --git a/src/RankManager.h b/src/RankManager.h index 5dff634b5..b3431b7d1 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -71,6 +71,10 @@ public: If the player has no rank assigned to them, returns the default rank's permissions. */ AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); + /** Returns the restrictions that the specified player has assigned to them. + If the player has no rank assigned to them, returns the default rank's restrictions. */ + AStringVector GetPlayerRestrictions(const AString & a_PlayerUUID); + /** Returns the names of groups that the specified rank has assigned to it. Returns an empty vector if the rank doesn't exist. */ AStringVector GetRankGroups(const AString & a_RankName); @@ -79,10 +83,18 @@ public: Returns an empty vector if the group doesn't exist. */ AStringVector GetGroupPermissions(const AString & a_GroupName); + /** Returns the restrictions that the specified group has assigned to it. + Returns an empty vector if the group doesn't exist. */ + AStringVector GetGroupRestrictions(const AString & a_GroupName); + /** Returns all permissions that the specified rank has assigned to it, through all its groups. Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankPermissions(const AString & a_RankName); + /** Returns all restrictions that the specified rank has assigned to it, through all its groups. + Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ + AStringVector GetRankRestrictions(const AString & a_RankName); + /** Returns the short uuids of all defined players. The returned players are ordered by their name (NOT their UUIDs). */ AStringVector GetAllPlayerUUIDs(void); @@ -95,6 +107,12 @@ public: /** Returns all the distinct permissions that are stored in the DB. */ AStringVector GetAllPermissions(void); + /** Returns all the distinct restrictions that are stored in the DB. */ + AStringVector GetAllRestrictions(void); + + /** Returns all the distinct permissions and restrictions that are stored in the DB. */ + AStringVector GetAllPermissionsRestrictions(void); + /** Returns the message visuals (prefix, postfix, color) for the specified player. Returns true if the visuals were read from the DB, false if not (player not found etc). */ bool GetPlayerMsgVisuals( @@ -128,17 +146,27 @@ public: Returns true if successful, false on error. */ bool AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName); + /** Adds the specified restriction to the specified group. + Fails if the group name is not found. + Returns true if successful, false on error. */ + bool AddRestrictionToGroup(const AString & a_Restriction, const AString & a_GroupName); + /** Adds the specified permissions to the specified permission group. Fails if the permission group name is not found. Returns true if successful, false on error. */ bool AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName); + /** Adds the specified restrictions to the specified group. + Fails if the group name is not found. + Returns true if successful, false on error. */ + bool AddRestrictionsToGroup(const AStringVector & a_Restrictions, const AString & a_GroupName); + /** Removes the specified rank. All players assigned to that rank will be re-assigned to a_ReplacementRankName. If a_ReplacementRankName is empty or not a valid rank, the player will be removed from the DB, which means they will receive the default rank the next time they are queried. If the rank being removed is the default rank, the default will be changed to the replacement - rank; the operation fails if there's no replacement. */ + rank; the operation fails silently if there's no replacement. */ void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); /** Removes the specified group completely. @@ -152,6 +180,9 @@ public: /** Removes the specified permission from the specified group. */ void RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName); + /** Removes the specified restriction from the specified group. */ + void RemoveRestrictionFromGroup(const AString & a_Restriction, const AString & a_GroupName); + /** Renames the specified rank. No action if the rank name is not found. Fails if the new name is already used. Updates the cached m_DefaultRank if the default rank is being renamed. @@ -208,6 +239,9 @@ public: /** Returns true iff the specified group contains the specified permission. */ bool IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName); + /** Returns true iff the specified group contains the specified restriction. */ + bool IsRestrictionInGroup(const AString & a_Restriction, const AString & a_GroupName); + /** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */ void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID); @@ -253,6 +287,13 @@ protected: /** Creates a default set of ranks / groups / permissions. */ void CreateDefaults(void); + + /** Returns true if the specified column exists in the specified table. */ + bool DoesColumnExist(const char * a_TableName, const char * a_ColumnName); + + /** If the specified table doesn't contain the specified column, it is added to the table. + The column type is used only when creating the column, it is not used when checking for existence. */ + void CreateColumnIfNotExists(const char * a_TableName, const char * a_ColumnName, const char * a_ColumnType = ""); } ; |