cPlayer reads ranks from cRankManager.
This commit is contained in:
parent
3a7089539c
commit
949aa2f383
@ -1803,49 +1803,30 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetGroups(lua_State * tolua_S)
|
||||
static int tolua_cPlayer_GetPermissions(lua_State * tolua_S)
|
||||
{
|
||||
// Function signature: cPlayer:GetPermissions() -> {permissions-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, NULL);
|
||||
|
||||
const cPlayer::GroupList & AllGroups = self->GetGroups();
|
||||
|
||||
lua_createtable(tolua_S, (int)AllGroups.size(), 0);
|
||||
int newTable = lua_gettop(tolua_S);
|
||||
int index = 1;
|
||||
cPlayer::GroupList::const_iterator iter = AllGroups.begin();
|
||||
while (iter != AllGroups.end())
|
||||
if (self == NULL)
|
||||
{
|
||||
const cGroup * Group = *iter;
|
||||
tolua_pushusertype(tolua_S, (void *)Group, "const cGroup");
|
||||
lua_rawseti(tolua_S, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetResolvedPermissions(lua_State * tolua_S)
|
||||
{
|
||||
cPlayer * self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
|
||||
|
||||
cPlayer::StringList AllPermissions = self->GetResolvedPermissions();
|
||||
|
||||
lua_createtable(tolua_S, (int)AllPermissions.size(), 0);
|
||||
int newTable = lua_gettop(tolua_S);
|
||||
int index = 1;
|
||||
cPlayer::StringList::iterator iter = AllPermissions.begin();
|
||||
while (iter != AllPermissions.end())
|
||||
{
|
||||
std::string & Permission = *iter;
|
||||
lua_pushlstring(tolua_S, Permission.c_str(), Permission.length());
|
||||
lua_rawseti(tolua_S, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
}
|
||||
// Push the permissions:
|
||||
L.Push(self->GetPermissions());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1902,6 +1883,40 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S)
|
||||
{
|
||||
// Function signature: cPlayer:PermissionMatches(PermissionStr, TemplateStr) -> bool
|
||||
|
||||
// Check the params:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cPlayer") ||
|
||||
!L.CheckParamString (2, 3) ||
|
||||
!L.CheckParamEnd (4)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
|
||||
return 0;
|
||||
}
|
||||
AString Permission, Template;
|
||||
L.GetStackValues(2, Permission, Template);
|
||||
|
||||
// Push the result of the match:
|
||||
L.Push(self->PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, ".")));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <
|
||||
class OBJTYPE,
|
||||
void (OBJTYPE::*SetCallback)(cPluginLua * a_Plugin, int a_FnRef)
|
||||
@ -3295,9 +3310,9 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlayer");
|
||||
tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups);
|
||||
tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions);
|
||||
tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions);
|
||||
tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow);
|
||||
tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cLuaWindow");
|
||||
|
@ -59,7 +59,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
|
||||
m_EnderChestContents(9, 3),
|
||||
m_CurrentWindow(NULL),
|
||||
m_InventoryWindow(NULL),
|
||||
m_Color('-'),
|
||||
m_GameMode(eGameMode_NotSet),
|
||||
m_IP(""),
|
||||
m_ClientHandle(a_Client),
|
||||
@ -1359,48 +1358,6 @@ void cPlayer::SetVisible(bool a_bVisible)
|
||||
|
||||
|
||||
|
||||
void cPlayer::AddToGroup( const AString & a_GroupName)
|
||||
{
|
||||
cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName);
|
||||
m_Groups.push_back( Group);
|
||||
LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str());
|
||||
ResolveGroups();
|
||||
ResolvePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::RemoveFromGroup( const AString & a_GroupName)
|
||||
{
|
||||
bool bRemoved = false;
|
||||
for (GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetName().compare(a_GroupName) == 0)
|
||||
{
|
||||
m_Groups.erase( itr);
|
||||
bRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRemoved)
|
||||
{
|
||||
LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str());
|
||||
ResolveGroups();
|
||||
ResolvePermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::HasPermission(const AString & a_Permission)
|
||||
{
|
||||
if (a_Permission.empty())
|
||||
@ -1409,47 +1366,18 @@ bool cPlayer::HasPermission(const AString & a_Permission)
|
||||
return true;
|
||||
}
|
||||
|
||||
AStringVector Split = StringSplit( a_Permission, ".");
|
||||
PermissionMap Possibilities = m_ResolvedPermissions;
|
||||
// Now search the namespaces
|
||||
while (Possibilities.begin() != Possibilities.end())
|
||||
{
|
||||
PermissionMap::iterator itr = Possibilities.begin();
|
||||
if (itr->second)
|
||||
{
|
||||
AStringVector OtherSplit = StringSplit( itr->first, ".");
|
||||
if (OtherSplit.size() <= Split.size())
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < OtherSplit.size(); ++i)
|
||||
{
|
||||
if (OtherSplit[i].compare( Split[i]) != 0)
|
||||
{
|
||||
if (OtherSplit[i].compare("*") == 0) return true; // WildCard man!! WildCard!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == Split.size()) return true;
|
||||
}
|
||||
}
|
||||
Possibilities.erase( itr);
|
||||
}
|
||||
AStringVector Split = StringSplit(a_Permission, ".");
|
||||
|
||||
// Nothing that matched :(
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::IsInGroup( const AString & a_Group)
|
||||
{
|
||||
for (GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr)
|
||||
// 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)
|
||||
{
|
||||
if (PermissionMatches(Split, *itr))
|
||||
{
|
||||
if (a_Group.compare( (*itr)->GetName().c_str()) == 0)
|
||||
return true;
|
||||
}
|
||||
} // for itr - m_SplitPermissions[]
|
||||
|
||||
// No granted permission matches
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1457,68 +1385,35 @@ bool cPlayer::IsInGroup( const AString & a_Group)
|
||||
|
||||
|
||||
|
||||
void cPlayer::ResolvePermissions()
|
||||
bool cPlayer::PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template)
|
||||
{
|
||||
m_ResolvedPermissions.clear(); // Start with an empty map
|
||||
|
||||
// Copy all player specific permissions into the resolved permissions map
|
||||
for (PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr)
|
||||
// Check the sub-items if they are the same or there's a wildcard:
|
||||
size_t lenP = a_Permission.size();
|
||||
size_t lenT = a_Template.size();
|
||||
size_t minLen = std::min(lenP, lenT);
|
||||
for (size_t i = 0; i < minLen; i++)
|
||||
{
|
||||
m_ResolvedPermissions[ itr->first ] = itr->second;
|
||||
if (a_Template[i] == "*")
|
||||
{
|
||||
// Has matched so far and now there's a wildcard in the template, so the permission matches:
|
||||
return true;
|
||||
}
|
||||
if (a_Permission[i] != a_Template[i])
|
||||
{
|
||||
// Found a mismatch
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr)
|
||||
// So far all the sub-items have matched
|
||||
// If the sub-item count is the same, then the permission matches:
|
||||
if (lenP == lenT)
|
||||
{
|
||||
const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions();
|
||||
for (cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr)
|
||||
{
|
||||
m_ResolvedPermissions[ itr->first ] = itr->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::ResolveGroups()
|
||||
{
|
||||
// Clear resolved groups first
|
||||
m_ResolvedGroups.clear();
|
||||
|
||||
// Get a complete resolved list of all groups the player is in
|
||||
std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates
|
||||
GroupList ToIterate;
|
||||
for (GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr)
|
||||
{
|
||||
ToIterate.push_back( *GroupItr);
|
||||
}
|
||||
while (ToIterate.begin() != ToIterate.end())
|
||||
{
|
||||
cGroup* CurrentGroup = *ToIterate.begin();
|
||||
if (AllGroups.find( CurrentGroup) != AllGroups.end())
|
||||
{
|
||||
LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!",
|
||||
GetName().c_str(), CurrentGroup->GetName().c_str()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
AllGroups[ CurrentGroup ] = true;
|
||||
m_ResolvedGroups.push_back( CurrentGroup); // Add group to resolved list
|
||||
const cGroup::GroupList & Inherits = CurrentGroup->GetInherits();
|
||||
for (cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr)
|
||||
{
|
||||
if (AllGroups.find( *itr) != AllGroups.end())
|
||||
{
|
||||
LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str());
|
||||
continue;
|
||||
}
|
||||
ToIterate.push_back( *itr);
|
||||
}
|
||||
}
|
||||
ToIterate.erase( ToIterate.begin());
|
||||
}
|
||||
// There are more sub-items in either the permission or the template, not a match:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1527,17 +1422,14 @@ void cPlayer::ResolveGroups()
|
||||
|
||||
AString cPlayer::GetColor(void) const
|
||||
{
|
||||
if (m_Color != '-')
|
||||
if (m_MsgNameColorCode.empty() || (m_MsgNameColorCode == "-"))
|
||||
{
|
||||
return cChatColor::Delimiter + m_Color;
|
||||
// Color has not been assigned, return an empty string:
|
||||
return AString();
|
||||
}
|
||||
|
||||
if (m_Groups.size() < 1)
|
||||
{
|
||||
return cChatColor::White;
|
||||
}
|
||||
|
||||
return (*m_Groups.begin())->GetColor();
|
||||
// Return the color, including the delimiter:
|
||||
return cChatColor::Delimiter + m_MsgNameColorCode;
|
||||
}
|
||||
|
||||
|
||||
@ -1653,48 +1545,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
|
||||
|
||||
|
||||
|
||||
void cPlayer::LoadPermissionsFromDisk()
|
||||
{
|
||||
m_Groups.clear();
|
||||
m_Permissions.clear();
|
||||
|
||||
cIniFile IniFile;
|
||||
if (IniFile.ReadFile("users.ini"))
|
||||
{
|
||||
AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default");
|
||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||
|
||||
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
|
||||
{
|
||||
if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr))
|
||||
{
|
||||
LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str());
|
||||
}
|
||||
AddToGroup(*itr);
|
||||
}
|
||||
|
||||
AString Color = IniFile.GetValue(GetName(), "Color", "-");
|
||||
if (!Color.empty())
|
||||
{
|
||||
m_Color = Color[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cGroupManager::GenerateDefaultUsersIni(IniFile);
|
||||
IniFile.AddValue("Groups", GetName(), "Default");
|
||||
AddToGroup("Default");
|
||||
}
|
||||
IniFile.WriteFile("users.ini");
|
||||
ResolvePermissions();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
|
||||
{
|
||||
LoadPermissionsFromDisk();
|
||||
LoadRank();
|
||||
|
||||
// Load from the UUID file:
|
||||
if (LoadFromFile(GetUUIDFileName(m_UUID), a_World))
|
||||
@ -1928,26 +1781,6 @@ bool cPlayer::SaveToDisk()
|
||||
|
||||
|
||||
|
||||
cPlayer::StringList cPlayer::GetResolvedPermissions()
|
||||
{
|
||||
StringList Permissions;
|
||||
|
||||
const PermissionMap& ResolvedPermissions = m_ResolvedPermissions;
|
||||
for (PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr)
|
||||
{
|
||||
if (itr->second)
|
||||
{
|
||||
Permissions.push_back( itr->first);
|
||||
}
|
||||
}
|
||||
|
||||
return Permissions;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::UseEquippedItem(int a_Amount)
|
||||
{
|
||||
if (IsGameModeCreative()) // No damage in creative
|
||||
@ -2206,6 +2039,27 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||
|
||||
|
||||
|
||||
void cPlayer::LoadRank(void)
|
||||
{
|
||||
// Load the values from cRankManager:
|
||||
cRankManager & RankMgr = cRoot::Get()->GetRankManager();
|
||||
m_Rank = RankMgr.GetPlayerRankName(m_UUID);
|
||||
m_Permissions = RankMgr.GetPlayerPermissions(m_UUID);
|
||||
RankMgr.GetPlayerMsgVisuals(m_UUID, 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)
|
||||
{
|
||||
m_SplitPermissions.push_back(StringSplit(*itr, "."));
|
||||
} // for itr - m_Permissions[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::Detach()
|
||||
{
|
||||
super::Detach();
|
||||
|
@ -236,24 +236,20 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
typedef std::list< cGroup* > GroupList;
|
||||
typedef std::list< std::string > StringList;
|
||||
bool HasPermission(const AString & a_Permission); // tolua_export
|
||||
|
||||
/** Adds a player to existing group or creates a new group when it doesn't exist */
|
||||
void AddToGroup( const AString & a_GroupName); // tolua_export
|
||||
/** Returns true iff a_Permission matches the a_Template.
|
||||
A match is defined by either being exactly the same, or each sub-item matches until there's a wildcard in a_Template.
|
||||
Ie. {"a", "b", "c"} matches {"a", "b", "*"} but doesn't match {"a", "b"} */
|
||||
static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template); // Exported in ManualBindings with AString params
|
||||
|
||||
/** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */
|
||||
void RemoveFromGroup( const AString & a_GroupName); // tolua_export
|
||||
|
||||
bool HasPermission( const AString & a_Permission); // tolua_export
|
||||
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
|
||||
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
bool IsInGroup( const AString & a_Group); // tolua_export
|
||||
/** Returns all the permissions that the player has assigned to them. */
|
||||
const AStringVector & GetPermissions(void) { return m_Permissions; } // Exported in ManualBindings.cpp
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the full color code to use for this player, based on their primary group or set in m_Color.
|
||||
The returned value includes the cChatColor::Delimiter. */
|
||||
/** Returns the full color code to use for this player, based on their rank.
|
||||
The returned value either is empty, or includes the cChatColor::Delimiter. */
|
||||
AString GetColor(void) const;
|
||||
|
||||
/** tosses the item in the selected hotbar slot */
|
||||
@ -347,8 +343,6 @@ public:
|
||||
*/
|
||||
bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World);
|
||||
|
||||
void LoadPermissionsFromDisk(void); // tolua_export
|
||||
|
||||
const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
|
||||
|
||||
void UseEquippedItem(int a_Amount = 1);
|
||||
@ -424,6 +418,11 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** (Re)loads the rank and permissions from the cRankManager.
|
||||
Expects the m_UUID member to be valid.
|
||||
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
|
||||
void LoadRank(void);
|
||||
|
||||
// cEntity overrides:
|
||||
virtual bool IsCrouched (void) const { return m_IsCrouched; }
|
||||
virtual bool IsSprinting(void) const { return m_IsSprinting; }
|
||||
@ -432,12 +431,22 @@ public:
|
||||
virtual void Detach(void);
|
||||
|
||||
protected:
|
||||
typedef std::map< std::string, bool > PermissionMap;
|
||||
PermissionMap m_ResolvedPermissions;
|
||||
PermissionMap m_Permissions;
|
||||
|
||||
GroupList m_ResolvedGroups;
|
||||
GroupList m_Groups;
|
||||
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
||||
|
||||
/** The name of the rank assigned to this player. */
|
||||
AString m_Rank;
|
||||
|
||||
/** All the permissions that this player has, based on their rank. */
|
||||
AStringVector m_Permissions;
|
||||
|
||||
/** 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;
|
||||
|
||||
// Message visuals:
|
||||
AString m_MsgPrefix, m_MsgSuffix;
|
||||
AString m_MsgNameColorCode;
|
||||
|
||||
AString m_PlayerName;
|
||||
AString m_LoadedWorldName;
|
||||
@ -482,8 +491,6 @@ protected:
|
||||
/** The player's last saved bed position */
|
||||
Vector3i m_LastBedPos;
|
||||
|
||||
char m_Color;
|
||||
|
||||
eGameMode m_GameMode;
|
||||
AString m_IP;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user