RankMgr: Implemented default rank, added defaults.
This commit is contained in:
parent
e034b64a5b
commit
0daacd14d9
@ -1 +1 @@
|
|||||||
Subproject commit 6627e570a5265ae270aae978a1cad80dfb8a2b18
|
Subproject commit 7cc99285ae5117418f657c3b295ca71f2b75b4f4
|
@ -7,6 +7,7 @@
|
|||||||
#include "RankManager.h"
|
#include "RankManager.h"
|
||||||
#include "inifile/iniFile.h"
|
#include "inifile/iniFile.h"
|
||||||
#include "Protocol/MojangAPI.h"
|
#include "Protocol/MojangAPI.h"
|
||||||
|
#include "ClientHandle.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -55,6 +56,9 @@ public:
|
|||||||
LOGD("Setting ranks...");
|
LOGD("Setting ranks...");
|
||||||
SetRanks();
|
SetRanks();
|
||||||
|
|
||||||
|
LOGD("Creating defaults...");
|
||||||
|
CreateDefaults();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +91,12 @@ protected:
|
|||||||
AString m_Name;
|
AString m_Name;
|
||||||
AStringVector m_Groups;
|
AStringVector m_Groups;
|
||||||
|
|
||||||
/** Assigned by ResolveUserUUIDs() */
|
/** Assigned by ResolveUserUUIDs(), contains the online (Mojang) UUID of the player. */
|
||||||
AString m_UUID;
|
AString m_UUID;
|
||||||
|
|
||||||
|
/** Assigned by ResolveUserUUIDs(), contains the offline (generated) UUID of the player. */
|
||||||
|
AString m_OfflineUUID;
|
||||||
|
|
||||||
|
|
||||||
sUser(void) {}
|
sUser(void) {}
|
||||||
|
|
||||||
@ -275,22 +282,15 @@ protected:
|
|||||||
m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames);
|
m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames);
|
||||||
|
|
||||||
// Assign the UUIDs back to players, remove those not resolved:
|
// Assign the UUIDs back to players, remove those not resolved:
|
||||||
for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); )
|
for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ++itr)
|
||||||
{
|
{
|
||||||
AString UUID = m_MojangAPI.GetUUIDFromPlayerName(itr->second.m_Name);
|
AString UUID = m_MojangAPI.GetUUIDFromPlayerName(itr->second.m_Name);
|
||||||
if (UUID.empty())
|
if (UUID.empty())
|
||||||
{
|
{
|
||||||
LOGWARNING("RankMigrator: Cannot resolve player %s to UUID, player will be left unranked", itr->second.m_Name.c_str());
|
LOGWARNING("RankMigrator: Cannot resolve player %s to online UUID, player will be left unranked in online mode", itr->second.m_Name.c_str());
|
||||||
sUserMap::iterator itr2 = itr;
|
|
||||||
++itr2;
|
|
||||||
m_Users.erase(itr);
|
|
||||||
itr = itr2;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
itr->second.m_UUID = UUID;
|
itr->second.m_UUID = UUID;
|
||||||
++itr;
|
itr->second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(itr->second.m_Name);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,10 +350,28 @@ protected:
|
|||||||
AddGroupsToRank(Groups, RankName);
|
AddGroupsToRank(Groups, RankName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the rank to the user:
|
// Set the rank to the user, using both the online and offline UUIDs:
|
||||||
m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName);
|
m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName);
|
||||||
|
m_RankManager.SetPlayerRank(itr->second.m_OfflineUUID, itr->second.m_Name, RankName);
|
||||||
} // for itr - m_Users[]
|
} // for itr - m_Users[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Creates the Default rank that contains the Default group, if it exists.
|
||||||
|
Sets the RankManager's default rank. */
|
||||||
|
void CreateDefaults(void)
|
||||||
|
{
|
||||||
|
if (!m_RankManager.RankExists("Default"))
|
||||||
|
{
|
||||||
|
m_RankManager.AddRank("Default", "", "", "");
|
||||||
|
if (!m_RankManager.IsGroupInRank("Default", "Default"))
|
||||||
|
{
|
||||||
|
m_RankManager.AddGroupToRank("Default", "Default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_RankManager.SetDefaultRank("Default");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -396,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 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 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 PermissionItem (PermGroupID INTEGER, Permission)");
|
||||||
|
m_DB.exec("CREATE TABLE IF NOT EXISTS DefaultRank (RankID INTEGER)");
|
||||||
|
|
||||||
m_IsInitialized = true;
|
m_IsInitialized = true;
|
||||||
|
|
||||||
@ -410,12 +429,39 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI)
|
|||||||
if (Migrator.Migrate())
|
if (Migrator.Migrate())
|
||||||
{
|
{
|
||||||
LOGINFO("Ranks migrated.");
|
LOGINFO("Ranks migrated.");
|
||||||
|
// The default rank has been set by the migrator
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migration failed. Add some defaults
|
||||||
|
LOGINFO("Rank migration failed, creating default ranks...");
|
||||||
|
CreateDefaults();
|
||||||
|
LOGINFO("Default ranks created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migration failed.
|
// Load the default rank:
|
||||||
// TODO: Check if tables empty, add some defaults then
|
try
|
||||||
|
{
|
||||||
|
SQLite::Statement stmt(m_DB,
|
||||||
|
"SELECT Rank.Name FROM Rank "
|
||||||
|
"LEFT JOIN DefaultRank ON Rank.RankID = DefaultRank.RankID"
|
||||||
|
);
|
||||||
|
if (stmt.executeStep())
|
||||||
|
{
|
||||||
|
m_DefaultRank = stmt.getColumn(0).getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const SQLite::Exception & ex)
|
||||||
|
{
|
||||||
|
LOGWARNING("%s: Cannot load default rank: %s", __FUNCTION__, ex.what());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the default rank cannot be loaded, use the first rank:
|
||||||
|
if (m_DefaultRank.empty())
|
||||||
|
{
|
||||||
|
SetDefaultRank(GetAllRanks()[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1086,6 +1132,13 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl
|
|||||||
ASSERT(m_IsInitialized);
|
ASSERT(m_IsInitialized);
|
||||||
cCSLock Lock(m_CS);
|
cCSLock Lock(m_CS);
|
||||||
|
|
||||||
|
// Check if the default rank is being removed with a proper replacement:
|
||||||
|
if ((a_RankName == m_DefaultRank) && !RankExists(a_ReplacementRankName))
|
||||||
|
{
|
||||||
|
LOGWARNING("%s: Cannot remove rank %s, it is the default rank and the replacement rank doesn't exist.", __FUNCTION__, a_RankName.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AStringVector res;
|
AStringVector res;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1143,6 +1196,12 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl
|
|||||||
stmt.bind(1, RemoveRankID);
|
stmt.bind(1, RemoveRankID);
|
||||||
stmt.exec();
|
stmt.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the default rank, if it was the one being removed:
|
||||||
|
if (a_RankName == m_DefaultRank)
|
||||||
|
{
|
||||||
|
m_DefaultRank = a_RankName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const SQLite::Exception & ex)
|
catch (const SQLite::Exception & ex)
|
||||||
{
|
{
|
||||||
@ -1310,21 +1369,30 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa
|
|||||||
stmt.bind(1, a_NewName);
|
stmt.bind(1, a_NewName);
|
||||||
if (stmt.executeStep())
|
if (stmt.executeStep())
|
||||||
{
|
{
|
||||||
LOGD("%s: Rank %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str());
|
LOGINFO("%s: Rank %s is already present, cannot rename %s", __FUNCTION__, a_NewName.c_str(), a_OldName.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename:
|
// Rename:
|
||||||
bool res;
|
|
||||||
{
|
{
|
||||||
SQLite::Statement stmt(m_DB, "UPDATE Rank SET Name = ? WHERE Name = ?");
|
SQLite::Statement stmt(m_DB, "UPDATE Rank SET Name = ? WHERE Name = ?");
|
||||||
stmt.bind(1, a_NewName);
|
stmt.bind(1, a_NewName);
|
||||||
stmt.bind(2, a_OldName);
|
stmt.bind(2, a_OldName);
|
||||||
res = (stmt.exec() > 0);
|
if (stmt.exec() <= 0)
|
||||||
|
{
|
||||||
|
LOGINFO("%s: There is no rank %s, cannot rename to %s.", __FUNCTION__, a_OldName.c_str(), a_NewName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
// Update the default rank, if it was the one being renamed:
|
||||||
|
if (a_OldName == m_DefaultRank)
|
||||||
|
{
|
||||||
|
m_DefaultRank = a_NewName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
catch (const SQLite::Exception & ex)
|
catch (const SQLite::Exception & ex)
|
||||||
{
|
{
|
||||||
@ -1692,6 +1760,57 @@ void cRankManager::NotifyNameUUID(const AString & a_PlayerName, const AString &
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cRankManager::SetDefaultRank(const AString & a_RankName)
|
||||||
|
{
|
||||||
|
ASSERT(m_IsInitialized);
|
||||||
|
cCSLock Lock(m_CS);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Find the rank's ID:
|
||||||
|
int RankID = 0;
|
||||||
|
{
|
||||||
|
SQLite::Statement stmt(m_DB, "SELECT RankID FROM Rank WHERE Name = ?");
|
||||||
|
stmt.bind(1, a_RankName);
|
||||||
|
if (!stmt.executeStep())
|
||||||
|
{
|
||||||
|
LOGINFO("%s: Cannot set rank %s as the default, it does not exist.", __FUNCTION__, a_RankName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the rank as the default:
|
||||||
|
{
|
||||||
|
SQLite::Statement stmt(m_DB, "UPDATE DefaultRank SET RankID = ?");
|
||||||
|
stmt.bind(1, RankID);
|
||||||
|
if (stmt.exec() < 1)
|
||||||
|
{
|
||||||
|
// Failed to update, there might be none in the DB, try inserting:
|
||||||
|
SQLite::Statement stmt2(m_DB, "INSERT INTO DefaultRank (RankID) VALUES (?)");
|
||||||
|
stmt2.bind(1, RankID);
|
||||||
|
if (stmt2.exec() < 1)
|
||||||
|
{
|
||||||
|
LOGINFO("%s: Cannot update the default rank in the DB to %s.", __FUNCTION__, a_RankName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the internal cache:
|
||||||
|
m_DefaultRank = a_RankName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (const SQLite::Exception & ex)
|
||||||
|
{
|
||||||
|
LOGWARNING("%s: Failed to update DB: %s", __FUNCTION__, ex.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cRankManager::AreDBTablesEmpty(void)
|
bool cRankManager::AreDBTablesEmpty(void)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -1699,7 +1818,8 @@ bool cRankManager::AreDBTablesEmpty(void)
|
|||||||
IsDBTableEmpty("PlayerRank") &&
|
IsDBTableEmpty("PlayerRank") &&
|
||||||
IsDBTableEmpty("PermGroup") &&
|
IsDBTableEmpty("PermGroup") &&
|
||||||
IsDBTableEmpty("RankPermGroup") &&
|
IsDBTableEmpty("RankPermGroup") &&
|
||||||
IsDBTableEmpty("PermissionItem")
|
IsDBTableEmpty("PermissionItem") &&
|
||||||
|
IsDBTableEmpty("DefaultRank")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1724,3 +1844,41 @@ bool cRankManager::IsDBTableEmpty(const AString & a_TableName)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cRankManager::CreateDefaults(void)
|
||||||
|
{
|
||||||
|
// Wrap everything in a big transaction to speed things up:
|
||||||
|
cMassChangeLock Lock(*this);
|
||||||
|
|
||||||
|
// Create ranks:
|
||||||
|
AddRank("Default", "", "", "");
|
||||||
|
AddRank("VIP", "", "", "");
|
||||||
|
AddRank("Operator", "", "", "");
|
||||||
|
AddRank("Admin", "", "", "");
|
||||||
|
|
||||||
|
// Create groups:
|
||||||
|
AddGroup("Default");
|
||||||
|
AddGroup("Kick");
|
||||||
|
AddGroup("Teleport");
|
||||||
|
AddGroup("Everything");
|
||||||
|
|
||||||
|
// Add groups to ranks:
|
||||||
|
AddGroupToRank("Default", "Default");
|
||||||
|
AddGroupToRank("Teleport", "VIP");
|
||||||
|
AddGroupToRank("Teleport", "Operator");
|
||||||
|
AddGroupToRank("Kick", "Operator");
|
||||||
|
AddGroupToRank("Everything", "Admin");
|
||||||
|
|
||||||
|
// Add permissions to groups:
|
||||||
|
AddPermissionToGroup("core.build", "Default");
|
||||||
|
AddPermissionToGroup("core.tp", "Teleport");
|
||||||
|
AddPermissionToGroup("core.kick", "Kick");
|
||||||
|
AddPermissionToGroup("*", "Everything");
|
||||||
|
|
||||||
|
// Set the default rank:
|
||||||
|
SetDefaultRank("Default");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +127,9 @@ public:
|
|||||||
/** Removes the specified rank.
|
/** Removes the specified rank.
|
||||||
All players assigned to that rank will be re-assigned to a_ReplacementRankName.
|
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,
|
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. */
|
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. */
|
||||||
void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName);
|
void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName);
|
||||||
|
|
||||||
/** Removes the specified group completely.
|
/** Removes the specified group completely.
|
||||||
@ -143,6 +145,7 @@ public:
|
|||||||
|
|
||||||
/** Renames the specified rank. No action if the rank name is not found.
|
/** Renames the specified rank. No action if the rank name is not found.
|
||||||
Fails if the new name is already used.
|
Fails if the new name is already used.
|
||||||
|
Updates the cached m_DefaultRank if the default rank is being renamed.
|
||||||
Returns true on success, false on failure. */
|
Returns true on success, false on failure. */
|
||||||
bool RenameRank(const AString & a_OldName, const AString & a_NewName);
|
bool RenameRank(const AString & a_OldName, const AString & a_NewName);
|
||||||
|
|
||||||
@ -199,12 +202,22 @@ public:
|
|||||||
/** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */
|
/** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */
|
||||||
void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID);
|
void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID);
|
||||||
|
|
||||||
|
/** Sets the specified rank as the default rank.
|
||||||
|
Returns true on success, false on failure (rank not found). */
|
||||||
|
bool SetDefaultRank(const AString & a_RankName);
|
||||||
|
|
||||||
|
/** Returns the name of the default rank. */
|
||||||
|
const AString & GetDefaultRank(void) const { return m_DefaultRank; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** The database storage for all the data. Protected by m_CS. */
|
/** The database storage for all the data. Protected by m_CS. */
|
||||||
SQLite::Database m_DB;
|
SQLite::Database m_DB;
|
||||||
|
|
||||||
/** The mutex protecting m_DB against multi-threaded access. */
|
/** The name of the default rank. Kept as a cache so that queries for it don't need to go through the DB. */
|
||||||
|
AString m_DefaultRank;
|
||||||
|
|
||||||
|
/** The mutex protecting m_DB and m_DefaultRank against multi-threaded access. */
|
||||||
cCriticalSection m_CS;
|
cCriticalSection m_CS;
|
||||||
|
|
||||||
/** Set to true once the manager is initialized. */
|
/** Set to true once the manager is initialized. */
|
||||||
@ -221,6 +234,9 @@ protected:
|
|||||||
/** Returns true iff the specified DB table is empty.
|
/** Returns true iff the specified DB table is empty.
|
||||||
If there's an error while querying, returns false. */
|
If there's an error while querying, returns false. */
|
||||||
bool IsDBTableEmpty(const AString & a_TableName);
|
bool IsDBTableEmpty(const AString & a_TableName);
|
||||||
|
|
||||||
|
/** Creates a default set of ranks / groups / permissions. */
|
||||||
|
void CreateDefaults(void);
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user