3 #include "AdminCache.h"
8 AdminCache::AdminCache()
10 m_pCmdOverrides = NULL;
11 m_pCmdGrpOverrides = NULL;
12 m_pStrings = new BaseStringTable(1024);
13 m_pMemory = m_pStrings->GetMemTable();
14 m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID;
15 m_pGroups = sm_trie_create();
18 AdminCache::~AdminCache()
20 if (m_pCmdGrpOverrides)
22 sm_trie_destroy(m_pCmdGrpOverrides);
27 sm_trie_destroy(m_pCmdOverrides);
30 InvalidateGroupCache();
34 sm_trie_destroy(m_pGroups);
40 void AdminCache::OnSourceModAllInitialized()
42 g_ShareSys.AddInterface(NULL, this);
45 void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag)
47 if (type == Override_Command)
49 _AddCommandOverride(cmd, flag);
50 } else if (type == Override_CommandGroup) {
51 _AddCommandGroupOverride(cmd, flag);
55 bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag)
57 if (type == Override_Command)
59 return _GetCommandOverride(cmd, pFlag);
60 } else if (type == Override_CommandGroup) {
61 return _GetCommandGroupOverride(cmd, pFlag);
67 void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type)
69 if (type == Override_Command)
71 return _UnsetCommandOverride(cmd);
72 } else if (type == Override_CommandGroup) {
73 return _UnsetCommandGroupOverride(cmd);
77 void AdminCache::_AddCommandGroupOverride(const char *group, AdminFlag flag)
79 if (!m_pCmdGrpOverrides)
81 m_pCmdGrpOverrides = sm_trie_create();
84 /* :TODO: Notify command system */
86 sm_trie_insert(m_pCmdGrpOverrides, group, (void *)flag);
89 void AdminCache::_AddCommandOverride(const char *cmd, AdminFlag flag)
93 m_pCmdOverrides = sm_trie_create();
96 /* :TODO: Notify command system */
98 sm_trie_insert(m_pCmdOverrides, cmd, (void *)flag);
101 bool AdminCache::_GetCommandGroupOverride(const char *cmd, AdminFlag *pFlag)
103 if (!m_pCmdGrpOverrides)
110 return sm_trie_retrieve(m_pCmdGrpOverrides, cmd, NULL);
114 if (ret=sm_trie_retrieve(m_pCmdGrpOverrides, cmd, &object))
116 *pFlag = (AdminFlag)(int)object;
122 bool AdminCache::_GetCommandOverride(const char *cmd, AdminFlag *pFlag)
124 if (!m_pCmdOverrides)
131 return sm_trie_retrieve(m_pCmdOverrides, cmd, NULL);
135 if (ret=sm_trie_retrieve(m_pCmdOverrides, cmd, &object))
137 *pFlag = (AdminFlag)(int)object;
143 void AdminCache::_UnsetCommandGroupOverride(const char *group)
145 if (!m_pCmdGrpOverrides)
150 /* :TODO: Notify command system */
152 sm_trie_delete(m_pCmdGrpOverrides, group);
155 void AdminCache::_UnsetCommandOverride(const char *cmd)
157 if (!m_pCmdOverrides)
162 /* :TODO: Notify command system */
164 sm_trie_delete(m_pCmdOverrides, cmd);
167 void AdminCache::DumpCommandOverrideCache(OverrideType type)
169 if (type == Override_Command && m_pCmdOverrides)
171 sm_trie_clear(m_pCmdOverrides);
172 } else if (type == Override_CommandGroup && m_pCmdGrpOverrides) {
173 sm_trie_clear(m_pCmdGrpOverrides);
177 GroupId AdminCache::AddGroup(const char *group_name)
179 if (sm_trie_retrieve(m_pGroups, group_name, NULL))
181 return INVALID_GROUP_ID;
186 if (m_FreeGroupList != INVALID_GROUP_ID)
188 pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList);
189 assert(pGroup->magic == GRP_MAGIC_UNSET);
190 id = m_FreeGroupList;
191 m_FreeGroupList = pGroup->next_grp;
193 id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup);
196 pGroup->immune_default = false;
197 pGroup->immune_global = false;
198 pGroup->immune_table = -1;
199 pGroup->magic = GRP_MAGIC_SET;
200 pGroup->next_grp = INVALID_GROUP_ID;
201 pGroup->pCmdGrpTable = NULL;
202 pGroup->pCmdTable = NULL;
203 pGroup->nameidx = m_pStrings->AddString(group_name);
204 memset(pGroup->addflags, 0, sizeof(AdminFlag) * AdminFlags_TOTAL);
206 if (m_FirstGroup == INVALID_GROUP_ID)
210 pGroup->prev_grp = INVALID_GROUP_ID;
212 AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
213 assert(pPrev->magic == GRP_MAGIC_SET);
214 pPrev->next_grp = id;
215 pGroup->prev_grp = m_LastGroup;
219 sm_trie_insert(m_pGroups, group_name, (void *)id);
224 GroupId AdminCache::FindGroupByName(const char *group_name)
228 if (!sm_trie_retrieve(m_pGroups, group_name, &object))
230 return INVALID_GROUP_ID;
233 GroupId id = (GroupId)object;
234 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
236 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
238 return INVALID_GROUP_ID;
244 void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled)
246 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
247 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
252 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
257 pGroup->addflags[flag] = enabled;
260 bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag)
262 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
263 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
268 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
273 return pGroup->addflags[flag];
276 unsigned int AdminCache::GetGroupAddFlags(GroupId id, AdminFlag flags[], unsigned int total)
278 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
279 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
286 for (unsigned int i = Admin_None + 1;
287 i < AdminFlags_TOTAL && r < total;
290 if (pGroup->addflags[i])
292 flags[r++] = (AdminFlag)i;
299 void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled)
301 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
302 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
307 if (type == Immunity_Default)
309 pGroup->immune_default = enabled;
310 } else if (type == Immunity_Global) {
311 pGroup->immune_global = enabled;
315 bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type)
317 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
318 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
323 if (type == Immunity_Default)
325 return pGroup->immune_default;
326 } else if (type == Immunity_Global) {
327 return pGroup->immune_global;
333 void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id)
335 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
336 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
341 AdminGroup *pOther = (AdminGroup *)m_pMemory->GetAddress(id);
342 if (!pOther || pOther->magic != GRP_MAGIC_SET)
347 /* We always need to resize the immunity table */
349 if (pOther->immune_table == -1)
351 tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table);
354 int *old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
355 tblidx = m_pMemory->CreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table);
356 /* Get the old address again in caes of resize */
357 old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
358 table[0] = old_table[0];
359 for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++)
361 table[i] = old_table[i];
366 pOther->immune_table = tblidx;
368 /* Add to the array */
370 table[table[0]] = other_id;
373 unsigned int AdminCache::GetGroupImmunityCount(GroupId id)
375 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
376 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
381 if (pGroup->immune_table == -1)
386 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
391 GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number)
393 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
394 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
396 return INVALID_GROUP_ID;
399 if (pGroup->immune_table == -1)
401 return INVALID_GROUP_ID;
404 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
405 if (number >= (unsigned int)table[0])
407 return INVALID_GROUP_ID;
410 return table[1 + number];
413 void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule)
415 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
416 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
422 if (type == Override_Command)
424 if (pGroup->pCmdTable == NULL)
426 pGroup->pCmdTable = sm_trie_create();
428 pTrie = pGroup->pCmdTable;
429 } else if (type == Override_CommandGroup) {
430 if (pGroup->pCmdGrpTable == NULL)
432 pGroup->pCmdGrpTable = sm_trie_create();
434 pTrie = pGroup->pCmdGrpTable;
439 sm_trie_insert(pTrie, name, (void *)(int)rule);
442 bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule)
444 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
445 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
451 if (type == Override_Command)
453 if (pGroup->pCmdTable == NULL)
457 pTrie = pGroup->pCmdTable;
458 } else if (type == Override_CommandGroup) {
459 if (pGroup->pCmdGrpTable == NULL)
463 pTrie = pGroup->pCmdGrpTable;
469 if (!sm_trie_retrieve(pTrie, name, &object))
476 *pRule = (OverrideRule)(int)object;
482 void AdminCache::InvalidateGroup(GroupId id)
484 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
487 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
492 const char *str = m_pStrings->GetString(pGroup->nameidx);
493 sm_trie_delete(m_pGroups, str);
495 /* Unlink from the live dbllink list */
496 if (id == m_FirstGroup && id == m_LastGroup)
498 m_LastGroup = INVALID_GROUP_ID;
499 m_FirstGroup = INVALID_GROUP_ID;
500 } else if (id == m_FirstGroup) {
501 m_FirstGroup = pGroup->next_grp;
502 pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup);
503 pOther->prev_grp = INVALID_GROUP_ID;
504 } else if (id == m_LastGroup) {
505 m_LastGroup = pGroup->prev_grp;
506 pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
507 pOther->next_grp = INVALID_GROUP_ID;
509 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp);
510 pOther->next_grp = pGroup->next_grp;
511 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp);
512 pOther->prev_grp = pGroup->prev_grp;
515 /* Free any used memory to be safe */
516 if (pGroup->pCmdGrpTable)
518 sm_trie_destroy(pGroup->pCmdGrpTable);
519 pGroup->pCmdGrpTable = NULL;
521 if (pGroup->pCmdTable)
523 sm_trie_destroy(pGroup->pCmdTable);
524 pGroup->pCmdTable = NULL;
527 /* Link into the free list */
528 pGroup->magic = GRP_MAGIC_UNSET;
529 pGroup->next_grp = m_FreeGroupList;
530 m_FreeGroupList = id;
532 /* :TODO: remove this group from any users */
535 void AdminCache::InvalidateGroupCache()
537 /* Nuke the free list */
538 m_FreeGroupList = -1;
540 /* Nuke reverse lookups */
541 sm_trie_clear(m_pGroups);
543 /* Free memory on groups */
544 GroupId cur = m_FirstGroup;
546 while (cur != INVALID_GROUP_ID)
548 pGroup = (AdminGroup *)m_pMemory->GetAddress(cur);
549 assert(pGroup->magic == GRP_MAGIC_SET);
550 if (pGroup->pCmdGrpTable)
552 sm_trie_destroy(pGroup->pCmdGrpTable);
554 if (pGroup->pCmdTable)
556 sm_trie_destroy(pGroup->pCmdTable);
558 cur = pGroup->next_grp;
561 m_FirstGroup = INVALID_GROUP_ID;
562 m_LastGroup = INVALID_GROUP_ID;
564 /* :TODO: dump the admin cache */
566 /* Reset the memory table */