From 27ed3df2b722b70feb6fa1fd683beb1254fbfc20 Mon Sep 17 00:00:00 2001 From: Chris Wall Date: Wed, 24 Jun 2026 00:47:23 -0400 Subject: [PATCH 1/5] getHazard -> GasPillar, add getSpawners, getSporeFlowers --- .../Private/Endpoints/World/Environment.cpp | 130 ++++++++++++++++++ .../Private/Endpoints/World/PlayerLibrary.cpp | 34 ----- .../Private/FicsitRemoteMonitoring.cpp | 5 +- .../Public/Endpoints/World/Environment.h | 16 +++ .../Public/Endpoints/World/PlayerLibrary.h | 1 - 5 files changed, 150 insertions(+), 36 deletions(-) create mode 100644 Source/FicsitRemoteMonitoring/Private/Endpoints/World/Environment.cpp create mode 100644 Source/FicsitRemoteMonitoring/Public/Endpoints/World/Environment.h diff --git a/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Environment.cpp b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Environment.cpp new file mode 100644 index 00000000..ce4916db --- /dev/null +++ b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Environment.cpp @@ -0,0 +1,130 @@ +#include "Endpoints/World/Environment.h" + +#include "FGCreatureSubsystem.h" +#include "FGGasPillar.h" +#include "FGSporeFlower.h" +#include "FicsitRemoteMonitoring.h" +#include "RemoteMonitoringLibrary.h" +#include "Creature/FGCreatureSpawner.h" +#include "Kismet/GameplayStatics.h" + +void UEnvironment::getHazards(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray) { + + UClass* GasPillarClass = AFGGasPillar::StaticClass(); + TArray FoundActors; + + UGameplayStatics::GetAllActorsOfClass(WorldContext->GetWorld(), GasPillarClass, FoundActors); + for (AActor* GasPillarActor : FoundActors) { + + AFGGasPillar* GasPillar = Cast(GasPillarActor); + + TSharedPtr JGasPillar = CreateBaseJsonObject(GasPillar); + + JGasPillar->Values.Add("ClassName", MakeShared(UKismetSystemLibrary::GetClassDisplayName(GasPillar->GetClass()))); + JGasPillar->Values.Add("location", MakeShared(getActorJSON(GasPillar))); + JGasPillar->Values.Add("features", MakeShared(getActorFeaturesJSON(GasPillar, TEXT("Gas Pillar"), TEXT("Gas Pillar")))); + + OutJsonArray.Add(MakeShared(JGasPillar)); + }; +}; + +void UEnvironment::getSpawners(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray) { + + UClass* CreatureSpawnerClass = AFGCreatureSpawner::StaticClass(); + TArray FoundActors; + + UFGGameUserSettings* UserSettings = UFGGameUserSettings::GetFGGameUserSettings(); + if (!UserSettings) + { + UE_LOG(LogFRMConfigManager, Error, TEXT("GetConfig: UserSettings is null")); + return; + } + + const bool bDisableArachnid = UserSettings->GetBoolOptionValue(TEXT("FG.GameRules.DisableArachnidCreatures")); + + UGameplayStatics::GetAllActorsOfClass(WorldContext->GetWorld(), CreatureSpawnerClass, FoundActors); + for (AActor* CreatureSpawnerActor : FoundActors) { + + AFGCreatureSpawner* CreatureSpawner = Cast(CreatureSpawnerActor); + + TSharedPtr JCreatureSpawner = CreateBaseJsonObject(CreatureSpawner); + + AFGCreature* SpawnableCreature; + + if (bDisableArachnid) + { + SpawnableCreature = CreatureSpawner->GetCreatureClassArachnidOverride()->GetDefaultObject(); + } else + { + SpawnableCreature = CreatureSpawner->GetCreatureClass()->GetDefaultObject(); + }; + + TSharedPtr JSpawnableCreature= MakeShared(); + + if (IsValid(SpawnableCreature)) + { + FString ClassName = UKismetSystemLibrary::GetClassDisplayName(SpawnableCreature->GetClass()); + + TSharedPtr JRoaming = MakeShared(); + JRoaming->SetNumberField("MinRoaming", SpawnableCreature->GetRoamingDistance().Min); + JRoaming->SetNumberField("MaxRoaming", SpawnableCreature->GetRoamingDistance().Max); + + JSpawnableCreature->SetStringField("ClassName", ClassName); + JSpawnableCreature->SetObjectField("Roaming", JRoaming); + JSpawnableCreature->SetNumberField("SpawnDistance", SpawnableCreature->GetSpawnDistance()); + JSpawnableCreature->SetStringField("State", StaticEnum()->GetNameStringByValue((int64)SpawnableCreature->GetCurrentBehaviorState())); + } + + JCreatureSpawner->Values.Add("ClassName", MakeShared(UKismetSystemLibrary::GetClassDisplayName(CreatureSpawner->GetClass()))); + JCreatureSpawner->Values.Add("location", MakeShared(getActorJSON(CreatureSpawner))); + JCreatureSpawner->Values.Add("TotalSpawnable", MakeShared(CreatureSpawner->GetTotalNumCreatures())); + JCreatureSpawner->Values.Add("Unspawned", MakeShared(CreatureSpawner->GetNumUnspawnedCreatures())); + JCreatureSpawner->Values.Add("SpawnDistance", MakeShared(CreatureSpawner->GetSpawnDistance())); + JCreatureSpawner->Values.Add("SpawnRadius", MakeShared(CreatureSpawner->GetSpawnRadius())); + JCreatureSpawner->Values.Add("RespawnTimeInDays", MakeShared(CreatureSpawner->mRespawnTimeIndays)); + JCreatureSpawner->Values.Add("CanSpawnDay", MakeShared(CreatureSpawner->CanSpawnDuringDay())); + JCreatureSpawner->Values.Add("CanSpawnNight", MakeShared(CreatureSpawner->CanSpawnDuringNight())); + JCreatureSpawner->Values.Add("IsNearBase", MakeShared(CreatureSpawner->IsNearBase())); + JCreatureSpawner->Values.Add("IsReadyToSpawn", MakeShared(CreatureSpawner->IsReadyToSpawn())); + JCreatureSpawner->Values.Add("IsSpawnerActive", MakeShared(CreatureSpawner->IsSpawnerActive())); + JCreatureSpawner->Values.Add("IsTimeForCreature", MakeShared(CreatureSpawner->IsTimeForCreature())); + JCreatureSpawner->Values.Add("SpawnableCreature", MakeShared(JSpawnableCreature)); + JCreatureSpawner->Values.Add("features", MakeShared(getActorFeaturesJSON(CreatureSpawner, TEXT("Creature Spawner"), TEXT("Creature Spawner")))); + + OutJsonArray.Add(MakeShared(JCreatureSpawner)); + }; +}; + +void UEnvironment::getSporeFlowers(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray) { + + UClass* SporeFlowerClass = AFGSporeFlower::StaticClass(); + TArray FoundActors; + + UGameplayStatics::GetAllActorsOfClass(WorldContext->GetWorld(), SporeFlowerClass, FoundActors); + for (AActor* SporeFlowerActor : FoundActors) { + + AFGSporeFlower* SporeFlower = Cast(SporeFlowerActor); + + TSharedPtr JSporeFlower = CreateBaseJsonObject(SporeFlower); + + AFicsitRemoteMonitoring* ModSubsystem = AFicsitRemoteMonitoring::Get(WorldContext->GetWorld()); + fgcheck(ModSubsystem); + + FString State; + FString GasState; + bool bIsSignificant; + bool bIsDead; + + ModSubsystem->SporeFlower_BIE(SporeFlower, State, GasState, bIsSignificant, bIsDead); + + JSporeFlower->Values.Add("ClassName", MakeShared(UKismetSystemLibrary::GetClassDisplayName(SporeFlower->GetClass()))); + JSporeFlower->Values.Add("location", MakeShared(getActorJSON(SporeFlower))); + JSporeFlower->Values.Add("State", MakeShared(State)); + JSporeFlower->Values.Add("GasState", MakeShared(GasState)); + JSporeFlower->Values.Add("Significant", MakeShared(bIsSignificant)); + JSporeFlower->Values.Add("Dead", MakeShared(bIsDead)); + JSporeFlower->Values.Add("features", MakeShared(getActorFeaturesJSON(SporeFlower, TEXT("Spore Flower"), TEXT("Spore Flower")))); + + OutJsonArray.Add(MakeShared(JSporeFlower)); + }; +}; \ No newline at end of file diff --git a/Source/FicsitRemoteMonitoring/Private/Endpoints/World/PlayerLibrary.cpp b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/PlayerLibrary.cpp index 863c5ee8..cbb3bcbe 100644 --- a/Source/FicsitRemoteMonitoring/Private/Endpoints/World/PlayerLibrary.cpp +++ b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/PlayerLibrary.cpp @@ -92,38 +92,4 @@ void UPlayerLibrary::getCreatures(UObject* WorldContext, FRequestData RequestDat OutJsonArray.Add(MakeShared(JCreature)); }; -}; - -void UPlayerLibrary::getHazards(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray) { - - UClass* SporeFlowerClass = AFGSporeFlower::StaticClass(); - TArray FoundActors; - - UGameplayStatics::GetAllActorsOfClass(WorldContext->GetWorld(), SporeFlowerClass, FoundActors); - for (AActor* SporeFlowerActor : FoundActors) { - - AFGSporeFlower* SporeFlower = Cast(SporeFlowerActor); - - TSharedPtr JSporeFlower = CreateBaseJsonObject(SporeFlower); - - AFicsitRemoteMonitoring* ModSubsystem = AFicsitRemoteMonitoring::Get(WorldContext->GetWorld()); - fgcheck(ModSubsystem); - - FString State; - FString GasState; - bool bIsSignificant; - bool bIsDead; - - ModSubsystem->SporeFlower_BIE(SporeFlower, State, GasState, bIsSignificant, bIsDead); - - JSporeFlower->Values.Add("ClassName", MakeShared(UKismetSystemLibrary::GetClassDisplayName(SporeFlower->GetClass()))); - JSporeFlower->Values.Add("location", MakeShared(getActorJSON(SporeFlower))); - JSporeFlower->Values.Add("State", MakeShared(State)); - JSporeFlower->Values.Add("GasState", MakeShared(GasState)); - JSporeFlower->Values.Add("Significant", MakeShared(bIsSignificant)); - JSporeFlower->Values.Add("Dead", MakeShared(bIsDead)); - JSporeFlower->Values.Add("features", MakeShared(getActorFeaturesJSON(SporeFlower, TEXT("Spore Flower"), TEXT("Spore Flower")))); - - OutJsonArray.Add(MakeShared(JSporeFlower)); - }; }; \ No newline at end of file diff --git a/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp b/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp index 6b0350a3..7c9ba367 100644 --- a/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp +++ b/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp @@ -21,6 +21,7 @@ #include "Endpoints/Travel/Trains.h" #include "Endpoints/Travel/Vehicles.h" #include "Endpoints/World/Communication.h" +#include "Endpoints/World/Environment.h" #include "Endpoints/World/EventsLibrary.h" #include "Endpoints/World/Inventory.h" #include "Endpoints/World/PlayerLibrary.h" @@ -762,7 +763,7 @@ void AFicsitRemoteMonitoring::InitAPIRegistry() RegisterEndpoint(FAPIEndpoint("GET", "getFrackingActivator", &UResources::getFrackingActivator)); RegisterEndpoint(FAPIEndpoint("GET", "getFuelGenerator", &UPower::getFuelGenerator)); RegisterEndpoint(FAPIEndpoint("GET", "getGeothermalGenerator", &UPower::getGeothermalGenerator)); - RegisterEndpoint(FAPIEndpoint("GET", "getHazards", &UPlayerLibrary::getHazards).RequiresGameThread()); + RegisterEndpoint(FAPIEndpoint("GET", "getHazards", &UEnvironment::getHazards).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getHUBTerminal", &USupport::getHubTerminal).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getHyperEntrance", &UHypertubes::getHyperEntrance)); RegisterEndpoint(FAPIEndpoint("GET", "getHypertube", &UHypertubes::getHypertube)); @@ -791,7 +792,9 @@ void AFicsitRemoteMonitoring::InitAPIRegistry() RegisterEndpoint(FAPIEndpoint("GET", "getResourceSink", &USession::getResourceSink)); RegisterEndpoint(FAPIEndpoint("GET", "getResourceSinkBuilding", &USupport::getResourceSinkBuilding)); RegisterEndpoint(FAPIEndpoint("GET", "getResourceWell", &UResources::getResourceWell).RequiresGameThread()); + RegisterEndpoint(FAPIEndpoint("GET", "getSpawners", &UEnvironment::getSpawners).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getSplitterMerger", &ULogistics::getSplitterMerger)); + RegisterEndpoint(FAPIEndpoint("GET", "getSporeFlowers", &UEnvironment::getSporeFlowers).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getSessionInfo", &USession::getSessionInfo).RequiresGameThread().UseFirstObject()); RegisterEndpoint(FAPIEndpoint("GET", "getSchematics", &UResearch::getSchematics).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getSinkList", &USession::getSinkList).RequiresGameThread()); diff --git a/Source/FicsitRemoteMonitoring/Public/Endpoints/World/Environment.h b/Source/FicsitRemoteMonitoring/Public/Endpoints/World/Environment.h new file mode 100644 index 00000000..417fa031 --- /dev/null +++ b/Source/FicsitRemoteMonitoring/Public/Endpoints/World/Environment.h @@ -0,0 +1,16 @@ +#pragma once + +#include "CoreMinimal.h" +#include "RemoteMonitoringLibrary.h" +#include "Environment.generated.h" + +UCLASS() +class FICSITREMOTEMONITORING_API UEnvironment : public URemoteMonitoringLibrary +{ + GENERATED_BODY() + +public: + static void getHazards(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); + static void getSpawners(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); + static void getSporeFlowers(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); +}; diff --git a/Source/FicsitRemoteMonitoring/Public/Endpoints/World/PlayerLibrary.h b/Source/FicsitRemoteMonitoring/Public/Endpoints/World/PlayerLibrary.h index 7047bc73..ae9488e5 100644 --- a/Source/FicsitRemoteMonitoring/Public/Endpoints/World/PlayerLibrary.h +++ b/Source/FicsitRemoteMonitoring/Public/Endpoints/World/PlayerLibrary.h @@ -13,5 +13,4 @@ class FICSITREMOTEMONITORING_API UPlayerLibrary : public URemoteMonitoringLibrar static void getPlayer(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); static void getDoggo(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); static void getCreatures(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); - static void getHazards(UObject* WorldContext, FRequestData RequestData, TArray>& OutJsonArray); }; From d0e70d0462c2c9ac34fb7681803dbee96c1c32a6 Mon Sep 17 00:00:00 2001 From: Chris Wall Date: Sat, 18 Jul 2026 08:51:00 -0400 Subject: [PATCH 2/5] feat: Actor Pitch --- .../Private/RemoteMonitoringLibrary.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/FicsitRemoteMonitoring/Private/RemoteMonitoringLibrary.cpp b/Source/FicsitRemoteMonitoring/Private/RemoteMonitoringLibrary.cpp index 9f6d5bce..0875a5a7 100644 --- a/Source/FicsitRemoteMonitoring/Private/RemoteMonitoringLibrary.cpp +++ b/Source/FicsitRemoteMonitoring/Private/RemoteMonitoringLibrary.cpp @@ -34,21 +34,23 @@ TSharedPtr URemoteMonitoringLibrary::getActorJSON(AActor* Actor) { TSharedPtr JLibrary = MakeShared(); - long double primaryX = Actor->GetActorLocation().X; - long double primaryY = Actor->GetActorLocation().Y; - long double primaryZ = Actor->GetActorLocation().Z; - + const long double primaryX = Actor->GetActorLocation().X; + const long double primaryY = Actor->GetActorLocation().Y; + const long double primaryZ = Actor->GetActorLocation().Z; + const long double pitch = Actor->GetActorRotation().Pitch; + // UE rotations range from -180 to 180 with zero as "forward" and negative values "left". // In Satisfactory this results in a rotation of zero being due east. // FRM will normalise this to a range of 0 <= x < 360 with zero as due north. long double rotation = Actor->GetActorRotation().Yaw; rotation += 450; rotation = fmod(rotation, 360); - + JLibrary->Values.Add("x", MakeShared(primaryX)); JLibrary->Values.Add("y", MakeShared(primaryY)); JLibrary->Values.Add("z", MakeShared(primaryZ)); JLibrary->Values.Add("rotation", MakeShared(rotation)); + JLibrary->Values.Add("pitch", MakeShared(pitch)); return JLibrary; From 57030441790a58d98705400d61a4be63611a2fe4 Mon Sep 17 00:00:00 2001 From: Robert Deaton Date: Wed, 12 Aug 2026 10:41:29 -0700 Subject: [PATCH 3/5] defensive checks around extractors to prevent a crash on /frm test endpoints --- .../Private/Endpoints/World/Resources.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Resources.cpp b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Resources.cpp index 65e36e91..7e8841a4 100644 --- a/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Resources.cpp +++ b/Source/FicsitRemoteMonitoring/Private/Endpoints/World/Resources.cpp @@ -248,7 +248,15 @@ void UResources::getExtractor(UObject* WorldContext, FRequestData RequestData, T float CurrentProd = Productivity * MaxProd; - TSharedPtr JProduct = GetItemValueObject(ResourceClass->GetResourceClass(), ExtractorInventory->GetNumItems(ItemClass), Extractor->GetFluidInventoryStackSizeScalar()); + // GetNumItems() asserts mInventoryStacks.Num() > 0 ("Inventory need to be + // initialized before use"), so an extractor whose output inventory has not + // been initialized yet - e.g. while the world is still streaming in - takes + // the whole game down. GetSizeLinear() reads the same array without asserting. + const int32 NumItems = (IsValid(ExtractorInventory) && ExtractorInventory->GetSizeLinear() > 0) + ? ExtractorInventory->GetNumItems(ItemClass) + : 0; + + TSharedPtr JProduct = GetItemValueObject(ResourceClass->GetResourceClass(), NumItems, Extractor->GetFluidInventoryStackSizeScalar()); JProduct->Values.Add("CurrentProd", MakeShared(CurrentProd)); JProduct->Values.Add("MaxProd", MakeShared(MaxProd)); JProduct->Values.Add("ProdPercent", MakeShared(100 * UKismetMathLibrary::SafeDivide(CurrentProd, MaxProd))); @@ -314,7 +322,10 @@ void UResources::getFrackingActivator(UObject* WorldContext, FRequestData Reques const float Productivity = SatelliteExtractor->GetProductivity(); const UFGInventoryComponent* ExtractorInventory = SatelliteExtractor->GetOutputInventory(); - const float NumItems = ExtractorInventory->GetNumItems(ItemClass); + // Same uninitialised-inventory assert as getExtractor above. + const float NumItems = (IsValid(ExtractorInventory) && ExtractorInventory->GetSizeLinear() > 0) + ? ExtractorInventory->GetNumItems(ItemClass) + : 0; BaseNumItems += NumItems; float CurrentProd = Productivity * MaxProd; From afdc8aef56c8af85e79a9b3a5d4526b88497bd9e Mon Sep 17 00:00:00 2001 From: Robert Deaton Date: Wed, 12 Aug 2026 10:42:11 -0700 Subject: [PATCH 4/5] Force more endpoints onto the main thread to avoid assert crashes --- .../Private/FicsitRemoteMonitoring.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp b/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp index 6b0350a3..b0ea137e 100644 --- a/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp +++ b/Source/FicsitRemoteMonitoring/Private/FicsitRemoteMonitoring.cpp @@ -756,10 +756,13 @@ void AFicsitRemoteMonitoring::InitAPIRegistry() RegisterEndpoint(FAPIEndpoint("GET", "getEncoder", &UFactoryLibrary::getEncoder)); RegisterEndpoint(FAPIEndpoint("GET", "getExplorationSink", &USession::getExplorationSink)); RegisterEndpoint(FAPIEndpoint("GET", "getExplorer", &UVehicles::getExplorer).RequiresGameThread()); - RegisterEndpoint(FAPIEndpoint("GET", "getExtractor", &UResources::getExtractor)); + // RequiresGameThread: calls AFGBuildableFactory::GetProductivity(), which + // check()s IsInGameThread() and crashes when served off the uWS event loop. + RegisterEndpoint(FAPIEndpoint("GET", "getExtractor", &UResources::getExtractor).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getFactoryCart", &UVehicles::getFactoryCart).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getFoundry", &UFactoryLibrary::getFoundry)); - RegisterEndpoint(FAPIEndpoint("GET", "getFrackingActivator", &UResources::getFrackingActivator)); + // RequiresGameThread: same GetProductivity() game-thread check as getExtractor. + RegisterEndpoint(FAPIEndpoint("GET", "getFrackingActivator", &UResources::getFrackingActivator).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getFuelGenerator", &UPower::getFuelGenerator)); RegisterEndpoint(FAPIEndpoint("GET", "getGeothermalGenerator", &UPower::getGeothermalGenerator)); RegisterEndpoint(FAPIEndpoint("GET", "getHazards", &UPlayerLibrary::getHazards).RequiresGameThread()); @@ -780,7 +783,10 @@ void AFicsitRemoteMonitoring::InitAPIRegistry() RegisterEndpoint(FAPIEndpoint("GET", "getPower", &UPower::getPower)); RegisterEndpoint(FAPIEndpoint("GET", "getPowerSlug", &UResources::getPowerSlug).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getPowerUsage", &UPower::getPowerUsage)); - RegisterEndpoint(FAPIEndpoint("GET", "getProdStats", &USession::getProdStats)); + // RequiresGameThread: walks every manufacturer/extractor/generator calling + // GetProductivity(), which check()s IsInGameThread(). This was the most + // frequent startup crash - the web UI polls it on a timer. + RegisterEndpoint(FAPIEndpoint("GET", "getProdStats", &USession::getProdStats).RequiresGameThread()); RegisterEndpoint(FAPIEndpoint("GET", "getPump", &ULogistics::getPump)); RegisterEndpoint(FAPIEndpoint("GET", "getRadarTower", &USupport::getRadarTower)); RegisterEndpoint(FAPIEndpoint("GET", "getRecipes", &UResearch::getRecipes).RequiresGameThread()); From 788f40e285ad250ca2b79b7203828d89bbef7bb6 Mon Sep 17 00:00:00 2001 From: Chris Wall <47161774+porisius@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:20:16 -0400 Subject: [PATCH 5/5] bump version --- FicsitRemoteMonitoring.uplugin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FicsitRemoteMonitoring.uplugin b/FicsitRemoteMonitoring.uplugin index d269b0cb..e5649833 100644 --- a/FicsitRemoteMonitoring.uplugin +++ b/FicsitRemoteMonitoring.uplugin @@ -1,8 +1,8 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "1.5.2", - "SemVersion": "1.5.2", + "VersionName": "1.5.3", + "SemVersion": "1.5.3", "AcceptsAnyRemoteVersion": true, "FriendlyName": "Ficsit Remote Monitoring", "Description": "Statistical and GeoLocation Monitoring for Satisfactory", @@ -42,4 +42,4 @@ "GameVersion": ">=491125", "RequiredOnRemote": false, "BuiltInInitialFeatureState": "Active" -} \ No newline at end of file +}