diff --git a/sources/AcediaReplicationInfo.uc b/sources/AcediaReplicationInfo.uc index 74141ed..cd77de8 100644 --- a/sources/AcediaReplicationInfo.uc +++ b/sources/AcediaReplicationInfo.uc @@ -1,6 +1,6 @@ /** * Facilitates some core replicated functions between client and server. - * Copyright 2019 Anton Tarasenko + * Copyright 2019-2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ -class AcediaReplicationInfo extends ReplicationInfo; +class AcediaReplicationInfo extends AcediaActor; var public PlayerController linkOwner; @@ -29,4 +29,12 @@ replication defaultproperties { + remoteRole = ROLE_SimulatedProxy + netUpdateFrequency = 10 + bAlwaysRelevant = true + bStatic = false + bNoDelete = false + bHidden = true + bOnlyDirtyReplication = true + bSkipActorPropertyReplication = true } \ No newline at end of file diff --git a/sources/Aliases/AliasService.uc b/sources/Aliases/AliasService.uc index 9617a21..980a2f2 100644 --- a/sources/Aliases/AliasService.uc +++ b/sources/Aliases/AliasService.uc @@ -42,7 +42,7 @@ var public config const class colorAliasesSource; var public config const class featureAliasesSource; var public config const class entityAliasesSource; -protected function OnLaunch() +protected simulated function OnLaunch() { local float actualInterval; actualInterval = saveInterval; @@ -53,12 +53,12 @@ protected function OnLaunch() SetTimer(actualInterval, true); } -protected function OnShutdown() +protected simulated function OnShutdown() { SaveAllPendingObjects(); } -public final function PendingSaveSource(AliasSource sourceToSave) +public simulated final function PendingSaveSource(AliasSource sourceToSave) { local int i; if (sourceToSave == none) return; @@ -70,7 +70,7 @@ public final function PendingSaveSource(AliasSource sourceToSave) sourcesPendingToSave[sourcesPendingToSave.length] = sourceToSave; } -public final function PendingSaveObject(Aliases objectToSave) +public simulated final function PendingSaveObject(Aliases objectToSave) { local int i; if (objectToSave == none) return; @@ -89,7 +89,7 @@ public final function PendingSaveObject(Aliases objectToSave) * * Does not reset the timer until next saving. */ -private final function DoSaveNextPendingObject() +private simulated final function DoSaveNextPendingObject() { if (sourcesPendingToSave.length > 0) { @@ -110,7 +110,7 @@ private final function DoSaveNextPendingObject() * Forces saving of all objects (both `AliasSource`s or `Aliases`s) in queue * to their config files. */ -private final function SaveAllPendingObjects() +private simulated final function SaveAllPendingObjects() { local int i; for (i = 0; i < sourcesPendingToSave.length; i += 1) { @@ -124,7 +124,7 @@ private final function SaveAllPendingObjects() aliasesPendingToSave.length = 0; } -event Timer() +public simulated function Timer() { DoSaveNextPendingObject(); } diff --git a/sources/Aliases/AliasSource.uc b/sources/Aliases/AliasSource.uc index 39f6aad..0baff89 100644 --- a/sources/Aliases/AliasSource.uc +++ b/sources/Aliases/AliasSource.uc @@ -55,7 +55,7 @@ var private HashTable aliasHash; var private LoggerAPI.Definition errIncorrectAliasPair, warnDuplicateAlias; // Load and hash all the data `AliasSource` creation. -protected function OnCreated() +protected simulated function OnCreated() { if (!AssertAliasesClassIsOwnedByThisSource()) { Destroy(); @@ -68,7 +68,7 @@ protected function OnCreated() HashValidAliasesFromPerObjectConfig(); } -protected function OnDestroyed() +protected simulated function OnDestroyed() { loadedAliasObjects.length = 0; _.memory.Free(aliasHash); @@ -77,7 +77,7 @@ protected function OnDestroyed() // Ensures that our `Aliases` class is properly linked with this // source's class. Logs failure otherwise. -private final function bool AssertAliasesClassIsOwnedByThisSource() +private simulated final function bool AssertAliasesClassIsOwnedByThisSource() { if (aliasesClass == none) return true; if (aliasesClass.default.sourceClass == class) return true; @@ -87,7 +87,7 @@ private final function bool AssertAliasesClassIsOwnedByThisSource() } // Load hashes from `AliasSource`'s config (`record` array) -private final function HashValidAliasesFromRecord() +private simulated final function HashValidAliasesFromRecord() { local int i; local Text aliasAsText, valueAsText; @@ -102,7 +102,7 @@ private final function HashValidAliasesFromRecord() } // Load hashes from `Aliases` objects' config -private final function HashValidAliasesFromPerObjectConfig() +private simulated final function HashValidAliasesFromPerObjectConfig() { local int i, j; local Text nextValue; @@ -123,7 +123,7 @@ private final function HashValidAliasesFromPerObjectConfig() // they already exist. // Takes care of lower case conversion to store aliases in `aliasHash` // in a case-insensitive way. -private final function InsertAlias(BaseText alias, BaseText value) +private simulated final function InsertAlias(BaseText alias, BaseText value) { local Text aliasLowerCaseCopy; local HashTable.Entry hashEntry; @@ -146,7 +146,7 @@ private final function InsertAlias(BaseText alias, BaseText value) * @param alias Alias to check, case-insensitive. * @return `true` if present, `false` otherwise. */ -public function bool HasAlias(BaseText alias) +public simulated function bool HasAlias(BaseText alias) { local bool result; local Text lowerCaseAlias; @@ -175,7 +175,9 @@ public function bool HasAlias(BaseText alias) * and `copyOnFailure == true` means method will return `alias.Copy()`. * If `alias == none` method always returns `none`. */ -public function Text Resolve(BaseText alias, optional bool copyOnFailure) +public simulated function Text Resolve( + BaseText alias, + optional bool copyOnFailure) { local Text result; local Text lowerCaseAlias; @@ -230,7 +232,7 @@ public function Text Resolve(BaseText alias, optional bool copyOnFailure) * this flag will be ignores. * @return `true` if alias was added and `false` otherwise (alias was invalid). */ -public final function bool AddAlias( +public simulated final function bool AddAlias( Text aliasToAdd, Text aliasValue, optional bool saveInObject) @@ -276,7 +278,7 @@ public final function bool AddAlias( * * @param aliasToRemove Alias that you want to remove from caller source. */ -public final function RemoveAlias(BaseText aliasToRemove) +public simulated final function RemoveAlias(BaseText aliasToRemove) { local int i; local bool isMatchingRecord; @@ -311,7 +313,7 @@ public final function RemoveAlias(BaseText aliasToRemove) } } -private final function LogDuplicateAliasWarning( +private simulated final function LogDuplicateAliasWarning( BaseText alias, BaseText existingValue) { @@ -324,7 +326,8 @@ private final function LogDuplicateAliasWarning( // Tries to find a loaded `Aliases` config object that stores aliases for // the given value. If such object does not exists - creates a new one. // Assumes `value != none`. -private final function Aliases GetAliasesObjectWithValue(BaseText value) +private simulated final function Aliases GetAliasesObjectWithValue( + BaseText value) { local int i; local Text nextValue; diff --git a/sources/ServerRealm/API/Unreal/Connections/ConnectionService.uc b/sources/ServerRealm/API/Unreal/Connections/ConnectionService.uc index f308f3b..de1b024 100644 --- a/sources/ServerRealm/API/Unreal/Connections/ConnectionService.uc +++ b/sources/ServerRealm/API/Unreal/Connections/ConnectionService.uc @@ -2,7 +2,7 @@ * This service tracks current connections to the server * as well as their basic information, * like IP or steam ID of connecting player. - * Copyright 2019 Anton Tarasenko + * Copyright 2019-2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * diff --git a/sources/Service.uc b/sources/Service.uc index 5043cae..776d472 100644 --- a/sources/Service.uc +++ b/sources/Service.uc @@ -1,7 +1,7 @@ /** * Parent class for all services used in Acedia. * Currently simply makes itself server-only. - * Copyright 2020 - 2021 Anton Tarasenko + * Copyright 2020 - 2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * @@ -28,9 +28,10 @@ var protected ServiceAnchor _self; var private LoggerAPI.Definition errNoService; // Enables feature of given class. -public static final function Service Require() +public simulated static final function Service Require() { local Service newInstance; + if (IsRunning()) { return Service(GetInstance()); } @@ -44,22 +45,22 @@ public static final function Service Require() } // Whether service is currently running is determined by -public static final function bool IsRunning() +public simulated static final function bool IsRunning() { return (GetInstance() != none); } -protected function OnLaunch(){} -protected function OnShutdown(){} +protected simulated function OnLaunch(){} +protected simulated function OnShutdown(){} -protected function OnCreated() +protected simulated function OnCreated() { default.blockSpawning = true; _self = ServiceAnchor(_.memory.Allocate(class'ServiceAnchor')); OnLaunch(); } -protected function OnDestroyed() +protected simulated function OnDestroyed() { OnShutdown(); _.memory.Free(_self); diff --git a/sources/Singleton.uc b/sources/Singleton.uc index 20e921d..560e7e1 100644 --- a/sources/Singleton.uc +++ b/sources/Singleton.uc @@ -3,7 +3,7 @@ * that allows for only one instance of it to exist. * To make sure your child class properly works, either don't overload * 'PreBeginPlay' or make sure to call it's parent's version. - * Copyright 2019 - 2021 Anton Tarasenko + * Copyright 2019-2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * @@ -32,14 +32,16 @@ var public Singleton activeInstance; // Only a default value is ever used. var protected bool blockSpawning; -protected static function StaticFinalizer() +protected simulated static function StaticFinalizer() { default.activeInstance = none; } -public final static function Singleton GetInstance(optional bool spawnIfMissing) +public simulated final static function Singleton GetInstance( + optional bool spawnIfMissing) { local bool instanceExists; + instanceExists = default.activeInstance != none && !default.activeInstance.bPendingDelete; if (instanceExists) { @@ -51,13 +53,13 @@ public final static function Singleton GetInstance(optional bool spawnIfMissing) return none; } -public final static function bool IsSingletonCreationBlocked() +public simulated final static function bool IsSingletonCreationBlocked() { return default.blockSpawning; } -protected function OnCreated(){} -protected function OnDestroyed(){} +protected simulated function OnCreated(){} +protected simulated function OnDestroyed(){} // Make sure only one instance of 'Singleton' exists at any point in time. // Instead of overloading this function we suggest you overload a special @@ -73,7 +75,7 @@ protected function OnDestroyed(){} // | if (bDeleteMe) // | return; // |___________________________________________________________________________ -event PreBeginPlay() +public simulated function PreBeginPlay() { if (default.blockSpawning || GetInstance() != none) { Destroy(); @@ -90,7 +92,7 @@ event PreBeginPlay() // instance is destroyed. // If you absolutely must overload this function in any child class - // first call this version of the method. -event Destroyed() +public simulated function Destroyed() { if (self == default.activeInstance) { diff --git a/sources/Types/AcediaActor.uc b/sources/Types/AcediaActor.uc index e910bcb..06578e4 100644 --- a/sources/Types/AcediaActor.uc +++ b/sources/Types/AcediaActor.uc @@ -70,7 +70,7 @@ var protected const array stringConstants; * * AVOID MANUALLY CALLING IT, UNLESS YOU ARE REIMPLEMENTING `MemoryAPI`. */ -public function _constructor() +public simulated function _constructor() { if (_isAllocated) return; _isAllocated = true; @@ -96,7 +96,7 @@ public function _constructor() * * AVOID MANUALLY CALLING IT, UNLESS YOU ARE REIMPLEMENTING `MemoryAPI`. */ -public function _finalizer() +public simulated function _finalizer() { if (!_isAllocated) return; _isAllocated = false; @@ -115,7 +115,7 @@ public function _finalizer() * @return `true` if static constructor should not be called * and `false` if it should. */ -protected final static function bool StaticConstructorGuard() +protected simulated final static function bool StaticConstructorGuard() { if (!default._staticConstructorWasCalled) { @@ -132,7 +132,7 @@ protected final static function bool StaticConstructorGuard() * * AVOID MANUALLY CALLING IT, UNLESS YOU ARE REIMPLEMENTING `MemoryAPI`. */ -protected function Constructor(){} +protected simulated function Constructor(){} /** * This method is called before actor is destroyed or deallocated by @@ -140,7 +140,7 @@ protected function Constructor(){} * * AVOID MANUALLY CALLING IT, UNLESS YOU ARE REIMPLEMENTING `MemoryAPI`. */ -protected function Finalizer(){} +protected simulated function Finalizer(){} /** * When using proper methods for creating objects (`MemoryAPI`), @@ -153,7 +153,7 @@ protected function Finalizer(){} * `if (StaticConstructorGuard()) return;` * otherwise behavior of constructors should be considered undefined. */ -public static function StaticConstructor() +public simulated static function StaticConstructor() { StaticConstructorGuard(); } @@ -162,7 +162,7 @@ public static function StaticConstructor() * This method is guaranteed to be called during Acedia's shutdown if * `StaticConstructor()` was called on the caller class. */ -protected static function StaticFinalizer(){} +protected simulated static function StaticFinalizer(){} // By default this method will only create `TextCache` instance if it // is needed, which is detected by checking whether `stringConstantsCopy` array @@ -171,7 +171,8 @@ protected static function StaticFinalizer(){} // `P()`, `C()` or `F()` methods that also use `TextCache`. // To force creating `TextCache` for them - set `forceCreation` parameter to // `true`. -private final static function CreateTextCache(optional bool forceCreation) +private simulated final static function CreateTextCache( + optional bool forceCreation) { local int i; local array stringConstantsCopy; @@ -196,7 +197,7 @@ private final static function CreateTextCache(optional bool forceCreation) * * AVOID MANUALLY CALLING IT. */ -public final function _deref() +public simulated final function _deref() { if (!_isAllocated) { return; @@ -211,7 +212,7 @@ public final function _deref() * * AVOID MANUALLY CALLING IT. */ -public final function int _getRefCount() +public simulated final function int _getRefCount() { if (!_isAllocated) { return 0; @@ -227,7 +228,7 @@ public final function int _getRefCount() * * @return Caller actor, to allow for easier use. */ -public final function AcediaActor NewRef() +public simulated final function AcediaActor NewRef() { if (!_isAllocated) { return none; @@ -245,7 +246,7 @@ public final function AcediaActor NewRef() * @return `true` if actor is allocated and ready to use, `false` otherwise * (`Destroy()` was called for it directly or through deallocation method). */ -public final function bool IsAllocated() +public simulated final function bool IsAllocated() { return _isAllocated; } @@ -254,7 +255,7 @@ public final function bool IsAllocated() * Deallocates caller `AcediaActor`, calling its finalizer and then * destroying it. */ -public final function FreeSelf() +public simulated final function FreeSelf() { if (IsAllocated()) { _.memory.Free(self); @@ -278,7 +279,7 @@ public final function FreeSelf() * @return `true` if `other` is considered equal to the caller object, * `false` otherwise. */ -public function bool IsEqual(Object other) +public simulated function bool IsEqual(Object other) { return (self == other); } @@ -295,7 +296,7 @@ public function bool IsEqual(Object other) * * @return Hash code for the caller object. */ -protected function int CalculateHashCode() +protected simulated function int CalculateHashCode() { return Rand(MaxInt); } @@ -310,7 +311,7 @@ protected function int CalculateHashCode() * * @return Hash code for the caller object. */ -public final function int GetHashCode() +public simulated final function int GetHashCode() { if (_hashCodeWasCached) { return _cachedHashCode; @@ -337,7 +338,7 @@ public final function int GetHashCode() * otherwise guaranteed to be not `none`. * Returned value should not be deallocated. */ -public static final function Text T(int index) +public simulated static final function Text T(int index) { // Here cache should already be created, but make extra sure CreateTextCache(true); @@ -358,7 +359,7 @@ public static final function Text T(int index) * Guaranteed to be allocated, not `none`. * Returned value should not be deallocated. */ -public static final function Text P(string string) +public simulated static final function Text P(string string) { CreateTextCache(true); return default._textCache.GetPlainText(string); @@ -379,7 +380,7 @@ public static final function Text P(string string) * Guaranteed to be allocated, not `none`. * Returned value should not be deallocated. */ -public static final function Text C(string string) +public simulated static final function Text C(string string) { CreateTextCache(true); return default._textCache.GetColoredText(string); @@ -400,7 +401,7 @@ public static final function Text C(string string) * Guaranteed to be allocated, not `none`. * Returned value should not be deallocated. */ -public static final function Text F(string string) +public simulated static final function Text F(string string) { CreateTextCache(true); return default._textCache.GetFormattedText(string); @@ -410,7 +411,7 @@ public static final function Text F(string string) * Static method accessor to API namespace, necessary for Acedia's * implementation. */ -public static final function Global __() +public simulated static final function Global __() { return class'Global'.static.GetInstance(); } @@ -419,7 +420,7 @@ public static final function Global __() * Static method accessor to server API namespace, necessary for Acedia's * implementation. */ -public static final function ServerGlobal __server() +public simulated static final function ServerGlobal __server() { return class'ServerGlobal'.static.GetInstance(); } @@ -428,7 +429,7 @@ public static final function ServerGlobal __server() * Static method accessor to client API namespace, necessary for Acedia's * implementation. */ -public static final function ClientGlobal __client() +public simulated static final function ClientGlobal __client() { return class'ClientGlobal'.static.GetInstance(); } @@ -437,7 +438,7 @@ public static final function ClientGlobal __client() * If you are overloading this event - you have to first call * `super.PreBeginPlay()`, otherwise Acedia might not function properly. */ -event PreBeginPlay() +public simulated function PreBeginPlay() { super.PreBeginPlay(); // Calling this early here makes sure `Actor`s that catch `PreBeginPlay()` @@ -450,7 +451,7 @@ event PreBeginPlay() * If you are overloading this event - you have to call `super.Destroyed()`, * otherwise Acedia might not function properly. */ -event Destroyed() +public simulated function Destroyed() { super.Destroyed(); _finalizer(); @@ -462,7 +463,7 @@ event Destroyed() * * AVOID MANUALLY CALLING IT. */ -public static function _cleanup() +public simulated static function _cleanup() { if (default._staticConstructorWasCalled) { StaticFinalizer();