core/AdminCache.cpp
author David Anderson <dvander@alliedmods.net>
Fri Jan 26 02:04:07 2007 +0000 (2007-01-26)
changeset 373 bf3335acefdd
parent 370 d3a484f98f6d
child 404 673ccd0935ba
permissions -rw-r--r--
added license headers to extensions
dvander@370
     1
/**
dvander@370
     2
 * ===============================================================
dvander@370
     3
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@370
     4
 * ===============================================================
dvander@370
     5
 *
dvander@370
     6
 * This file is not open source and may not be copied without explicit
dvander@370
     7
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@370
     8
 * in whole or significant part.
dvander@370
     9
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@370
    10
 *
dvander@370
    11
 * Version: $Id$
dvander@370
    12
 */
dvander@370
    13
dvander@335
    14
#include <string.h>
dvander@335
    15
#include <assert.h>
dvander@335
    16
#include "AdminCache.h"
dvander@335
    17
#include "ShareSys.h"
dvander@336
    18
#include "ForwardSys.h"
dvander@335
    19
dvander@335
    20
AdminCache g_Admins;
dvander@335
    21
dvander@335
    22
AdminCache::AdminCache()
dvander@335
    23
{
dvander@335
    24
	m_pCmdOverrides = NULL;
dvander@335
    25
	m_pCmdGrpOverrides = NULL;
dvander@335
    26
	m_pStrings = new BaseStringTable(1024);
dvander@335
    27
	m_pMemory = m_pStrings->GetMemTable();
dvander@335
    28
	m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID;
dvander@335
    29
	m_pGroups = sm_trie_create();
dvander@336
    30
	m_pCacheFwd = NULL;
dvander@335
    31
}
dvander@335
    32
dvander@335
    33
AdminCache::~AdminCache()
dvander@335
    34
{
dvander@335
    35
	if (m_pCmdGrpOverrides)
dvander@335
    36
	{
dvander@335
    37
		sm_trie_destroy(m_pCmdGrpOverrides);
dvander@335
    38
	}
dvander@335
    39
dvander@335
    40
	if (m_pCmdOverrides)
dvander@335
    41
	{
dvander@335
    42
		sm_trie_destroy(m_pCmdOverrides);
dvander@335
    43
	}
dvander@335
    44
dvander@335
    45
	InvalidateGroupCache();
dvander@335
    46
dvander@335
    47
	if (m_pGroups)
dvander@335
    48
	{
dvander@335
    49
		sm_trie_destroy(m_pGroups);
dvander@335
    50
	}
dvander@335
    51
dvander@335
    52
	delete m_pStrings;
dvander@335
    53
}
dvander@335
    54
dvander@335
    55
void AdminCache::OnSourceModAllInitialized()
dvander@335
    56
{
dvander@336
    57
	m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell);
dvander@335
    58
	g_ShareSys.AddInterface(NULL, this);
dvander@335
    59
}
dvander@335
    60
dvander@336
    61
void AdminCache::OnSourceModShutdown()
dvander@336
    62
{
dvander@336
    63
	g_Forwards.ReleaseForward(m_pCacheFwd);
dvander@336
    64
	m_pCacheFwd = NULL;
dvander@336
    65
}
dvander@336
    66
dvander@335
    67
void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag)
dvander@335
    68
{
dvander@335
    69
	if (type == Override_Command)
dvander@335
    70
	{
dvander@335
    71
		_AddCommandOverride(cmd, flag);
dvander@335
    72
	} else if (type == Override_CommandGroup) {
dvander@335
    73
		_AddCommandGroupOverride(cmd, flag);
dvander@335
    74
	}
dvander@335
    75
}
dvander@335
    76
dvander@335
    77
bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag)
dvander@335
    78
{
dvander@335
    79
	if (type == Override_Command)
dvander@335
    80
	{
dvander@335
    81
		return _GetCommandOverride(cmd, pFlag);
dvander@335
    82
	} else if (type == Override_CommandGroup) {
dvander@335
    83
		return _GetCommandGroupOverride(cmd, pFlag);
dvander@335
    84
	}
dvander@335
    85
dvander@335
    86
	return false;
dvander@335
    87
}
dvander@335
    88
dvander@335
    89
void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type)
dvander@335
    90
{
dvander@335
    91
	if (type == Override_Command)
dvander@335
    92
	{
dvander@335
    93
		return _UnsetCommandOverride(cmd);
dvander@335
    94
	} else if (type == Override_CommandGroup) {
dvander@335
    95
		return _UnsetCommandGroupOverride(cmd);
dvander@335
    96
	}
dvander@335
    97
}
dvander@335
    98
dvander@335
    99
void AdminCache::_AddCommandGroupOverride(const char *group, AdminFlag flag)
dvander@335
   100
{
dvander@335
   101
	if (!m_pCmdGrpOverrides)
dvander@335
   102
	{
dvander@335
   103
		m_pCmdGrpOverrides = sm_trie_create();
dvander@335
   104
	}
dvander@335
   105
dvander@335
   106
	/* :TODO: Notify command system */
dvander@335
   107
dvander@335
   108
	sm_trie_insert(m_pCmdGrpOverrides, group, (void *)flag);
dvander@335
   109
}
dvander@335
   110
dvander@335
   111
void AdminCache::_AddCommandOverride(const char *cmd, AdminFlag flag)
dvander@335
   112
{
dvander@335
   113
	if (!m_pCmdOverrides)
dvander@335
   114
	{
dvander@335
   115
		m_pCmdOverrides = sm_trie_create();
dvander@335
   116
	}
dvander@335
   117
dvander@335
   118
	/* :TODO: Notify command system */
dvander@335
   119
dvander@335
   120
	sm_trie_insert(m_pCmdOverrides, cmd, (void *)flag);
dvander@335
   121
}
dvander@335
   122
dvander@335
   123
bool AdminCache::_GetCommandGroupOverride(const char *cmd, AdminFlag *pFlag)
dvander@335
   124
{
dvander@335
   125
	if (!m_pCmdGrpOverrides)
dvander@335
   126
	{
dvander@335
   127
		return false;
dvander@335
   128
	}
dvander@335
   129
dvander@335
   130
	if (!pFlag)
dvander@335
   131
	{
dvander@335
   132
		return sm_trie_retrieve(m_pCmdGrpOverrides, cmd, NULL);
dvander@335
   133
	} else {
dvander@335
   134
		void *object;
dvander@335
   135
		bool ret;
dvander@335
   136
		if (ret=sm_trie_retrieve(m_pCmdGrpOverrides, cmd, &object))
dvander@335
   137
		{
dvander@335
   138
			*pFlag = (AdminFlag)(int)object;
dvander@335
   139
		}
dvander@335
   140
		return ret;
dvander@335
   141
	}
dvander@335
   142
}
dvander@335
   143
dvander@335
   144
bool AdminCache::_GetCommandOverride(const char *cmd, AdminFlag *pFlag)
dvander@335
   145
{
dvander@335
   146
	if (!m_pCmdOverrides)
dvander@335
   147
	{
dvander@335
   148
		return false;
dvander@335
   149
	}
dvander@335
   150
dvander@335
   151
	if (!pFlag)
dvander@335
   152
	{
dvander@335
   153
		return sm_trie_retrieve(m_pCmdOverrides, cmd, NULL);
dvander@335
   154
	} else {
dvander@335
   155
		void *object;
dvander@335
   156
		bool ret;
dvander@335
   157
		if (ret=sm_trie_retrieve(m_pCmdOverrides, cmd, &object))
dvander@335
   158
		{
dvander@335
   159
			*pFlag = (AdminFlag)(int)object;
dvander@335
   160
		}
dvander@335
   161
		return ret;
dvander@335
   162
	}
dvander@335
   163
}
dvander@335
   164
dvander@335
   165
void AdminCache::_UnsetCommandGroupOverride(const char *group)
dvander@335
   166
{
dvander@335
   167
	if (!m_pCmdGrpOverrides)
dvander@335
   168
	{
dvander@335
   169
		return;
dvander@335
   170
	}
dvander@335
   171
dvander@335
   172
	/* :TODO: Notify command system */
dvander@335
   173
dvander@335
   174
	sm_trie_delete(m_pCmdGrpOverrides, group);
dvander@335
   175
}
dvander@335
   176
dvander@335
   177
void AdminCache::_UnsetCommandOverride(const char *cmd)
dvander@335
   178
{
dvander@335
   179
	if (!m_pCmdOverrides)
dvander@335
   180
	{
dvander@335
   181
		return;
dvander@335
   182
	}
dvander@335
   183
dvander@335
   184
	/* :TODO: Notify command system */
dvander@335
   185
dvander@335
   186
	sm_trie_delete(m_pCmdOverrides, cmd);
dvander@335
   187
}
dvander@335
   188
dvander@335
   189
void AdminCache::DumpCommandOverrideCache(OverrideType type)
dvander@335
   190
{
dvander@335
   191
	if (type == Override_Command && m_pCmdOverrides)
dvander@335
   192
	{
dvander@335
   193
		sm_trie_clear(m_pCmdOverrides);
dvander@335
   194
	} else if (type == Override_CommandGroup && m_pCmdGrpOverrides) {
dvander@335
   195
		sm_trie_clear(m_pCmdGrpOverrides);
dvander@335
   196
	}
dvander@335
   197
}
dvander@335
   198
dvander@335
   199
GroupId AdminCache::AddGroup(const char *group_name)
dvander@335
   200
{
dvander@335
   201
	if (sm_trie_retrieve(m_pGroups, group_name, NULL))
dvander@335
   202
	{
dvander@335
   203
		return INVALID_GROUP_ID;
dvander@335
   204
	}
dvander@335
   205
dvander@335
   206
	GroupId id;
dvander@335
   207
	AdminGroup *pGroup;
dvander@335
   208
	if (m_FreeGroupList != INVALID_GROUP_ID)
dvander@335
   209
	{
dvander@335
   210
		pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList);
dvander@335
   211
		assert(pGroup->magic == GRP_MAGIC_UNSET);
dvander@335
   212
		id = m_FreeGroupList;
dvander@335
   213
		m_FreeGroupList = pGroup->next_grp;
dvander@335
   214
	} else {
dvander@335
   215
		id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup);
dvander@335
   216
	}
dvander@335
   217
dvander@335
   218
	pGroup->immune_default = false;
dvander@335
   219
	pGroup->immune_global = false;
dvander@335
   220
	pGroup->immune_table = -1;
dvander@335
   221
	pGroup->magic = GRP_MAGIC_SET;
dvander@335
   222
	pGroup->next_grp = INVALID_GROUP_ID;
dvander@335
   223
	pGroup->pCmdGrpTable = NULL;
dvander@335
   224
	pGroup->pCmdTable = NULL;
dvander@335
   225
	pGroup->nameidx = m_pStrings->AddString(group_name);
dvander@335
   226
	memset(pGroup->addflags, 0, sizeof(AdminFlag) * AdminFlags_TOTAL);
dvander@335
   227
dvander@335
   228
	if (m_FirstGroup == INVALID_GROUP_ID)
dvander@335
   229
	{
dvander@335
   230
		m_FirstGroup = id;
dvander@335
   231
		m_LastGroup = id;
dvander@335
   232
		pGroup->prev_grp = INVALID_GROUP_ID;
dvander@335
   233
	} else {
dvander@335
   234
		AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
dvander@335
   235
		assert(pPrev->magic == GRP_MAGIC_SET);
dvander@335
   236
		pPrev->next_grp = id;
dvander@335
   237
		pGroup->prev_grp = m_LastGroup;
dvander@335
   238
		m_LastGroup = id;
dvander@335
   239
	}
dvander@335
   240
dvander@335
   241
	sm_trie_insert(m_pGroups, group_name, (void *)id);
dvander@335
   242
dvander@335
   243
	return id;
dvander@335
   244
}
dvander@335
   245
dvander@335
   246
GroupId AdminCache::FindGroupByName(const char *group_name)
dvander@335
   247
{
dvander@335
   248
	void *object;
dvander@335
   249
dvander@335
   250
	if (!sm_trie_retrieve(m_pGroups, group_name, &object))
dvander@335
   251
	{
dvander@335
   252
		return INVALID_GROUP_ID;
dvander@335
   253
	}
dvander@335
   254
dvander@335
   255
	GroupId id = (GroupId)object;
dvander@335
   256
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   257
dvander@335
   258
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   259
	{
dvander@335
   260
		return INVALID_GROUP_ID;
dvander@335
   261
	}
dvander@335
   262
dvander@335
   263
	return id;
dvander@335
   264
}
dvander@335
   265
dvander@335
   266
void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled)
dvander@335
   267
{
dvander@335
   268
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   269
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   270
	{
dvander@335
   271
		return;
dvander@335
   272
	}
dvander@335
   273
dvander@335
   274
	if (flag < Admin_None || flag >= AdminFlags_TOTAL)
dvander@335
   275
	{
dvander@335
   276
		return;
dvander@335
   277
	}
dvander@335
   278
dvander@335
   279
	pGroup->addflags[flag] = enabled;
dvander@335
   280
}
dvander@335
   281
dvander@335
   282
bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag)
dvander@335
   283
{
dvander@335
   284
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   285
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   286
	{
dvander@335
   287
		return false;
dvander@335
   288
	}
dvander@335
   289
dvander@335
   290
	if (flag < Admin_None || flag >= AdminFlags_TOTAL)
dvander@335
   291
	{
dvander@335
   292
		return false;
dvander@335
   293
	}
dvander@335
   294
dvander@335
   295
	return pGroup->addflags[flag];
dvander@335
   296
}
dvander@335
   297
dvander@336
   298
unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total)
dvander@335
   299
{
dvander@335
   300
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   301
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   302
	{
dvander@335
   303
		return 0;
dvander@335
   304
	}
dvander@335
   305
dvander@336
   306
	unsigned int i;
dvander@335
   307
dvander@336
   308
	for (i = Admin_None;
dvander@336
   309
		 i < AdminFlags_TOTAL && i < total;
dvander@335
   310
		 i++)
dvander@335
   311
	{
dvander@336
   312
		flags[i] = pGroup->addflags[i];
dvander@335
   313
	}
dvander@335
   314
dvander@336
   315
	return i;
dvander@335
   316
}
dvander@335
   317
dvander@335
   318
void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled)
dvander@335
   319
{
dvander@335
   320
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   321
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   322
	{
dvander@335
   323
		return;
dvander@335
   324
	}
dvander@335
   325
dvander@335
   326
	if (type == Immunity_Default)
dvander@335
   327
	{
dvander@335
   328
		pGroup->immune_default = enabled;
dvander@335
   329
	} else if (type == Immunity_Global) {
dvander@335
   330
		pGroup->immune_global = enabled;
dvander@335
   331
	} 
dvander@335
   332
}
dvander@335
   333
dvander@335
   334
bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type)
dvander@335
   335
{
dvander@335
   336
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   337
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   338
	{
dvander@335
   339
		return false;
dvander@335
   340
	}
dvander@335
   341
dvander@335
   342
	if (type == Immunity_Default)
dvander@335
   343
	{
dvander@335
   344
		return pGroup->immune_default;
dvander@335
   345
	} else if (type == Immunity_Global) {
dvander@335
   346
		return pGroup->immune_global;
dvander@335
   347
	}
dvander@335
   348
dvander@335
   349
	return false;
dvander@335
   350
}
dvander@335
   351
dvander@335
   352
void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id)
dvander@335
   353
{
dvander@335
   354
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   355
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   356
	{
dvander@335
   357
		return;
dvander@335
   358
	}
dvander@335
   359
dvander@335
   360
	AdminGroup *pOther = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   361
	if (!pOther || pOther->magic != GRP_MAGIC_SET)
dvander@335
   362
	{
dvander@335
   363
		return;
dvander@335
   364
	}
dvander@335
   365
dvander@335
   366
	/* We always need to resize the immunity table */
dvander@335
   367
	int *table, tblidx;
dvander@335
   368
	if (pOther->immune_table == -1)
dvander@335
   369
	{
dvander@335
   370
		tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table);
dvander@335
   371
		table[0] = 0;
dvander@335
   372
	} else {
dvander@335
   373
		int *old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
dvander@335
   374
		tblidx = m_pMemory->CreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table);
dvander@335
   375
		/* Get the old address again in caes of resize */
dvander@335
   376
		old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
dvander@335
   377
		table[0] = old_table[0];
dvander@335
   378
		for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++)
dvander@335
   379
		{
dvander@335
   380
			table[i] = old_table[i];
dvander@335
   381
		}
dvander@335
   382
	}
dvander@335
   383
dvander@335
   384
	/* Assign */
dvander@335
   385
	pOther->immune_table = tblidx;
dvander@335
   386
dvander@335
   387
	/* Add to the array */
dvander@335
   388
	table[0]++;
dvander@335
   389
	table[table[0]] = other_id;
dvander@335
   390
}
dvander@335
   391
dvander@335
   392
unsigned int AdminCache::GetGroupImmunityCount(GroupId id)
dvander@335
   393
{
dvander@335
   394
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   395
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   396
	{
dvander@335
   397
		return 0;
dvander@335
   398
	}
dvander@335
   399
dvander@335
   400
	if (pGroup->immune_table == -1)
dvander@335
   401
	{
dvander@335
   402
		return 0;
dvander@335
   403
	}
dvander@335
   404
dvander@335
   405
	int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
dvander@335
   406
dvander@335
   407
	return table[0];
dvander@335
   408
}
dvander@335
   409
dvander@335
   410
GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number)
dvander@335
   411
{
dvander@335
   412
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   413
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   414
	{
dvander@335
   415
		return INVALID_GROUP_ID;
dvander@335
   416
	}
dvander@335
   417
dvander@335
   418
	if (pGroup->immune_table == -1)
dvander@335
   419
	{
dvander@335
   420
		return INVALID_GROUP_ID;
dvander@335
   421
	}
dvander@335
   422
dvander@335
   423
	int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
dvander@335
   424
	if (number >= (unsigned int)table[0])
dvander@335
   425
	{
dvander@335
   426
		return INVALID_GROUP_ID;
dvander@335
   427
	}
dvander@335
   428
dvander@335
   429
	return table[1 + number];
dvander@335
   430
}
dvander@335
   431
dvander@335
   432
void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule)
dvander@335
   433
{
dvander@335
   434
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   435
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   436
	{
dvander@335
   437
		return;
dvander@335
   438
	}
dvander@335
   439
dvander@335
   440
	Trie *pTrie = NULL;
dvander@335
   441
	if (type == Override_Command)
dvander@335
   442
	{
dvander@335
   443
		if (pGroup->pCmdTable == NULL)
dvander@335
   444
		{
dvander@335
   445
			pGroup->pCmdTable = sm_trie_create();
dvander@335
   446
		}
dvander@335
   447
		pTrie = pGroup->pCmdTable;
dvander@335
   448
	} else if (type == Override_CommandGroup) {
dvander@335
   449
		if (pGroup->pCmdGrpTable == NULL)
dvander@335
   450
		{
dvander@335
   451
			pGroup->pCmdGrpTable = sm_trie_create();
dvander@335
   452
		}
dvander@335
   453
		pTrie = pGroup->pCmdGrpTable;
dvander@335
   454
	} else {
dvander@335
   455
		return;
dvander@335
   456
	}
dvander@335
   457
dvander@335
   458
	sm_trie_insert(pTrie, name, (void *)(int)rule);
dvander@335
   459
}
dvander@335
   460
dvander@335
   461
bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule)
dvander@335
   462
{
dvander@335
   463
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   464
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   465
	{
dvander@335
   466
		return false;
dvander@335
   467
	}
dvander@335
   468
dvander@335
   469
	Trie *pTrie = NULL;
dvander@335
   470
	if (type == Override_Command)
dvander@335
   471
	{
dvander@335
   472
		if (pGroup->pCmdTable == NULL)
dvander@335
   473
		{
dvander@335
   474
			return false;
dvander@335
   475
		}
dvander@335
   476
		pTrie = pGroup->pCmdTable;
dvander@335
   477
	} else if (type == Override_CommandGroup) {
dvander@335
   478
		if (pGroup->pCmdGrpTable == NULL)
dvander@335
   479
		{
dvander@335
   480
			return false;
dvander@335
   481
		}
dvander@335
   482
		pTrie = pGroup->pCmdGrpTable;
dvander@335
   483
	} else {
dvander@335
   484
		return false;
dvander@335
   485
	}
dvander@335
   486
dvander@335
   487
	void *object;
dvander@335
   488
	if (!sm_trie_retrieve(pTrie, name, &object))
dvander@335
   489
	{
dvander@335
   490
		return false;
dvander@335
   491
	}
dvander@335
   492
dvander@335
   493
	if (pRule)
dvander@335
   494
	{
dvander@335
   495
		*pRule = (OverrideRule)(int)object;
dvander@335
   496
	}
dvander@335
   497
	
dvander@335
   498
	return true;
dvander@335
   499
}
dvander@335
   500
dvander@335
   501
void AdminCache::InvalidateGroup(GroupId id)
dvander@335
   502
{
dvander@335
   503
	AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
dvander@335
   504
	AdminGroup *pOther;
dvander@335
   505
dvander@335
   506
	if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
dvander@335
   507
	{
dvander@335
   508
		return;
dvander@335
   509
	}
dvander@335
   510
dvander@335
   511
	const char *str = m_pStrings->GetString(pGroup->nameidx);
dvander@335
   512
	sm_trie_delete(m_pGroups, str);
dvander@335
   513
dvander@335
   514
	/* Unlink from the live dbllink list */
dvander@335
   515
	if (id == m_FirstGroup && id == m_LastGroup)
dvander@335
   516
	{
dvander@335
   517
		m_LastGroup = INVALID_GROUP_ID;
dvander@335
   518
		m_FirstGroup = INVALID_GROUP_ID;
dvander@335
   519
	} else if (id == m_FirstGroup) {
dvander@335
   520
		m_FirstGroup = pGroup->next_grp;
dvander@335
   521
		pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup);
dvander@335
   522
		pOther->prev_grp = INVALID_GROUP_ID;
dvander@335
   523
	} else if (id == m_LastGroup) {
dvander@335
   524
		m_LastGroup = pGroup->prev_grp;
dvander@335
   525
		pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
dvander@335
   526
		pOther->next_grp = INVALID_GROUP_ID;
dvander@335
   527
	} else {
dvander@335
   528
		pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp);
dvander@335
   529
		pOther->next_grp = pGroup->next_grp;
dvander@335
   530
		pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp);
dvander@335
   531
		pOther->prev_grp = pGroup->prev_grp;
dvander@335
   532
	}
dvander@335
   533
dvander@335
   534
	/* Free any used memory to be safe */
dvander@335
   535
	if (pGroup->pCmdGrpTable)
dvander@335
   536
	{
dvander@335
   537
		sm_trie_destroy(pGroup->pCmdGrpTable);
dvander@335
   538
		pGroup->pCmdGrpTable = NULL;
dvander@335
   539
	}
dvander@335
   540
	if (pGroup->pCmdTable)
dvander@335
   541
	{
dvander@335
   542
		sm_trie_destroy(pGroup->pCmdTable);
dvander@335
   543
		pGroup->pCmdTable = NULL;
dvander@335
   544
	}
dvander@335
   545
dvander@335
   546
	/* Link into the free list */
dvander@335
   547
	pGroup->magic = GRP_MAGIC_UNSET;
dvander@335
   548
	pGroup->next_grp = m_FreeGroupList;
dvander@335
   549
	m_FreeGroupList = id;
dvander@335
   550
dvander@335
   551
	/* :TODO: remove this group from any users */
dvander@335
   552
}
dvander@335
   553
dvander@335
   554
void AdminCache::InvalidateGroupCache()
dvander@335
   555
{
dvander@335
   556
	/* Nuke the free list */
dvander@335
   557
	m_FreeGroupList = -1;
dvander@335
   558
dvander@335
   559
	/* Nuke reverse lookups */
dvander@335
   560
	sm_trie_clear(m_pGroups);
dvander@335
   561
dvander@335
   562
	/* Free memory on groups */
dvander@335
   563
	GroupId cur = m_FirstGroup;
dvander@335
   564
	AdminGroup *pGroup;
dvander@335
   565
	while (cur != INVALID_GROUP_ID)
dvander@335
   566
	{
dvander@335
   567
		pGroup = (AdminGroup *)m_pMemory->GetAddress(cur);
dvander@335
   568
		assert(pGroup->magic == GRP_MAGIC_SET);
dvander@335
   569
		if (pGroup->pCmdGrpTable)
dvander@335
   570
		{
dvander@335
   571
			sm_trie_destroy(pGroup->pCmdGrpTable);
dvander@335
   572
		}
dvander@335
   573
		if (pGroup->pCmdTable)
dvander@335
   574
		{
dvander@335
   575
			sm_trie_destroy(pGroup->pCmdTable);
dvander@335
   576
		}
dvander@335
   577
		cur = pGroup->next_grp;
dvander@335
   578
	}
dvander@335
   579
dvander@335
   580
	m_FirstGroup = INVALID_GROUP_ID;
dvander@335
   581
	m_LastGroup = INVALID_GROUP_ID;
dvander@335
   582
dvander@335
   583
	/* :TODO: dump the admin cache */
dvander@335
   584
dvander@335
   585
	/* Reset the memory table */
dvander@335
   586
	m_pMemory->Reset();
dvander@335
   587
}
dvander@336
   588
dvander@336
   589
void AdminCache::AddAdminListener(IAdminListener *pListener)
dvander@336
   590
{
dvander@336
   591
	m_hooks.push_back(pListener);
dvander@336
   592
}
dvander@336
   593
dvander@336
   594
void AdminCache::RemoveAdminListener(IAdminListener *pListener)
dvander@336
   595
{
dvander@336
   596
	m_hooks.remove(pListener);
dvander@336
   597
}
dvander@336
   598
dvander@336
   599
void AdminCache::DumpAdminCache(int cache_flags, bool rebuild)
dvander@336
   600
{
dvander@336
   601
	if (cache_flags & ADMIN_CACHE_OVERRIDES)
dvander@336
   602
	{
dvander@336
   603
		DumpCommandOverrideCache(Override_Command);
dvander@336
   604
		DumpCommandOverrideCache(Override_CommandGroup);
dvander@336
   605
	}
dvander@336
   606
dvander@336
   607
	if ((cache_flags & ADMIN_CACHE_ADMINS) ||
dvander@336
   608
		(cache_flags & ADMIN_CACHE_GROUPS))
dvander@336
   609
	{
dvander@336
   610
		/* Make sure the flag is set */
dvander@336
   611
		cache_flags |= ADMIN_CACHE_ADMINS;
dvander@336
   612
		/* :TODO: Dump admin cache */
dvander@336
   613
	}
dvander@336
   614
dvander@336
   615
	if (cache_flags & ADMIN_CACHE_GROUPS)
dvander@336
   616
	{
dvander@336
   617
		InvalidateGroupCache();
dvander@336
   618
	}
dvander@336
   619
dvander@336
   620
	if (rebuild)
dvander@336
   621
	{
dvander@336
   622
		List<IAdminListener *>::iterator iter;
dvander@336
   623
		IAdminListener *pListener;
dvander@345
   624
		cell_t result;
dvander@336
   625
		for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
dvander@336
   626
		{
dvander@336
   627
			pListener = (*iter);
dvander@336
   628
			pListener->OnRebuildAdminCache(cache_flags);
dvander@336
   629
		}
dvander@345
   630
		m_pCacheFwd->PushCell(cache_flags);
dvander@345
   631
		m_pCacheFwd->Execute(&result);
dvander@336
   632
	}
dvander@336
   633
}