diff --git a/sources/Global.uc b/sources/Global.uc
index 01849ea..f04d72a 100644
--- a/sources/Global.uc
+++ b/sources/Global.uc
@@ -28,6 +28,7 @@ var public TextAPI text;
var public MemoryAPI memory;
var public ConsoleAPI console;
var public ColorAPI color;
+var public UserAPI users;
// TODO: APIs must be `remoteRole = ROLE_None`
protected function OnCreated()
@@ -46,4 +47,6 @@ protected function OnCreated()
console = ConsoleAPI(class'ConsoleAPI'.static.GetInstance());
Spawn(class'ColorAPI');
color = ColorAPI(class'ColorAPI'.static.GetInstance());
+ Spawn(class'UserAPI');
+ users = UserAPI(class'UserAPI'.static.GetInstance());
}
\ No newline at end of file
diff --git a/sources/Manifest.uc b/sources/Manifest.uc
index c60fa1e..2b0b1be 100644
--- a/sources/Manifest.uc
+++ b/sources/Manifest.uc
@@ -31,5 +31,5 @@ defaultproperties
testCases(3) = class'TEST_Text'
testCases(4) = class'TEST_TextAPI'
testCases(5) = class'TEST_Parser'
- testCases(6) = class'TEST_Player'
+ testCases(6) = class'TEST_User'
}
\ No newline at end of file
diff --git a/sources/Players/APlayer.uc b/sources/Players/APlayer.uc
index 53a0360..f98a38e 100644
--- a/sources/Players/APlayer.uc
+++ b/sources/Players/APlayer.uc
@@ -1,7 +1,9 @@
/**
- * Main and only Acedia mutator used for loading Acedia packages
- * and providing access to mutator events' calls.
- * Name is chosen to make config files more readable.
+ * 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.
@@ -19,8 +21,41 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
-class APlayer extends AcediaObject;
+class APlayer extends AcediaActor;
+
+var private User identity;
+var private PlayerController ownerController;
+
+// Shortcut to `ConnectionEvents`, so that we don't have to write
+// `class'ConnectionEvents'` every time.
+var const class events;
+
+public final function Initialize(PlayerController initOwnerController)
+{
+ ownerController = initOwnerController;
+ identity = _.users.FetchByIDHash(initOwnerController.GetPlayerIDHash());
+ events.static.CallPlayerConnected(self);
+}
+
+public final function PlayerController GetController()
+{
+ return ownerController;
+}
+
+public final function Update()
+{
+ if (ownerController == none) {
+ events.static.CallPlayerDisconnected(self);
+ Destroy();
+ }
+}
+
+event Tick(float delta)
+{
+ Update();
+}
defaultproperties
{
+ events = class'PlayerEvents'
}
\ No newline at end of file
diff --git a/sources/Players/ConnectionListener_Player.uc b/sources/Players/ConnectionListener_Player.uc
new file mode 100644
index 0000000..0837192
--- /dev/null
+++ b/sources/Players/ConnectionListener_Player.uc
@@ -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 .
+ */
+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'
+}
\ No newline at end of file
diff --git a/sources/Players/PlayerEvents.uc b/sources/Players/PlayerEvents.uc
new file mode 100644
index 0000000..14f2be7
--- /dev/null
+++ b/sources/Players/PlayerEvents.uc
@@ -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 .
+ */
+class PlayerEvents extends Events
+ abstract;
+
+static function CallPlayerConnected(APlayer newPlayer)
+{
+ local int i;
+ local array< class > listeners;
+ listeners = GetListeners();
+ for (i = 0; i < listeners.length; i += 1)
+ {
+ class(listeners[i])
+ .static.PlayerConnected(newPlayer);
+ }
+}
+
+static function CallPlayerDisconnected(APlayer lostPlayer)
+{
+ local int i;
+ local array< class > listeners;
+ listeners = GetListeners();
+ for (i = 0; i < listeners.length; i += 1)
+ {
+ class(listeners[i])
+ .static.PlayerDisconnected(lostPlayer);
+ }
+}
+
+defaultproperties
+{
+ relatedListener = class'PlayerListenerBase'
+ connectedServiceClass = class'PlayerService'
+}
\ No newline at end of file
diff --git a/sources/Players/PlayerListenerBase.uc b/sources/Players/PlayerListenerBase.uc
new file mode 100644
index 0000000..d95b559
--- /dev/null
+++ b/sources/Players/PlayerListenerBase.uc
@@ -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 .
+ */
+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'
+}
\ No newline at end of file
diff --git a/sources/Players/PlayerService.uc b/sources/Players/PlayerService.uc
new file mode 100644
index 0000000..f99dca3
--- /dev/null
+++ b/sources/Players/PlayerService.uc
@@ -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 .
+ */
+class PlayerService extends Service;
+
+var private array 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 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
+{
+}
\ No newline at end of file
diff --git a/sources/Services/Connection/ConnectionEvents.uc b/sources/Services/Connection/ConnectionEvents.uc
index aad9d42..5adcb0d 100644
--- a/sources/Services/Connection/ConnectionEvents.uc
+++ b/sources/Services/Connection/ConnectionEvents.uc
@@ -21,7 +21,8 @@ class ConnectionEvents extends Events
dependson(ConnectionService)
abstract;
-static function CallPlayerConnected(ConnectionService.Connection connection)
+static function CallConnectionEstablished(
+ ConnectionService.Connection connection)
{
local int i;
local array< class > listeners;
@@ -29,11 +30,11 @@ static function CallPlayerConnected(ConnectionService.Connection connection)
for (i = 0; i < listeners.length; i += 1)
{
class(listeners[i])
- .static.PlayerConnected(connection);
+ .static.ConnectionEstablished(connection);
}
}
-static function CallPlayerDisconnected(ConnectionService.Connection connection)
+static function CallConnectionLost(ConnectionService.Connection connection)
{
local int i;
local array< class > listeners;
@@ -41,7 +42,7 @@ static function CallPlayerDisconnected(ConnectionService.Connection connection)
for (i = 0; i < listeners.length; i += 1)
{
class(listeners[i])
- .static.PlayerDisconnected(connection);
+ .static.ConnectionLost(connection);
}
}
diff --git a/sources/Services/Connection/ConnectionListenerBase.uc b/sources/Services/Connection/ConnectionListenerBase.uc
index 204f2fc..beb77ff 100644
--- a/sources/Services/Connection/ConnectionListenerBase.uc
+++ b/sources/Services/Connection/ConnectionListenerBase.uc
@@ -22,11 +22,11 @@ class ConnectionListenerBase extends Listener
abstract;
// `PlayerConnected` is called the moment we detect a new player on a server.
-static function PlayerConnected(ConnectionService.Connection connection);
+static function ConnectionEstablished(ConnectionService.Connection connection);
// `PlayerDisconnected` is called the moment we
// detect a player leaving the server.
-static function PlayerDisconnected(ConnectionService.Connection connection);
+static function ConnectionLost(ConnectionService.Connection connection);
defaultproperties
{
diff --git a/sources/Services/Connection/ConnectionService.uc b/sources/Services/Connection/ConnectionService.uc
index a374813..974940e 100644
--- a/sources/Services/Connection/ConnectionService.uc
+++ b/sources/Services/Connection/ConnectionService.uc
@@ -25,7 +25,7 @@ class ConnectionService extends Service;
struct Connection
{
var public string networkAddress;
- var public string steamID;
+ var public string idHash;
var public PlayerController controllerReference;
// Reference to `AcediaReplicationInfo` for this client,
// in case it was created.
@@ -38,11 +38,12 @@ var private array activeConnections;
// `class'ConnectionEvents'` every time.
var const class events;
-// Find all players manually on launch
+// Clean disconnected and manually find all new players on launch
protected function OnLaunch()
{
local Controller nextController;
local PlayerController nextPlayerController;
+ RemoveBrokenConnections();
nextController = level.controllerList;
while (nextController != none)
{
@@ -98,7 +99,7 @@ private function RemoveBrokenConnections()
if (activeConnections[i].acediaRI != none) {
activeConnections[i].acediaRI.Destroy();
}
- events.static.CallPlayerDisconnected(activeConnections[i]);
+ events.static.CallConnectionLost(activeConnections[i]);
activeConnections.Remove(i, 1);
}
else {
@@ -147,13 +148,13 @@ public final function bool RegisterConnection(PlayerController player)
newConnection.acediaRI = Spawn(class'AcediaReplicationInfo', player);
newConnection.acediaRI.linkOwner = player;
}*/
+ newConnection.idHash = player.GetPlayerIDHash();
newConnection.networkAddress = player.GetPlayerNetworkAddress();
- newConnection.steamID = player.GetPlayerIDHash();
activeConnections[activeConnections.length] = newConnection;
// Remember recorded connections in case someone decides to
// nuke this service
default.activeConnections = activeConnections;
- events.static.CallPlayerConnected(newConnection);
+ events.static.CallConnectionEstablished(newConnection);
return true;
}
diff --git a/sources/Players/Tests/TEST_Player.uc b/sources/Users/Tests/TEST_User.uc
similarity index 83%
rename from sources/Players/Tests/TEST_Player.uc
rename to sources/Users/Tests/TEST_User.uc
index f85beea..6120ecf 100644
--- a/sources/Players/Tests/TEST_Player.uc
+++ b/sources/Users/Tests/TEST_User.uc
@@ -17,7 +17,8 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
-class TEST_Player extends TestCase
+class TEST_User extends TestCase
+ dependson(UserID)
abstract;
protected static function TESTS()
@@ -40,19 +41,19 @@ protected static function Test_UserID()
Issue("`UserID` incorrectly handles SteamID.");
TEST_ExpectTrue(testID.GetUniqueID() == "76561198025127722");
- TEST_ExpectTrue(testID.GetSteamID() == "STEAM_1:0:32430997");
- TEST_ExpectTrue(testID.GetSteamID3() == "U:1:64861994");
- TEST_ExpectTrue(testID.GetSteamID32() == 64861994);
- TEST_ExpectTrue(testID.GetSteamID64() == "76561198025127722");
+ TEST_ExpectTrue(testID.GetSteamIDString() == "STEAM_1:0:32430997");
+ TEST_ExpectTrue(testID.GetSteamID3String() == "U:1:64861994");
+ TEST_ExpectTrue(testID.GetSteamID32String() == 64861994);
+ TEST_ExpectTrue(testID.GetSteamID64String() == "76561198025127722");
Issue("Two `UserID` equality check is incorrect.");
testID2 = UserID(_().memory.Allocate(class'UserID'));
testID3 = UserID(_().memory.Allocate(class'UserID'));
testID2.Initialize("76561198025127722");
testID3.Initialize("76561198044316328");
- TEST_ExpectTrue(testID.IsEqual(testID2));
+ TEST_ExpectTrue(testID.IsEqualTo(testID2));
TEST_ExpectTrue(testID.IsEqualToSteamID(testID2.GetSteamID()));
- TEST_ExpectFalse(testID3.IsEqual(testID));
+ TEST_ExpectFalse(testID3.IsEqualTo(testID));
Issue("Steam data returned by `UserID` is incorrect.");
SteamID = testID3.GetSteamID();
@@ -65,5 +66,5 @@ protected static function Test_UserID()
defaultproperties
{
- caseName = "Player"
+ caseName = "User"
}
\ No newline at end of file
diff --git a/sources/Users/User.uc b/sources/Users/User.uc
new file mode 100644
index 0000000..7486c09
--- /dev/null
+++ b/sources/Users/User.uc
@@ -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 .
+ */
+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
+{
+}
\ No newline at end of file
diff --git a/sources/Users/UserAPI.uc b/sources/Users/UserAPI.uc
new file mode 100644
index 0000000..189b060
--- /dev/null
+++ b/sources/Users/UserAPI.uc
@@ -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 .
+ */
+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
+{
+}
\ No newline at end of file
diff --git a/sources/Users/UserDatabase.uc b/sources/Users/UserDatabase.uc
new file mode 100644
index 0000000..1fc3469
--- /dev/null
+++ b/sources/Users/UserDatabase.uc
@@ -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 .
+ */
+class UserDatabase extends AcediaObject
+ config(Acedia)
+ abstract;
+
+var private UserDatabase activeDatabase;
+var private array sessionUsers;
+var private array 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
+{
+}
\ No newline at end of file
diff --git a/sources/Players/UserID.uc b/sources/Users/UserID.uc
similarity index 91%
rename from sources/Players/UserID.uc
rename to sources/Users/UserID.uc
index 8336a21..94d47ea 100644
--- a/sources/Players/UserID.uc
+++ b/sources/Users/UserID.uc
@@ -133,7 +133,7 @@ private final function string GetSteamAccountTypeCharacter()
* @param steamID64 Steam64 ID's decimal representation in a plain string.
* @return `SteamID` generated from a given Steam64 ID `steamID64`.
*/
-public static final function SteamID GetSteamIDFromSteamID64(
+public static final function SteamID GetSteamIDFromIDHash(
string steamID64)
{
local int i;
@@ -178,8 +178,29 @@ public final function bool Initialize(string steamID64)
if (initialized) {
return false;
}
+ initializedData = GetSteamIDFromIDHash(steamID64);
+ initialized = true;
+ return true;
+}
- initializedData = GetSteamIDFromSteamID64(steamID64);
+/**
+ * Initializes caller `UserID` from a given `SteamID` structure.
+ *
+ * Each `UserID` can only be initialized once and becomes immutable
+ * afterwards.
+ *
+ * @param steamID Valid `SteamID` structure that caller `UserID` will
+ * represent.
+ *
+ * @return `true` if initialization was successful and `false` otherwise
+ * (can only happen if caller `UserID` was already initialized).
+ */
+public final function bool InitializeWithSteamID(SteamID steamID)
+{
+ if (initialized) {
+ return false;
+ }
+ initializedData = steamID;
initialized = true;
return true;
}
@@ -217,7 +238,7 @@ public final function SteamID GetSteamID()
* `false` otherwise. If at least one of the `UserID`s being compared is
* uninitialized, the result will be `false`.
*/
-public final function bool IsEqual(UserID otherID)
+public final function bool IsEqualTo(UserID otherID)
{
if (!IsInitialized()) return false;
if (!otherID.IsInitialized()) return false;
@@ -268,7 +289,7 @@ public final function string GetUniqueID()
* @return String representation of the caller `UserID` in
* form "STEAM_X:Y:Z" if it was initialized and empty `string` otherwise.
*/
-public final function string GetSteamID()
+public final function string GetSteamIDString()
{
local int Y, Z;
Y = 0;
@@ -294,7 +315,7 @@ public final function string GetSteamID()
* @return String representation of the caller `UserID` in
* form "C:U:A" if it was initialized and empty `string` otherwise.
*/
-public final function string GetSteamID3()
+public final function string GetSteamID3String()
{
return (GetSteamAccountTypeCharacter()
$ ":" $ initializedData.universe
@@ -310,7 +331,7 @@ public final function string GetSteamID3()
* @return Unique `int` representation of the caller `UserID`
* if it was initialized and `-1` otherwise.
*/
-public final function int GetSteamID32()
+public final function int GetSteamID32String()
{
if (!IsInitialized()) return -1;
return initializedData.steamID32;
@@ -329,7 +350,7 @@ public final function int GetSteamID32()
* @return String representation of the Steam64 ID of the caller `UserID`
* if it was initialized and empty `string` otherwise.
*/
-public final function string GetSteamID64()
+public final function string GetSteamID64String()
{
if (!IsInitialized()) return "";
return initializedData.steamID64;