Browse Source

Document classes related to `APlayer` and `User`

pull/8/head
Anton Tarasenko 4 years ago
parent
commit
15c54c5b50
  1. 2
      sources/Events/Events.uc
  2. 41
      sources/Players/APlayer.uc
  3. 5
      sources/Players/ConnectionListener_Player.uc
  4. 12
      sources/Players/PlayerListenerBase.uc
  5. 29
      sources/Players/PlayerService.uc
  6. 2
      sources/Users/Tests/TEST_User.uc
  7. 29
      sources/Users/User.uc
  8. 37
      sources/Users/UserAPI.uc
  9. 38
      sources/Users/UserDatabase.uc
  10. 4
      sources/Users/UserID.uc

2
sources/Events/Events.uc

@ -70,7 +70,7 @@ var private array< class<Listener> > listeners;
var public const class<Listener> relatedListener; var public const class<Listener> relatedListener;
// Even class can also auto-spawn a `Service`, // Event class can also auto-spawn a `Service`,
// in case it's require to generate events // in case it's require to generate events
var public const class<Service> connectedServiceClass; var public const class<Service> connectedServiceClass;
// Set this to `true`if you want `connectedServiceClass` service to also // Set this to `true`if you want `connectedServiceClass` service to also

41
sources/Players/APlayer.uc

@ -1,9 +1,11 @@
/** /**
* Objects of this class are meant to represent a "server user": * Represents a connected player connection and serves to provide access to
* not a particular `PlayerController`, but an entity that server would * both it's server data and in-game pawn representation.
* recognize to be the same person even after reconnections. * Unlike `User`, - changes when player reconnects the server.
* It is supposed to store and recognize various stats and * This object SHOULD NOT be created manually, please rely on
* server privileges. * `AcediaCore` for that.
* Killing floor 1 note: inherently linked to
* a particular `PlayerController`.
* Copyright 2020 Anton Tarasenko * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -23,25 +25,50 @@
*/ */
class APlayer extends AcediaActor; class APlayer extends AcediaActor;
// How this `APlayer` is identified by the server
var private User identity; var private User identity;
// Controller
var private PlayerController ownerController; var private PlayerController ownerController;
// Shortcut to `ConnectionEvents`, so that we don't have to write // Shortcut to `ConnectionEvents`, so that we don't have to write
// `class'ConnectionEvents'` every time. // `class'ConnectionEvents'` every time.
var const class<PlayerEvents> events; var const class<PlayerEvents> events;
public final function Initialize(PlayerController initOwnerController) /**
* Initializes caller `APlayer`. Should be called right after `APlayer`
* was spawned.
*
* Initialization should (and can) only be done once.
* Before a `Initialize()` call, any other method calls on such `User`
* must be considerate to have undefined behavior.
*
* @param newController Controller that caller `APLayer` will correspond to.
*/
public final function Initialize(PlayerController newController)
{ {
ownerController = initOwnerController; ownerController = initOwnerController;
identity = _.users.FetchByIDHash(initOwnerController.GetPlayerIDHash()); identity = _.users.FetchByIDHash(initOwnerController.GetPlayerIDHash());
events.static.CallPlayerConnected(self); events.static.CallPlayerConnected(self);
} }
/**
* Returns associated controller.
*
* @return Controller that caller `APLayer` corresponds to.
*/
public final function PlayerController GetController() public final function PlayerController GetController()
{ {
return ownerController; return ownerController;
} }
/**
* IMPORTANT: this is a helper function that is not supposed to be
* called manually.
*
* Causes `APlayer` to update it's inner state and should be triggered by
* various outside events. A necessary work-around, since we cannot make
* an event to trigger a protected function.
*/
public final function Update() public final function Update()
{ {
if (ownerController == none) { if (ownerController == none) {
@ -50,6 +77,8 @@ public final function Update()
} }
} }
// This is one of the most important objects for `Acedia` and should be kept
// up-to-date as much as possible.
event Tick(float delta) event Tick(float delta)
{ {
Update(); Update();

5
sources/Players/ConnectionListener_Player.uc

@ -1,5 +1,5 @@
/** /**
* Listener for events generated by 'ConnectionService'. * `PlayerService`'s listener for events generated by 'ConnectionService'.
* Copyright 2019 Anton Tarasenko * Copyright 2019 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -19,7 +19,6 @@
*/ */
class ConnectionListener_Player extends ConnectionListenerBase; class ConnectionListener_Player extends ConnectionListenerBase;
// `PlayerConnected` is called the moment we detect a new player on a server.
static function ConnectionEstablished(ConnectionService.Connection connection) static function ConnectionEstablished(ConnectionService.Connection connection)
{ {
local PlayerService service; local PlayerService service;
@ -32,8 +31,6 @@ static function ConnectionEstablished(ConnectionService.Connection connection)
service.RegisterPlayer(connection.controllerReference); service.RegisterPlayer(connection.controllerReference);
} }
// `PlayerDisconnected` is called the moment we
// detect a player leaving the server.
static function ConnectionLost(ConnectionService.Connection connection) static function ConnectionLost(ConnectionService.Connection connection)
{ {
local PlayerService service; local PlayerService service;

12
sources/Players/PlayerListenerBase.uc

@ -20,11 +20,21 @@
class PlayerListenerBase extends Listener class PlayerListenerBase extends Listener
abstract; abstract;
// `PlayerConnected` is called the moment we detect a new player on a server. /**
* `PlayerConnected` is called the moment we detect a new player on a server.
*
* @param newPlayer Player that just connected.
*/
static function PlayerConnected(APlayer newPlayer); static function PlayerConnected(APlayer newPlayer);
// `PlayerDisconnected` is called the moment we // `PlayerDisconnected` is called the moment we
// detect a player leaving the server. // detect a player leaving the server.
/**
* `PlayerDisconnected` is called the moment we detect a player leaving
* the server.
*
* @param lostPlayer Player that just disconnected.
*/
static function PlayerDisconnected(APlayer lostPlayer); static function PlayerDisconnected(APlayer lostPlayer);
defaultproperties defaultproperties

29
sources/Players/PlayerService.uc

@ -1,7 +1,5 @@
/** /**
* Service for tracking currently connected players. * 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 * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -21,8 +19,11 @@
*/ */
class PlayerService extends Service; class PlayerService extends Service;
// Record of all current players
var private array<APlayer> allPlayers; var private array<APlayer> allPlayers;
// Cleans all our player records just in case something caused certain
// `APlayer` to get destroyed.
private final function RemoveNonePlayers() private final function RemoveNonePlayers()
{ {
local int i; local int i;
@ -37,6 +38,17 @@ private final function RemoveNonePlayers()
} }
} }
/**
* Creates a new `APlayer` instance for a given `newPlayerController`
* controller.
*
* If given controller is `none` or it's `APLayer` was already created,
* - does nothing.
*
* @param newPlayerController Controller for which we must
* create new `APlayer`.
* @return `true` if new `APlayer` was created and `false` otherwise.
*/
public final function bool RegisterPlayer(PlayerController newPlayerController) public final function bool RegisterPlayer(PlayerController newPlayerController)
{ {
local int i; local int i;
@ -63,12 +75,25 @@ public final function bool RegisterPlayer(PlayerController newPlayerController)
return true; return true;
} }
/**
* Fetches current array of all player (registered `APLayer`s).
*
* @return Current array of all player (registered `APLayer`s). Guaranteed to
* not contain `none` values.
*/
public final function array<APlayer> GetAllPlayers() public final function array<APlayer> GetAllPlayers()
{ {
RemoveNonePlayers(); RemoveNonePlayers();
return allPlayers; return allPlayers;
} }
/**
* IMPORTANT: this is a helper function that is not supposed to be
* called manually.
*
* Causes status of all players to update.
* See `APlayer.Update()` for details.
*/
public final function UpdateAllPlayers() public final function UpdateAllPlayers()
{ {
local int i; local int i;

2
sources/Users/Tests/TEST_User.uc

@ -1,5 +1,5 @@
/** /**
* Set of tests for `APlayer` and related classes. * Set of tests for `User` and related classes.
* Copyright 2020 Anton Tarasenko * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.

29
sources/Users/User.uc

@ -1,9 +1,7 @@
/** /**
* Objects of this class are meant to represent a "server user": * Object that is supposed to store a persistent data about the
* not a particular `PlayerController`, but an entity that server would * certain player. That is data that will be remembered even after player
* recognize to be the same person even after reconnections. * reconnects or server changes map/restarts.
* It is supposed to store and recognize various stats and
* server privileges.
* Copyright 2020 Anton Tarasenko * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -23,20 +21,41 @@
*/ */
class User extends AcediaObject; class User extends AcediaObject;
// Unique identifier for which this `User` stores it's data
var private UserID id; var private UserID id;
// A numeric "key" assigned to this user for a session that can serve as
// an easy reference in console commands
var private int key; var private int key;
/**
* Initializes caller `User` with id and it's session key. Should be called
* right after `APlayer` was created.
*
* Initialization should (and can) only be done once.
* Before a `Initialize()` call, any other method calls on such `User`
* must be considerate to have undefined behavior.
*/
public final function Initialize(UserID initID, int initKey) public final function Initialize(UserID initID, int initKey)
{ {
id = initID; id = initID;
key = initKey; key = initKey;
} }
/**
* Return id for which caller `User` stores data.
*
* @return `UserID` that caller `User` was initialized with.
*/
public final function UserID GetID() public final function UserID GetID()
{ {
return id; return id;
} }
/**
* Return session key of the caller `User`.
*
* @return Session key of the caller `User`.
*/
public final function int GetKey() public final function int GetKey()
{ {
return key; return key;

37
sources/Users/UserAPI.uc

@ -1,10 +1,5 @@
/** /**
* API that provides functions for managing objects and actors by providing * API that allows easy access to `User` persistent data and `UserID`s.
* 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 * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -24,16 +19,38 @@
*/ */
class UserAPI extends Singleton; class UserAPI extends Singleton;
/**
* Returns reference to the database of user records that Acedia was
* set up to use.
*
* @return Main `UserDatabase` that Acedia currently uses to load and
* store user information. Guaranteed to be a valid non-`none` reference.
*/
public final function UserDatabase GetDatabase() public final function UserDatabase GetDatabase()
{ {
return class'UserDatabase'.static.GetInstance(); return class'UserDatabase'.static.GetInstance();
} }
/**
* Fetches `User` object that stores persistent data for a given `userID`.
*
* @param userID ID for which to fetch a persistent data storage.
* @return `User` object for a given `UserID`. Guaranteed to be a valid
* non-`none` reference if passed `userID` is not `none` and initialized
* (which is guaranteed unless you manually created it).
*/
public final function User Fetch(UserID userID) public final function User Fetch(UserID userID)
{ {
return class'UserDatabase'.static.GetInstance().FetchUser(userID); return class'UserDatabase'.static.GetInstance().FetchUser(userID);
} }
/**
* Fetches appropriate `User` object for a player, given his id as a `string`.
*
* @param idHash `string` representation of someone's id.
* @return Corresponding `User` object. Guaranteed to be a valid non-`none`
* reference.
*/
public final function User FetchByIDHash(string idHash) public final function User FetchByIDHash(string idHash)
{ {
local UserID userID; local UserID userID;
@ -43,6 +60,14 @@ public final function User FetchByIDHash(string idHash)
return userDB.FetchUser(userID); return userDB.FetchUser(userID);
} }
/**
* Fetches appropriate `User` object for a player, given his session key.
*
* @param userKey Key corresponding to a `User` method must to get.
* @return Corresponding `User` object. Guaranteed to be a valid non-`none`
* reference if `userKey` was actually assigned to any `User` during
* current playing session; `none` otherwise.
*/
public final function User FetchByKey(int userKey) public final function User FetchByKey(int userKey)
{ {
return class'UserDatabase'.static.GetInstance().FetchUserByKey(userKey); return class'UserDatabase'.static.GetInstance().FetchUserByKey(userKey);

38
sources/Users/UserDatabase.uc

@ -1,5 +1,6 @@
/** /**
* Simple user database for Acedia. * Simple user database for Acedia.
* Only stores data for a session, map or server restarts will clear it.
* Copyright 2020 Anton Tarasenko * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
@ -21,10 +22,25 @@ class UserDatabase extends AcediaObject
config(Acedia) config(Acedia)
abstract; abstract;
// This is used as a global variable only (`default.activeDatabase`) to store
// a reference to main database for persistent data, used by Acedia.
var private UserDatabase activeDatabase; var private UserDatabase activeDatabase;
// `User` records that were stored this session
var private array<User> sessionUsers; var private array<User> sessionUsers;
// `UserID`s generated during this session.
// Instead of constantly creating new ones - just reuse already created.
// This array should not grow too huge under normal circumstances.
var private array<UserID> storedUserIDs; var private array<UserID> storedUserIDs;
/**
* Provides a reference to the database of user records that Acedia was
* set up to use.
*
* Provided reference is guaranteed to not change during one session.
*
* @return reference to the database of user records that Acedia was
* set up to use.
*/
public final static function UserDatabase GetInstance() public final static function UserDatabase GetInstance()
{ {
if (default.activeDatabase == none) if (default.activeDatabase == none)
@ -35,6 +51,12 @@ public final static function UserDatabase GetInstance()
return default.activeDatabase; return default.activeDatabase;
} }
/**
* Converts `string` representation of someone's id into appropriate
* `UserID` object.
*
* Always returns the same object for the same `idHash`.
*/
public final function UserID FetchUserID(string idHash) public final function UserID FetchUserID(string idHash)
{ {
local int i; local int i;
@ -53,6 +75,14 @@ public final function UserID FetchUserID(string idHash)
return newUserID; return newUserID;
} }
/**
* Fetches `User` object that stores persistent data for a given `userID`.
*
* @param userID ID for which to fetch a persistent data storage.
* @return `User` object for a given `UserID`. Guaranteed to be a valid
* non-`none` reference if passed `userID` is not `none` and initialized
* (which is guaranteed unless you manually created it).
*/
public final function User FetchUser(UserID userID) public final function User FetchUser(UserID userID)
{ {
local int i; local int i;
@ -69,6 +99,14 @@ public final function User FetchUser(UserID userID)
return newUser; return newUser;
} }
/**
* Fetches appropriate `User` object for a player, given his session key.
*
* @param userKey Key corresponding to a `User` method must to get.
* @return Corresponding `User` object. Guaranteed to be a valid non-`none`
* reference if `userKey` was actually assigned to any `User` during
* current playing session; `none` otherwise.
*/
public final function User FetchUserByKey(int userKey) public final function User FetchUserByKey(int userKey)
{ {
local int i; local int i;

4
sources/Users/UserID.uc

@ -1,9 +1,5 @@
/** /**
* Acedia's class for storing user's ID. * Acedia's class for storing user's ID.
* This class is inherently linked to steam and it's SteamIDs, since
* Killing Floor 1 is all but guaranteed to be steam-exclusive.
* Still, if you wish to use it in a portable manner, limit yourself to
* `Initialize()`, `IsInitialized()`, `IsEqual()` and `GetUniqueID()`.
* Copyright 2020 Anton Tarasenko * Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.

Loading…
Cancel
Save