Browse Source

Fix usage of object references in user-related classes

References returned from methods should be deallocated and methods that
return those references should increment reference count to account for
that. These classes were writted before this system and didn't correctly
handle references. This patch addresses that.
pull/8/head
Anton Tarasenko 2 years ago
parent
commit
ea112e426a
  1. 27
      sources/Users/User.uc
  2. 39
      sources/Users/UserAPI.uc
  3. 3
      sources/Users/UserDatabase.uc
  4. 2
      sources/Users/UserID.uc

27
sources/Users/User.uc

@ -2,7 +2,7 @@
* Object that is supposed to store a persistent data about the * Object that is supposed to store a persistent data about the
* certain player. That is data that will be remembered even after player * certain player. That is data that will be remembered even after player
* reconnects or server changes map/restarts. * reconnects or server changes map/restarts.
* Copyright 2020 - 2021 Anton Tarasenko * Copyright 2020-2022 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *
@ -34,10 +34,20 @@ var private JSONPointer persistentSettingsPointer;
var private LoggerAPI.Definition errNoUserDataDatabase; var private LoggerAPI.Definition errNoUserDataDatabase;
// TODO: redo this comment protected function Finalizer()
{
if (id != none) {
id.FreeSelf();
}
if (persistentSettingsPointer != none) {
persistentSettingsPointer.FreeSelf();
}
id = none;
persistentSettingsPointer = none;
}
/** /**
* Initializes caller `User` with id and it's session key. Should be called * Initializes caller `User` with id and it's session key.
* right after `EPlayer` was created.
* *
* Initialization should (and can) only be done once. * Initialization should (and can) only be done once.
* Before a `Initialize()` call, any other method calls on such `User` * Before a `Initialize()` call, any other method calls on such `User`
@ -47,6 +57,9 @@ public final function Initialize(UserID initID, int initKey)
{ {
id = initID; id = initID;
key = initKey; key = initKey;
if (initID != none) {
initID.NewRef();
}
} }
/** /**
@ -56,6 +69,9 @@ public final function Initialize(UserID initID, int initKey)
*/ */
public final function UserID GetID() public final function UserID GetID()
{ {
if (id != none) {
id.NewRef();
}
return id; return id;
} }
@ -88,6 +104,7 @@ public final function int GetKey()
public final function DBReadTask ReadGroupOfPersistentData(BaseText groupName) public final function DBReadTask ReadGroupOfPersistentData(BaseText groupName)
{ {
local DBReadTask task; local DBReadTask task;
if (groupName == none) return none; if (groupName == none) return none;
if (!SetupDatabaseVariables()) return none; if (!SetupDatabaseVariables()) return none;
@ -120,6 +137,7 @@ public final function DBReadTask ReadPersistentData(
BaseText dataName) BaseText dataName)
{ {
local DBReadTask task; local DBReadTask task;
if (groupName == none) return none; if (groupName == none) return none;
if (dataName == none) return none; if (dataName == none) return none;
if (!SetupDatabaseVariables()) return none; if (!SetupDatabaseVariables()) return none;
@ -157,6 +175,7 @@ public final function DBWriteTask WritePersistentData(
{ {
local DBWriteTask task; local DBWriteTask task;
local HashTable emptyObject; local HashTable emptyObject;
if (groupName == none) return none; if (groupName == none) return none;
if (dataName == none) return none; if (dataName == none) return none;
if (!SetupDatabaseVariables()) return none; if (!SetupDatabaseVariables()) return none;

39
sources/Users/UserAPI.uc

@ -1,6 +1,6 @@
/** /**
* API that allows easy access to `User` persistent data and `UserID`s. * API that allows easy access to `User` persistent data and `UserID`s.
* Copyright 2020 - 2021 Anton Tarasenko * Copyright 2020-2021 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *
@ -44,7 +44,16 @@ public final function UserDatabase GetDatabase()
*/ */
public final function User Fetch(UserID userID) public final function User Fetch(UserID userID)
{ {
return class'UserDatabase'.static.GetInstance().FetchUser(userID); local User result;
local UserDatabase userDB;
userDB = class'UserDatabase'.static.GetInstance();
if (userDB == none) {
return none;
}
result = userDB.FetchUser(userID);
userDB.FreeSelf();
return result;
} }
/** /**
@ -58,9 +67,20 @@ public final function User FetchByIDHash(BaseText idHash)
{ {
local UserID userID; local UserID userID;
local UserDatabase userDB; local UserDatabase userDB;
local User result;
userDB = class'UserDatabase'.static.GetInstance(); userDB = class'UserDatabase'.static.GetInstance();
if (userDB == none) {
return none;
}
userID = userDB.FetchUserID(idHash); userID = userDB.FetchUserID(idHash);
return userDB.FetchUser(userID); userDB.FreeSelf();
if (userID == none) {
return none;
}
result = userDB.FetchUser(userID);
userID.FreeSelf();
return result;
} }
/** /**
@ -73,7 +93,16 @@ public final function User FetchByIDHash(BaseText idHash)
*/ */
public final function User FetchByKey(int userKey) public final function User FetchByKey(int userKey)
{ {
return class'UserDatabase'.static.GetInstance().FetchUserByKey(userKey); local User result;
local UserDatabase userDB;
userDB = class'UserDatabase'.static.GetInstance();
if (userDB != none) {
return none;
}
result = userDB.FetchUserByKey(userKey);
userDB.FreeSelf();
return result;
} }
/** /**
@ -101,7 +130,7 @@ public final function Text GetUserDataLink()
*/ */
public final function bool PersistentStorageExists() public final function bool PersistentStorageExists()
{ {
return (_.db.Load(P(userDataDBLink)) != none); return _.db.ExistsLocal(P(userDataDBLink));
} }
defaultproperties defaultproperties

3
sources/Users/UserDatabase.uc

@ -52,6 +52,7 @@ public final static function UserDatabase GetInstance()
default.activeDatabase = default.activeDatabase =
UserDatabase(__().memory.Allocate(class'UserDatabase')); UserDatabase(__().memory.Allocate(class'UserDatabase'));
} }
default.activeDatabase.NewRef();
return default.activeDatabase; return default.activeDatabase;
} }
@ -80,6 +81,7 @@ public final function UserID FetchUserID(BaseText idHash)
if (storedUserIDs[i].IsEqualToSteamID(steamID)) if (storedUserIDs[i].IsEqualToSteamID(steamID))
{ {
_.memory.Free(steamID.steamID64); _.memory.Free(steamID.steamID64);
storedUserIDs[i].NewRef();
return storedUserIDs[i]; return storedUserIDs[i];
} }
} }
@ -88,6 +90,7 @@ public final function UserID FetchUserID(BaseText idHash)
if (newUserID.IsInitialized()) if (newUserID.IsInitialized())
{ {
storedUserIDs[storedUserIDs.length] = newUserID; storedUserIDs[storedUserIDs.length] = newUserID;
newUserID.newRef();
return newUserID; return newUserID;
} }
_.memory.Free(steamID.steamID64); _.memory.Free(steamID.steamID64);

2
sources/Users/UserID.uc

@ -1,6 +1,6 @@
/** /**
* Acedia's class for storing user's ID. * Acedia's class for storing user's ID.
* Copyright 2020 - 2021 Anton Tarasenko * Copyright 2020-2021 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Acedia. * This file is part of Acedia.
* *

Loading…
Cancel
Save