/**
* ???
* 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'
}