Optimized forwards, now paused functions are stored in a temp list so we dont have to check if they're runnable on each function execution.
2 * ===============================================================
3 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
4 * ===============================================================
6 * This file is not open source and may not be copied without explicit
7 * written permission of AlliedModders LLC. This file may not be redistributed
8 * in whole or significant part.
9 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
16 #include "AdminCache.h"
18 #include "ForwardSys.h"
22 AdminCache::AdminCache()
24 m_pCmdOverrides = NULL;
25 m_pCmdGrpOverrides = NULL;
26 m_pStrings = new BaseStringTable(1024);
27 m_pMemory = m_pStrings->GetMemTable();
28 m_FreeGroupList = m_FirstGroup = m_LastGroup = INVALID_GROUP_ID;
29 m_FreeUserList = m_FirstUser = m_LastUser = INVALID_ADMIN_ID;
30 m_pGroups = sm_trie_create();
33 m_pAuthTables = sm_trie_create();
36 AdminCache::~AdminCache()
38 if (m_pCmdGrpOverrides)
40 sm_trie_destroy(m_pCmdGrpOverrides);
45 sm_trie_destroy(m_pCmdOverrides);
48 DumpAdminCache(0xFFFFFFFF, false);
52 sm_trie_destroy(m_pGroups);
55 List<AuthMethod>::iterator iter;
56 for (iter=m_AuthMethods.begin();
57 iter!=m_AuthMethods.end();
60 sm_trie_destroy((*iter).table);
63 sm_trie_destroy(m_pAuthTables);
68 void AdminCache::OnSourceModStartup(bool late)
70 RegisterAuthIdentType("steam");
71 RegisterAuthIdentType("name");
72 RegisterAuthIdentType("ip");
75 void AdminCache::OnSourceModAllInitialized()
77 m_pCacheFwd = g_Forwards.CreateForward("OnRebuildAdminCache", ET_Ignore, 1, NULL, Param_Cell);
78 g_ShareSys.AddInterface(NULL, this);
81 void AdminCache::OnSourceModShutdown()
83 g_Forwards.ReleaseForward(m_pCacheFwd);
87 void AdminCache::AddCommandOverride(const char *cmd, OverrideType type, AdminFlag flag)
89 if (type == Override_Command)
91 _AddCommandOverride(cmd, flag);
92 } else if (type == Override_CommandGroup) {
93 _AddCommandGroupOverride(cmd, flag);
97 bool AdminCache::GetCommandOverride(const char *cmd, OverrideType type, AdminFlag *pFlag)
99 if (type == Override_Command)
101 return _GetCommandOverride(cmd, pFlag);
102 } else if (type == Override_CommandGroup) {
103 return _GetCommandGroupOverride(cmd, pFlag);
109 void AdminCache::UnsetCommandOverride(const char *cmd, OverrideType type)
111 if (type == Override_Command)
113 return _UnsetCommandOverride(cmd);
114 } else if (type == Override_CommandGroup) {
115 return _UnsetCommandGroupOverride(cmd);
119 void AdminCache::_AddCommandGroupOverride(const char *group, AdminFlag flag)
121 if (!m_pCmdGrpOverrides)
123 m_pCmdGrpOverrides = sm_trie_create();
126 /* :TODO: Notify command system */
128 sm_trie_insert(m_pCmdGrpOverrides, group, (void *)flag);
131 void AdminCache::_AddCommandOverride(const char *cmd, AdminFlag flag)
133 if (!m_pCmdOverrides)
135 m_pCmdOverrides = sm_trie_create();
138 /* :TODO: Notify command system */
140 sm_trie_insert(m_pCmdOverrides, cmd, (void *)flag);
143 bool AdminCache::_GetCommandGroupOverride(const char *cmd, AdminFlag *pFlag)
145 if (!m_pCmdGrpOverrides)
152 return sm_trie_retrieve(m_pCmdGrpOverrides, cmd, NULL);
156 if (ret=sm_trie_retrieve(m_pCmdGrpOverrides, cmd, &object))
158 *pFlag = (AdminFlag)(int)object;
164 bool AdminCache::_GetCommandOverride(const char *cmd, AdminFlag *pFlag)
166 if (!m_pCmdOverrides)
173 return sm_trie_retrieve(m_pCmdOverrides, cmd, NULL);
177 if (ret=sm_trie_retrieve(m_pCmdOverrides, cmd, &object))
179 *pFlag = (AdminFlag)(int)object;
185 void AdminCache::_UnsetCommandGroupOverride(const char *group)
187 if (!m_pCmdGrpOverrides)
192 /* :TODO: Notify command system */
194 sm_trie_delete(m_pCmdGrpOverrides, group);
197 void AdminCache::_UnsetCommandOverride(const char *cmd)
199 if (!m_pCmdOverrides)
204 /* :TODO: Notify command system */
206 sm_trie_delete(m_pCmdOverrides, cmd);
209 void AdminCache::DumpCommandOverrideCache(OverrideType type)
211 if (type == Override_Command && m_pCmdOverrides)
213 sm_trie_clear(m_pCmdOverrides);
214 } else if (type == Override_CommandGroup && m_pCmdGrpOverrides) {
215 sm_trie_clear(m_pCmdGrpOverrides);
219 AdminId AdminCache::CreateAdmin(const char *name)
224 if (m_FreeUserList != INVALID_ADMIN_ID)
226 pUser = (AdminUser *)m_pMemory->GetAddress(m_FreeUserList);
227 assert(pUser->magic == USR_MAGIC_UNSET);
229 m_FreeUserList = pUser->next_user;
231 id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
233 pUser->grp_table = -1;
236 memset(pUser->flags, 0, sizeof(pUser->flags));
237 memset(pUser->eflags, 0, sizeof(pUser->flags));
238 pUser->grp_count = 0;
239 pUser->password = -1;
240 pUser->magic = USR_MAGIC_SET;
241 pUser->auth.identidx = -1;
242 pUser->auth.index = 0;
244 if (m_FirstUser == INVALID_ADMIN_ID)
249 AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
250 pPrev->next_user = id;
251 pUser->prev_user = m_LastUser;
255 if (name && name[0] != '\0')
257 pUser->nameidx = m_pStrings->AddString(name);
263 GroupId AdminCache::AddGroup(const char *group_name)
265 if (sm_trie_retrieve(m_pGroups, group_name, NULL))
267 return INVALID_GROUP_ID;
272 if (m_FreeGroupList != INVALID_GROUP_ID)
274 pGroup = (AdminGroup *)m_pMemory->GetAddress(m_FreeGroupList);
275 assert(pGroup->magic == GRP_MAGIC_UNSET);
276 id = m_FreeGroupList;
277 m_FreeGroupList = pGroup->next_grp;
279 id = m_pMemory->CreateMem(sizeof(AdminGroup), (void **)&pGroup);
282 pGroup->immune_default = false;
283 pGroup->immune_global = false;
284 pGroup->immune_table = -1;
285 pGroup->magic = GRP_MAGIC_SET;
286 pGroup->next_grp = INVALID_GROUP_ID;
287 pGroup->pCmdGrpTable = NULL;
288 pGroup->pCmdTable = NULL;
289 memset(pGroup->addflags, 0, sizeof(AdminFlag) * AdminFlags_TOTAL);
291 if (m_FirstGroup == INVALID_GROUP_ID)
295 pGroup->prev_grp = INVALID_GROUP_ID;
297 AdminGroup *pPrev = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
298 assert(pPrev->magic == GRP_MAGIC_SET);
299 pPrev->next_grp = id;
300 pGroup->prev_grp = m_LastGroup;
304 pGroup->nameidx = m_pStrings->AddString(group_name);
306 sm_trie_insert(m_pGroups, group_name, (void *)id);
311 GroupId AdminCache::FindGroupByName(const char *group_name)
315 if (!sm_trie_retrieve(m_pGroups, group_name, &object))
317 return INVALID_GROUP_ID;
320 GroupId id = (GroupId)object;
321 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
323 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
325 return INVALID_GROUP_ID;
331 void AdminCache::SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled)
333 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
334 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
339 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
344 pGroup->addflags[flag] = enabled;
347 bool AdminCache::GetGroupAddFlag(GroupId id, AdminFlag flag)
349 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
350 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
355 if (flag < Admin_None || flag >= AdminFlags_TOTAL)
360 return pGroup->addflags[flag];
363 unsigned int AdminCache::GetGroupAddFlagBits(GroupId id, bool flags[], unsigned int total)
365 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
366 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
374 i < AdminFlags_TOTAL && i < total;
377 flags[i] = pGroup->addflags[i];
383 void AdminCache::SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled)
385 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
386 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
391 if (type == Immunity_Default)
393 pGroup->immune_default = enabled;
394 } else if (type == Immunity_Global) {
395 pGroup->immune_global = enabled;
399 bool AdminCache::GetGroupGenericImmunity(GroupId id, ImmunityType type)
401 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
402 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
407 if (type == Immunity_Default)
409 return pGroup->immune_default;
410 } else if (type == Immunity_Global) {
411 return pGroup->immune_global;
417 void AdminCache::AddGroupImmunity(GroupId id, GroupId other_id)
419 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
420 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
425 AdminGroup *pOther = (AdminGroup *)m_pMemory->GetAddress(id);
426 if (!pOther || pOther->magic != GRP_MAGIC_SET)
431 /* We always need to resize the immunity table */
433 if (pOther->immune_table == -1)
435 tblidx = m_pMemory->CreateMem(sizeof(int) * 2, (void **)&table);
438 int *old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
439 tblidx = m_pMemory->CreateMem(sizeof(int) * (old_table[0] + 2), (void **)&table);
440 /* Get the old address again in caes of resize */
441 old_table = (int *)m_pMemory->GetAddress(pOther->immune_table);
442 table[0] = old_table[0];
443 for (unsigned int i=1; i<=(unsigned int)old_table[0]; i++)
445 table[i] = old_table[i];
450 pOther->immune_table = tblidx;
452 /* Add to the array */
454 table[table[0]] = other_id;
457 unsigned int AdminCache::GetGroupImmunityCount(GroupId id)
459 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
460 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
465 if (pGroup->immune_table == -1)
470 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
475 GroupId AdminCache::GetGroupImmunity(GroupId id, unsigned int number)
477 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
478 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
480 return INVALID_GROUP_ID;
483 if (pGroup->immune_table == -1)
485 return INVALID_GROUP_ID;
488 int *table = (int *)m_pMemory->GetAddress(pGroup->immune_table);
489 if (number >= (unsigned int)table[0])
491 return INVALID_GROUP_ID;
494 return table[1 + number];
497 void AdminCache::AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule)
499 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
500 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
506 if (type == Override_Command)
508 if (pGroup->pCmdTable == NULL)
510 pGroup->pCmdTable = sm_trie_create();
512 pTrie = pGroup->pCmdTable;
513 } else if (type == Override_CommandGroup) {
514 if (pGroup->pCmdGrpTable == NULL)
516 pGroup->pCmdGrpTable = sm_trie_create();
518 pTrie = pGroup->pCmdGrpTable;
523 sm_trie_insert(pTrie, name, (void *)(int)rule);
526 bool AdminCache::GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule)
528 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
529 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
535 if (type == Override_Command)
537 if (pGroup->pCmdTable == NULL)
541 pTrie = pGroup->pCmdTable;
542 } else if (type == Override_CommandGroup) {
543 if (pGroup->pCmdGrpTable == NULL)
547 pTrie = pGroup->pCmdGrpTable;
553 if (!sm_trie_retrieve(pTrie, name, &object))
560 *pRule = (OverrideRule)(int)object;
566 Trie *AdminCache::GetMethodByIndex(unsigned int index)
568 List<AuthMethod>::iterator iter;
569 for (iter=m_AuthMethods.begin();
570 iter!=m_AuthMethods.end();
575 return (*iter).table;
582 bool AdminCache::InvalidateAdmin(AdminId id)
584 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
586 if (!pUser || pUser->magic != USR_MAGIC_SET)
591 /* Unlink from the dbl link list */
592 if (id == m_FirstUser && id == m_LastUser)
594 m_FirstUser = INVALID_ADMIN_ID;
595 m_LastUser = INVALID_ADMIN_ID;
596 } else if (id == m_FirstUser) {
597 m_FirstUser = pUser->next_user;
598 pOther = (AdminUser *)m_pMemory->GetAddress(m_FirstUser);
599 pOther->prev_user = INVALID_ADMIN_ID;
600 } else if (id == m_LastUser) {
601 m_LastUser = pUser->prev_user;
602 pOther = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
603 pOther->next_user = INVALID_ADMIN_ID;
605 pOther = (AdminUser *)m_pMemory->GetAddress(pUser->prev_user);
606 pOther->next_user = pUser->next_user;
607 pOther = (AdminUser *)m_pMemory->GetAddress(pUser->next_user);
608 pOther->prev_user = pUser->prev_user;
611 /* Unlink from auth tables */
612 if (pUser->auth.identidx != -1)
614 Trie *pTrie = GetMethodByIndex(pUser->auth.index);
617 sm_trie_delete(pTrie, m_pStrings->GetString(pUser->auth.identidx));
621 /* Clear table counts */
622 pUser->grp_count = 0;
624 /* Link into free list */
625 pUser->magic = USR_MAGIC_UNSET;
626 pUser->next_user = m_FreeUserList;
633 void AdminCache::InvalidateGroup(GroupId id)
635 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(id);
638 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
643 const char *str = m_pStrings->GetString(pGroup->nameidx);
644 sm_trie_delete(m_pGroups, str);
646 /* Unlink from the live dbllink list */
647 if (id == m_FirstGroup && id == m_LastGroup)
649 m_LastGroup = INVALID_GROUP_ID;
650 m_FirstGroup = INVALID_GROUP_ID;
651 } else if (id == m_FirstGroup) {
652 m_FirstGroup = pGroup->next_grp;
653 pOther = (AdminGroup *)m_pMemory->GetAddress(m_FirstGroup);
654 pOther->prev_grp = INVALID_GROUP_ID;
655 } else if (id == m_LastGroup) {
656 m_LastGroup = pGroup->prev_grp;
657 pOther = (AdminGroup *)m_pMemory->GetAddress(m_LastGroup);
658 pOther->next_grp = INVALID_GROUP_ID;
660 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->prev_grp);
661 pOther->next_grp = pGroup->next_grp;
662 pOther = (AdminGroup *)m_pMemory->GetAddress(pGroup->next_grp);
663 pOther->prev_grp = pGroup->prev_grp;
666 /* Free any used memory to be safe */
667 if (pGroup->pCmdGrpTable)
669 sm_trie_destroy(pGroup->pCmdGrpTable);
670 pGroup->pCmdGrpTable = NULL;
672 if (pGroup->pCmdTable)
674 sm_trie_destroy(pGroup->pCmdTable);
675 pGroup->pCmdTable = NULL;
678 /* Link into the free list */
679 pGroup->magic = GRP_MAGIC_UNSET;
680 pGroup->next_grp = m_FreeGroupList;
681 m_FreeGroupList = id;
683 int idx = m_FirstUser;
686 while (idx != INVALID_ADMIN_ID)
688 pUser = (AdminUser *)m_pMemory->GetAddress(idx);
689 if (pUser->grp_count > 0)
691 table = (int *)m_pMemory->GetAddress(pUser->grp_table);
692 for (unsigned int i=0; i<pUser->grp_count; i++)
696 /* We have to remove this entry */
697 for (unsigned int j=i+1; j<pUser->grp_count; j++)
699 /* Move everything down by one */
700 table[j-1] = table[j];
704 /* Recalculate effective flags */
705 memset(pUser->eflags, 0, sizeof(pUser->eflags));
706 for (unsigned int j=0; j<pUser->grp_count; j++)
708 pOther = (AdminGroup *)m_pMemory->GetAddress(table[j]);
709 for (unsigned int k=0; k<AdminFlags_TOTAL; k++)
711 pUser->eflags[k] = (pUser->flags[k] || pOther->addflags[k]);
714 /* Break now, duplicates aren't allowed */
719 idx = pUser->next_user;
723 void AdminCache::InvalidateGroupCache()
725 /* Nuke the free list */
726 m_FreeGroupList = -1;
728 /* Nuke reverse lookups */
729 sm_trie_clear(m_pGroups);
731 /* Free memory on groups */
732 GroupId cur = m_FirstGroup;
734 while (cur != INVALID_GROUP_ID)
736 pGroup = (AdminGroup *)m_pMemory->GetAddress(cur);
737 assert(pGroup->magic == GRP_MAGIC_SET);
738 if (pGroup->pCmdGrpTable)
740 sm_trie_destroy(pGroup->pCmdGrpTable);
742 if (pGroup->pCmdTable)
744 sm_trie_destroy(pGroup->pCmdTable);
746 cur = pGroup->next_grp;
749 m_FirstGroup = INVALID_GROUP_ID;
750 m_LastGroup = INVALID_GROUP_ID;
752 InvalidateAdminCache(false);
754 /* Reset the memory table */
758 void AdminCache::AddAdminListener(IAdminListener *pListener)
760 m_hooks.push_back(pListener);
763 void AdminCache::RemoveAdminListener(IAdminListener *pListener)
765 m_hooks.remove(pListener);
768 void AdminCache::RegisterAuthIdentType(const char *name)
770 if (sm_trie_retrieve(m_pAuthTables, name, NULL))
775 Trie *pAuth = sm_trie_create();
778 method.name.assign(name);
779 method.table = pAuth;
781 m_AuthMethods.push_back(method);
783 sm_trie_insert(m_pAuthTables, name, pAuth);
786 void AdminCache::InvalidateAdminCache(bool unlink_admins)
788 /* Wipe the identity cache first */
789 List<AuthMethod>::iterator iter;
790 for (iter=m_AuthMethods.begin();
791 iter!=m_AuthMethods.end();
794 sm_trie_clear((*iter).table);
799 while (m_FirstUser != INVALID_ADMIN_ID)
801 InvalidateAdmin(m_FirstUser);
810 void AdminCache::DumpAdminCache(int cache_flags, bool rebuild)
812 if (cache_flags & ADMIN_CACHE_OVERRIDES)
814 DumpCommandOverrideCache(Override_Command);
815 DumpCommandOverrideCache(Override_CommandGroup);
818 /* This will auto-invalidate the admin cache */
819 if (cache_flags & ADMIN_CACHE_GROUPS)
821 InvalidateGroupCache();
824 /* If we only requested an admin rebuild, re-use the internal memory */
825 if (((cache_flags & ADMIN_CACHE_ADMINS) == ADMIN_CACHE_ADMINS)
826 && ((cache_flags & (1<<2)) != (1<<2)))
828 InvalidateAdminCache(true);
833 List<IAdminListener *>::iterator iter;
834 IAdminListener *pListener;
836 for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
839 pListener->OnRebuildAdminCache(cache_flags);
841 m_pCacheFwd->PushCell(cache_flags);
842 m_pCacheFwd->Execute(&result);
846 const char *AdminCache::GetAdminName(AdminId id)
848 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
849 if (!pUser || pUser->magic != USR_MAGIC_SET)
854 return m_pStrings->GetString(pUser->nameidx);
857 bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
859 List<AuthMethod>::iterator iter;
860 unsigned int index = 0;
861 for (iter=m_AuthMethods.begin();
862 iter!=m_AuthMethods.end();
865 if ((*iter).name.compare(name) == 0)
875 bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
877 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
878 if (!pUser || pUser->magic != USR_MAGIC_SET)
884 if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
889 if (sm_trie_retrieve(pTable, ident, NULL))
894 pUser->auth.identidx = m_pStrings->AddString(ident);
895 GetMethodIndex(auth, &pUser->auth.index);
897 return sm_trie_insert(pTable, ident, (void **)id);
900 AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
903 if (!sm_trie_retrieve(m_pAuthTables, auth, (void **)&pTable))
905 return INVALID_ADMIN_ID;
909 if (!sm_trie_retrieve(pTable, identity, &object))
911 return INVALID_ADMIN_ID;
914 return (AdminId)object;
917 void AdminCache::SetAdminFlag(AdminId id, AdminFlag flag, bool enabled)
919 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
920 if (!pUser || pUser->magic != USR_MAGIC_SET)
925 if (flag < Admin_None
926 || flag >= AdminFlags_TOTAL)
931 pUser->flags[enabled] = false;
934 bool AdminCache::GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode)
936 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
937 if (!pUser || pUser->magic != USR_MAGIC_SET)
942 if (flag < Admin_None
943 || flag >= AdminFlags_TOTAL)
948 if (mode == Access_Real)
950 return pUser->flags[flag];
951 } else if (mode == Access_Effective) {
952 return (pUser->flags[flag] || pUser->eflags[flag]);
958 unsigned int AdminCache::GetAdminFlags(AdminId id, bool flags[], unsigned int total, AccessMode mode)
960 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
961 if (!pUser || pUser->magic != USR_MAGIC_SET)
967 if (mode == Access_Real)
969 for (i=0; i<AdminFlags_TOTAL && i<total; i++)
971 flags[i] = pUser->flags[i];
973 } else if (mode == Access_Effective) {
974 for (i=0; i<AdminFlags_TOTAL && i<total; i++)
976 flags[i] = (pUser->flags[i] || pUser->eflags[i]);
983 bool AdminCache::AdminInheritGroup(AdminId id, GroupId gid)
985 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
986 if (!pUser || pUser->magic != USR_MAGIC_SET)
991 AdminGroup *pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
992 if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
998 if (pUser->grp_count + 1 > pUser->grp_size)
1003 if (pUser->grp_size == 0)
1007 new_size = pUser->grp_size * 2;
1010 /* Create and refresh pointers */
1011 tblidx = m_pMemory->CreateMem(new_size * sizeof(int), (void **)&table);
1012 pUser = (AdminUser *)m_pMemory->GetAddress(id);
1013 pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
1015 /* Copy old data if necessary */
1016 if (pUser->grp_table != -1)
1018 int *old_table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1019 memcpy(table, old_table, sizeof(int) * pUser->grp_count);
1021 pUser->grp_table = tblidx;
1022 pUser->grp_size = new_size;
1024 table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1027 for (unsigned int i=0; i<pUser->grp_count; i++)
1029 if (table[i] == gid)
1035 table[pUser->grp_count] = gid;
1038 /* Compute new effective flags */
1039 for (unsigned int i=Admin_None;
1043 /* Only inherit flags additive flags we don't have */
1044 if (!pUser->eflags[i])
1046 pUser->eflags[i] = pGroup->addflags[i];
1053 unsigned int AdminCache::GetAdminGroupCount(AdminId id)
1055 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1056 if (!pUser || pUser->magic != USR_MAGIC_SET)
1061 return pUser->grp_count;
1064 GroupId AdminCache::GetAdminGroup(AdminId id, unsigned int index, const char **name)
1066 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1067 if (!pUser || pUser->magic != USR_MAGIC_SET || index >= pUser->grp_count)
1069 return INVALID_GROUP_ID;
1072 int *table = (int *)m_pMemory->GetAddress(pUser->grp_table);
1074 return table[index];
1077 const char *AdminCache::GetAdminPassword(AdminId id)
1079 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1080 if (!pUser || pUser->magic != USR_MAGIC_SET)
1085 return m_pStrings->GetString(pUser->password);
1088 void AdminCache::SetAdminPassword(AdminId id, const char *password)
1090 AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
1091 if (!pUser || pUser->magic != USR_MAGIC_SET)
1096 pUser->password = m_pStrings->AddString(password);