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