merged changes back from 1.0.1
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401992
This commit is contained in:
parent
3d349378ad
commit
b455ac4f4e
@ -41,12 +41,14 @@
|
|||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
|
#include "sm_srvcmds.h"
|
||||||
|
|
||||||
#define LEVEL_STATE_NONE 0
|
#define LEVEL_STATE_NONE 0
|
||||||
#define LEVEL_STATE_LEVELS 1
|
#define LEVEL_STATE_LEVELS 1
|
||||||
#define LEVEL_STATE_FLAGS 2
|
#define LEVEL_STATE_FLAGS 2
|
||||||
|
|
||||||
AdminCache g_Admins;
|
AdminCache g_Admins;
|
||||||
|
char g_ReverseFlags[26];
|
||||||
AdminFlag g_FlagLetters[26];
|
AdminFlag g_FlagLetters[26];
|
||||||
bool g_FlagSet[26];
|
bool g_FlagSet[26];
|
||||||
|
|
||||||
@ -299,8 +301,23 @@ void AdminCache::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
void AdminCache::OnSourceModLevelChange(const char *mapName)
|
void AdminCache::OnSourceModLevelChange(const char *mapName)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
AdminFlag flag;
|
||||||
|
|
||||||
/* For now, we only read these once per level. */
|
/* For now, we only read these once per level. */
|
||||||
s_FlagReader.LoadLevels();
|
s_FlagReader.LoadLevels();
|
||||||
|
|
||||||
|
for (i = 0; i < 26; i++)
|
||||||
|
{
|
||||||
|
if (FindFlag('a' + i, &flag))
|
||||||
|
{
|
||||||
|
g_ReverseFlags[flag] = 'a' + i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_ReverseFlags[flag] = '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdminCache::OnSourceModShutdown()
|
void AdminCache::OnSourceModShutdown()
|
||||||
@ -434,7 +451,9 @@ AdminId AdminCache::CreateAdmin(const char *name)
|
|||||||
assert(pUser->magic == USR_MAGIC_UNSET);
|
assert(pUser->magic == USR_MAGIC_UNSET);
|
||||||
id = m_FreeUserList;
|
id = m_FreeUserList;
|
||||||
m_FreeUserList = pUser->next_user;
|
m_FreeUserList = pUser->next_user;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
|
id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
|
||||||
pUser->grp_size = 0;
|
pUser->grp_size = 0;
|
||||||
pUser->grp_table = -1;
|
pUser->grp_table = -1;
|
||||||
@ -454,19 +473,28 @@ AdminId AdminCache::CreateAdmin(const char *name)
|
|||||||
{
|
{
|
||||||
m_FirstUser = id;
|
m_FirstUser = id;
|
||||||
m_LastUser = id;
|
m_LastUser = id;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
|
AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
|
||||||
pPrev->next_user = id;
|
pPrev->next_user = id;
|
||||||
pUser->prev_user = m_LastUser;
|
pUser->prev_user = m_LastUser;
|
||||||
m_LastUser = id;
|
m_LastUser = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Since we always append to the tail, we should invalidate their next */
|
||||||
|
pUser->next_user = -1;
|
||||||
|
|
||||||
if (name && name[0] != '\0')
|
if (name && name[0] != '\0')
|
||||||
{
|
{
|
||||||
int nameidx = m_pStrings->AddString(name);
|
int nameidx = m_pStrings->AddString(name);
|
||||||
pUser = (AdminUser *)m_pMemory->GetAddress(id);
|
pUser = (AdminUser *)m_pMemory->GetAddress(id);
|
||||||
pUser->nameidx = nameidx;
|
pUser->nameidx = nameidx;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pUser->nameidx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -1587,7 +1615,9 @@ bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
|
|||||||
|
|
||||||
bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
|
bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
|
||||||
{
|
{
|
||||||
if (c < 'a' || c > 'z')
|
if (c < 'a'
|
||||||
|
|| c > 'z'
|
||||||
|
|| !g_FlagSet[(unsigned)c - (unsigned)'a'])
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1600,6 +1630,21 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
|
||||||
|
{
|
||||||
|
if (!g_FlagSet[flag])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
*c = g_ReverseFlags[flag];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
|
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
|
||||||
{
|
{
|
||||||
FlagBits bits = 0;
|
FlagBits bits = 0;
|
||||||
@ -1730,3 +1775,303 @@ bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool o
|
|||||||
|
|
||||||
return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0;
|
return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int flags;
|
||||||
|
char flagstr[64];
|
||||||
|
|
||||||
|
fp = (FILE *)data;
|
||||||
|
flags = (int)*value;
|
||||||
|
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t\"%s\"\t\t\"%s\"\n", key, flagstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterator_glob_grp_override(Trie *pTrie, const char *key, void **value, void *data)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int flags;
|
||||||
|
char flagstr[64];
|
||||||
|
|
||||||
|
fp = (FILE *)data;
|
||||||
|
flags = (int)*value;
|
||||||
|
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterator_group_basic_override(Trie *pTrie, const char *key, void **value, void *data)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int flags;
|
||||||
|
char flagstr[64];
|
||||||
|
|
||||||
|
fp = (FILE *)data;
|
||||||
|
flags = (int)*value;
|
||||||
|
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", key, flagstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterator_group_grp_override(Trie *pTrie, const char *key, void **value, void *data)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int flags;
|
||||||
|
char flagstr[64];
|
||||||
|
|
||||||
|
fp = (FILE *)data;
|
||||||
|
flags = (int)*value;
|
||||||
|
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdminCache::DumpCache(FILE *fp)
|
||||||
|
{
|
||||||
|
int *itable;
|
||||||
|
AdminId aid;
|
||||||
|
GroupId gid;
|
||||||
|
char flagstr[64];
|
||||||
|
unsigned int num;
|
||||||
|
AdminUser *pAdmin;
|
||||||
|
AdminGroup *pGroup;
|
||||||
|
char name_buffer[512];
|
||||||
|
|
||||||
|
fprintf(fp, "\"Groups\"\n{\n");
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
gid = m_FirstGroup;
|
||||||
|
while (gid != INVALID_GROUP_ID
|
||||||
|
&& (pGroup = GetGroup(gid)) != NULL)
|
||||||
|
{
|
||||||
|
num++;
|
||||||
|
FillFlagString(pGroup->addflags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t/* num = %d, gid = 0x%X */\n", num, gid);
|
||||||
|
fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pGroup->nameidx));
|
||||||
|
fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
|
||||||
|
fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pGroup->immunity_level);
|
||||||
|
|
||||||
|
if (pGroup->immune_table != -1
|
||||||
|
&& (itable = (int *)m_pMemory->GetAddress(pGroup->immune_table)) != NULL)
|
||||||
|
{
|
||||||
|
AdminGroup *pAltGroup;
|
||||||
|
const char *gname, *mod;
|
||||||
|
|
||||||
|
for (int i = 1; i <= itable[0]; i++)
|
||||||
|
{
|
||||||
|
if ((pAltGroup = GetGroup(itable[i])) == NULL)
|
||||||
|
{
|
||||||
|
/* Assume the rest of the table is corrupt */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gname = GetString(pAltGroup->nameidx);
|
||||||
|
if (atoi(gname) != 0)
|
||||||
|
{
|
||||||
|
mod = "@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mod = "";
|
||||||
|
}
|
||||||
|
fprintf(fp, "\t\t\"immunity\"\t\t\"%s%s\"\n", mod, gname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "\n\t\t\"Overrides\"\n\t\t{\n");
|
||||||
|
if (pGroup->pCmdGrpTable != NULL)
|
||||||
|
{
|
||||||
|
sm_trie_bad_iterator(pGroup->pCmdGrpTable,
|
||||||
|
name_buffer,
|
||||||
|
sizeof(name_buffer),
|
||||||
|
iterator_group_grp_override,
|
||||||
|
fp);
|
||||||
|
}
|
||||||
|
if (pGroup->pCmdTable != NULL)
|
||||||
|
{
|
||||||
|
sm_trie_bad_iterator(pGroup->pCmdTable,
|
||||||
|
name_buffer,
|
||||||
|
sizeof(name_buffer),
|
||||||
|
iterator_group_basic_override,
|
||||||
|
fp);
|
||||||
|
}
|
||||||
|
fprintf(fp, "\t\t}\n");
|
||||||
|
|
||||||
|
fprintf(fp, "\t}\n");
|
||||||
|
|
||||||
|
if ((gid = pGroup->next_grp) != INVALID_GROUP_ID)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "}\n\n");
|
||||||
|
fprintf(fp, "\"Admins\"\n{\n");
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
aid = m_FirstUser;
|
||||||
|
while (aid != INVALID_ADMIN_ID
|
||||||
|
&& (pAdmin = GetUser(aid)) != NULL)
|
||||||
|
{
|
||||||
|
num++;
|
||||||
|
FillFlagString(pAdmin->flags, flagstr, sizeof(flagstr));
|
||||||
|
|
||||||
|
fprintf(fp, "\t/* num = %d, aid = 0x%X, serialno = 0x%X*/\n", num, aid, pAdmin->serialchange);
|
||||||
|
|
||||||
|
if (pAdmin->nameidx != -1)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pAdmin->nameidx));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(fp, "\t\"\"\n\t{\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pAdmin->auth.identidx != -1)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\t\t\"auth\"\t\t\t\"%s\"\n", GetMethodName(pAdmin->auth.index));
|
||||||
|
fprintf(fp, "\t\t\"identity\"\t\t\"%s\"\n", GetString(pAdmin->auth.identidx));
|
||||||
|
}
|
||||||
|
if (pAdmin->password != -1)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\t\t\"password\"\t\t\"%s\"\n", GetString(pAdmin->password));
|
||||||
|
}
|
||||||
|
fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
|
||||||
|
fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pAdmin->immunity_level);
|
||||||
|
|
||||||
|
if (pAdmin->grp_count != 0
|
||||||
|
&& pAdmin->grp_table != -1
|
||||||
|
&& (itable = (int *)m_pMemory->GetAddress(pAdmin->grp_table)) != NULL)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < pAdmin->grp_count; i++)
|
||||||
|
{
|
||||||
|
if ((pGroup = GetGroup(itable[i])) == NULL)
|
||||||
|
{
|
||||||
|
/* Assume the rest of the table is corrupt */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(fp, "\t\t\"group\"\t\t\t\"%s\"\n", GetString(pGroup->nameidx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "\t}\n");
|
||||||
|
|
||||||
|
if ((aid = pAdmin->next_user) != INVALID_ADMIN_ID)
|
||||||
|
{
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "}\n\n");
|
||||||
|
|
||||||
|
fprintf(fp, "\"Overrides\"\n{\n");
|
||||||
|
if (m_pCmdGrpOverrides != NULL)
|
||||||
|
{
|
||||||
|
sm_trie_bad_iterator(m_pCmdGrpOverrides,
|
||||||
|
name_buffer,
|
||||||
|
sizeof(name_buffer),
|
||||||
|
iterator_glob_grp_override,
|
||||||
|
fp);
|
||||||
|
}
|
||||||
|
if (m_pCmdOverrides != NULL)
|
||||||
|
{
|
||||||
|
sm_trie_bad_iterator(m_pCmdOverrides,
|
||||||
|
name_buffer,
|
||||||
|
sizeof(name_buffer),
|
||||||
|
iterator_glob_basic_override,
|
||||||
|
fp);
|
||||||
|
}
|
||||||
|
fprintf(fp, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminGroup *AdminCache::GetGroup(GroupId gid)
|
||||||
|
{
|
||||||
|
AdminGroup *pGroup;
|
||||||
|
|
||||||
|
pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
|
||||||
|
if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminUser *AdminCache::GetUser(AdminId aid)
|
||||||
|
{
|
||||||
|
AdminUser *pAdmin;
|
||||||
|
|
||||||
|
pAdmin = (AdminUser *)m_pMemory->GetAddress(aid);
|
||||||
|
if (!pAdmin || pAdmin->magic != USR_MAGIC_SET)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *AdminCache::GetMethodName(unsigned int index)
|
||||||
|
{
|
||||||
|
List<AuthMethod>::iterator iter;
|
||||||
|
for (iter=m_AuthMethods.begin();
|
||||||
|
iter!=m_AuthMethods.end();
|
||||||
|
iter++)
|
||||||
|
{
|
||||||
|
if (index-- == 0)
|
||||||
|
{
|
||||||
|
return (*iter).name.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *AdminCache::GetString(int idx)
|
||||||
|
{
|
||||||
|
return m_pStrings->GetString(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AdminCache::FillFlagString(FlagBits bits, char *buffer, size_t maxlen)
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
unsigned int i, num_flags;
|
||||||
|
AdminFlag flags[AdminFlags_TOTAL];
|
||||||
|
|
||||||
|
num_flags = FlagBitsToArray(bits, flags, AdminFlags_TOTAL);
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
for (i = 0; pos < maxlen && i < num_flags; i++)
|
||||||
|
{
|
||||||
|
if (FindFlagChar(flags[i], &buffer[pos]))
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[pos] = '\0';
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
|
||||||
|
|
||||||
|
if ((fp = fopen(buffer, "wt")) == NULL)
|
||||||
|
{
|
||||||
|
g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_Admins.DumpCache(fp);
|
||||||
|
|
||||||
|
g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
@ -153,6 +153,7 @@ public: //IAdminSystem
|
|||||||
bool FindFlag(const char *str, AdminFlag *pFlag);
|
bool FindFlag(const char *str, AdminFlag *pFlag);
|
||||||
bool FindFlag(char c, AdminFlag *pAdmFlag);
|
bool FindFlag(char c, AdminFlag *pAdmFlag);
|
||||||
FlagBits ReadFlagString(const char *flags, const char **end);
|
FlagBits ReadFlagString(const char *flags, const char **end);
|
||||||
|
size_t FillFlagString(FlagBits bits, char *buffer, size_t maxlen);
|
||||||
unsigned int GetAdminSerialChange(AdminId id);
|
unsigned int GetAdminSerialChange(AdminId id);
|
||||||
bool CanAdminUseCommand(int client, const char *cmd);
|
bool CanAdminUseCommand(int client, const char *cmd);
|
||||||
const char *GetGroupName(GroupId gid);
|
const char *GetGroupName(GroupId gid);
|
||||||
@ -164,8 +165,13 @@ public: //IAdminSystem
|
|||||||
const char *cmd,
|
const char *cmd,
|
||||||
FlagBits flags,
|
FlagBits flags,
|
||||||
bool override_only);
|
bool override_only);
|
||||||
|
bool FindFlagChar(AdminFlag flag, char *c);
|
||||||
public:
|
public:
|
||||||
bool IsValidAdmin(AdminId id);
|
bool IsValidAdmin(AdminId id);
|
||||||
|
void DumpCache(FILE *fp);
|
||||||
|
AdminGroup *GetGroup(GroupId gid);
|
||||||
|
AdminUser *GetUser(AdminId id);
|
||||||
|
const char *GetString(int idx);
|
||||||
private:
|
private:
|
||||||
void _UnsetCommandOverride(const char *cmd);
|
void _UnsetCommandOverride(const char *cmd);
|
||||||
void _UnsetCommandGroupOverride(const char *group);
|
void _UnsetCommandGroupOverride(const char *group);
|
||||||
@ -174,6 +180,7 @@ private:
|
|||||||
void DumpCommandOverrideCache(OverrideType type);
|
void DumpCommandOverrideCache(OverrideType type);
|
||||||
Trie *GetMethodByIndex(unsigned int index);
|
Trie *GetMethodByIndex(unsigned int index);
|
||||||
bool GetMethodIndex(const char *name, unsigned int *_index);
|
bool GetMethodIndex(const char *name, unsigned int *_index);
|
||||||
|
const char *GetMethodName(unsigned int index);
|
||||||
void NameFlag(const char *str, AdminFlag flag);
|
void NameFlag(const char *str, AdminFlag flag);
|
||||||
public:
|
public:
|
||||||
BaseStringTable *m_pStrings;
|
BaseStringTable *m_pStrings;
|
||||||
|
@ -357,6 +357,57 @@ void AddFloat(char **buf_p, size_t &maxlen, double fval, int width, int prec, in
|
|||||||
*buf_p = buf;
|
*buf_p = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddBinary(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
||||||
|
{
|
||||||
|
char text[32];
|
||||||
|
int digits;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
digits = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (val & 1)
|
||||||
|
{
|
||||||
|
text[digits++] = '1';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text[digits++] = '0';
|
||||||
|
}
|
||||||
|
val >>= 1;
|
||||||
|
} while (val);
|
||||||
|
|
||||||
|
buf = *buf_p;
|
||||||
|
|
||||||
|
if (!(flags & LADJUST))
|
||||||
|
{
|
||||||
|
while (digits < width && maxlen)
|
||||||
|
{
|
||||||
|
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||||
|
width--;
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (digits-- && maxlen)
|
||||||
|
{
|
||||||
|
*buf++ = text[digits];
|
||||||
|
width--;
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & LADJUST)
|
||||||
|
{
|
||||||
|
while (width-- && maxlen)
|
||||||
|
{
|
||||||
|
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||||
|
maxlen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf_p = buf;
|
||||||
|
}
|
||||||
|
|
||||||
void AddUInt(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
void AddUInt(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
||||||
{
|
{
|
||||||
char text[32];
|
char text[32];
|
||||||
@ -623,6 +674,13 @@ reswitch:
|
|||||||
arg++;
|
arg++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'b':
|
||||||
|
{
|
||||||
|
int *value = (int *)args[arg];
|
||||||
|
AddBinary(&buf_p, llen, *value, width, flags);
|
||||||
|
arg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
@ -809,6 +867,15 @@ reswitch:
|
|||||||
arg++;
|
arg++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'b':
|
||||||
|
{
|
||||||
|
CHECK_ARGS(0);
|
||||||
|
cell_t *value;
|
||||||
|
pCtx->LocalToPhysAddr(params[arg], &value);
|
||||||
|
AddBinary(&buf_p, llen, *value, width, flags);
|
||||||
|
arg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
|
@ -90,3 +90,32 @@ size_t sm_trie_mem_usage(Trie *trie)
|
|||||||
{
|
{
|
||||||
return trie->k.mem_usage();
|
return trie->k.mem_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct trie_iter_data
|
||||||
|
{
|
||||||
|
SM_TRIE_BAD_ITERATOR iter;
|
||||||
|
void *ptr;
|
||||||
|
Trie *pTrie;
|
||||||
|
};
|
||||||
|
|
||||||
|
void our_trie_iterator(KTrie<void *> *pTrie, const char *name, void *& obj, void *data)
|
||||||
|
{
|
||||||
|
trie_iter_data *our_iter;
|
||||||
|
|
||||||
|
our_iter = (trie_iter_data *)data;
|
||||||
|
our_iter->iter(our_iter->pTrie, name, &obj, our_iter->ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_trie_bad_iterator(Trie *trie,
|
||||||
|
char *buffer,
|
||||||
|
size_t maxlength,
|
||||||
|
SM_TRIE_BAD_ITERATOR iter,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
trie_iter_data our_iter;
|
||||||
|
|
||||||
|
our_iter.iter = iter;
|
||||||
|
our_iter.ptr = data;
|
||||||
|
our_iter.pTrie = trie;
|
||||||
|
trie->k.bad_iterator(buffer, maxlength, &our_iter, our_trie_iterator);
|
||||||
|
}
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
struct Trie;
|
struct Trie;
|
||||||
|
|
||||||
|
typedef void (*SM_TRIE_BAD_ITERATOR)(Trie *pTrie, const char *key, void **value, void *data);
|
||||||
|
|
||||||
Trie *sm_trie_create();
|
Trie *sm_trie_create();
|
||||||
void sm_trie_destroy(Trie *trie);
|
void sm_trie_destroy(Trie *trie);
|
||||||
bool sm_trie_insert(Trie *trie, const char *key, void *value);
|
bool sm_trie_insert(Trie *trie, const char *key, void *value);
|
||||||
@ -42,5 +44,10 @@ bool sm_trie_retrieve(Trie *trie, const char *key, void **value);
|
|||||||
bool sm_trie_delete(Trie *trie, const char *key);
|
bool sm_trie_delete(Trie *trie, const char *key);
|
||||||
void sm_trie_clear(Trie *trie);
|
void sm_trie_clear(Trie *trie);
|
||||||
size_t sm_trie_mem_usage(Trie *trie);
|
size_t sm_trie_mem_usage(Trie *trie);
|
||||||
|
void sm_trie_bad_iterator(Trie *trie,
|
||||||
|
char *buffer,
|
||||||
|
size_t maxlength,
|
||||||
|
SM_TRIE_BAD_ITERATOR iter,
|
||||||
|
void *data);
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_SIMPLE_TRIE_H_
|
#endif //_INCLUDE_SOURCEMOD_SIMPLE_TRIE_H_
|
||||||
|
@ -15,7 +15,7 @@ cellsof chars sizeof tagof
|
|||||||
|
|
||||||
# Predefined constants
|
# Predefined constants
|
||||||
false true cellbits cellmax cellmin charbits charmax charmin myinfo INVALID_HANDLE
|
false true cellbits cellmax cellmin charbits charmax charmin myinfo INVALID_HANDLE
|
||||||
__version
|
__version NULL_VECTOR NULL_STRING
|
||||||
|
|
||||||
# Predefined tag names
|
# Predefined tag names
|
||||||
bool Float Handle String
|
bool Float Handle String
|
||||||
|
BIN
editor/crimson/tools/compile.cmd
Normal file
BIN
editor/crimson/tools/compile.cmd
Normal file
Binary file not shown.
@ -415,6 +415,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "217"
|
||||||
|
"linux" "218"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,6 +498,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "217"
|
||||||
|
"linux" "218"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,6 +582,11 @@
|
|||||||
"windows" "30"
|
"windows" "30"
|
||||||
"linux" "31"
|
"linux" "31"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "211"
|
||||||
|
"linux" "212"
|
||||||
|
}
|
||||||
|
|
||||||
/* Temp Entities */
|
/* Temp Entities */
|
||||||
"TE_GetServerClass"
|
"TE_GetServerClass"
|
||||||
@ -675,6 +690,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "220"
|
||||||
|
"linux" "221"
|
||||||
|
}
|
||||||
|
|
||||||
/* Offset into CBaseTempEntity constructor.
|
/* Offset into CBaseTempEntity constructor.
|
||||||
* On Windows Dsytopia is heavily inlined; we use the function
|
* On Windows Dsytopia is heavily inlined; we use the function
|
||||||
@ -767,6 +787,11 @@
|
|||||||
"windows" "24"
|
"windows" "24"
|
||||||
"linux" "25"
|
"linux" "25"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "215"
|
||||||
|
"linux" "216"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,6 +871,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "217"
|
||||||
|
"linux" "218"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1020,6 +1050,11 @@
|
|||||||
"windows" "27"
|
"windows" "27"
|
||||||
"linux" "28"
|
"linux" "28"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "227"
|
||||||
|
"linux" "228"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Signatures"
|
"Signatures"
|
||||||
@ -1187,6 +1222,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "221"
|
||||||
|
"linux" "222"
|
||||||
|
}
|
||||||
|
|
||||||
/* Offset into LevelShutdown for CGlobalEntList */
|
/* Offset into LevelShutdown for CGlobalEntList */
|
||||||
"gEntList"
|
"gEntList"
|
||||||
@ -1281,6 +1321,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "217"
|
||||||
|
"linux" "218"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,6 +1405,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "217"
|
||||||
|
"linux" "218"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,6 +1490,11 @@
|
|||||||
"windows" "0"
|
"windows" "0"
|
||||||
"linux" "0"
|
"linux" "0"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "198"
|
||||||
|
"linux" "199"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Signatures"
|
"Signatures"
|
||||||
@ -1537,6 +1592,11 @@
|
|||||||
{
|
{
|
||||||
"windows" "7"
|
"windows" "7"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "198"
|
||||||
|
"linux" "199"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Signatures"
|
"Signatures"
|
||||||
@ -1656,6 +1716,11 @@
|
|||||||
"windows" "25"
|
"windows" "25"
|
||||||
"linux" "26"
|
"linux" "26"
|
||||||
}
|
}
|
||||||
|
"WeaponEquip"
|
||||||
|
{
|
||||||
|
"windows" "219"
|
||||||
|
"linux" "220"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"Signatures"
|
"Signatures"
|
||||||
{
|
{
|
||||||
|
@ -67,16 +67,6 @@ enum TFTeam
|
|||||||
*/
|
*/
|
||||||
native TF2_SetPlayerInvuln(client, bool:enabled);
|
native TF2_SetPlayerInvuln(client, bool:enabled);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a client on fire for 10 seconds.
|
|
||||||
*
|
|
||||||
* @param client Player's index.
|
|
||||||
* @noreturn
|
|
||||||
* @error Invalid client index, client not in game, or no mod support.
|
|
||||||
*/
|
|
||||||
native TF2_IgnitePlayer(client, target);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respawns a client
|
* Respawns a client
|
||||||
*
|
*
|
||||||
|
@ -648,6 +648,117 @@ public:
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterates over the trie returning all known values.
|
||||||
|
*
|
||||||
|
* Note: This function is for debugging. Do not use it as a
|
||||||
|
* production iterator since it's inefficient. Iteration is
|
||||||
|
* guaranteed to be sorted ascendingly.
|
||||||
|
*
|
||||||
|
* The callback function takes:
|
||||||
|
* (KTrie) - Pointer to this Trie
|
||||||
|
* (const char *) - String containing key name.
|
||||||
|
* (K &) - By-reference object at the key.
|
||||||
|
* (data) - User pointer.
|
||||||
|
*
|
||||||
|
* @param buffer Buffer to use as a key name cache.
|
||||||
|
* @param maxlength Maximum length of the key name buffer.
|
||||||
|
* @param data User pointer for passing to the iterator.
|
||||||
|
* @param func Iterator callback function.
|
||||||
|
*/
|
||||||
|
void bad_iterator(char *buffer,
|
||||||
|
size_t maxlength,
|
||||||
|
void *data,
|
||||||
|
void (*func)(KTrie *, const char *, K & obj, void *data))
|
||||||
|
{
|
||||||
|
bad_iterator_r(buffer, maxlength, 0, data, func, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void bad_iterator_r(char *buffer,
|
||||||
|
size_t maxlength,
|
||||||
|
size_t buf_pos,
|
||||||
|
void *data,
|
||||||
|
void (*func)(KTrie *, const char *, K & obj, void *data),
|
||||||
|
unsigned int root)
|
||||||
|
{
|
||||||
|
char *term;
|
||||||
|
unsigned int idx, limit, start;
|
||||||
|
|
||||||
|
limit = 255;
|
||||||
|
start = m_base[root].idx;
|
||||||
|
|
||||||
|
/* Bound our limits */
|
||||||
|
if (start + limit > m_baseSize)
|
||||||
|
{
|
||||||
|
limit = m_baseSize - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search for strings */
|
||||||
|
for (unsigned int i = 1; i <= limit; i++)
|
||||||
|
{
|
||||||
|
idx = start + i;
|
||||||
|
if (m_base[idx].mode == Node_Unused
|
||||||
|
|| m_base[idx].parent != root)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_base[idx].mode == Node_Arc)
|
||||||
|
{
|
||||||
|
if (buf_pos < maxlength - 1)
|
||||||
|
{
|
||||||
|
buffer[buf_pos++] = (char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_base[idx].valset)
|
||||||
|
{
|
||||||
|
buffer[buf_pos] = '\0';
|
||||||
|
func(this, buffer, m_base[idx].value, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bad_iterator_r(buffer,
|
||||||
|
maxlength,
|
||||||
|
buf_pos,
|
||||||
|
data,
|
||||||
|
func,
|
||||||
|
idx);
|
||||||
|
|
||||||
|
buf_pos--;
|
||||||
|
}
|
||||||
|
else if (m_base[idx].mode == Node_Term
|
||||||
|
&& m_base[idx].valset == true)
|
||||||
|
{
|
||||||
|
size_t save_buf_pos;
|
||||||
|
|
||||||
|
save_buf_pos = buf_pos;
|
||||||
|
if (buf_pos < maxlength - 1)
|
||||||
|
{
|
||||||
|
buffer[buf_pos++] = (char)i;
|
||||||
|
}
|
||||||
|
if (buf_pos < maxlength - 1)
|
||||||
|
{
|
||||||
|
size_t destlen, j;
|
||||||
|
|
||||||
|
term = &m_stringtab[m_base[idx].idx];
|
||||||
|
destlen = strlen(term);
|
||||||
|
for (j = 0;
|
||||||
|
j < destlen && j + buf_pos < maxlength - 1;
|
||||||
|
j++)
|
||||||
|
{
|
||||||
|
buffer[buf_pos + j] = term[j];
|
||||||
|
}
|
||||||
|
buf_pos += j;
|
||||||
|
}
|
||||||
|
buffer[buf_pos] = '\0';
|
||||||
|
|
||||||
|
func(this, buffer, m_base[idx].value, data);
|
||||||
|
|
||||||
|
buf_pos = save_buf_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
KTrie()
|
KTrie()
|
||||||
{
|
{
|
||||||
|
@ -2777,15 +2777,21 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
|
|||||||
constvalue *enumroot,int *errorfound)
|
constvalue *enumroot,int *errorfound)
|
||||||
{
|
{
|
||||||
cell dsize,totalsize;
|
cell dsize,totalsize;
|
||||||
int idx,abortparse;
|
int idx,abortparse,needbrace;
|
||||||
|
|
||||||
assert(cur>=0 && cur<numdim);
|
assert(cur>=0 && cur<numdim);
|
||||||
assert(startlit>=0);
|
assert(startlit>=0);
|
||||||
assert(cur+2<=numdim);/* there must be 2 dimensions or more to do */
|
assert(cur+2<=numdim);/* there must be 2 dimensions or more to do */
|
||||||
assert(errorfound!=NULL && *errorfound==FALSE);
|
assert(errorfound!=NULL && *errorfound==FALSE);
|
||||||
totalsize=0;
|
totalsize=0;
|
||||||
|
needbrace=1;
|
||||||
needtoken('{');
|
needtoken('{');
|
||||||
for (idx=0,abortparse=FALSE; !abortparse; idx++) {
|
for (idx=0,abortparse=FALSE; !abortparse; idx++) {
|
||||||
|
if (matchtoken('}'))
|
||||||
|
{
|
||||||
|
needbrace=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* In case the major dimension is zero, we need to store the offset
|
/* In case the major dimension is zero, we need to store the offset
|
||||||
* to the newly detected sub-array into the indirection table; i.e.
|
* to the newly detected sub-array into the indirection table; i.e.
|
||||||
* this table needs to be expanded and updated.
|
* this table needs to be expanded and updated.
|
||||||
@ -2815,7 +2821,10 @@ static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
|
|||||||
if (*errorfound || !matchtoken(','))
|
if (*errorfound || !matchtoken(','))
|
||||||
abortparse=TRUE;
|
abortparse=TRUE;
|
||||||
} /* for */
|
} /* for */
|
||||||
|
if (needbrace)
|
||||||
|
{
|
||||||
needtoken('}');
|
needtoken('}');
|
||||||
|
}
|
||||||
assert(counteddim!=NULL);
|
assert(counteddim!=NULL);
|
||||||
if (counteddim[cur]>0) {
|
if (counteddim[cur]>0) {
|
||||||
if (idx<counteddim[cur])
|
if (idx<counteddim[cur])
|
||||||
@ -2917,7 +2926,7 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
|
|||||||
if (size==0 || (litidx-curlit)==0)
|
if (size==0 || (litidx-curlit)==0)
|
||||||
error(41); /* invalid ellipsis, array size unknown */
|
error(41); /* invalid ellipsis, array size unknown */
|
||||||
else if ((litidx-curlit)==(int)size)
|
else if ((litidx-curlit)==(int)size)
|
||||||
error(18); /* initialisation data exceeds declared size */
|
error(18); /* initialization data exceeds declared size */
|
||||||
while ((litidx-curlit)<(int)size) {
|
while ((litidx-curlit)<(int)size) {
|
||||||
prev1+=step;
|
prev1+=step;
|
||||||
litadd(prev1);
|
litadd(prev1);
|
||||||
@ -2930,7 +2939,7 @@ static cell initvector(int ident,int tag,cell size,int fillzero,
|
|||||||
if (size==0) {
|
if (size==0) {
|
||||||
size=litidx-curlit; /* number of elements defined */
|
size=litidx-curlit; /* number of elements defined */
|
||||||
} else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
|
} else if (litidx-curlit>(int)size) { /* e.g. "myvar[3]={1,2,3,4};" */
|
||||||
error(18); /* initialisation data exceeds declared size */
|
error(18); /* initialization data exceeds declared size */
|
||||||
litidx=(int)size+curlit; /* avoid overflow in memory moves */
|
litidx=(int)size+curlit; /* avoid overflow in memory moves */
|
||||||
} /* if */
|
} /* if */
|
||||||
return size;
|
return size;
|
||||||
|
Loading…
Reference in New Issue
Block a user