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;
// Even class can also auto-spawn a `Service`,
// Event class can also auto-spawn a `Service`,
// in case it's require to generate events
var public const class<Service> connectedServiceClass;
// 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":
* 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.
* Represents a connected player connection and serves to provide access to
* both it's server data and in-game pawn representation.
* Unlike `User`, - changes when player reconnects the server.
* This object SHOULD NOT be created manually, please rely on
* `AcediaCore` for that.
* Killing floor 1 note: inherently linked to
* a particular `PlayerController`.
* Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
@ -23,25 +25,50 @@
*/
class APlayer extends AcediaActor;
// How this `APlayer` is identified by the server
var private User identity;
// Controller
var private PlayerController ownerController;
// Shortcut to `ConnectionEvents`, so that we don't have to write
// `class'ConnectionEvents'` every time.
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;
identity = _.users.FetchByIDHash(initOwnerController.GetPlayerIDHash());
events.static.CallPlayerConnected(self);
}
/**
* Returns associated controller.
*
* @return Controller that caller `APLayer` corresponds to.
*/
public final function PlayerController GetController()
{
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()
{
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)
{
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
*------------------------------------------------------------------------------
* This file is part of Acedia.
@ -19,7 +19,6 @@
*/
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;
@ -32,8 +31,6 @@ static function ConnectionEstablished(ConnectionService.Connection connection)
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;

12
sources/Players/PlayerListenerBase.uc

@ -20,11 +20,21 @@
class PlayerListenerBase extends Listener
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);
// `PlayerDisconnected` is called the moment we
// 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);
defaultproperties

29
sources/Players/PlayerService.uc

@ -1,7 +1,5 @@
/**
* 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.
@ -21,8 +19,11 @@
*/
class PlayerService extends Service;
// Record of all current players
var private array<APlayer> allPlayers;
// Cleans all our player records just in case something caused certain
// `APlayer` to get destroyed.
private final function RemoveNonePlayers()
{
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)
{
local int i;
@ -63,12 +75,25 @@ public final function bool RegisterPlayer(PlayerController newPlayerController)
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()
{
RemoveNonePlayers();
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()
{
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
*------------------------------------------------------------------------------
* 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":
* 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.
* Object that is supposed to store a persistent data about the
* certain player. That is data that will be remembered even after player
* reconnects or server changes map/restarts.
* Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
@ -23,20 +21,41 @@
*/
class User extends AcediaObject;
// Unique identifier for which this `User` stores it's data
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;
/**
* 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)
{
id = initID;
key = initKey;
}
/**
* Return id for which caller `User` stores data.
*
* @return `UserID` that caller `User` was initialized with.
*/
public final function UserID GetID()
{
return id;
}
/**
* Return session key of the caller `User`.
*
* @return Session key of the caller `User`.
*/
public final function int GetKey()
{
return key;

37
sources/Users/UserAPI.uc

@ -1,10 +1,5 @@
/**
* 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.
* API that allows easy access to `User` persistent data and `UserID`s.
* Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
@ -24,16 +19,38 @@
*/
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()
{
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)
{
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)
{
local UserID userID;
@ -43,6 +60,14 @@ public final function User FetchByIDHash(string idHash)
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)
{
return class'UserDatabase'.static.GetInstance().FetchUserByKey(userKey);

38
sources/Users/UserDatabase.uc

@ -1,5 +1,6 @@
/**
* Simple user database for Acedia.
* Only stores data for a session, map or server restarts will clear it.
* Copyright 2020 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
@ -21,10 +22,25 @@ class UserDatabase extends AcediaObject
config(Acedia)
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;
// `User` records that were stored this session
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;
/**
* 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()
{
if (default.activeDatabase == none)
@ -35,6 +51,12 @@ public final static function UserDatabase GetInstance()
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)
{
local int i;
@ -53,6 +75,14 @@ public final function UserID FetchUserID(string idHash)
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)
{
local int i;
@ -69,6 +99,14 @@ public final function User FetchUser(UserID userID)
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)
{
local int i;

4
sources/Users/UserID.uc

@ -1,9 +1,5 @@
/**
* 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
*------------------------------------------------------------------------------
* This file is part of Acedia.

Loading…
Cancel
Save