Browse Source
Refactors `User` to simply store persistent data, while making `APlayer` represent a connecte playr with appropriate links to `User` and (in future) his in-game pawn representation.pull/8/head
Anton Tarasenko
4 years ago
15 changed files with 501 additions and 31 deletions
@ -0,0 +1,52 @@ |
|||||||
|
/** |
||||||
|
* Listener for events generated by 'ConnectionService'. |
||||||
|
* Copyright 2019 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class ConnectionListener_Player extends ConnectionListenerBase; |
||||||
|
|
||||||
|
// `PlayerConnected` is called the moment we detect a new player on a server. |
||||||
|
static function ConnectionEstablished(ConnectionService.Connection connection) |
||||||
|
{ |
||||||
|
local PlayerService service; |
||||||
|
service = PlayerService(class'PlayerService'.static.Require()); |
||||||
|
if (service == none) { |
||||||
|
_().logger.Fatal("Cannot start `PlayerService` service" |
||||||
|
@ "Acedia will not properly work from now on."); |
||||||
|
return; |
||||||
|
} |
||||||
|
service.RegisterPlayer(connection.controllerReference); |
||||||
|
} |
||||||
|
|
||||||
|
// `PlayerDisconnected` is called the moment we |
||||||
|
// detect a player leaving the server. |
||||||
|
static function ConnectionLost(ConnectionService.Connection connection) |
||||||
|
{ |
||||||
|
local PlayerService service; |
||||||
|
service = PlayerService(class'PlayerService'.static.Require()); |
||||||
|
if (service == none) { |
||||||
|
_().logger.Fatal("Cannot start `PlayerService` service" |
||||||
|
@ "Acedia will not properly work from now on."); |
||||||
|
return; |
||||||
|
} |
||||||
|
service.UpdateAllPlayers(); |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
relatedEvents = class'ConnectionEvents' |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/** |
||||||
|
* Event generator for 'ConnectionService'. |
||||||
|
* Copyright 2019 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class PlayerEvents extends Events |
||||||
|
abstract; |
||||||
|
|
||||||
|
static function CallPlayerConnected(APlayer newPlayer) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local array< class<Listener> > listeners; |
||||||
|
listeners = GetListeners(); |
||||||
|
for (i = 0; i < listeners.length; i += 1) |
||||||
|
{ |
||||||
|
class<PlayerListenerBase>(listeners[i]) |
||||||
|
.static.PlayerConnected(newPlayer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static function CallPlayerDisconnected(APlayer lostPlayer) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local array< class<Listener> > listeners; |
||||||
|
listeners = GetListeners(); |
||||||
|
for (i = 0; i < listeners.length; i += 1) |
||||||
|
{ |
||||||
|
class<PlayerListenerBase>(listeners[i]) |
||||||
|
.static.PlayerDisconnected(lostPlayer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
relatedListener = class'PlayerListenerBase' |
||||||
|
connectedServiceClass = class'PlayerService' |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/** |
||||||
|
* Listener for events generated by 'ConnectionService'. |
||||||
|
* Copyright 2019 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class PlayerListenerBase extends Listener |
||||||
|
abstract; |
||||||
|
|
||||||
|
// `PlayerConnected` is called the moment we detect a new player on a server. |
||||||
|
static function PlayerConnected(APlayer newPlayer); |
||||||
|
|
||||||
|
// `PlayerDisconnected` is called the moment we |
||||||
|
// detect a player leaving the server. |
||||||
|
static function PlayerDisconnected(APlayer lostPlayer); |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
relatedEvents = class'PlayerEvents' |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
/** |
||||||
|
* Service for tracking currently connected players. |
||||||
|
* Besides simply storing all players it also separately stores (caches) |
||||||
|
* players belonging to specific groups to make appropriate getters faster. |
||||||
|
* Copyright 2020 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class PlayerService extends Service; |
||||||
|
|
||||||
|
var private array<APlayer> allPlayers; |
||||||
|
|
||||||
|
private final function RemoveNonePlayers() |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
while (i < allPlayers.length) |
||||||
|
{ |
||||||
|
if (allPlayers[i] == none) { |
||||||
|
allPlayers.Remove(i, 1); |
||||||
|
} |
||||||
|
else { |
||||||
|
i += 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public final function bool RegisterPlayer(PlayerController newPlayerController) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local APlayer newPlayer; |
||||||
|
if (newPlayerController == none) return false; |
||||||
|
|
||||||
|
RemoveNonePlayers(); |
||||||
|
for (i = 0; i < allPlayers.length; i += 1) |
||||||
|
{ |
||||||
|
if (allPlayers[i] == none) continue; |
||||||
|
if (allPlayers[i].GetController() == newPlayerController) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
newPlayer = APlayer(_.memory.Allocate(class'APlayer')); |
||||||
|
if (newPlayer == none) |
||||||
|
{ |
||||||
|
_.logger.Fatal("Cannot spawn a new instance of `APlayer`." |
||||||
|
@ "Acedia will not properly work from now on."); |
||||||
|
return false; |
||||||
|
} |
||||||
|
newPlayer.Initialize(newPlayerController); |
||||||
|
allPlayers[allPlayers.length] = newPlayer; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public final function array<APlayer> GetAllPlayers() |
||||||
|
{ |
||||||
|
RemoveNonePlayers(); |
||||||
|
return allPlayers; |
||||||
|
} |
||||||
|
|
||||||
|
public final function UpdateAllPlayers() |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
RemoveNonePlayers(); |
||||||
|
for (i = 0; i < allPlayers.length; i += 1) |
||||||
|
{ |
||||||
|
if (allPlayers[i] != none){ |
||||||
|
allPlayers[i].Update(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
/** |
||||||
|
* Objects of this class are meant to represent a "server user": |
||||||
|
* not a particular `PlayerController`, but an entity that server would |
||||||
|
* recognize to be the same person even after reconnections. |
||||||
|
* It is supposed to store and recognize various stats and |
||||||
|
* server privileges. |
||||||
|
* Copyright 2020 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class User extends AcediaObject; |
||||||
|
|
||||||
|
var private UserID id; |
||||||
|
var private int key; |
||||||
|
|
||||||
|
public final function Initialize(UserID initID, int initKey) |
||||||
|
{ |
||||||
|
id = initID; |
||||||
|
key = initKey; |
||||||
|
} |
||||||
|
|
||||||
|
public final function UserID GetID() |
||||||
|
{ |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public final function int GetKey() |
||||||
|
{ |
||||||
|
return key; |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/** |
||||||
|
* API that provides functions for managing objects and actors by providing |
||||||
|
* easy and general means to create and destroy them, that allow to make use of |
||||||
|
* temporary `Object`s in a more efficient way. |
||||||
|
* This is a low-level API that most users of Acedia, most likely, |
||||||
|
* would not have to use, since creation of most objects would use their own |
||||||
|
* wrapper functions around this API. |
||||||
|
* Copyright 2020 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class UserAPI extends Singleton; |
||||||
|
|
||||||
|
public final function UserDatabase GetDatabase() |
||||||
|
{ |
||||||
|
return class'UserDatabase'.static.GetInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
public final function User Fetch(UserID userID) |
||||||
|
{ |
||||||
|
return class'UserDatabase'.static.GetInstance().FetchUser(userID); |
||||||
|
} |
||||||
|
|
||||||
|
public final function User FetchByIDHash(string idHash) |
||||||
|
{ |
||||||
|
local UserID userID; |
||||||
|
local UserDatabase userDB; |
||||||
|
userDB = class'UserDatabase'.static.GetInstance(); |
||||||
|
userID = userDB.FetchUserID(idHash); |
||||||
|
return userDB.FetchUser(userID); |
||||||
|
} |
||||||
|
|
||||||
|
public final function User FetchByKey(int userKey) |
||||||
|
{ |
||||||
|
return class'UserDatabase'.static.GetInstance().FetchUserByKey(userKey); |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
/** |
||||||
|
* Simple user database for Acedia. |
||||||
|
* Copyright 2020 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 <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class UserDatabase extends AcediaObject |
||||||
|
config(Acedia) |
||||||
|
abstract; |
||||||
|
|
||||||
|
var private UserDatabase activeDatabase; |
||||||
|
var private array<User> sessionUsers; |
||||||
|
var private array<UserID> storedUserIDs; |
||||||
|
|
||||||
|
public final static function UserDatabase GetInstance() |
||||||
|
{ |
||||||
|
if (default.activeDatabase == none) |
||||||
|
{ |
||||||
|
default.activeDatabase = |
||||||
|
UserDatabase(_().memory.Allocate(class'UserDatabase')); |
||||||
|
} |
||||||
|
return default.activeDatabase; |
||||||
|
} |
||||||
|
|
||||||
|
public final function UserID FetchUserID(string idHash) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local UserID.SteamID steamID; |
||||||
|
local UserID newUserID; |
||||||
|
steamID = class'UserID'.static.GetSteamIDFromIDHash(idHash); |
||||||
|
for (i = 0; i < storedUserIDs.length; i += 1) |
||||||
|
{ |
||||||
|
if (storedUserIDs[i].IsEqualToSteamID(steamID)) { |
||||||
|
return storedUserIDs[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
newUserID = UserID(_().memory.Allocate(class'UserID')); |
||||||
|
newUserID.InitializeWithSteamID(steamID); |
||||||
|
storedUserIDs[storedUserIDs.length] = newUserID; |
||||||
|
return newUserID; |
||||||
|
} |
||||||
|
|
||||||
|
public final function User FetchUser(UserID userID) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local User newUser; |
||||||
|
for (i = 0; i < sessionUsers.length; i += 1) |
||||||
|
{ |
||||||
|
if (sessionUsers[i].GetID().IsEqualTo(userID)) { |
||||||
|
return sessionUsers[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
newUser = User(_().memory.Allocate(class'User')); |
||||||
|
newUser.Initialize(userID, sessionUsers.length + 1); |
||||||
|
sessionUsers[sessionUsers.length] = newUser; |
||||||
|
return newUser; |
||||||
|
} |
||||||
|
|
||||||
|
public final function User FetchUserByKey(int userKey) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
for (i = 0; i < sessionUsers.length; i += 1) |
||||||
|
{ |
||||||
|
if (sessionUsers[i].GetKey() == userKey) { |
||||||
|
return sessionUsers[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
return none; |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
} |
Loading…
Reference in new issue