/** * ??? * Copyright 2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * * Acedia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * (at your option) any later version. * * Acedia is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ class Users_Feature extends Feature; var private /*config*/ bool useDatabase; var private /*config*/ string databaseLink; var private /*config*/ array userGroup; // Defines order var private array loadedUserGroups; // `HashTable` (with group name keys) that stores `HashTable`s used as // a set data structure (has user id as keys and always `none` as a value). var private HashTable loadedGroupToUsersMap; protected function SwapConfig(FeatureConfig config) { local Users newConfig; newConfig = Users(config); if (newConfig == none) { return; } useDatabase = newConfig.useDatabase; databaseLink = newConfig.databaseLink; userGroup = newConfig.localUserGroup; } private final function LoadLocalData() { LoadLocalGroupNames(); LoadLocalGroupToUserMap(); } private final function LoadLocalGroupNames() { local int i, j; local bool isDuplicate; local Text nextUserGroup; _.memory.FreeMany(loadedUserGroups); loadedUserGroups.length = 0; for (i = 0; i < userGroup.length; i += 1) { isDuplicate = false; nextUserGroup = _.text.FromString(userGroup[i]); for(j = 0; j < loadedUserGroups.length; j += 1) { if (loadedUserGroups[j].Compare(nextUserGroup, SCASE_INSENSITIVE)) { isDuplicate = true; break; } } if (!isDuplicate) { loadedUserGroups[loadedUserGroups.length] = nextUserGroup.LowerCopy(); } nextUserGroup.FreeSelf(); } } private final function LoadLocalGroupToUserMap() { local int i, j; local Text newSteamID; local HashTable newPlayerSet; local UserGroup nextGroupConfig; local array nextGroupUserArray; _.memory.Free(loadedGroupToUsersMap); loadedGroupToUsersMap = _.collections.EmptyHashTable(); class'UserGroup'.static.Initialize(); // Go over every group for (i = 0; i < loadedUserGroups.length; i += 1) { nextGroupConfig = UserGroup( class'UserGroup'.static.GetConfigInstance(loadedUserGroups[i])); if (nextGroupConfig == none) { // !!! Log missing group continue; } // Copy player IDs from `string` array into `HashTable` // that is serving as a set data structure newPlayerSet = _.collections.EmptyHashTable(); nextGroupUserArray = nextGroupConfig.user; for (j = 0; j < nextGroupUserArray.length; j += 1) { newSteamID = _.text.FromString(nextGroupUserArray[j]); newPlayerSet.SetItem(newSteamID, none); newSteamID.FreeSelf(); } loadedGroupToUsersMap.SetItem(loadedUserGroups[i], newPlayerSet); newPlayerSet.FreeSelf(); nextGroupConfig.FreeSelf(); } } private final function SaveLocalData() { local Text nextGroup, activeConfigName; local Users currentConfig; local HashTableIterator iter; if (useDatabase) return; if (loadedGroupToUsersMap == none) return; userGroup.length = 0; iter = HashTableIterator(loadedGroupToUsersMap.Iterate()); while (!iter.HasFinished()) { nextGroup = Text(iter.GetKey()); if (nextGroup != none) { userGroup[userGroup.length] = nextGroup.ToString(); nextGroup.FreeSelf(); } iter.Next(); } iter.FreeSelf(); activeConfigName = GetCurrentConfig(); if (activeConfigName != none) { currentConfig = Users(class'Users'.static .GetConfigInstance(activeConfigName)); } if (currentConfig != none) { currentConfig.localUserGroup = userGroup; // !!! save config !!! } _.memory.Free(currentConfig); _.memory.Free(activeConfigName); } public final function array GetGroupsForUserID(UserID user) { return GetLocalGroupsForUserID(user); } private final function array GetLocalGroupsForUserID(UserID id) { local Text steamID; local array result; local HashTableIterator iter; local Text nextGroup; local HashTable nextGroupUsers; if (loadedGroupToUsersMap == none) return result; if (id == none) return result; steamID = id.GetSteamID64String(); if (steamID == none) return result; iter = HashTableIterator(loadedGroupToUsersMap.Iterate()); while (!iter.HasFinished()) { nextGroup = Text(iter.GetKey()); nextGroupUsers = HashTable(iter.Get()); if ( nextGroup != none && nextGroupUsers != none && nextGroupUsers.HasKey(steamID)) { result[result.length] = nextGroup.Copy(); } iter.Next(); _.memory.Free(nextGroup); _.memory.Free(nextGroupUsers); } steamID.FreeSelf(); return result; } public final function array GetGroupsForUser(User user) { return GetLocalGroupsForUser(user); } private final function array GetLocalGroupsForUser(User user) { local UserID id; local array result; if (user == none) { return result; } id = user.GetID(); result = GetLocalGroupsForUserID(id); _.memory.Free(id); return result; } public final function array GetUserIDsInGroup(Text groupName) { return GetUserIDsInLocalGroup(groupName); } private final function array GetUserIDsInLocalGroup(Text groupName) { local int i; local Text lowerCaseGroupName; local HashTable groupUsers; local array groupUserNames; local UserID nextUserID; local array result; if (loadedGroupToUsersMap == none) return result; if (groupName == none) return result; lowerCaseGroupName = groupName.LowerCopy(); groupUsers = loadedGroupToUsersMap.GetHashTable(lowerCaseGroupName); lowerCaseGroupName.FreeSelf(); if (groupUsers == none) { groupUserNames = groupUsers.GetTextKeys(); } _.memory.Free(groupUsers); for (i = 0; i < groupUserNames.length; i += 1) { nextUserID = UserID(_.memory.Allocate(class'UserID')); nextUserID.Initialize(groupUserNames[i]); if (nextUserID.IsInitialized()) { result[result.length] = nextUserID; } else { nextUserID.FreeSelf(); } } _.memory.FreeMany(groupUserNames); return result; } defaultproperties { configClass = class'Users' }