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