1
0

cPlayer reads ranks from cRankManager.

This commit is contained in:
Mattes D 2014-08-19 17:34:11 +02:00
parent 3a7089539c
commit 949aa2f383
3 changed files with 144 additions and 268 deletions

View File

@ -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); cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
if (self == 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())
{ {
const cGroup * Group = *iter; LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
tolua_pushusertype(tolua_S, (void *)Group, "const cGroup"); return 0;
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
}
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; 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 < template <
class OBJTYPE, class OBJTYPE,
void (OBJTYPE::*SetCallback)(cPluginLua * a_Plugin, int a_FnRef) 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_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlayer"); tolua_beginmodule(tolua_S, "cPlayer");
tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups); tolua_function(tolua_S, "GetPermissions", tolua_cPlayer_GetPermissions);
tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions); tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow);
tolua_function(tolua_S, "OpenWindow", tolua_cPlayer_OpenWindow); tolua_function(tolua_S, "PermissionMatches", tolua_cPlayer_PermissionMatches);
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cLuaWindow"); tolua_beginmodule(tolua_S, "cLuaWindow");

View File

@ -59,7 +59,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) :
m_EnderChestContents(9, 3), m_EnderChestContents(9, 3),
m_CurrentWindow(NULL), m_CurrentWindow(NULL),
m_InventoryWindow(NULL), m_InventoryWindow(NULL),
m_Color('-'),
m_GameMode(eGameMode_NotSet), m_GameMode(eGameMode_NotSet),
m_IP(""), m_IP(""),
m_ClientHandle(a_Client), 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) bool cPlayer::HasPermission(const AString & a_Permission)
{ {
if (a_Permission.empty()) if (a_Permission.empty())
@ -1409,47 +1366,18 @@ bool cPlayer::HasPermission(const AString & a_Permission)
return true; return true;
} }
AStringVector Split = StringSplit( a_Permission, "."); AStringVector Split = StringSplit(a_Permission, ".");
PermissionMap Possibilities = m_ResolvedPermissions;
// Now search the namespaces // Iterate over all granted permissions; if any matches, then return success:
while (Possibilities.begin() != Possibilities.end()) for (AStringVectorVector::const_iterator itr = m_SplitPermissions.begin(), end = m_SplitPermissions.end(); itr != end; ++itr)
{ {
PermissionMap::iterator itr = Possibilities.begin(); if (PermissionMatches(Split, *itr))
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);
}
// Nothing that matched :(
return false;
}
bool cPlayer::IsInGroup( const AString & a_Group)
{
for (GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr)
{
if (a_Group.compare( (*itr)->GetName().c_str()) == 0)
return true; return true;
} }
} // for itr - m_SplitPermissions[]
// No granted permission matches
return false; 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 // Check the sub-items if they are the same or there's a wildcard:
size_t lenP = a_Permission.size();
// Copy all player specific permissions into the resolved permissions map size_t lenT = a_Template.size();
for (PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr) 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] == "*")
}
for (GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr)
{
const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions();
for (cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr)
{ {
m_ResolvedPermissions[ itr->first ] = itr->second; // 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;
} }
} }
}
// So far all the sub-items have matched
// If the sub-item count is the same, then the permission matches:
if (lenP == lenT)
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); return true;
}
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 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 the color, including the delimiter:
{ return cChatColor::Delimiter + m_MsgNameColorCode;
return cChatColor::White;
}
return (*m_Groups.begin())->GetColor();
} }
@ -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) bool cPlayer::LoadFromDisk(cWorldPtr & a_World)
{ {
LoadPermissionsFromDisk(); LoadRank();
// Load from the UUID file: // Load from the UUID file:
if (LoadFromFile(GetUUIDFileName(m_UUID), a_World)) 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) void cPlayer::UseEquippedItem(int a_Amount)
{ {
if (IsGameModeCreative()) // No damage in creative 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() void cPlayer::Detach()
{ {
super::Detach(); super::Detach();

View File

@ -236,24 +236,20 @@ public:
// tolua_end // tolua_end
typedef std::list< cGroup* > GroupList; bool HasPermission(const AString & a_Permission); // tolua_export
typedef std::list< std::string > StringList;
/** Adds a player to existing group or creates a new group when it doesn't exist */ /** Returns true iff a_Permission matches the a_Template.
void AddToGroup( const AString & a_GroupName); // tolua_export 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"} */
/** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */ static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template); // Exported in ManualBindings with AString params
void RemoveFromGroup( const AString & a_GroupName); // tolua_export
/** Returns all the permissions that the player has assigned to them. */
bool HasPermission( const AString & a_Permission); // tolua_export const AStringVector & GetPermissions(void) { return m_Permissions; } // Exported in ManualBindings.cpp
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
bool IsInGroup( const AString & a_Group); // tolua_export
// tolua_begin // tolua_begin
/** Returns the full color code to use for this player, based on their primary group or set in m_Color. /** Returns the full color code to use for this player, based on their rank.
The returned value includes the cChatColor::Delimiter. */ The returned value either is empty, or includes the cChatColor::Delimiter. */
AString GetColor(void) const; AString GetColor(void) const;
/** tosses the item in the selected hotbar slot */ /** tosses the item in the selected hotbar slot */
@ -347,8 +343,6 @@ public:
*/ */
bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World); bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World);
void LoadPermissionsFromDisk(void); // tolua_export
const AString & GetLoadedWorldName() { return m_LoadedWorldName; } const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
void UseEquippedItem(int a_Amount = 1); void UseEquippedItem(int a_Amount = 1);
@ -424,6 +418,11 @@ public:
// tolua_end // 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: // cEntity overrides:
virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsCrouched (void) const { return m_IsCrouched; }
virtual bool IsSprinting(void) const { return m_IsSprinting; } virtual bool IsSprinting(void) const { return m_IsSprinting; }
@ -432,12 +431,22 @@ public:
virtual void Detach(void); virtual void Detach(void);
protected: protected:
typedef std::map< std::string, bool > PermissionMap;
PermissionMap m_ResolvedPermissions;
PermissionMap m_Permissions;
GroupList m_ResolvedGroups; typedef std::vector<std::vector<AString> > AStringVectorVector;
GroupList m_Groups;
/** 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_PlayerName;
AString m_LoadedWorldName; AString m_LoadedWorldName;
@ -482,8 +491,6 @@ protected:
/** The player's last saved bed position */ /** The player's last saved bed position */
Vector3i m_LastBedPos; Vector3i m_LastBedPos;
char m_Color;
eGameMode m_GameMode; eGameMode m_GameMode;
AString m_IP; AString m_IP;