Browse Source

Move `UnrealAPI` into `ServerGlobal`

pull/8/head
Anton Tarasenko 2 years ago
parent
commit
5e6f414c0b
  1. 2
      sources/Avarice/AvariceLink.uc
  2. 7
      sources/BaseRealm/Global.uc
  3. 8
      sources/Chat/ChatAPI.uc
  4. 8
      sources/Commands/Commands_Feature.uc
  5. 2
      sources/Data/Database/DBAPI.uc
  6. 15
      sources/Data/Database/Local/DBRecord.uc
  7. 8
      sources/Data/Database/Local/LocalDatabaseInstance.uc
  8. 2
      sources/Data/Database/Tests/TEST_LocalDatabase.uc
  9. 6
      sources/Events/Signal.uc
  10. 2
      sources/Events/Slot.uc
  11. 14
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFAmmo.uc
  12. 2
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFFlashlightAmmo.uc
  13. 59
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFInventory.uc
  14. 2
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFMedicAmmo.uc
  15. 2
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFPawn.uc
  16. 2
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFSyringeAmmo.uc
  17. 3
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFUnknownItem.uc
  18. 2
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFUnknownPlaceable.uc
  19. 6
      sources/Gameplay/KF1Frontend/BaseImplementation/EKFWeapon.uc
  20. 8
      sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc
  21. 2
      sources/Gameplay/KF1Frontend/Templates/KF1_TemplatesComponent.uc
  22. 12
      sources/Gameplay/KF1Frontend/Trading/KF1_Trader.uc
  23. 35
      sources/Gameplay/KF1Frontend/Trading/KF1_TradingComponent.uc
  24. 2
      sources/InfoQueryHandler/InfoQueryHandler.uc
  25. 2
      sources/Players/EPlayer.uc
  26. 6
      sources/ServerRealm/ServerGlobal.uc
  27. 6
      sources/Time/Timer.uc
  28. 8
      sources/Unreal/BroadcastsAPI/BroadcastAPI.uc
  29. 14
      sources/Unreal/Connections/ConnectionService.uc
  30. 6
      sources/Unreal/GameRulesAPI/GameRulesAPI.uc
  31. 2
      sources/Unreal/InventoryAPI/InventoryService.uc
  32. 86
      sources/Unreal/Tests/TEST_ServerUnrealAPI.uc
  33. 4
      sources/Unreal/UnrealService.uc

2
sources/Avarice/AvariceLink.uc

@ -132,7 +132,7 @@ public final function Initialize(BaseText name, BaseText host, int port)
linkName = name.Copy(); linkName = name.Copy();
linkHost = host.Copy(); linkHost = host.Copy();
linkPort = port; linkPort = port;
tcpStream = _.unreal.ActorRef(none); tcpStream = _server.unreal.ActorRef(none);
} }
/** /**

7
sources/BaseRealm/Global.uc

@ -29,8 +29,6 @@ var public RefAPI ref;
var public BoxAPI box; var public BoxAPI box;
var public LoggerAPI logger; var public LoggerAPI logger;
var public CollectionsAPI collections; var public CollectionsAPI collections;
var public ServerUnrealAPI unreal;
var public TimeAPI time;
var public AliasesAPI alias; var public AliasesAPI alias;
var public TextAPI text; var public TextAPI text;
var public MemoryAPI memory; var public MemoryAPI memory;
@ -69,8 +67,6 @@ protected function Initialize()
logger = LoggerAPI(memory.Allocate(class'LoggerAPI')); logger = LoggerAPI(memory.Allocate(class'LoggerAPI'));
color = ColorAPI(memory.Allocate(class'ColorAPI')); color = ColorAPI(memory.Allocate(class'ColorAPI'));
alias = AliasesAPI(memory.Allocate(class'AliasesAPI')); alias = AliasesAPI(memory.Allocate(class'AliasesAPI'));
unreal = ServerUnrealAPI(memory.Allocate(class'ServerUnrealAPI'));
time = TimeAPI(memory.Allocate(class'TimeAPI'));
console = ConsoleAPI(memory.Allocate(class'ConsoleAPI')); console = ConsoleAPI(memory.Allocate(class'ConsoleAPI'));
chat = ChatAPI(memory.Allocate(class'ChatAPI')); chat = ChatAPI(memory.Allocate(class'ChatAPI'));
users = UserAPI(memory.Allocate(class'UserAPI')); users = UserAPI(memory.Allocate(class'UserAPI'));
@ -88,9 +84,6 @@ public function DropCoreAPI()
box = none; box = none;
text = none; text = none;
collections = none; collections = none;
unreal.DropAPI();
unreal = none;
time = none;
logger = none; logger = none;
alias = none; alias = none;
console = none; console = none;

8
sources/Chat/ChatAPI.uc

@ -38,8 +38,8 @@ protected function Finalizer()
_.memory.Free(onMessageForSignal); _.memory.Free(onMessageForSignal);
onMessageSignal = none; onMessageSignal = none;
onMessageForSignal = none; onMessageForSignal = none;
_.unreal.broadcasts.OnHandleText(self).Disconnect(); _server.unreal.broadcasts.OnHandleText(self).Disconnect();
_.unreal.broadcasts.OnHandleTextFor(self).Disconnect(); _server.unreal.broadcasts.OnHandleTextFor(self).Disconnect();
connectedToBroadcastAPI = false; connectedToBroadcastAPI = false;
} }
@ -49,8 +49,8 @@ private final function TryConnectingBroadcastSignals()
return; return;
} }
connectedToBroadcastAPI = true; connectedToBroadcastAPI = true;
_.unreal.broadcasts.OnHandleText(self).connect = HandleText; _server.unreal.broadcasts.OnHandleText(self).connect = HandleText;
_.unreal.broadcasts.OnHandleTextFor(self).connect = HandleTextFor; _server.unreal.broadcasts.OnHandleTextFor(self).connect = HandleTextFor;
} }
/** /**

8
sources/Commands/Commands_Feature.uc

@ -70,7 +70,7 @@ protected function OnDisabled()
_.chat.OnMessage(self).Disconnect(); _.chat.OnMessage(self).Disconnect();
} }
if (useMutateInput) { if (useMutateInput) {
_.unreal.mutator.OnMutate(self).Disconnect(); _server.unreal.mutator.OnMutate(self).Disconnect();
} }
useChatInput = false; useChatInput = false;
useMutateInput = false; useMutateInput = false;
@ -110,10 +110,10 @@ protected function SwapConfig(FeatureConfig config)
{ {
useMutateInput = newConfig.useMutateInput; useMutateInput = newConfig.useMutateInput;
if (newConfig.useMutateInput) { if (newConfig.useMutateInput) {
_.unreal.mutator.OnMutate(self).connect = HandleMutate; _server.unreal.mutator.OnMutate(self).connect = HandleMutate;
} }
else { else {
_.unreal.mutator.OnMutate(self).Disconnect(); _server.unreal.mutator.OnMutate(self).Disconnect();
} }
} }
} }
@ -143,7 +143,7 @@ public final static function EmergencyEnable()
{ {
default.emergencyEnabledMutate = true; default.emergencyEnabledMutate = true;
feature.emergencyEnabledMutate = true; feature.emergencyEnabledMutate = true;
__().unreal.mutator.OnMutate(feature).connect = HandleMutate; __server().unreal.mutator.OnMutate(feature).connect = HandleMutate;
} }
} }

2
sources/Data/Database/DBAPI.uc

@ -262,7 +262,7 @@ private function EraseAllPackageData(BaseText packageToErase)
if (packageName == "") { if (packageName == "") {
return; return;
} }
game = _.unreal.GetGameType(); game = _server.unreal.GetGameType();
game.DeletePackage(packageName); game.DeletePackage(packageName);
// Delete any leftover objects. This has to be done *after* // Delete any leftover objects. This has to be done *after*
// `DeletePackage()` call, otherwise removed garbage can reappear. // `DeletePackage()` call, otherwise removed garbage can reappear.

15
sources/Data/Database/Local/DBRecord.uc

@ -258,6 +258,11 @@ public static final function Global __()
return class'Global'.static.GetInstance(); return class'Global'.static.GetInstance();
} }
public static final function ServerGlobal __server()
{
return class'ServerGlobal'.static.GetInstance();
}
/** /**
* Method for creating a new `DBRecord` in a package named `dbPackageName`, * Method for creating a new `DBRecord` in a package named `dbPackageName`,
* picking an appropriate and unique name for it. * picking an appropriate and unique name for it.
@ -293,7 +298,7 @@ private final static function DBRecord NewRecordFor(string dbPackageName)
if (recordCandidate != none) { if (recordCandidate != none) {
continue; continue;
} }
recordCandidate = __().unreal.GetGameType() recordCandidate = __server().unreal.GetGameType()
.CreateDataObject(class'DBRecord', nextName, dbPackageName); .CreateDataObject(class'DBRecord', nextName, dbPackageName);
recordCandidate.package = dbPackageName; recordCandidate.package = dbPackageName;
return recordCandidate; return recordCandidate;
@ -319,7 +324,7 @@ private final static function DBRecord LoadRecordFor(
string name, string name,
string package) string package)
{ {
return __().unreal.GetGameType() return __server().unreal.GetGameType()
.LoadDataObject(class'DBRecord', name, package); .LoadDataObject(class'DBRecord', name, package);
} }
@ -678,7 +683,7 @@ private final function SetItem(
if (oldRecord != none) { if (oldRecord != none) {
oldRecord.EmptySelf(); oldRecord.EmptySelf();
} }
__().unreal.GetGameType() __server().unreal.GetGameType()
.DeleteDataObject(class'DBRecord', oldItem.s, package); .DeleteDataObject(class'DBRecord', oldItem.s, package);
} }
} }
@ -712,7 +717,7 @@ private final function RemoveItem(int index)
if (oldRecord != none) { if (oldRecord != none) {
oldRecord.EmptySelf(); oldRecord.EmptySelf();
} }
__().unreal.GetGameType() __server().unreal.GetGameType()
.DeleteDataObject(class'DBRecord', oldItem.s, package); .DeleteDataObject(class'DBRecord', oldItem.s, package);
} }
storage.Remove(index, 1); storage.Remove(index, 1);
@ -861,7 +866,7 @@ public final function EmptySelf()
return; return;
} }
lockEraseSelf = true; lockEraseSelf = true;
game = __().unreal.GetGameType(); game = __server().unreal.GetGameType();
for (i = 0; i < storage.length; i += 1) for (i = 0; i < storage.length; i += 1)
{ {
if (storage[i].t != DBAT_Reference) continue; if (storage[i].t != DBAT_Reference) continue;

8
sources/Data/Database/Local/LocalDatabaseInstance.uc

@ -88,7 +88,7 @@ var private int lastTaskLifeVersion;
protected function Constructor() protected function Constructor()
{ {
_.unreal.OnTick(self).connect = CompleteAllTasks; _server.unreal.OnTick(self).connect = CompleteAllTasks;
} }
protected function Finalizer() protected function Finalizer()
@ -98,7 +98,7 @@ protected function Finalizer()
CompleteAllTasks(); CompleteAllTasks();
WriteToDisk(); WriteToDisk();
rootRecord = none; rootRecord = none;
_.unreal.OnTick(self).Disconnect(); _server.unreal.OnTick(self).Disconnect();
_.memory.Free(diskUpdateTimer); _.memory.Free(diskUpdateTimer);
diskUpdateTimer = none; diskUpdateTimer = none;
configEntry = none; configEntry = none;
@ -125,7 +125,7 @@ private final function LocalDatabaseInstance ScheduleDiskUpdate()
} }
WriteToDisk(); WriteToDisk();
needsDiskUpdate = false; needsDiskUpdate = false;
diskUpdateTimer = _.time.StartTimer( diskUpdateTimer = _server.time.StartTimer(
class'LocalDBSettings'.default.writeToDiskDelay); class'LocalDBSettings'.default.writeToDiskDelay);
diskUpdateTimer.OnElapsed(self).connect = DoDiskUpdate; diskUpdateTimer.OnElapsed(self).connect = DoDiskUpdate;
return self; return self;
@ -153,7 +153,7 @@ private final function WriteToDisk()
packageName = _.text.ToString(configEntry.GetPackageName()); packageName = _.text.ToString(configEntry.GetPackageName());
} }
if (packageName != "") { if (packageName != "") {
_.unreal.GetGameType().SavePackage(packageName); _server.unreal.GetGameType().SavePackage(packageName);
} }
} }

2
sources/Data/Database/Tests/TEST_LocalDatabase.uc

@ -99,7 +99,7 @@ protected static function int CountRecordsInPackage(string package)
local int counter; local int counter;
local DBRecord nextRecord; local DBRecord nextRecord;
local GameInfo game; local GameInfo game;
game = __().unreal.GetGameType(); game = __server().unreal.GetGameType();
foreach game.AllDataObjects(class'DBRecord', nextRecord, package) { foreach game.AllDataObjects(class'DBRecord', nextRecord, package) {
counter += 1; counter += 1;
} }

6
sources/Events/Signal.uc

@ -8,15 +8,15 @@
* (`Slot` wraps over a single delegate, allowing us to store them in array), * (`Slot` wraps over a single delegate, allowing us to store them in array),
* but, unlike them, makes it possible to add several handlers for any event in * but, unlike them, makes it possible to add several handlers for any event in
* a convenient to use way, e.g.: * a convenient to use way, e.g.:
* `_.unreal.OnTick(self).connect = myTickHandler` * `_server.unreal.OnTick(self).connect = myTickHandler`
* To create your own `Signal` you need to: * To create your own `Signal` you need to:
* 1. Make a non-abstract child class of `Signal`; * 1. Make a non-abstract child class of `Signal`;
* 2. Use one of the templates presented in this file below; * 2. Use one of the templates presented in this file below;
* 3. Create a paired `Slot` class and set it's class to `relatedSlotClass` * 3. Create a paired `Slot` class and set it's class to `relatedSlotClass`
* in `defaultproperties`. * in `defaultproperties`.
* 4. (Recommended) Provide a standard interface by defining an event * 4. (Recommended) Provide a standard interface by defining an event
* method (similar to `_.unreal.OnTick()`) in an object that will own * method (similar to `_server.unreal.OnTick()`) in an object that will
* this signal, example of definition is also listed below. * own this signal, example of definition is also listed below.
* More detailed information can be found in documentation. * More detailed information can be found in documentation.
* Copyright 2021 Anton Tarasenko * Copyright 2021 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------

2
sources/Events/Slot.uc

@ -8,7 +8,7 @@
* (`Slot` wraps over a single delegate, allowing us to store them in array), * (`Slot` wraps over a single delegate, allowing us to store them in array),
* but, unlike them, makes it possible to add several handlers for any event in * but, unlike them, makes it possible to add several handlers for any event in
* a convenient to use way, e.g.: * a convenient to use way, e.g.:
* `_.unreal.OnTick(self).connect = myTickHandler` * `_server.unreal.OnTick(self).connect = myTickHandler`
* To create your own `Slot` you need to: * To create your own `Slot` you need to:
* 1. Make a non-abstract child class of `Signal`; * 1. Make a non-abstract child class of `Signal`;
* 2. Use one of the templates presented in this file below. * 2. Use one of the templates presented in this file below.

14
sources/Gameplay/KF1Frontend/BaseImplementation/EKFAmmo.uc

@ -48,7 +48,8 @@ public final static /*unreal*/ function EKFAmmo Wrap(
if (ammunitionInstance.class == class'KFMod.FlashlightAmmo') return none; if (ammunitionInstance.class == class'KFMod.FlashlightAmmo') return none;
newReference = EKFAmmo(__().memory.Allocate(class'EKFAmmo')); newReference = EKFAmmo(__().memory.Allocate(class'EKFAmmo'));
newReference.ammunitionReference = __().unreal.ActorRef(ammunitionInstance); newReference.ammunitionReference =
__server().unreal.ActorRef(ammunitionInstance);
return newReference; return newReference;
} }
@ -193,11 +194,12 @@ private function KFWeapon GetOwnerWeapon()
{ {
nextWeapon = KFWeapon(nextInventory); nextWeapon = KFWeapon(nextInventory);
nextInventory = nextInventory.inventory; nextInventory = nextInventory.inventory;
if (_.unreal.inventory.GetAmmoClass(nextWeapon, 0) == ammunition.class) if ( _server.unreal.inventory.GetAmmoClass(nextWeapon, 0)
== ammunition.class)
{ {
return nextWeapon; return nextWeapon;
} }
else if ( _.unreal.inventory.GetAmmoClass(nextWeapon, 1) else if ( _server.unreal.inventory.GetAmmoClass(nextWeapon, 1)
== ammunition.class) { == ammunition.class) {
return nextWeapon; return nextWeapon;
} }
@ -309,10 +311,12 @@ private function int GetLoadedAmmo()
// We can also quit as soon as we have found a single weapon that // We can also quit as soon as we have found a single weapon that
// uses our ammo, since one weapon per ammo type is how Killing Floor // uses our ammo, since one weapon per ammo type is how Killing Floor
// does things. // does things.
if (_.unreal.inventory.GetAmmoClass(ownerWeapon, 0) == ammunition.class) { if ( _server.unreal.inventory.GetAmmoClass(ownerWeapon, 0)
== ammunition.class)
{
return ownerWeapon.magAmmoRemaining; return ownerWeapon.magAmmoRemaining;
} }
else if ( _.unreal.inventory.GetAmmoClass(ownerWeapon, 1) else if ( _server.unreal.inventory.GetAmmoClass(ownerWeapon, 1)
== ammunition.class) == ammunition.class)
{ {
return 1; // M4 203 return 1; // M4 203

2
sources/Gameplay/KF1Frontend/BaseImplementation/EKFFlashlightAmmo.uc

@ -48,7 +48,7 @@ public final static /*unreal*/ function EKFFlashlightAmmo Wrap(
} }
newReference = newReference =
EKFFlashlightAmmo(__().memory.Allocate(class'EKFFlashlightAmmo')); EKFFlashlightAmmo(__().memory.Allocate(class'EKFFlashlightAmmo'));
newReference.pawnReference = __().unreal.ActorRef(kfHumanPawn); newReference.pawnReference = __server().unreal.ActorRef(kfHumanPawn);
return newReference; return newReference;
} }

59
sources/Gameplay/KF1Frontend/BaseImplementation/EKFInventory.uc

@ -209,7 +209,7 @@ private function KillRefInventory(NativeActorRef itemRef)
nativeReference.Destroy(); nativeReference.Destroy();
} }
if (destroyedClass != none) { if (destroyedClass != none) {
_.unreal.GetKFGameType().WeaponDestroyed(destroyedClass); _server.unreal.GetKFGameType().WeaponDestroyed(destroyedClass);
} }
} }
@ -244,7 +244,7 @@ private function KFWeapon GetByRootWithDualRole(
local InventoryAPI api; local InventoryAPI api;
local class<KFWeapon> nextWeaponClass; local class<KFWeapon> nextWeaponClass;
local class<KFWeaponPickup> itemRoot, nextRoot; local class<KFWeaponPickup> itemRoot, nextRoot;
api = _.unreal.inventory; api = _server.unreal.inventory;
itemRoot = api.GetRootPickupClass(inventoryClass); itemRoot = api.GetRootPickupClass(inventoryClass);
while (inventoryChain != none) while (inventoryChain != none)
{ {
@ -285,7 +285,7 @@ public function EItem Add(EItem newItem, optional bool forceAddition)
// Dead entity - nothing to add // Dead entity - nothing to add
return none; return none;
} }
dualClass = _.unreal.inventory.GetDualClass(nativeWeapon.class); dualClass = _server.unreal.inventory.GetDualClass(nativeWeapon.class);
// The only possible complication here are dual weapons - `newItem` might // The only possible complication here are dual weapons - `newItem` might
// cause addition of completely different weapon. // cause addition of completely different weapon.
if (dualClass != none) if (dualClass != none)
@ -294,7 +294,7 @@ public function EItem Add(EItem newItem, optional bool forceAddition)
pawn.inventory, DWR_Single); pawn.inventory, DWR_Single);
if (conflictWeapon != none) if (conflictWeapon != none)
{ {
nativeWeapon = KFWeapon(_.unreal.inventory nativeWeapon = KFWeapon(_server.unreal.inventory
.MergeWeapons(pawn, dualClass, nativeWeapon, conflictWeapon)); .MergeWeapons(pawn, dualClass, nativeWeapon, conflictWeapon));
} }
if (nativeWeapon != none) { if (nativeWeapon != none) {
@ -339,7 +339,7 @@ public function EItem AddTemplate(
return none; return none;
} }
// Handle dual pistols merging // Handle dual pistols merging
dualClass = _.unreal.inventory.GetDualClass(newWeaponClass); dualClass = _server.unreal.inventory.GetDualClass(newWeaponClass);
if (dualClass != none) if (dualClass != none)
{ {
collidingWeapon = GetByRootWithDualRole(newWeaponClass, collidingWeapon = GetByRootWithDualRole(newWeaponClass,
@ -349,7 +349,7 @@ public function EItem AddTemplate(
} }
} }
// Add regular weapons // Add regular weapons
newWeapon = KFWeapon(_.unreal.inventory newWeapon = KFWeapon(_server.unreal.inventory
.MergeWeapons(GetOwnerPawn(), newWeaponClass, collidingWeapon)); .MergeWeapons(GetOwnerPawn(), newWeaponClass, collidingWeapon));
if (newWeapon != none) { if (newWeapon != none) {
return class'EKFWeapon'.static.Wrap(newWeapon); return class'EKFWeapon'.static.Wrap(newWeapon);
@ -464,13 +464,13 @@ private function Text CanAddWeaponClassExplain(
// Start with checking conflicting weapons, since in case of conflicting // Start with checking conflicting weapons, since in case of conflicting
// dual weapons we might need to update `additionalWeight` variable. // dual weapons we might need to update `additionalWeight` variable.
conflictingWeapon = conflictingWeapon =
_.unreal.inventory.GetByRoot(kfWeaponClass, kfPawn.inventory); _server.unreal.inventory.GetByRoot(kfWeaponClass, kfPawn.inventory);
if (conflictingWeapon != none) if (conflictingWeapon != none)
{ {
// `GetByRoot()` is a simple check that thinks handcannon is in // `GetByRoot()` is a simple check that thinks handcannon is in
// a conflict with another handcannon, so we need to handle // a conflict with another handcannon, so we need to handle
// dual wieldable weapons differently // dual wieldable weapons differently
dualWeildingRole = _.unreal.inventory.GetDualWieldingRole( dualWeildingRole = _server.unreal.inventory.GetDualWieldingRole(
class<KFWeapon>(conflictingWeapon.class)); class<KFWeapon>(conflictingWeapon.class));
if (dualWeildingRole != DWR_None) if (dualWeildingRole != DWR_None)
{ {
@ -478,7 +478,7 @@ private function Text CanAddWeaponClassExplain(
return ReportConflictingItem(conflictingWeapon); return ReportConflictingItem(conflictingWeapon);
} }
// Update additional weight // Update additional weight
dualVersion = _.unreal.inventory.GetDualClass(kfWeaponClass); dualVersion = _server.unreal.inventory.GetDualClass(kfWeaponClass);
if (dualVersion != none) if (dualVersion != none)
{ {
additionalWeight = additionalWeight =
@ -512,7 +512,7 @@ private function bool HasDualWieldingConflict(
return false; return false;
} }
addingSingle = false; addingSingle = false;
dualClass = _.unreal.inventory.GetDualClass(kfWeaponClass); dualClass = _server.unreal.inventory.GetDualClass(kfWeaponClass);
if (dualClass == none) if (dualClass == none)
{ {
dualClass = kfWeaponClass; dualClass = kfWeaponClass;
@ -526,14 +526,14 @@ private function bool HasDualWieldingConflict(
// 2. If we do have a dual version, but we are forcing this addition and // 2. If we do have a dual version, but we are forcing this addition and
// are adding single when there is no other single pistol yet // are adding single when there is no other single pistol yet
if ( addingSingle && forceAddition if ( addingSingle && forceAddition
&& _.unreal.inventory.Get(kfWeaponClass, pawn.inventory) == none) && _server.unreal.inventory.Get(kfWeaponClass, pawn.inventory) == none)
{ {
return false; return false;
} }
// 3. If we do have a dual version, but we are forcing this addition and // 3. If we do have a dual version, but we are forcing this addition and
// are adding a different skin // are adding a different skin
if ( forceAddition if ( forceAddition
&& _.unreal.inventory.Get(dualClass, pawn.inventory) == none) && _server.unreal.inventory.Get(dualClass, pawn.inventory) == none)
{ {
return false; return false;
} }
@ -591,7 +591,7 @@ public function bool Remove(
if (!forceRemoval && kfWeapon != none && kfWeapon.bKFNeverThrow) { if (!forceRemoval && kfWeapon != none && kfWeapon.bKFNeverThrow) {
return false; return false;
} }
if (!_.unreal.inventory.Contains(kfWeapon, pawn.inventory)) { if (!_server.unreal.inventory.Contains(kfWeapon, pawn.inventory)) {
return false; return false;
} }
// This code is an overkill for removing a single item and is not // This code is an overkill for removing a single item and is not
@ -601,8 +601,8 @@ public function bool Remove(
// Only optimize this if this method will become // Only optimize this if this method will become
// a bottleneck somewhere. // a bottleneck somewhere.
removalList = _.collections.EmptyDynamicArray(); removalList = _.collections.EmptyDynamicArray();
removalList.AddItem(_.unreal.ActorRef(nativeInstance), true); removalList.AddItem(_server.unreal.ActorRef(nativeInstance), true);
pawnRef = _.unreal.ActorRef(pawn); pawnRef = _server.unreal.ActorRef(pawn);
result = RemoveInventoryArray( pawnRef, removalList, result = RemoveInventoryArray( pawnRef, removalList,
keepItem, forceRemoval, true); keepItem, forceRemoval, true);
_.memory.Free(removalList); _.memory.Free(removalList);
@ -634,7 +634,7 @@ public function bool RemoveTemplate(
pawn = GetOwnerPawn(); pawn = GetOwnerPawn();
if (pawn == none) return false; if (pawn == none) return false;
pawnRef = _.unreal.ActorRef(pawn); pawnRef = _server.unreal.ActorRef(pawn);
removalList = _.collections.EmptyDynamicArray(); removalList = _.collections.EmptyDynamicArray();
// All removal works the same - form a "kill list", then remove // All removal works the same - form a "kill list", then remove
// all `Inventory` at once with `RemoveInventoryArray` // all `Inventory` at once with `RemoveInventoryArray`
@ -645,7 +645,7 @@ public function bool RemoveTemplate(
removalList, removalList,
keepItem, keepItem,
forceRemoval, forceRemoval,
_.unreal.inventory.GetDualWieldingRole(weaponClass) == DWR_Dual); _server.unreal.inventory.GetDualWieldingRole(weaponClass) == DWR_Dual);
_.memory.Free(removalList); _.memory.Free(removalList);
_.memory.Free(pawnRef); _.memory.Free(pawnRef);
return result; return result;
@ -672,7 +672,7 @@ private function AddClassForRemoval(
if (nextInventory == none) return; if (nextInventory == none) return;
dualClass = dualClass =
_.unreal.inventory.GetDualClass(class<KFWeapon>(inventoryClass)); _server.unreal.inventory.GetDualClass(class<KFWeapon>(inventoryClass));
while (nextInventory != none) while (nextInventory != none)
{ {
// We want to "remove" dual handcannons if removal of single handcannon // We want to "remove" dual handcannons if removal of single handcannon
@ -686,7 +686,7 @@ private function AddClassForRemoval(
} }
if (canRemoveInventory) if (canRemoveInventory)
{ {
removalArray.AddItem(_.unreal.ActorRef(nextInventory), true); removalArray.AddItem(_server.unreal.ActorRef(nextInventory), true);
if (!removeAll) { if (!removeAll) {
break; break;
} }
@ -723,12 +723,15 @@ public function bool RemoveAll(
&& (forceRemoval || !kfWeapon.bKFNeverThrow); && (forceRemoval || !kfWeapon.bKFNeverThrow);
canRemoveItem = canRemoveItem canRemoveItem = canRemoveItem
|| (includeHidden && Ammunition(nextInventory) == none); || (includeHidden && Ammunition(nextInventory) == none);
if (canRemoveItem) { if (canRemoveItem)
inventoryToRemove.AddItem(_.unreal.ActorRef(nextInventory), true); {
inventoryToRemove.AddItem(
_server.unreal.ActorRef(nextInventory),
true);
} }
nextInventory = nextInventory.inventory; nextInventory = nextInventory.inventory;
} }
pawnRef = _.unreal.ActorRef(pawn); pawnRef = _server.unreal.ActorRef(pawn);
result = RemoveInventoryArray( pawnRef, inventoryToRemove, result = RemoveInventoryArray( pawnRef, inventoryToRemove,
keepItems, forceRemoval, true); keepItems, forceRemoval, true);
_.memory.Free(inventoryToRemove); _.memory.Free(inventoryToRemove);
@ -757,7 +760,7 @@ private function bool RemoveInventoryArray(
ownerPawn = Pawn(ownerPawnRef.Get()); ownerPawn = Pawn(ownerPawnRef.Get());
if (ownerPawn == none) return false; if (ownerPawn == none) return false;
equippedWeapon = _.unreal.ActorRef(ownerPawn.weapon); equippedWeapon = _server.unreal.ActorRef(ownerPawn.weapon);
for(i = 0; i < itemsToRemove.GetLength(); i += 1) for(i = 0; i < itemsToRemove.GetLength(); i += 1)
{ {
// `itemsToRemove` is guaranteed to contain valid `ActorRef`s // `itemsToRemove` is guaranteed to contain valid `ActorRef`s
@ -822,7 +825,8 @@ private function AppendSingleClass(
if (kfWeaponInstance == none) { if (kfWeaponInstance == none) {
return; return;
} }
singleClass = _.unreal.inventory.GetSingleClass(kfWeaponInstance.class); singleClass =
_server.unreal.inventory.GetSingleClass(kfWeaponInstance.class);
if (singleClass != none) { if (singleClass != none) {
singleClasses[singleClasses.length] = singleClass; singleClasses[singleClasses.length] = singleClass;
} }
@ -857,7 +861,7 @@ private function bool HandleInventoryRemoval(
{ {
if (KFWeapon(inventory) != none) if (KFWeapon(inventory) != none)
{ {
singleClass = _.unreal.inventory singleClass = _server.unreal.inventory
.GetSingleClass(class<KFWeapon>(inventory.class)); .GetSingleClass(class<KFWeapon>(inventory.class));
} }
if (singleClass != none && singleClass.default.bKFNeverThrow) { if (singleClass != none && singleClass.default.bKFNeverThrow) {
@ -914,7 +918,8 @@ private function DestroyWeaponSingle(
if (kfWeaponToDestroy == none) { if (kfWeaponToDestroy == none) {
return; return;
} }
singleClass = _.unreal.inventory.GetSingleClass(kfWeaponToDestroy.class); singleClass =
_server.unreal.inventory.GetSingleClass(kfWeaponToDestroy.class);
if (singleClass != none) if (singleClass != none)
{ {
totalAmmoPrimary = kfWeaponToDestroy.AmmoAmount(0); totalAmmoPrimary = kfWeaponToDestroy.AmmoAmount(0);
@ -924,7 +929,7 @@ private function DestroyWeaponSingle(
KillRefInventory(inventoryToDestroy); KillRefInventory(inventoryToDestroy);
if (singleClass != none) if (singleClass != none)
{ {
_.unreal.inventory _server.unreal.inventory
.AddWeaponWithAmmo( Pawn(ownerPawnRef.Get()), singleClass, .AddWeaponWithAmmo( Pawn(ownerPawnRef.Get()), singleClass,
totalAmmoPrimary / 2, totalAmmoSecondary / 2, totalAmmoPrimary / 2, totalAmmoSecondary / 2,
magazineAmmo / 2, true); magazineAmmo / 2, true);

2
sources/Gameplay/KF1Frontend/BaseImplementation/EKFMedicAmmo.uc

@ -47,7 +47,7 @@ public final static /*unreal*/ function EKFMedicAmmo Wrap(
} }
newReference = EKFMedicAmmo(__().memory.Allocate(class'EKFMedicAmmo')); newReference = EKFMedicAmmo(__().memory.Allocate(class'EKFMedicAmmo'));
newReference.medicWeaponReference = newReference.medicWeaponReference =
__().unreal.ActorRef(medicWeaponInstance); __server().unreal.ActorRef(medicWeaponInstance);
return newReference; return newReference;
} }

2
sources/Gameplay/KF1Frontend/BaseImplementation/EKFPawn.uc

@ -43,7 +43,7 @@ public final static /*unreal*/ function EKFPawn Wrap(Pawn pawnInstance)
return none; return none;
} }
newReference = EKFPawn(__().memory.Allocate(class'EKFPawn')); newReference = EKFPawn(__().memory.Allocate(class'EKFPawn'));
newReference.pawnReference = __().unreal.ActorRef(pawnInstance); newReference.pawnReference = __server().unreal.ActorRef(pawnInstance);
return newReference; return newReference;
} }

2
sources/Gameplay/KF1Frontend/BaseImplementation/EKFSyringeAmmo.uc

@ -47,7 +47,7 @@ public final static /*unreal*/ function EKFSyringeAmmo Wrap(
} }
newReference = EKFSyringeAmmo(__().memory.Allocate(class'EKFSyringeAmmo')); newReference = EKFSyringeAmmo(__().memory.Allocate(class'EKFSyringeAmmo'));
newReference.syringeReference = newReference.syringeReference =
__().unreal.ActorRef(syringeInstance); __server().unreal.ActorRef(syringeInstance);
return newReference; return newReference;
} }

3
sources/Gameplay/KF1Frontend/BaseImplementation/EKFUnknownItem.uc

@ -47,7 +47,8 @@ public final static /*unreal*/ function EKFUnknownItem Wrap(
if (inventoryInstance.class == class'KFMod.FlashlightAmmo') return none; if (inventoryInstance.class == class'KFMod.FlashlightAmmo') return none;
newReference = EKFUnknownItem(__().memory.Allocate(class'EKFUnknownItem')); newReference = EKFUnknownItem(__().memory.Allocate(class'EKFUnknownItem'));
newReference.inventoryReference = __().unreal.ActorRef(inventoryInstance); newReference.inventoryReference =
__server().unreal.ActorRef(inventoryInstance);
return newReference; return newReference;
} }

2
sources/Gameplay/KF1Frontend/BaseImplementation/EKFUnknownPlaceable.uc

@ -46,7 +46,7 @@ public final static /*unreal*/ function EKFUnknownPlaceable Wrap(
} }
newReference = EKFUnknownPlaceable( newReference = EKFUnknownPlaceable(
__().memory.Allocate(class'EKFUnknownPlaceable')); __().memory.Allocate(class'EKFUnknownPlaceable'));
newReference.actorReference = __().unreal.ActorRef(actorInstance); newReference.actorReference = __server().unreal.ActorRef(actorInstance);
return newReference; return newReference;
} }

6
sources/Gameplay/KF1Frontend/BaseImplementation/EKFWeapon.uc

@ -45,7 +45,7 @@ public final static /*unreal*/ function EKFWeapon Wrap(KFWeapon weaponInstance)
return none; return none;
} }
newReference = EKFWeapon(__().memory.Allocate(class'EKFWeapon')); newReference = EKFWeapon(__().memory.Allocate(class'EKFWeapon'));
newReference.weaponReference = __().unreal.ActorRef(weaponInstance); newReference.weaponReference = __server().unreal.ActorRef(weaponInstance);
return newReference; return newReference;
} }
@ -216,8 +216,8 @@ public function array<EAmmo> GetAvailableAmmo()
if (kfWeapon == none) return result; if (kfWeapon == none) return result;
if (kfWeapon.owner == none) return result; if (kfWeapon.owner == none) return result;
ammoClass1 = _.unreal.inventory.GetAmmoClass(kfWeapon, 0); ammoClass1 = _server.unreal.inventory.GetAmmoClass(kfWeapon, 0);
ammoClass2 = _.unreal.inventory.GetAmmoClass(kfWeapon, 1); ammoClass2 = _server.unreal.inventory.GetAmmoClass(kfWeapon, 1);
nextInventory = kfWeapon.owner.inventory; nextInventory = kfWeapon.owner.inventory;
while (nextInventory != none) while (nextInventory != none)
{ {

8
sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc

@ -35,8 +35,8 @@ protected function Finalizer()
super.Finalizer(); super.Finalizer();
if (connectedToGameRules) if (connectedToGameRules)
{ {
_.unreal.gameRules.OnNetDamage(self).Disconnect(); _server.unreal.gameRules.OnNetDamage(self).Disconnect();
_.unreal.gameRules.OnScoreKill(self).Disconnect(); _server.unreal.gameRules.OnScoreKill(self).Disconnect();
connectedToGameRules = false; connectedToGameRules = false;
} }
} }
@ -54,9 +54,9 @@ private final function TryConnectToGameRules()
return; return;
} }
connectedToGameRules = true; connectedToGameRules = true;
_.unreal.gameRules.OnNetDamage(self).connect = OnNetDamageHandler; _server.unreal.gameRules.OnNetDamage(self).connect = OnNetDamageHandler;
// Fixes achievements // Fixes achievements
_.unreal.gameRules.OnScoreKill(self).connect = UpdateBileAchievement; _server.unreal.gameRules.OnScoreKill(self).connect = UpdateBileAchievement;
} }
private final function TryReplaceDamageTypes() private final function TryReplaceDamageTypes()

2
sources/Gameplay/KF1Frontend/Templates/KF1_TemplatesComponent.uc

@ -88,7 +88,7 @@ private function BuildKFWeaponLists()
local LevelInfo level; local LevelInfo level;
local KFLevelRules kfLevelRules; local KFLevelRules kfLevelRules;
if (listsAreReady) return; if (listsAreReady) return;
level = _.unreal.GetLevel(); level = _server.unreal.GetLevel();
if (level == none) return; if (level == none) return;
foreach level.DynamicActors(class'KFMod.KFLevelRules', kfLevelRules) break; foreach level.DynamicActors(class'KFMod.KFLevelRules', kfLevelRules) break;
if (kfLevelRules == none) return; if (kfLevelRules == none) return;

12
sources/Gameplay/KF1Frontend/Trading/KF1_Trader.uc

@ -84,7 +84,7 @@ private static function Text GetShopVolumeName(ShopVolume newShopVolume)
return namedShopVolumesCopy[i].name.Copy(); return namedShopVolumesCopy[i].name.Copy();
} }
} }
newRecord.reference = __().unreal.ActorRef(newShopVolume); newRecord.reference = __server().unreal.ActorRef(newShopVolume);
newRecord.name = newRecord.name =
__().text.FromString("trader" $ namedShopVolumesCopy.length); __().text.FromString("trader" $ namedShopVolumesCopy.length);
default.namedShopVolumes[default.namedShopVolumes.length] = newRecord; default.namedShopVolumes[default.namedShopVolumes.length] = newRecord;
@ -114,11 +114,11 @@ public final /* unreal */ function bool Initialize(ShopVolume initShopVolume)
return false; return false;
} }
if ( initShopVolume.bObjectiveModeOnly if ( initShopVolume.bObjectiveModeOnly
&& !__().unreal.GetKFGameType().bUsingObjectiveMode) { && !__server().unreal.GetKFGameType().bUsingObjectiveMode) {
return false; return false;
} }
myName = GetShopVolumeName(initShopVolume); myName = GetShopVolumeName(initShopVolume);
myShopVolume = _.unreal.ActorRef(initShopVolume); myShopVolume = _server.unreal.ActorRef(initShopVolume);
return true; return true;
} }
@ -216,7 +216,7 @@ protected function UpdateShopList()
shopVolumes[shopVolumes.length] = nextShopVolume; shopVolumes[shopVolumes.length] = nextShopVolume;
} }
_.unreal.GetKFGameType().shopList = shopVolumes; _server.unreal.GetKFGameType().shopList = shopVolumes;
} }
public function bool IsAutoOpen() public function bool IsAutoOpen()
@ -279,7 +279,7 @@ public function bool IsSelected()
if (vanillaShopVolume == none) { if (vanillaShopVolume == none) {
return false; return false;
} }
kfGameRI = _.unreal.GetKFGameRI(); kfGameRI = _server.unreal.GetKFGameRI();
if (kfGameRI != none) { if (kfGameRI != none) {
return (kfGameRI.currentShop == vanillaShopVolume); return (kfGameRI.currentShop == vanillaShopVolume);
} }
@ -294,7 +294,7 @@ public function ETrader Select()
if (vanillaShopVolume == none) { if (vanillaShopVolume == none) {
return self; return self;
} }
kfGameRI = _.unreal.GetKFGameRI(); kfGameRI = _server.unreal.GetKFGameRI();
if (kfGameRI != none) { if (kfGameRI != none) {
kfGameRI.currentShop = vanillaShopVolume; kfGameRI.currentShop = vanillaShopVolume;
} }

35
sources/Gameplay/KF1Frontend/Trading/KF1_TradingComponent.uc

@ -42,11 +42,11 @@ protected function Constructor()
local KF1_Trader nextTrader; local KF1_Trader nextTrader;
local ShopVolume nextShopVolume; local ShopVolume nextShopVolume;
super.Constructor(); super.Constructor();
_.unreal.OnTick(self).connect = Tick; _server.unreal.OnTick(self).connect = Tick;
// Build `registeredTraders` cache to avoid looking through // Build `registeredTraders` cache to avoid looking through
// all actors each time // all actors each time
level = __().unreal.GetLevel(); level = __server().unreal.GetLevel();
kfGame = __().unreal.GetKFGameType(); kfGame = __server().unreal.GetKFGameType();
foreach level.AllActors(class'ShopVolume', nextShopVolume) foreach level.AllActors(class'ShopVolume', nextShopVolume)
{ {
if (nextShopVolume == none) { if (nextShopVolume == none) {
@ -70,7 +70,7 @@ protected function Constructor()
protected function Finalizer() protected function Finalizer()
{ {
super.Finalizer(); super.Finalizer();
_.unreal.OnTick(self).Disconnect(); _server.unreal.OnTick(self).Disconnect();
_.memory.Free(lastSelectedTrader); _.memory.Free(lastSelectedTrader);
_.memory.FreeMany(registeredTraders); _.memory.FreeMany(registeredTraders);
lastSelectedTrader = none; lastSelectedTrader = none;
@ -110,7 +110,7 @@ public function ETrader GetTrader(BaseText traderName)
public function bool IsTradingActive() public function bool IsTradingActive()
{ {
local KFGameType kfGame; local KFGameType kfGame;
kfGame = _.unreal.GetKFGameType(); kfGame = _server.unreal.GetKFGameType();
return kfGame.IsInState('MatchInProgress') && !kfGame.bWaveInProgress; return kfGame.IsInState('MatchInProgress') && !kfGame.bWaveInProgress;
} }
@ -129,8 +129,8 @@ public function SetTradingStatus(bool makeActive)
SetCountDown(0); SetCountDown(0);
return; return;
} }
kfGame = _.unreal.GetKFGameType(); kfGame = _server.unreal.GetKFGameType();
kfGameRI = _.unreal.GetKFGameRI(); kfGameRI = _server.unreal.GetKFGameRI();
foreach kfGame.DynamicActors(class'KFMonster', nextZed) foreach kfGame.DynamicActors(class'KFMonster', nextZed)
{ {
if (nextZed == none) continue; if (nextZed == none) continue;
@ -163,7 +163,7 @@ public function SelectTrader(ETrader newSelection)
} }
else else
{ {
kfGameRI = _.unreal.GetKFGameRI(); kfGameRI = _server.unreal.GetKFGameRI();
if (kfGameRI != none) { if (kfGameRI != none) {
kfGameRI.currentShop = none; kfGameRI.currentShop = none;
} }
@ -190,13 +190,13 @@ public function SelectTrader(ETrader newSelection)
public function int GetTradingInterval() public function int GetTradingInterval()
{ {
return _.unreal.GetKFGameType().timeBetweenWaves; return _server.unreal.GetKFGameType().timeBetweenWaves;
} }
public function SetTradingInterval(int newTradingInterval) public function SetTradingInterval(int newTradingInterval)
{ {
if (newTradingInterval > 0) { if (newTradingInterval > 0) {
_.unreal.GetKFGameType().timeBetweenWaves = Max(newTradingInterval, 1); _server.unreal.GetKFGameType().timeBetweenWaves = Max(newTradingInterval, 1);
} }
} }
@ -205,7 +205,7 @@ public function int GetCountDown()
if (!IsTradingActive()) { if (!IsTradingActive()) {
return 0; return 0;
} }
return _.unreal.GetKFGameType().waveCountDown; return _server.unreal.GetKFGameType().waveCountDown;
} }
public function SetCountDown(int newCountDownValue) public function SetCountDown(int newCountDownValue)
@ -214,9 +214,9 @@ public function SetCountDown(int newCountDownValue)
if (!IsTradingActive()) { if (!IsTradingActive()) {
return; return;
} }
kfGame = _.unreal.GetKFGameType(); kfGame = _server.unreal.GetKFGameType();
if (kfGame.waveCountDown >= 5 && newCountDownValue < 5) { if (kfGame.waveCountDown >= 5 && newCountDownValue < 5) {
_.unreal.GetKFGameRI().waveNumber = kfGame.waveNum; _server.unreal.GetKFGameRI().waveNumber = kfGame.waveNum;
} }
kfGame.waveCountDown = Max(newCountDownValue, 1); kfGame.waveCountDown = Max(newCountDownValue, 1);
pausedCountDownValue = newCountDownValue; pausedCountDownValue = newCountDownValue;
@ -237,7 +237,8 @@ public function SetCountDownPause(bool doPause)
if (IsTradingActive()) { if (IsTradingActive()) {
// `+1` makes client counter stop closer to the moment // `+1` makes client counter stop closer to the moment
// `SetCountDownPause()` was called // `SetCountDownPause()` was called
pausedCountDownValue = _.unreal.GetKFGameType().waveCountDown + 1; pausedCountDownValue =
_server.unreal.GetKFGameType().waveCountDown + 1;
} }
else { else {
// If trading time isn't active, then we do not yet know how long // If trading time isn't active, then we do not yet know how long
@ -286,10 +287,10 @@ protected function Tick(float delta, float timeScaleCoefficient)
if (isActiveNow && tradingCountDownPaused) if (isActiveNow && tradingCountDownPaused)
{ {
if (pausedCountDownValue >= 0) { if (pausedCountDownValue >= 0) {
_.unreal.GetKFGameType().waveCountDown = pausedCountDownValue; _server.unreal.GetKFGameType().waveCountDown = pausedCountDownValue;
} }
else { else {
pausedCountDownValue = _.unreal.GetKFGameType().waveCountDown; pausedCountDownValue = _server.unreal.GetKFGameType().waveCountDown;
} }
} }
} }
@ -299,7 +300,7 @@ protected function CheckNativeTraderSwap()
{ {
local ETrader newSelectedTrader; local ETrader newSelectedTrader;
if ( lastSelectedTrader == none if ( lastSelectedTrader == none
&& _.unreal.GetKFGameRI().currentShop == none) { && _server.unreal.GetKFGameRI().currentShop == none) {
return; return;
} }
if (lastSelectedTrader != none && lastSelectedTrader.IsSelected()) { if (lastSelectedTrader != none && lastSelectedTrader.IsSelected()) {

2
sources/InfoQueryHandler/InfoQueryHandler.uc

@ -52,7 +52,7 @@ public static function StaticConstructor()
__().memory.Allocate(class'InfoQueryHandler_OnQuery_Signal')); __().memory.Allocate(class'InfoQueryHandler_OnQuery_Signal'));
// We cannot make an instance of an abstract `InfoQueryHandler` class, // We cannot make an instance of an abstract `InfoQueryHandler` class,
// use created `ConsoleWriter` to connect // use created `ConsoleWriter` to connect
__().unreal.mutator.OnMutate(default.anchor).connect = HandleMutate; __server().unreal.mutator.OnMutate(default.anchor).connect = HandleMutate;
} }
/** /**

2
sources/Players/EPlayer.uc

@ -99,7 +99,7 @@ public final /* unreal */ function bool Initialize(
idHash = none; idHash = none;
} }
signalsReferences = playerSignals; signalsReferences = playerSignals;
controller = _.unreal.ActorRef(initController); controller = _server.unreal.ActorRef(initController);
return true; return true;
} }

6
sources/ServerRealm/ServerGlobal.uc

@ -26,6 +26,8 @@ class ServerGlobal extends CoreGlobal;
var protected ServerGlobal myself; var protected ServerGlobal myself;
var public KFFrontend kf; var public KFFrontend kf;
var public ServerUnrealAPI unreal;
var public TimeAPI time;
public final static function ServerGlobal GetInstance() public final static function ServerGlobal GetInstance()
{ {
@ -47,6 +49,8 @@ protected function Initialize()
} }
super.Initialize(); super.Initialize();
_ = class'Global'.static.GetInstance(); _ = class'Global'.static.GetInstance();
unreal = ServerUnrealAPI(_.memory.Allocate(class'ServerUnrealAPI'));
time = TimeAPI(_.memory.Allocate(class'TimeAPI'));
kf = KFFrontend(_.memory.Allocate(class'KF1_Frontend')); kf = KFFrontend(_.memory.Allocate(class'KF1_Frontend'));
initialized = true; initialized = true;
} }
@ -63,7 +67,7 @@ public final function bool ConnectServerLevelCore()
if (class'SideEffects'.default.allowHookingIntoMutate) if (class'SideEffects'.default.allowHookingIntoMutate)
{ {
class'InfoQueryHandler'.static.StaticConstructor(); class'InfoQueryHandler'.static.StaticConstructor();
_.unreal.mutator.OnMutate( unreal.mutator.OnMutate(
ServiceAnchor(_.memory.Allocate(class'ServiceAnchor'))) ServiceAnchor(_.memory.Allocate(class'ServiceAnchor')))
.connect = EnableCommandsFeature; .connect = EnableCommandsFeature;
} }

6
sources/Time/Timer.uc

@ -57,7 +57,7 @@ protected function Constructor()
protected function Finalizer() protected function Finalizer()
{ {
_.memory.Free(onElapsedSignal); _.memory.Free(onElapsedSignal);
StopMe(); // Disconnects from listening to `_.unreal.OnTick()` StopMe(); // Disconnects from listening to `_server.unreal.OnTick()`
} }
/** /**
@ -189,7 +189,7 @@ public final function Timer Start()
return self; return self;
} }
if (!isTimerEnabled) { if (!isTimerEnabled) {
_.unreal.OnTick(self).connect = Tick; _server.unreal.OnTick(self).connect = Tick;
} }
isTimerEnabled = true; isTimerEnabled = true;
totalElapsedTime = 0.0; totalElapsedTime = 0.0;
@ -203,7 +203,7 @@ public final function Timer Start()
*/ */
public final function Timer StopMe() public final function Timer StopMe()
{ {
_.unreal.OnTick(self).Disconnect(); _server.unreal.OnTick(self).Disconnect();
isTimerEnabled = false; isTimerEnabled = false;
clearEventQueue = true; clearEventQueue = true;
return self; return self;

8
sources/Unreal/BroadcastsAPI/BroadcastAPI.uc

@ -288,7 +288,7 @@ private final function TryInjectBroadcastHandler(UnrealService service)
} }
triedToInjectBroadcasthandler = true; triedToInjectBroadcasthandler = true;
usedLevel = class'SideEffects'.default.broadcastHandlerInjectionLevel; usedLevel = class'SideEffects'.default.broadcastHandlerInjectionLevel;
broadcastObserver = BroadcastEventsObserver(_.unreal.broadcasts.Add( broadcastObserver = BroadcastEventsObserver(_server.unreal.broadcasts.Add(
class'BroadcastEventsObserver', usedLevel)); class'BroadcastEventsObserver', usedLevel));
if (broadcastObserver != none) if (broadcastObserver != none)
{ {
@ -341,7 +341,7 @@ public final function BroadcastHandler Add(
local LevelInfo level; local LevelInfo level;
local BroadcastHandler newBroadcastHandler; local BroadcastHandler newBroadcastHandler;
if (injectionLevel == BHIJ_None) return none; if (injectionLevel == BHIJ_None) return none;
level = _.unreal.GetLevel(); level = _server.unreal.GetLevel();
if (level == none || level.game == none) return none; if (level == none || level.game == none) return none;
if (IsAdded(newBHClass)) return none; if (IsAdded(newBHClass)) return none;
@ -382,7 +382,7 @@ public final function bool Remove(class<BroadcastHandler> BHClassToRemove)
{ {
local LevelInfo level; local LevelInfo level;
local BroadcastHandler previousBH, currentBH; local BroadcastHandler previousBH, currentBH;
level = _.unreal.GetLevel(); level = _server.unreal.GetLevel();
if (level == none || level.game == none) { if (level == none || level.game == none) {
return false; return false;
} }
@ -440,7 +440,7 @@ public final function BroadcastHandler FindInstance(
if (BHClassToFind == none) { if (BHClassToFind == none) {
return none; return none;
} }
BHIter = _.unreal.GetGameType().broadcastHandler; BHIter = _server.unreal.GetGameType().broadcastHandler;
while (BHIter != none) while (BHIter != none)
{ {
if (BHIter.class == BHClassToFind) { if (BHIter.class == BHClassToFind) {

14
sources/Unreal/Connections/ConnectionService.uc

@ -97,9 +97,11 @@ protected function OnLaunch()
{ {
local Controller nextController; local Controller nextController;
local PlayerController nextPlayerController; local PlayerController nextPlayerController;
_.unreal.mutator.OnModifyLogin(_self).connect = RememberLoginOptions; _server.unreal.mutator.OnModifyLogin(_self).connect =
_.unreal.mutator.OnCheckReplacement(_self).connect = TryAddingController; RememberLoginOptions;
_.unreal.mutator.OnCheckReplacement(_self).connect = _server.unreal.mutator.OnCheckReplacement(_self).connect =
TryAddingController;
_server.unreal.mutator.OnCheckReplacement(_self).connect =
RecordPendingInformation; RecordPendingInformation;
onConnectionEstablishedSignal = onConnectionEstablishedSignal =
Connection_Signal(_.memory.Allocate(class'Connection_Signal')); Connection_Signal(_.memory.Allocate(class'Connection_Signal'));
@ -120,8 +122,8 @@ protected function OnLaunch()
protected function OnShutdown() protected function OnShutdown()
{ {
default.activeConnections = activeConnections; default.activeConnections = activeConnections;
_.unreal.mutator.OnModifyLogin(_self).Disconnect(); _server.unreal.mutator.OnModifyLogin(_self).Disconnect();
_.unreal.mutator.OnCheckReplacement(_self).Disconnect(); _server.unreal.mutator.OnCheckReplacement(_self).Disconnect();
_.memory.Free(onConnectionEstablishedSignal); _.memory.Free(onConnectionEstablishedSignal);
_.memory.Free(onConnectionLostSignal); _.memory.Free(onConnectionLostSignal);
onConnectionEstablishedSignal = none; onConnectionEstablishedSignal = none;
@ -277,7 +279,7 @@ public final function array<Connection> GetActiveConnections(
private function RememberLoginOptions(out string portal, out string options) private function RememberLoginOptions(out string portal, out string options)
{ {
lastNickNameFromModifyLogin = lastNickNameFromModifyLogin =
_.unreal.GetGameType().ParseOption(options, "Name"); _server.unreal.GetGameType().ParseOption(options, "Name");
} }
private function bool RecordPendingInformation( private function bool RecordPendingInformation(

6
sources/Unreal/GameRulesAPI/GameRulesAPI.uc

@ -318,7 +318,7 @@ public final function GameRules Add(class<GameRules> newRulesClass)
return none; return none;
} }
newGameRules = GameRules(_.memory.Allocate(newRulesClass)); newGameRules = GameRules(_.memory.Allocate(newRulesClass));
_.unreal.GetGameType().AddGameModifier(newGameRules); _server.unreal.GetGameType().AddGameModifier(newGameRules);
return newGameRules; return newGameRules;
} }
@ -336,7 +336,7 @@ public final function bool Remove(class<GameRules> rulesClassToRemove)
local GameRules rulesIter; local GameRules rulesIter;
local GameRules rulesToDestroy; local GameRules rulesToDestroy;
if (rulesClassToRemove == none) return false; if (rulesClassToRemove == none) return false;
game = _.unreal.GetGameType(); game = _server.unreal.GetGameType();
if (game.gameRulesModifiers == none) return false; if (game.gameRulesModifiers == none) return false;
// Check root rules // Check root rules
@ -380,7 +380,7 @@ public final function GameRules FindInstance(
if (rulesClassToFind == none) { if (rulesClassToFind == none) {
return none; return none;
} }
rulesIter = _.unreal.GetGameType().gameRulesModifiers; rulesIter = _server.unreal.GetGameType().gameRulesModifiers;
while (rulesIter != none) while (rulesIter != none)
{ {
if (rulesIter.class == rulesClassToFind) { if (rulesIter.class == rulesClassToFind) {

2
sources/Unreal/InventoryAPI/InventoryService.uc

@ -37,7 +37,7 @@ public function Weapon AddWeaponWithAmmo(
if (newWeapon == none) return none; if (newWeapon == none) return none;
// It is possible that `newWeapon` can get destroyed somewhere here, // It is possible that `newWeapon` can get destroyed somewhere here,
// so add two more checks // so add two more checks
_.unreal.GetKFGameType().WeaponSpawned(newWeapon); _server.unreal.GetKFGameType().WeaponSpawned(newWeapon);
if (newWeapon == none) return none; if (newWeapon == none) return none;
newWeapon.GiveTo(pawn); newWeapon.GiveTo(pawn);
if (newWeapon == none) return none; if (newWeapon == none) return none;

86
sources/Unreal/Tests/TEST_ServerUnrealAPI.uc

@ -26,7 +26,7 @@ protected static function int CountRulesAmount(class<gameRules> gameRulesClass)
if (gameRulesClass == none) { if (gameRulesClass == none) {
return 0; return 0;
} }
rulesIter = __().unreal.GetGameType().gameRulesModifiers; rulesIter = __server().unreal.GetGameType().gameRulesModifiers;
while (rulesIter != none) while (rulesIter != none)
{ {
if (rulesIter.class == gameRulesClass) { if (rulesIter.class == gameRulesClass) {
@ -48,11 +48,12 @@ protected static function Test_GameType()
{ {
Context("Testing methods for returning `GameType` class."); Context("Testing methods for returning `GameType` class.");
Issue("`GetGameType()` returns `none`."); Issue("`GetGameType()` returns `none`.");
TEST_ExpectNotNone(__().unreal.GetGameType()); TEST_ExpectNotNone(__server().unreal.GetGameType());
Issue("`GetKFGameType()` returns `none`."); Issue("`GetKFGameType()` returns `none`.");
TEST_ExpectNotNone(__().unreal.GetKFGameType()); TEST_ExpectNotNone(__server().unreal.GetKFGameType());
Issue("`GetGameType()` and `GetKFGameType()` return different values."); Issue("`GetGameType()` and `GetKFGameType()` return different values.");
TEST_ExpectTrue(__().unreal.GetGameType() == __().unreal.GetKFGameType()); TEST_ExpectTrue( __server().unreal.GetGameType()
== __server().unreal.GetKFGameType());
} }
protected static function Test_GameRules() protected static function Test_GameRules()
@ -65,30 +66,30 @@ protected static function Test_GameRules()
protected static function SubTest_AddRemoveGameRules() protected static function SubTest_AddRemoveGameRules()
{ {
Issue("`gameRules.Add()` does not add game rules."); Issue("`gameRules.Add()` does not add game rules.");
__().unreal.gameRules.Add(class'MockGameRulesA'); __server().unreal.gameRules.Add(class'MockGameRulesA');
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1);
__().unreal.gameRules.Add(class'MockGameRulesA'); __server().unreal.gameRules.Add(class'MockGameRulesA');
Issue("Calling `gameRules.Add()` twice leads to rule duplication."); Issue("Calling `gameRules.Add()` twice leads to rule duplication.");
TEST_ExpectFalse(CountRulesAmount(class'MockGameRulesA') > 1); TEST_ExpectFalse(CountRulesAmount(class'MockGameRulesA') > 1);
Issue("Calling `gameRules.Add()` leads to rule not being added."); Issue("Calling `gameRules.Add()` leads to rule not being added.");
TEST_ExpectFalse(CountRulesAmount(class'MockGameRulesA') == 0); TEST_ExpectFalse(CountRulesAmount(class'MockGameRulesA') == 0);
Issue("Adding new rules with `gameRules.Add()` does not work properly."); Issue("Adding new rules with `gameRules.Add()` does not work properly.");
__().unreal.gameRules.Add(class'MockGameRulesB'); __server().unreal.gameRules.Add(class'MockGameRulesB');
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1);
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 1); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 1);
Issue("Adding/removing rules with `gameRules.Remove()` leads to" @ Issue("Adding/removing rules with `gameRules.Remove()` leads to" @
"unexpected results."); "unexpected results.");
__().unreal.gameRules.Remove(class'MockGameRulesB'); __server().unreal.gameRules.Remove(class'MockGameRulesB');
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 1);
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 0); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 0);
__().unreal.gameRules.Add(class'MockGameRulesB'); __server().unreal.gameRules.Add(class'MockGameRulesB');
__().unreal.gameRules.Remove(class'MockGameRulesA'); __server().unreal.gameRules.Remove(class'MockGameRulesA');
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 0); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 0);
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 1); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 1);
__().unreal.gameRules.Remove(class'MockGameRulesB'); __server().unreal.gameRules.Remove(class'MockGameRulesB');
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 0); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesA') == 0);
TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 0); TEST_ExpectTrue(CountRulesAmount(class'MockGameRulesB') == 0);
} }
@ -100,28 +101,35 @@ protected static function SubTest_CheckGameRules()
@ "are currently added."; @ "are currently added.";
issueForNotAdded = "`gameRules.AreAdded()` returns `true` for rules that" @ issueForNotAdded = "`gameRules.AreAdded()` returns `true` for rules that" @
"are not currently added."; "are not currently added.";
__().unreal.gameRules.Remove(class'MockGameRulesA'); __server().unreal.gameRules.Remove(class'MockGameRulesA');
__().unreal.gameRules.Remove(class'MockGameRulesB'); __server().unreal.gameRules.Remove(class'MockGameRulesB');
Issue(issueForNotAdded); Issue(issueForNotAdded);
TEST_ExpectFalse(__().unreal.gameRules.AreAdded(class'MockGameRulesA')); TEST_ExpectFalse(__server().unreal.gameRules
TEST_ExpectFalse(__().unreal.gameRules.AreAdded(class'MockGameRulesB')); .AreAdded(class'MockGameRulesA'));
TEST_ExpectFalse(__server().unreal.gameRules
.AreAdded(class'MockGameRulesB'));
__().unreal.gameRules.Add(class'MockGameRulesB'); __server().unreal.gameRules.Add(class'MockGameRulesB');
Issue(issueForNotAdded); Issue(issueForNotAdded);
TEST_ExpectFalse(__().unreal.gameRules.AreAdded(class'MockGameRulesA')); TEST_ExpectFalse(__server().unreal.gameRules
.AreAdded(class'MockGameRulesA'));
Issue(issueForAdded); Issue(issueForAdded);
TEST_ExpectTrue(__().unreal.gameRules.AreAdded(class'MockGameRulesB')); TEST_ExpectTrue(__server().unreal.gameRules
.AreAdded(class'MockGameRulesB'));
__().unreal.gameRules.Add(class'MockGameRulesA'); __server().unreal.gameRules.Add(class'MockGameRulesA');
Issue(issueForAdded); Issue(issueForAdded);
TEST_ExpectTrue(__().unreal.gameRules.AreAdded(class'MockGameRulesA')); TEST_ExpectTrue(__server().unreal.gameRules
TEST_ExpectTrue(__().unreal.gameRules.AreAdded(class'MockGameRulesB')); .AreAdded(class'MockGameRulesA'));
TEST_ExpectTrue(__server().unreal.gameRules
.AreAdded(class'MockGameRulesB'));
__().unreal.gameRules.Remove(class'MockGameRulesB'); __server().unreal.gameRules.Remove(class'MockGameRulesB');
Issue(issueForAdded); Issue(issueForAdded);
TEST_ExpectTrue(__().unreal.gameRules.AreAdded(class'MockGameRulesA')); TEST_ExpectTrue(__server().unreal.gameRules
.AreAdded(class'MockGameRulesA'));
Issue(issueForNotAdded); Issue(issueForNotAdded);
TEST_ExpectFalse(__().unreal.gameRules.AreAdded(class'MockGameRulesB')); TEST_ExpectFalse(__server().unreal.gameRules.AreAdded(class'MockGameRulesB'));
} }
protected static function Test_InventoryChainFetching() protected static function Test_InventoryChainFetching()
@ -156,35 +164,35 @@ protected static function SubTest_InventoryChainFetchingSingle(Inventory chain)
{ {
Issue("Does not find correct first entry inside the inventory chain."); Issue("Does not find correct first entry inside the inventory chain.");
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryA', chain) __server().unreal.inventory.Get(class'MockInventoryA', chain)
== chain.inventory.inventory); == chain.inventory.inventory);
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryB', chain) __server().unreal.inventory.Get(class'MockInventoryB', chain)
== chain.inventory); == chain.inventory);
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryAChild', chain) __server().unreal.inventory.Get(class'MockInventoryAChild', chain)
== chain); == chain);
Issue("Incorrectly finds missing inventory entries."); Issue("Incorrectly finds missing inventory entries.");
TEST_ExpectNone(__().unreal.inventory.Get(none, chain)); TEST_ExpectNone(__server().unreal.inventory.Get(none, chain));
TEST_ExpectNone(__().unreal.inventory.Get(class'Winchester', chain)); TEST_ExpectNone(__server().unreal.inventory.Get(class'Winchester', chain));
Issue("Does not find correct first entry inside the inventory chain when" @ Issue("Does not find correct first entry inside the inventory chain when" @
"allowing for child classes."); "allowing for child classes.");
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryA', chain, true) __server().unreal.inventory.Get(class'MockInventoryA', chain, true)
== chain); == chain);
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryB', chain, true) __server().unreal.inventory.Get(class'MockInventoryB', chain, true)
== chain.inventory); == chain.inventory);
TEST_ExpectTrue( TEST_ExpectTrue(
__().unreal.inventory.Get(class'MockInventoryAChild', chain, true) __server().unreal.inventory.Get(class'MockInventoryAChild', chain, true)
== chain); == chain);
Issue("Incorrectly finds missing inventory entries when allowing for" @ Issue("Incorrectly finds missing inventory entries when allowing for" @
"child classes."); "child classes.");
TEST_ExpectNone(__().unreal.inventory.Get(none, chain, true)); TEST_ExpectNone(__server().unreal.inventory.Get(none, chain, true));
TEST_ExpectNone(__().unreal.inventory.Get( class'Winchester', chain, TEST_ExpectNone(__server().unreal.inventory.Get( class'Winchester', chain,
true)); true));
} }
@ -192,7 +200,7 @@ protected static function SubTest_InventoryChainFetchingMany(Inventory chain)
{ {
local array<Inventory> result; local array<Inventory> result;
Issue("Does not find correct entries inside the inventory chain."); Issue("Does not find correct entries inside the inventory chain.");
result = __().unreal.inventory.GetAll(class'MockInventoryB', chain); result = __server().unreal.inventory.GetAll(class'MockInventoryB', chain);
TEST_ExpectTrue(result.length == 2); TEST_ExpectTrue(result.length == 2);
TEST_ExpectTrue(result[0] == chain.inventory); TEST_ExpectTrue(result[0] == chain.inventory);
TEST_ExpectTrue(result[1] == chain.inventory.inventory.inventory.inventory); TEST_ExpectTrue(result[1] == chain.inventory.inventory.inventory.inventory);
@ -200,12 +208,12 @@ protected static function SubTest_InventoryChainFetchingMany(Inventory chain)
Issue("Does not find correct entries inside the inventory chain when" @ Issue("Does not find correct entries inside the inventory chain when" @
"allowing for child classes."); "allowing for child classes.");
result = result =
__().unreal.inventory.GetAll(class'MockInventoryB', chain, true); __server().unreal.inventory.GetAll(class'MockInventoryB', chain, true);
TEST_ExpectTrue(result.length == 2); TEST_ExpectTrue(result.length == 2);
TEST_ExpectTrue(result[0] == chain.inventory); TEST_ExpectTrue(result[0] == chain.inventory);
TEST_ExpectTrue(result[1] == chain.inventory.inventory.inventory.inventory); TEST_ExpectTrue(result[1] == chain.inventory.inventory.inventory.inventory);
result = result =
__().unreal.inventory.GetAll(class'MockInventoryA', chain, true); __server().unreal.inventory.GetAll(class'MockInventoryA', chain, true);
TEST_ExpectTrue(result.length == 5); TEST_ExpectTrue(result.length == 5);
TEST_ExpectTrue(result[0] == chain); TEST_ExpectTrue(result[0] == chain);
TEST_ExpectTrue(result[1] == chain.inventory.inventory); TEST_ExpectTrue(result[1] == chain.inventory.inventory);
@ -218,9 +226,9 @@ protected static function SubTest_InventoryChainFetchingMany(Inventory chain)
== chain.inventory.inventory.inventory.inventory.inventory.inventory); == chain.inventory.inventory.inventory.inventory.inventory.inventory);
Issue("Does not return empty array for non-existing inventory class."); Issue("Does not return empty array for non-existing inventory class.");
result = __().unreal.inventory.GetAll(class'Winchester', chain); result = __server().unreal.inventory.GetAll(class'Winchester', chain);
TEST_ExpectTrue(result.length == 0); TEST_ExpectTrue(result.length == 0);
result = __().unreal.inventory.GetAll(class'Winchester', chain, true); result = __server().unreal.inventory.GetAll(class'Winchester', chain, true);
TEST_ExpectTrue(result.length == 0); TEST_ExpectTrue(result.length == 0);
} }

4
sources/Unreal/UnrealService.uc

@ -48,8 +48,8 @@ protected function OnShutdown()
{ {
local int i; local int i;
_.unreal.broadcasts.Remove(class'BroadcastEventsObserver'); _server.unreal.broadcasts.Remove(class'BroadcastEventsObserver');
_.unreal.gameRules.Remove(class'AcediaGameRules'); _server.unreal.gameRules.Remove(class'AcediaGameRules');
for (i = 0; i < serviceSignals.length; i += 1) { for (i = 0; i < serviceSignals.length; i += 1) {
_.memory.Free(serviceSignals[i].instance); _.memory.Free(serviceSignals[i].instance);
} }

Loading…
Cancel
Save