initial import of binding user admin ids to players in game

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40464
This commit is contained in:
David Anderson 2007-02-09 01:08:59 +00:00
parent fdba3e1f66
commit 1c80875ea3
8 changed files with 338 additions and 0 deletions

View File

@ -16,6 +16,7 @@
#include "AdminCache.h"
#include "ShareSys.h"
#include "ForwardSys.h"
#include "CPlayerManager.h"
AdminCache g_Admins;
@ -31,6 +32,7 @@ AdminCache::AdminCache()
m_pCacheFwd = NULL;
m_FirstGroup = -1;
m_pAuthTables = sm_trie_create();
m_InvalidatingAdmins = false;
}
AdminCache::~AdminCache()
@ -544,6 +546,11 @@ bool AdminCache::InvalidateAdmin(AdminId id)
return false;
}
if (!m_InvalidatingAdmins)
{
g_Players.ClearAdminId(id);
}
/* Unlink from the dbl link list */
if (id == m_FirstUser && id == m_LastUser)
{
@ -738,6 +745,8 @@ void AdminCache::RegisterAuthIdentType(const char *name)
void AdminCache::InvalidateAdminCache(bool unlink_admins)
{
m_InvalidatingAdmins = true;
g_Players.ClearAllAdmins();
/* Wipe the identity cache first */
List<AuthMethod>::iterator iter;
for (iter=m_AuthMethods.begin();
@ -758,6 +767,7 @@ void AdminCache::InvalidateAdminCache(bool unlink_admins)
m_LastUser = -1;
m_FreeUserList = -1;
}
m_InvalidatingAdmins = false;
}
void AdminCache::DumpAdminCache(AdminCachePart part, bool rebuild)
@ -950,6 +960,23 @@ FlagBits AdminCache::GetAdminFlags(AdminId id, AccessMode mode)
return 0;
}
void AdminCache::SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits)
{
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
if (!pUser || pUser->magic != USR_MAGIC_SET)
{
return;
}
if (mode == Access_Real)
{
pUser->flags = bits;
pUser->eflags = bits;
} else if (mode == Access_Effective) {
pUser->eflags = bits;
}
}
bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
{
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
@ -1025,6 +1052,12 @@ bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
return true;
}
bool AdminCache::IsValidAdmin(AdminId id)
{
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
return (pUser != NULL && pUser->magic == USR_MAGIC_SET);
}
unsigned int AdminCache::GetAdminGroupCount(AdminId id)
{
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);

View File

@ -131,6 +131,9 @@ public: //IAdminSystem
unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize);
bool CheckAdminFlags(AdminId id, FlagBits bits);
bool CanAdminTarget(AdminId id, AdminId target);
void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits);
public:
bool IsValidAdmin(AdminId id);
private:
void _UnsetCommandOverride(const char *cmd);
void _UnsetCommandGroupOverride(const char *group);
@ -155,6 +158,7 @@ public:
int m_FirstUser;
int m_LastUser;
int m_FreeUserList;
bool m_InvalidatingAdmins;
};
extern AdminCache g_Admins;

View File

@ -14,6 +14,7 @@
#include "CPlayerManager.h"
#include "ForwardSys.h"
#include "ShareSys.h"
#include "AdminCache.h"
CPlayerManager g_Players;
@ -383,6 +384,26 @@ IGamePlayer *CPlayerManager::GetGamePlayer(int client)
return GetPlayerByIndex(client);
}
void CPlayerManager::ClearAdminId(AdminId id)
{
for (int i=1; i<=m_maxClients; i++)
{
if (m_Players[i].m_Admin == id)
{
m_Players[i].DumpAdmin(true);
}
}
}
void CPlayerManager::ClearAllAdmins()
{
for (int i=1; i<=m_maxClients; i++)
{
m_Players[i].DumpAdmin(true);
}
}
/*******************
*** PLAYER CODE ***
*******************/
@ -393,6 +414,8 @@ CPlayer::CPlayer()
m_IsInGame = false;
m_IsAuthorized = false;
m_pEdict = NULL;
m_Admin = INVALID_ADMIN_ID;
m_TempAdmin = false;
}
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@ -416,6 +439,7 @@ void CPlayer::Authorize(const char *steamid)
void CPlayer::Disconnect()
{
DumpAdmin(false);
m_IsConnected = false;
m_IsInGame = false;
m_IsAuthorized = false;
@ -469,3 +493,34 @@ bool CPlayer::IsFakeClient() const
{
return (strcmp(m_AuthID.c_str(), "BOT") == 0);
}
void CPlayer::SetAdminId(AdminId id, bool temporary)
{
if (!m_IsConnected)
{
return;
}
DumpAdmin(false);
m_Admin = id;
m_TempAdmin = temporary;
}
AdminId CPlayer::GetAdminId() const
{
return m_Admin;
}
void CPlayer::DumpAdmin(bool deleting)
{
if (m_Admin != INVALID_ADMIN_ID)
{
if (m_TempAdmin && !deleting)
{
g_Admins.InvalidateAdmin(m_Admin);
}
m_Admin = INVALID_ADMIN_ID;
m_TempAdmin = false;
}
}

View File

@ -19,6 +19,7 @@
#include "sourcemm_api.h"
#include <IForwardSys.h>
#include <IPlayerHelpers.h>
#include <IAdminSystem.h>
#include <sh_string.h>
#include <sh_list.h>
#include <sh_vector.h>
@ -39,12 +40,15 @@ public:
bool IsConnected() const;
bool IsAuthorized() const;
bool IsFakeClient() const;
void SetAdminId(AdminId id, bool temporary);
AdminId GetAdminId() const;
private:
void Initialize(const char *name, const char *ip, edict_t *pEntity);
void Connect();
void Authorize(const char *steamid);
void Disconnect();
void SetName(const char *name);
void DumpAdmin(bool deleting);
private:
bool m_IsConnected;
bool m_IsInGame;
@ -52,6 +56,8 @@ private:
String m_Name;
String m_Ip;
String m_AuthID;
AdminId m_Admin;
bool m_TempAdmin;
edict_t *m_pEdict;
};
@ -68,6 +74,8 @@ public: //SMGlobalClass
public:
CPlayer *GetPlayerByIndex(int client) const;
void RunAuthChecks();
void ClearAdminId(AdminId id);
void ClearAllAdmins();
public:
bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
bool OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);

View File

@ -12,6 +12,7 @@
*/
#include "CPlayerManager.h"
#include "AdminCache.h"
#include "sm_stringutil.h"
static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
@ -230,6 +231,150 @@ static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
return 1;
}
static cell_t SetUserAdmin(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
if (!g_Admins.IsValidAdmin(params[2]))
{
return pContext->ThrowNativeError("AdminId %x is not valid.", params[2]);
}
pPlayer->SetAdminId(params[2], params[3] ? true : false);
return 1;
}
static cell_t GetUserAdmin(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
return pPlayer->GetAdminId();
}
static cell_t AddUserFlags(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
AdminId id;
if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
{
id = g_Admins.CreateAdmin(NULL);
pPlayer->SetAdminId(id, true);
}
cell_t *addr;
for (int i=2; i<=params[0]; i++)
{
pContext->LocalToPhysAddr(params[i], &addr);
g_Admins.SetAdminFlag(id, (AdminFlag)*addr, true);
}
return 1;
}
static cell_t RemoveUserFlags(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
AdminId id;
if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
{
return 0;
}
cell_t *addr;
for (int i=2; i<=params[0]; i++)
{
pContext->LocalToPhysAddr(params[i], &addr);
g_Admins.SetAdminFlag(id, (AdminFlag)*addr, false);
}
return 1;
}
static cell_t SetUserFlagBits(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
AdminId id;
if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
{
id = g_Admins.CreateAdmin(NULL);
pPlayer->SetAdminId(id, true);
}
g_Admins.SetAdminFlags(id, Access_Effective, params[2]);
return 1;
}
static cell_t GetUserFlagBits(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Invalid client index %d.", client);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected.", client);
}
AdminId id;
if ((id=pPlayer->GetAdminId()) == INVALID_ADMIN_ID)
{
return 0;
}
return g_Admins.GetAdminFlags(id, Access_Effective);
}
REGISTER_NATIVES(playernatives)
{
{"GetMaxClients", sm_GetMaxClients},
@ -244,6 +389,11 @@ REGISTER_NATIVES(playernatives)
{"PrintToServer", sm_PrintToServer},
{"PrintToConsole", sm_PrintToConsole},
{"GetClientInfo", sm_GetClientInfo},
{"SetUserAdmin", SetUserAdmin},
{"AddUserFlags", AddUserFlags},
{"RemoveUserFlags", RemoveUserFlags},
{"SetUserFlagBits", SetUserFlagBits},
{"GetUserFlagBits", GetUserFlagBits},
{NULL, NULL}
};

View File

@ -235,9 +235,72 @@ native bool:IsPlayerFakeClient(client);
* @param value Buffer to store value.
* @param maxlen Maximum length of valve (UTF-8 safe).
* @return True on success, false otherwise.
* @error Invalid client index, or client not connected.
*/
native bool:GetClientInfo(client, const String:key[], String:value[], maxlen);
/**
* Sets a client's AdminId.
*
* @param client Player's index.
* @param id AdminId to set. INVALID_ADMIN_ID removes admin permissions.
* @param temp True if the id should be freed on disconnect.
* @noreturn
* @error Invalid client index, client not connected, or bogus AdminId.
*/
native SetUserAdmin(client, AdminId:id, bool:temp=false);
/**
* Retrieves a client's AdminId.
*
* @param client Player's index.
* @return AdminId of the client, or INVALID_ADMIN_ID if none.
* @error Invalid client index, or client not connected.
*/
native AdminId:GetUserAdmin(client);
/**
* Sets access flags on a client. If the client is not an admin,
* a temporary, anonymous AdminId is given.
*
* @param client Player's index.
* @param ... Flags to set on the client.
* @noreturn
* @error Invalid client index, or client not connected.
*/
native AddUserFlags(client, {AdminFlag}:...);
/**
* Removes flags from a client. If the client is not an admin,
* this has no effect.
*
* @param client Player's index.
* @param ... Flags to remove from the client.
* @noreturn
* @error Invalid client index, or client not connected.
*/
native RemoveUserFlags(client, {AdminFlag}:...);
/**
* Sets access flags on a client using bits instead of flags. If the
* client is not an admin, and flags not 0, a temporary, anonymous AdminId is given.
*
* @param client Player's index.
* @param flags Bitstring of flags to set on client.
* @noreturn
*/
native SetUserFlagBits(client, flags);
/**
* Returns client access flags. If the client is not an admin,
* the result is always 0.
*
* @param client Player's index.
* @return Flags
* @error Invalid client index, or client not connected.
*/
native GetUserFlagBits(client);
/**
* Sends a message to the server console.
*

View File

@ -444,6 +444,15 @@ namespace SourceMod
*/
virtual FlagBits GetAdminFlags(AdminId id, AccessMode mode) =0;
/**
* @brief Sets the bitstring of access flags on an admin.
*
* @param id AdminId index of the admin.
* @param mode Access mode to use (real affects both).
* @param bits Bitstring to set.
*/
virtual void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits) =0;
/**
* @brief Adds a group to an admin's inherited group list.
* Any flags the group has will be added to the admin's effective flags.

View File

@ -20,6 +20,7 @@
#define _INCLUDE_SOURCEMOD_INTERFACE_IPLAYERHELPERS_H_
#include <IShareSys.h>
#include <IAdminSystem.h>
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
#define SMINTERFACE_PLAYERMANAGER_VERSION 1
@ -92,6 +93,21 @@ namespace SourceMod
* @return True if a fake client, false otherwise.
*/
virtual bool IsFakeClient() const =0;
/**
* @brief Returns the client's AdminId, if any.
*
* @return AdminId, or INVALID_ADMIN_ID if none.
*/
virtual AdminId GetAdminId() const =0;
/**
* @brief Sets the client's AdminId.
*
* @param id AdminId to set.
* @param temp If true, the id will be invalidated on disconnect.
*/
virtual void SetAdminId(AdminId id, bool temp) =0;
};
/**