Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ public UIController(IUIService uiService, IWindowService windowService)
_windowService = windowService;
}

[Get("/api/v1/ui/alerts")]
[EndpointMetadata("Retrieve a list of all currently active right-hand screen alerts (e.g., 'Need Defenses', 'Major Break Risk').")]
public async Task GetActiveAlerts(HttpListenerContext context)
{
var result = await GameThreadUtility.InvokeAsync(() => _uiService.GetActiveAlerts());

await context.SendJsonResponse(result);
}

[Post("/api/v1/ui/message")]
public async Task ShowMessage(HttpListenerContext context)
{
Expand Down
16 changes: 16 additions & 0 deletions Source/RIMAPI/RimworldRestApi/Models/UI/AlertsDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

using System.Collections.Generic;

namespace RIMAPI.Models.UI
{
public class AlertDto
{
public string Label { get; set; }
public string Explanation { get; set; }

// e.g., "Critical", "High", "Medium"
public string Priority { get; set; }
public List<int> Targets { get; set; }
public List<string> Cells { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace RIMAPI.Services.Interfaces
{
public interface IUIService
{
ApiResult<List<AlertDto>> GetActiveAlerts();
ApiResult OpenTab(string tabName);
ApiResult SendLetterSimple(SendLetterRequestDto body);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
using RimWorld;
using Verse;
using RIMAPI.Core;
using RIMAPI.Models.UI;
using RIMAPI.Services.Interfaces;
using RIMAPI.Helpers;
using System.Linq;
using RIMAPI.Models;
using RimWorld.Planet;

namespace RIMAPI.Services
{
Expand All @@ -18,6 +20,84 @@ public class UIService : IUIService
BindingFlags.Instance | BindingFlags.NonPublic
);

public ApiResult<List<AlertDto>> GetActiveAlerts()
{
if (Current.ProgramState != ProgramState.Playing)
{
return ApiResult<List<AlertDto>>.Fail("Cannot fetch alerts: Game is not currently playing.");
}

if (Find.Alerts == null)
{
return ApiResult<List<AlertDto>>.Fail("Alerts system is currently unavailable.");
}

if (ActiveAlertsField == null)
{
return ApiResult<List<AlertDto>>.Fail("Reflection failed: Could not find the activeAlerts field.");
}

var alertDtos = new List<AlertDto>();

try
{
var activeAlerts = (List<Alert>)ActiveAlertsField.GetValue(Find.Alerts);

if (activeAlerts != null)
{
foreach (Alert alert in activeAlerts)
{
try
{
var alertDto = new AlertDto
{
Label = alert.GetLabel(),
Explanation = alert.GetExplanation(),
Priority = alert.Priority.ToString(),
Targets = new List<int>(),
Cells = new List<string>()
};

AlertReport report = alert.GetReport();
if (report.AllCulprits != null)
{
foreach (GlobalTargetInfo target in report.AllCulprits)
{
if (!target.IsValid) continue;

if (target.HasThing)
{
alertDto.Targets.Add(target.Thing.thingIDNumber);
}
else if (target.HasWorldObject)
{
alertDto.Targets.Add(target.WorldObject.ID);
}
else if (target.Cell.IsValid)
{
alertDto.Cells.Add($"Cell_{target.Cell.x}_{target.Cell.z}");
}
}
}

alertDtos.Add(alertDto);
}
catch (Exception ex)
{
Log.Warning($"[RIMAPI] Failed to parse alert of type {alert.GetType().Name}: {ex.Message}");
}
}
}
}
catch (Exception ex)
{
Log.Error($"[RIMAPI] Critical reflection error while reading alerts: {ex}");
return ApiResult<List<AlertDto>>.Fail("Internal server error reading memory.");
}

return ApiResult<List<AlertDto>>.Ok(alertDtos);
}

public ApiResult OpenTab(string tabName)
{
try
Expand Down
2 changes: 1 addition & 1 deletion tests/bruno_api_collection/Camera/Screenshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ http:
data: |-
{
"format": "png",
"hide_ui": false
"hide_ui": true
}
auth: inherit

Expand Down
15 changes: 15 additions & 0 deletions tests/bruno_api_collection/UI/Alerts List.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
info:
name: Alerts List
type: http
seq: 1

http:
method: GET
url: "{{baseURL}}/api/v1/ui/alerts"
auth: inherit

settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5
6 changes: 6 additions & 0 deletions tests/bruno_api_collection/UI/folder.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
info:
name: UI
type: folder
seq: 22

request: {}