summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/RankManager.cpp381
-rw-r--r--src/RankManager.h4
2 files changed, 4 insertions, 381 deletions
diff --git a/src/RankManager.cpp b/src/RankManager.cpp
index 87e538d28..f4f594c17 100644
--- a/src/RankManager.cpp
+++ b/src/RankManager.cpp
@@ -5,7 +5,6 @@
#include "Globals.h"
#include "RankManager.h"
-#include "IniFile.h"
#include "Protocol/MojangAPI.h"
#include "ClientHandle.h"
@@ -14,371 +13,6 @@
////////////////////////////////////////////////////////////////////////////////
-// cRankManagerIniMigrator:
-
-/** Migrates from groups.ini and users.ini into the rankmanager DB */
-class cRankManagerIniMigrator
-{
-public:
- cRankManagerIniMigrator(cRankManager & a_RankManager, cMojangAPI & a_MojangAPI) :
- m_RankManager(a_RankManager),
- m_MojangAPI(a_MojangAPI)
- {
- }
-
-
-
- /** Performs the complete migration from INI files to DB. */
- bool Migrate(void)
- {
- cRankManager::cMassChangeLock Lock(m_RankManager);
-
- LOGD("Reading groups...");
- if (!ReadGroups())
- {
- return false;
- }
- LOGD("Cleaning groups inheritance...");
- CleanGroupInheritance();
- LOGD("Creating groups...");
- CreateGroups();
-
- LOGD("Reading users...");
- if (!ReadUsers())
- {
- return false;
- }
- LOGD("Cleaning user groups...");
- CleanUserGroups();
- LOGD("Resolving user UUIDs...");
- ResolveUserUUIDs();
-
- LOGD("Setting ranks...");
- SetRanks();
-
- LOGD("Creating defaults...");
- CreateDefaults();
-
- return true;
- }
-
-protected:
-
- /** Container for a group read from an INI file. */
- struct sGroup
- {
- AString m_Name;
- AString m_Color;
- AStringVector m_Inherits;
- AStringVector m_Permissions;
-
- sGroup(void) {}
-
- sGroup(const AString & a_Name, const AString & a_Color, const AStringVector & a_Inherits, const AStringVector & a_Permissions):
- m_Name(a_Name),
- m_Color(a_Color),
- m_Inherits(a_Inherits),
- m_Permissions(a_Permissions)
- {
- }
- };
- typedef std::map<AString, sGroup> sGroupMap;
-
-
- /** Container for a single user read from an INI file. */
- struct sUser
- {
- AString m_Name;
- AStringVector m_Groups;
-
- /** Assigned by ResolveUserUUIDs(), contains the online (Mojang) UUID of the player. */
- cUUID m_UUID;
-
- /** Assigned by ResolveUserUUIDs(), contains the offline (generated) UUID of the player. */
- cUUID m_OfflineUUID;
-
-
- sUser(void) {}
-
- sUser(const AString & a_Name, const AStringVector & a_Groups):
- m_Name(a_Name),
- m_Groups(a_Groups)
- {
- }
- };
- typedef std::map<AString, sUser> sUserMap;
-
- typedef std::map<AString, AString> cStringMap;
-
-
- /** The parent Rank manager where we will create the groups, ranks and players */
- cRankManager & m_RankManager;
-
- /** The player name to UUID resolver */
- cMojangAPI & m_MojangAPI;
-
- /** List of all groups read from the ini file */
- sGroupMap m_Groups;
-
- /** List of all players read from the ini file. */
- sUserMap m_Users;
-
- /** Maps lists of groups to rank names.
- Each group list is either a simple "<Group>" if there's only one group,
- or "<PrimaryGroup>, <FirstSecondaryGroup>, <SecondSecondaryGroup>...", where the secondary groups are
- lowercased and alpha-sorted. This makes the group lists comparable for equivalence, simply by comparing
- their string names.
- The ranks are named "<Group>" for single-group players, and "AutoMigratedRank_N" for the composite ranks,
- where N is a unique number. */
- cStringMap m_GroupsToRanks;
-
-
-
- /** Reads the groups from the "groups.ini" file into m_Groups */
- bool ReadGroups(void)
- {
- // Read the file:
- cIniFile Groups;
- if (!Groups.ReadFile("groups.ini"))
- {
- return false;
- }
-
- // Read all the groups into a map:
- int NumGroups = Groups.GetNumKeys();
- for (int i = 0; i < NumGroups; i++)
- {
- AString GroupName = Groups.GetKeyName(i);
- AString lcGroupName = StrToLower(GroupName);
- if (m_Groups.find(lcGroupName) != m_Groups.end())
- {
- LOGINFO("groups.ini contains a duplicate definition of group %s, ignoring the latter.", GroupName.c_str());
- continue;
- }
- m_Groups[lcGroupName] = sGroup(
- GroupName,
- Groups.GetValue(GroupName, "Color", ""),
- StringSplitAndTrim(Groups.GetValue(GroupName, "Inherits"), ","),
- StringSplitAndTrim(Groups.GetValue(GroupName, "Permissions"), ",")
- );
- } // for i - Groups' keys
- return true;
- }
-
-
-
- /** Removes non-existent groups from all the groups' inheritance */
- void CleanGroupInheritance(void)
- {
- for (sGroupMap::iterator itrG = m_Groups.begin(), endG = m_Groups.end(); itrG != endG; ++itrG)
- {
- AStringVector & Inherits = itrG->second.m_Inherits;
- for (AStringVector::iterator itrI = Inherits.begin(); itrI != Inherits.end();)
- {
- AString lcInherits = StrToLower(*itrI);
- if (m_Groups.find(lcInherits) != m_Groups.end())
- {
- // Inherited group exists, continue checking the next one
- ++itrI;
- continue;
- }
- // Inherited group doesn't exist, remove it from the list:
- LOGWARNING("RankMigrator: Group \"%s\" inherits from a non-existent group \"%s\", this inheritance will be ignored.",
- itrG->second.m_Name.c_str(), itrI->c_str()
- );
- AStringVector::iterator itrI2 = itrI;
- ++itrI2;
- Inherits.erase(itrI);
- itrI = itrI2;
- } // for itrI - Inherits[]
- } // for itrG - m_Groups[]
- }
-
-
-
- /** Reads the users from the "users.ini" file into m_Users */
- bool ReadUsers(void)
- {
- // Read the file:
- cIniFile Users;
- if (!Users.ReadFile("users.ini"))
- {
- return false;
- }
-
- // Read all the users into a map:
- int NumUsers = Users.GetNumKeys();
- for (int i = 0; i < NumUsers; i++)
- {
- AString UserName = Users.GetKeyName(i);
- AString lcUserName = StrToLower(UserName);
- if (m_Users.find(lcUserName) != m_Users.end())
- {
- LOGINFO("users.ini contains a duplicate definition of user %s, ignoring the latter.", UserName.c_str());
- continue;
- }
- m_Users[lcUserName] = sUser(
- UserName,
- StringSplitAndTrim(Users.GetValue(UserName, "Groups", ""), ",")
- );
- } // for i - Users' keys
- return true;
- }
-
-
-
- /** Removes non-existent groups from each user's definition. */
- void CleanUserGroups(void)
- {
- for (sUserMap::iterator itrU = m_Users.begin(), endU = m_Users.end(); itrU != endU; ++itrU)
- {
- AStringVector & Groups = itrU->second.m_Groups;
- for (AStringVector::iterator itrG = Groups.begin(); itrG != Groups.end();)
- {
- AString lcGroup = StrToLower(*itrG);
- if (m_Groups.find(lcGroup) != m_Groups.end())
- {
- // Assigned group exists, continue checking the next one
- ++itrG;
- continue;
- }
- // Assigned group doesn't exist, remove it from the list:
- LOGWARNING("RankMigrator: User \"%s\" is assigned a non-existent group \"%s\", this assignment will be ignored.",
- itrU->second.m_Name.c_str(), itrG->c_str()
- );
- AStringVector::iterator itrG2 = itrG;
- ++itrG2;
- Groups.erase(itrG);
- itrG = itrG2;
- } // for itrG - Groups[]
- } // for itrU - m_Users[]
- }
-
-
-
- /** Creates groups based on m_Groups.
- Ignores group inheritance. */
- void CreateGroups(void)
- {
- // Create each group, with its permissions:
- for (sGroupMap::const_iterator itr = m_Groups.begin(), end = m_Groups.end(); itr != end; ++itr)
- {
- m_RankManager.AddGroup(itr->second.m_Name);
- m_RankManager.AddPermissionsToGroup(itr->second.m_Permissions, itr->second.m_Name);
- } // for itr - m_Groups[]
- }
-
-
- /** Resolves the UUID of each user in m_Users.
- If a user doesn't resolve, they are removed and logged in the console. */
- void ResolveUserUUIDs(void)
- {
- // Resolve all PlayerNames at once (the API doesn't like single-name queries):
- AStringVector PlayerNames;
- for (sUserMap::const_iterator itr = m_Users.begin(), end = m_Users.end(); itr != end; ++itr)
- {
- PlayerNames.push_back(itr->second.m_Name);
- }
- m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames);
-
- // Assign the UUIDs back to players, remove those not resolved:
- for (auto & User : m_Users)
- {
- cUUID UUID = m_MojangAPI.GetUUIDFromPlayerName(User.second.m_Name);
- if (UUID.IsNil())
- {
- LOGWARNING("RankMigrator: Cannot resolve player %s to online UUID, player will be left unranked in online mode", User.second.m_Name.c_str());
- }
- User.second.m_UUID = UUID;
- User.second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(User.second.m_Name);
- }
- }
-
-
-
- /** Adds the specified groups to the specified ranks. Recurses on the groups' inheritance. */
- void AddGroupsToRank(const AStringVector & a_Groups, const AString & a_RankName)
- {
- for (AStringVector::const_iterator itr = a_Groups.begin(), end = a_Groups.end(); itr != end; ++itr)
- {
- // Normalize the group name:
- sGroup & Group = m_Groups[StrToLower(*itr)];
-
- // Avoid loops, check if the group is already added:
- if (m_RankManager.IsGroupInRank(Group.m_Name, a_RankName))
- {
- continue;
- }
-
- // Add the group, and all the groups it inherits from recursively:
- m_RankManager.AddGroupToRank(Group.m_Name, a_RankName);
- AddGroupsToRank(Group.m_Inherits, a_RankName);
- } // for itr - a_Groups[]
- }
-
-
-
- /** Creates a rank for each player, based on the master groups they are assigned. */
- void SetRanks(void)
- {
- for (sUserMap::const_iterator itr = m_Users.begin(), end = m_Users.end(); itr != end; ++itr)
- {
- // Ignore users with no groups:
- const AStringVector & Groups = itr->second.m_Groups;
- if (Groups.empty())
- {
- LOGWARNING("RankMigrator: Player %s has no groups assigned to them, skipping the player.", itr->second.m_Name.c_str());
- continue;
- }
-
- // Compose the rank name out of group names:
- AString RankName;
- for (AStringVector::const_iterator itrG = Groups.begin(), endG = Groups.end(); itrG != endG; ++itrG)
- {
- AString GroupName = m_Groups[StrToLower(*itrG)].m_Name; // Normalize group name
- if (!RankName.empty())
- {
- RankName.push_back(',');
- }
- RankName.append(GroupName);
- } // for itrG - Groups[]
-
- // Create the rank, with al its groups:
- if (!m_RankManager.RankExists(RankName))
- {
- m_RankManager.AddRank(RankName, "", "", m_Groups[StrToLower(Groups[0])].m_Color);
- AddGroupsToRank(Groups, RankName);
- }
-
- // 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_OfflineUUID, itr->second.m_Name, RankName);
- } // 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");
- }
-};
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
// cRankManager:
cRankManager::cRankManager(void) :
@@ -421,21 +55,10 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI)
a_MojangAPI.SetRankManager(this);
- // Check if tables empty, migrate from ini files then
+ // If tables are empty, create default ranks
if (AreDBTablesEmpty())
{
- LOGINFO("There are no ranks, migrating old-style INI files to new DB ranks...");
- LOGINFO("(This might take a while)");
- cRankManagerIniMigrator Migrator(*this, a_MojangAPI);
- if (Migrator.Migrate())
- {
- LOGINFO("Ranks migrated.");
- // The default rank has been set by the migrator
- return;
- }
-
- // Migration failed. Add some defaults
- LOGINFO("Rank migration failed, creating default ranks...");
+ LOGINFO("Creating default ranks...");
CreateDefaults();
LOGINFO("Default ranks created.");
}
diff --git a/src/RankManager.h b/src/RankManager.h
index abe860b1c..e2600dde0 100644
--- a/src/RankManager.h
+++ b/src/RankManager.h
@@ -53,7 +53,7 @@ public:
~cRankManager();
/** Initializes the rank manager. Performs migration and default-setting if no data is found in the DB.
- The a_MojangAPI param is used when migrating from old ini files, to look up player UUIDs. */
+ The a_MojangAPI param is used to keep player names in sync with UUIDs, since Mojang allows username changes. */
void Initialize(cMojangAPI & a_MojangAPI);
/** Returns the name of the rank that the specified player has assigned to them.
@@ -273,7 +273,7 @@ protected:
/** Set to true once the manager is initialized. */
bool m_IsInitialized;
- /** The MojangAPI instance that is used for translating playernames to UUIDs.
+ /** The MojangAPI instance that is used for keeping player names and UUIDs in sync.
Set in Initialize(), may be nullptr. */
cMojangAPI * m_MojangAPI;