build: C# 6 compatible port + build script + csproj
- Convert all C# 7/8 features to C# 6 for mono mcs compatibility: - Tuple switch → if-else chain - Switch expressions → if-else blocks - Expression-bodied switch → regular switch statement - Verified compilation succeeds (only missing game DLL refs) - Added mod/ONIAgentBridge.csproj for dotnet SDK builds - Added scripts/build_mod.sh for mono-based builds - Auto-detects ONI installation path - References required game DLLs - Outputs to mod/bin/
This commit is contained in:
@ -76,298 +76,481 @@ namespace ONIAgentBridge
|
|||||||
|
|
||||||
string responseJson;
|
string responseJson;
|
||||||
|
|
||||||
switch (path, method)
|
bool _handled = false;
|
||||||
{
|
|
||||||
// --- Health ---
|
// --- Health ---
|
||||||
case ("/health", "GET"):
|
if (path == "/health" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = JsonSerializer.Serialize(new { status = "ok", service = "oni-agent-bridge" });
|
responseJson = JsonSerializer.Serialize(new { status = "ok", service = "oni-agent-bridge" });
|
||||||
break;
|
}
|
||||||
|
|
||||||
// --- State Queries ---
|
// --- State Queries ---
|
||||||
case ("/api/state/game", "GET"):
|
if (path == "/api/state/game" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetGameState();
|
responseJson = GetGameState();
|
||||||
break;
|
}
|
||||||
case ("/api/state/resources", "GET"):
|
if (path == "/api/state/resources" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetResources();
|
responseJson = GetResources();
|
||||||
break;
|
}
|
||||||
case ("/api/state/duplicants", "GET"):
|
if (path == "/api/state/duplicants" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetDuplicants();
|
responseJson = GetDuplicants();
|
||||||
break;
|
}
|
||||||
case ("/api/state/buildings", "GET"):
|
if (path == "/api/state/buildings" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetBuildings();
|
responseJson = GetBuildings();
|
||||||
break;
|
}
|
||||||
case ("/api/state/research", "GET"):
|
if (path == "/api/state/research" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetResearch();
|
responseJson = GetResearch();
|
||||||
break;
|
}
|
||||||
case ("/api/state/research/detail", "GET"):
|
if (path == "/api/state/research/detail" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetResearchDetail();
|
responseJson = GetResearchDetail();
|
||||||
break;
|
}
|
||||||
case ("/api/state/building_detail", "GET"):
|
if (path == "/api/state/building_detail" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetBuildingDetail(query);
|
responseJson = GetBuildingDetail(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/geysers", "GET"):
|
if (path == "/api/state/geysers" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetGeysers();
|
responseJson = GetGeysers();
|
||||||
break;
|
}
|
||||||
case ("/api/state/alert", "GET"):
|
if (path == "/api/state/alert" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetAlerts();
|
responseJson = GetAlerts();
|
||||||
break;
|
}
|
||||||
case ("/api/state/critters", "GET"):
|
if (path == "/api/state/critters" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetCritters();
|
responseJson = GetCritters();
|
||||||
break;
|
}
|
||||||
case ("/api/state/plants", "GET"):
|
if (path == "/api/state/plants" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPlants();
|
responseJson = GetPlants();
|
||||||
break;
|
}
|
||||||
case ("/api/state/rooms", "GET"):
|
if (path == "/api/state/rooms" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetRooms();
|
responseJson = GetRooms();
|
||||||
break;
|
}
|
||||||
case ("/api/state/queue", "GET"):
|
if (path == "/api/state/queue" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetTaskQueue(query);
|
responseJson = GetTaskQueue(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/priorities", "GET"):
|
if (path == "/api/state/priorities" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPriorities();
|
responseJson = GetPriorities();
|
||||||
break;
|
}
|
||||||
case ("/api/state/events", "GET"):
|
if (path == "/api/state/events" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetEvents(query);
|
responseJson = GetEvents(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/power", "GET"):
|
if (path == "/api/state/power" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPowerGrid();
|
responseJson = GetPowerGrid();
|
||||||
break;
|
}
|
||||||
case ("/api/state/pipes", "GET"):
|
if (path == "/api/state/pipes" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPipes(query);
|
responseJson = GetPipes(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/co2", "GET"):
|
if (path == "/api/state/co2" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetCO2();
|
responseJson = GetCO2();
|
||||||
break;
|
}
|
||||||
case ("/api/state/temperature/zones", "GET"):
|
if (path == "/api/state/temperature/zones" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetTempZones();
|
responseJson = GetTempZones();
|
||||||
break;
|
}
|
||||||
case ("/api/state/morale", "GET"):
|
if (path == "/api/state/morale" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetMorale();
|
responseJson = GetMorale();
|
||||||
break;
|
}
|
||||||
case ("/api/state/diseases", "GET"):
|
if (path == "/api/state/diseases" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetDiseases();
|
responseJson = GetDiseases();
|
||||||
break;
|
}
|
||||||
case ("/api/state/storage", "GET"):
|
if (path == "/api/state/storage" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetStorage();
|
responseJson = GetStorage();
|
||||||
break;
|
}
|
||||||
case ("/api/state/duplicants/skills", "GET"):
|
if (path == "/api/state/duplicants/skills" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetDuplicantSkills();
|
responseJson = GetDuplicantSkills();
|
||||||
break;
|
}
|
||||||
case ("/api/state/saves", "GET"):
|
if (path == "/api/state/saves" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetSaves();
|
responseJson = GetSaves();
|
||||||
break;
|
}
|
||||||
case ("/api/state/buildable", "GET"):
|
if (path == "/api/state/buildable" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetBuildable();
|
responseJson = GetBuildable();
|
||||||
break;
|
}
|
||||||
case ("/api/state/printing_pod", "GET"):
|
if (path == "/api/state/printing_pod" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPrintingPod();
|
responseJson = GetPrintingPod();
|
||||||
break;
|
}
|
||||||
case ("/api/state/atmo_suits", "GET"):
|
if (path == "/api/state/atmo_suits" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetAtmoSuits();
|
responseJson = GetAtmoSuits();
|
||||||
break;
|
}
|
||||||
case ("/api/state/sensors", "GET"):
|
if (path == "/api/state/sensors" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetSensors();
|
responseJson = GetSensors();
|
||||||
break;
|
}
|
||||||
case ("/api/state/overlay", "GET"):
|
if (path == "/api/state/overlay" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetOverlay();
|
responseJson = GetOverlay();
|
||||||
break;
|
}
|
||||||
|
|
||||||
// --- Cell-level map data ---
|
// --- Cell-level map data ---
|
||||||
case ("/api/state/cell", "GET"):
|
if (path == "/api/state/cell" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetCell(query);
|
responseJson = GetCell(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/cells", "GET"):
|
if (path == "/api/state/cells" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetCells(query);
|
responseJson = GetCells(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/cells/slice", "GET"):
|
if (path == "/api/state/cells/slice" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetCellSlice(query);
|
responseJson = GetCellSlice(query);
|
||||||
break;
|
}
|
||||||
case ("/api/state/gas", "GET"):
|
if (path == "/api/state/gas" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetGas(query);
|
responseJson = GetGas(query);
|
||||||
break;
|
}
|
||||||
|
|
||||||
// --- Entity Registry (for AI reference) ---
|
// --- Entity Registry (for AI reference) ---
|
||||||
case ("/api/registry/buildings", "GET"):
|
if (path == "/api/registry/buildings" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetBuildingRegistry();
|
responseJson = GetBuildingRegistry();
|
||||||
break;
|
}
|
||||||
case ("/api/registry/elements", "GET"):
|
if (path == "/api/registry/elements" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetElementRegistry();
|
responseJson = GetElementRegistry();
|
||||||
break;
|
}
|
||||||
case ("/api/registry/techs", "GET"):
|
if (path == "/api/registry/techs" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetTechRegistry();
|
responseJson = GetTechRegistry();
|
||||||
break;
|
}
|
||||||
case ("/api/registry/priorities", "GET"):
|
if (path == "/api/registry/priorities" && method == "GET")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = GetPriorityRegistry();
|
responseJson = GetPriorityRegistry();
|
||||||
break;
|
}
|
||||||
|
|
||||||
// --- Actions ---
|
// --- Actions ---
|
||||||
case ("/api/action/dig", "POST"):
|
if (path == "/api/action/dig" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDig(ctx);
|
responseJson = ExecuteDig(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/build", "POST"):
|
if (path == "/api/action/build" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteBuild(ctx);
|
responseJson = ExecuteBuild(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/deconstruct", "POST"):
|
if (path == "/api/action/deconstruct" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDeconstruct(ctx);
|
responseJson = ExecuteDeconstruct(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/prioritize", "POST"):
|
if (path == "/api/action/prioritize" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePrioritize(ctx);
|
responseJson = ExecutePrioritize(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/research", "POST"):
|
if (path == "/api/action/research" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteResearch(ctx);
|
responseJson = ExecuteResearch(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/schedule", "POST"):
|
if (path == "/api/action/schedule" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSchedule(ctx);
|
responseJson = ExecuteSchedule(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/wardrobe", "POST"):
|
if (path == "/api/action/wardrobe" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteWardrobe(ctx);
|
responseJson = ExecuteWardrobe(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/mop", "POST"):
|
if (path == "/api/action/mop" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteMop(ctx);
|
responseJson = ExecuteMop(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/harvest", "POST"):
|
if (path == "/api/action/harvest" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteHarvest(ctx);
|
responseJson = ExecuteHarvest(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/cancel", "POST"):
|
if (path == "/api/action/cancel" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCancel(ctx);
|
responseJson = ExecuteCancel(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/batch", "POST"):
|
if (path == "/api/action/batch" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteBatch(ctx);
|
responseJson = ExecuteBatch(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/priority_global", "POST"):
|
if (path == "/api/action/priority_global" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePriorityGlobal(ctx);
|
responseJson = ExecutePriorityGlobal(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/priority_type", "POST"):
|
if (path == "/api/action/priority_type" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePriorityType(ctx);
|
responseJson = ExecutePriorityType(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/pause", "POST"):
|
if (path == "/api/action/pause" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePause(ctx);
|
responseJson = ExecutePause(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/unpause", "POST"):
|
if (path == "/api/action/unpause" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteUnpause(ctx);
|
responseJson = ExecuteUnpause(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/speed", "POST"):
|
if (path == "/api/action/speed" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSpeed(ctx);
|
responseJson = ExecuteSpeed(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/save", "POST"):
|
if (path == "/api/action/save" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSave(ctx);
|
responseJson = ExecuteSave(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/save_as", "POST"):
|
if (path == "/api/action/save_as" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSaveAs(ctx);
|
responseJson = ExecuteSaveAs(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/load", "POST"):
|
if (path == "/api/action/load" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteLoad(ctx);
|
responseJson = ExecuteLoad(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/assign_job", "POST"):
|
if (path == "/api/action/assign_job" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteAssignJob(ctx);
|
responseJson = ExecuteAssignJob(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/build_pipe", "POST"):
|
if (path == "/api/action/build_pipe" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteBuildPipe(ctx);
|
responseJson = ExecuteBuildPipe(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/build_wire", "POST"):
|
if (path == "/api/action/build_wire" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteBuildWire(ctx);
|
responseJson = ExecuteBuildWire(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/screenshot", "POST"):
|
if (path == "/api/action/screenshot" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteScreenshot(ctx);
|
responseJson = ExecuteScreenshot(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/camera", "POST"):
|
if (path == "/api/action/camera" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCamera(ctx);
|
responseJson = ExecuteCamera(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/toggle", "POST"):
|
if (path == "/api/action/toggle" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteToggle(ctx);
|
responseJson = ExecuteToggle(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/set_recipe", "POST"):
|
if (path == "/api/action/set_recipe" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSetRecipe(ctx);
|
responseJson = ExecuteSetRecipe(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/empty", "POST"):
|
if (path == "/api/action/empty" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteEmpty(ctx);
|
responseJson = ExecuteEmpty(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/cancel_errand", "POST"):
|
if (path == "/api/action/cancel_errand" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCancelErrand(ctx);
|
responseJson = ExecuteCancelErrand(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/research_cancel", "POST"):
|
if (path == "/api/action/research_cancel" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteResearchCancel(ctx);
|
responseJson = ExecuteResearchCancel(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/set_building_priority", "POST"):
|
if (path == "/api/action/set_building_priority" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSetBuildingPriority(ctx);
|
responseJson = ExecuteSetBuildingPriority(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/set_automation", "POST"):
|
if (path == "/api/action/set_automation" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSetAutomation(ctx);
|
responseJson = ExecuteSetAutomation(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/printing_pod_select", "POST"):
|
if (path == "/api/action/printing_pod_select" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePrintingPodSelect(ctx);
|
responseJson = ExecutePrintingPodSelect(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/critter_attack", "POST"):
|
if (path == "/api/action/critter_attack" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCritterAttack(ctx);
|
responseJson = ExecuteCritterAttack(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/door_lock", "POST"):
|
if (path == "/api/action/door_lock" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDoorLock(ctx);
|
responseJson = ExecuteDoorLock(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/door_one_way", "POST"):
|
if (path == "/api/action/door_one_way" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDoorOneWay(ctx);
|
responseJson = ExecuteDoorOneWay(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/dupe_move", "POST"):
|
if (path == "/api/action/dupe_move" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDupeMove(ctx);
|
responseJson = ExecuteDupeMove(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/dupe_cancel_task", "POST"):
|
if (path == "/api/action/dupe_cancel_task" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDupeCancelTask(ctx);
|
responseJson = ExecuteDupeCancelTask(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/critter_wrangle", "POST"):
|
if (path == "/api/action/critter_wrangle" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCritterWrangle(ctx);
|
responseJson = ExecuteCritterWrangle(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/plant_uproot", "POST"):
|
if (path == "/api/action/plant_uproot" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecutePlantUproot(ctx);
|
responseJson = ExecutePlantUproot(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/storage_filter", "POST"):
|
if (path == "/api/action/storage_filter" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteStorageFilter(ctx);
|
responseJson = ExecuteStorageFilter(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/door_open", "POST"):
|
if (path == "/api/action/door_open" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDoorOpen(ctx);
|
responseJson = ExecuteDoorOpen(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/sensor_threshold", "POST"):
|
if (path == "/api/action/sensor_threshold" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSensorThreshold(ctx);
|
responseJson = ExecuteSensorThreshold(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/sweep", "POST"):
|
if (path == "/api/action/sweep" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteSweep(ctx);
|
responseJson = ExecuteSweep(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/disinfect", "POST"):
|
if (path == "/api/action/disinfect" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDisinfect(ctx);
|
responseJson = ExecuteDisinfect(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/clear", "POST"):
|
if (path == "/api/action/clear" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteClear(ctx);
|
responseJson = ExecuteClear(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/rotate", "POST"):
|
if (path == "/api/action/rotate" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteRotate(ctx);
|
responseJson = ExecuteRotate(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/copy_settings", "POST"):
|
if (path == "/api/action/copy_settings" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteCopySettings(ctx);
|
responseJson = ExecuteCopySettings(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/overlay", "POST"):
|
if (path == "/api/action/overlay" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteOverlay(ctx);
|
responseJson = ExecuteOverlay(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/dupe_personal_priority", "POST"):
|
if (path == "/api/action/dupe_personal_priority" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteDupePersonalPriority(ctx);
|
responseJson = ExecuteDupePersonalPriority(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/battery_charge", "POST"):
|
if (path == "/api/action/battery_charge" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteBatteryCharge(ctx);
|
responseJson = ExecuteBatteryCharge(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/valve_flow", "POST"):
|
if (path == "/api/action/valve_flow" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteValveFlow(ctx);
|
responseJson = ExecuteValveFlow(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/vent_pressure", "POST"):
|
if (path == "/api/action/vent_pressure" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteVentPressure(ctx);
|
responseJson = ExecuteVentPressure(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/incubator_setting", "POST"):
|
if (path == "/api/action/incubator_setting" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteIncubatorSetting(ctx);
|
responseJson = ExecuteIncubatorSetting(ctx);
|
||||||
break;
|
}
|
||||||
case ("/api/action/fridge_temp", "POST"):
|
if (path == "/api/action/fridge_temp" && method == "POST")
|
||||||
|
{
|
||||||
|
_handled = true;
|
||||||
responseJson = ExecuteFridgeTemp(ctx);
|
responseJson = ExecuteFridgeTemp(ctx);
|
||||||
break;
|
}
|
||||||
|
|
||||||
default:
|
if (!_handled)
|
||||||
|
{
|
||||||
ctx.Response.StatusCode = 404;
|
ctx.Response.StatusCode = 404;
|
||||||
responseJson = JsonSerializer.Serialize(new { error = "not_found", path = path, method = method });
|
responseJson = JsonSerializer.Serialize(new { error = "not_found", path = path, method = method });
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = Encoding.UTF8.GetBytes(responseJson);
|
var buffer = Encoding.UTF8.GetBytes(responseJson);
|
||||||
@ -1011,18 +1194,17 @@ namespace ONIAgentBridge
|
|||||||
var levels = new List<object>();
|
var levels = new List<object>();
|
||||||
for (int i = 1; i <= 9; i++)
|
for (int i = 1; i <= 9; i++)
|
||||||
{
|
{
|
||||||
string label = i switch
|
string label;
|
||||||
{
|
if (i == 1) label = "Lowest (only idle dupes)";
|
||||||
1 => "Lowest (only idle dupes)",
|
else if (i == 2) label = "Very Low";
|
||||||
2 => "Very Low",
|
else if (i == 3) label = "Low";
|
||||||
3 => "Low",
|
else if (i == 4) label = "Below Normal";
|
||||||
4 => "Below Normal",
|
else if (i == 5) label = "Normal (default)";
|
||||||
5 => "Normal (default)",
|
else if (i == 6) label = "Above Normal";
|
||||||
6 => "Above Normal",
|
else if (i == 7) label = "High";
|
||||||
7 => "High",
|
else if (i == 8) label = "Very High";
|
||||||
8 => "Very High",
|
else if (i == 9) label = "Emergency / Yellow Alert";
|
||||||
9 => "Emergency / Yellow Alert"
|
else label = "Normal";
|
||||||
};
|
|
||||||
levels.Add(new { priority = i, label, isYellowAlert = i == 9 });
|
levels.Add(new { priority = i, label, isYellowAlert = i == 9 });
|
||||||
}
|
}
|
||||||
return JsonSerializer.Serialize(levels);
|
return JsonSerializer.Serialize(levels);
|
||||||
@ -1848,24 +2030,54 @@ namespace ONIAgentBridge
|
|||||||
foreach (var kv in dict) fb.data[kv.Key] = kv.Value;
|
foreach (var kv in dict) fb.data[kv.Key] = kv.Value;
|
||||||
}
|
}
|
||||||
// Auto-suggest for common errors
|
// Auto-suggest for common errors
|
||||||
fb.suggestion = error switch
|
// Map error codes to suggestions
|
||||||
|
switch (error)
|
||||||
{
|
{
|
||||||
"cell_occupied" => "Choose a different location, or deconstruct the existing building first",
|
case "cell_occupied":
|
||||||
"cell_solid" => "Use dig action first to clear the area",
|
fb.suggestion = "Choose a different location, or deconstruct the existing building first";
|
||||||
"cell_occupied_by_dupe" => "Wait for the duplicant to move, or cancel their current task",
|
break;
|
||||||
"material_shortage" => "Check resource availability and produce or deliver the required material",
|
case "cell_solid":
|
||||||
"cell_out_of_bounds" => "Stay within the playable area",
|
fb.suggestion = "Use dig action first to clear the area";
|
||||||
"unknown_building" => "Use 'registry buildings' to find valid building IDs",
|
break;
|
||||||
"unknown_tech" => "Use 'registry techs' to find valid tech IDs",
|
case "cell_occupied_by_dupe":
|
||||||
"missing_prerequisites" => "Research the prerequisite technologies first",
|
fb.suggestion = "Wait for the duplicant to move, or cancel their current task";
|
||||||
"tech_already_complete" => "The technology has already been researched",
|
break;
|
||||||
"no_building_at_cell" => "Use the buildings command to find buildings and their coordinates",
|
case "material_shortage":
|
||||||
"no_liquid_at_cell" => "Use the cell command to check what is at that location",
|
fb.suggestion = "Check resource availability and produce or deliver the required material";
|
||||||
"liquid_too_thin" => "Wait for more liquid to accumulate before mopping",
|
break;
|
||||||
"invalid_priority" => "Use a value between 1 (lowest) and 9 (emergency/yellow alert)",
|
case "cell_out_of_bounds":
|
||||||
"blocks_not_diggable" => "Neutronium borders and abyssalite cannot be dug",
|
fb.suggestion = "Stay within the playable area";
|
||||||
_ => null
|
break;
|
||||||
};
|
case "unknown_building":
|
||||||
|
fb.suggestion = "Use 'registry buildings' to find valid building IDs";
|
||||||
|
break;
|
||||||
|
case "unknown_tech":
|
||||||
|
fb.suggestion = "Use 'registry techs' to find valid tech IDs";
|
||||||
|
break;
|
||||||
|
case "missing_prerequisites":
|
||||||
|
fb.suggestion = "Research the prerequisite technologies first";
|
||||||
|
break;
|
||||||
|
case "tech_already_complete":
|
||||||
|
fb.suggestion = "The technology has already been researched";
|
||||||
|
break;
|
||||||
|
case "no_building_at_cell":
|
||||||
|
fb.suggestion = "Use the buildings command to find buildings and their coordinates";
|
||||||
|
break;
|
||||||
|
case "no_liquid_at_cell":
|
||||||
|
fb.suggestion = "Use the cell command to check what is at that location";
|
||||||
|
break;
|
||||||
|
case "liquid_too_thin":
|
||||||
|
fb.suggestion = "Wait for more liquid to accumulate before mopping";
|
||||||
|
break;
|
||||||
|
case "invalid_priority":
|
||||||
|
fb.suggestion = "Use a value between 1 (lowest) and 9 (emergency/yellow alert)";
|
||||||
|
break;
|
||||||
|
case "blocks_not_diggable":
|
||||||
|
fb.suggestion = "Neutronium borders and abyssalite cannot be dug";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3531,20 +3743,16 @@ namespace ONIAgentBridge
|
|||||||
string wireType = data.type ?? "regular";
|
string wireType = data.type ?? "regular";
|
||||||
string mode = data.mode ?? "line";
|
string mode = data.mode ?? "line";
|
||||||
|
|
||||||
string conduitId = wireType switch
|
string conduitId;
|
||||||
{
|
if (wireType == "heavy") conduitId = "HeaviWatWire";
|
||||||
"heavy" => "HeaviWatWire",
|
else if (wireType == "conductive") conduitId = "ConductiveWire";
|
||||||
"conductive" => "ConductiveWire",
|
else if (wireType == "heavy_conductive") conduitId = "HeaviWatConductiveWire";
|
||||||
"heavy_conductive" => "HeaviWatConductiveWire",
|
else conduitId = "Wire";
|
||||||
_ => "Wire"
|
string bridgeId;
|
||||||
};
|
if (wireType == "heavy") bridgeId = "HeaviWatBridge";
|
||||||
string bridgeId = wireType switch
|
else if (wireType == "conductive") bridgeId = "ConductiveWireBridge";
|
||||||
{
|
else if (wireType == "heavy_conductive") bridgeId = "HeaviWatConductiveBridge";
|
||||||
"heavy" => "HeaviWatBridge",
|
else bridgeId = "WireBridge";
|
||||||
"conductive" => "ConductiveWireBridge",
|
|
||||||
"heavy_conductive" => "HeaviWatConductiveBridge",
|
|
||||||
_ => "WireBridge"
|
|
||||||
};
|
|
||||||
|
|
||||||
int cellsPlaced = 0;
|
int cellsPlaced = 0;
|
||||||
int bridgesPlaced = 0;
|
int bridgesPlaced = 0;
|
||||||
|
|||||||
32
mod/ONIAgentBridge.csproj
Normal file
32
mod/ONIAgentBridge.csproj
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net471</TargetFramework>
|
||||||
|
<AssemblyName>ONIAgentBridge</AssemblyName>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<RootNamespace>ONIAgentBridge</RootNamespace>
|
||||||
|
<LangVersion>7</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Lib.Harmony" Version="2.2.2" />
|
||||||
|
<PackageReference Include="System.Text.Json" Version="6.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- Point these to your ONI installation directory -->
|
||||||
|
<Reference Include="Assembly-CSharp">
|
||||||
|
<HintPath>$(ONI_Path)/Assembly-CSharp.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Assembly-CSharp-firstpass">
|
||||||
|
<HintPath>$(ONI_Path)/Assembly-CSharp-firstpass.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine">
|
||||||
|
<HintPath>$(ONI_Path)/UnityEngine.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="UnityEngine.CoreModule">
|
||||||
|
<HintPath>$(ONI_Path)/UnityEngine.CoreModule.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
69
scripts/build_mod.sh
Executable file
69
scripts/build_mod.sh
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build the ONI Agent Bridge Mod
|
||||||
|
# Requires: mono-complete (for mcs compiler)
|
||||||
|
# Requires: ONI game installed to get reference DLLs
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
MOD_DIR="$SCRIPT_DIR/mod"
|
||||||
|
OUTPUT_DIR="$MOD_DIR/bin"
|
||||||
|
|
||||||
|
# Find ONI installation
|
||||||
|
ONI_PATH="${ONI_PATH:-}"
|
||||||
|
if [ -z "$ONI_PATH" ]; then
|
||||||
|
# Common paths
|
||||||
|
for candidate in \
|
||||||
|
"$HOME/.local/share/Steam/steamapps/common/OxygenNotIncluded" \
|
||||||
|
"$HOME/Library/Application Support/Steam/steamapps/common/OxygenNotIncluded" \
|
||||||
|
"/c/Program Files (x86)/Steam/steamapps/common/OxygenNotIncluded" \
|
||||||
|
"/mnt/c/Program Files (x86)/Steam/steamapps/common/OxygenNotIncluded"; do
|
||||||
|
if [ -d "$candidate" ]; then
|
||||||
|
ONI_PATH="$candidate"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$ONI_PATH" ]; then
|
||||||
|
echo "[!] ONI installation not found. Set ONI_PATH environment variable."
|
||||||
|
echo " export ONI_PATH=/path/to/OxygenNotIncluded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[Build] ONI path: $ONI_PATH"
|
||||||
|
|
||||||
|
# Check required DLLs
|
||||||
|
GAME_DLLS=(
|
||||||
|
"$ONI_PATH/Assembly-CSharp.dll"
|
||||||
|
"$ONI_PATH/Assembly-CSharp-firstpass.dll"
|
||||||
|
"$ONI_PATH/UnityEngine.dll"
|
||||||
|
"$ONI_PATH/UnityEngine.CoreModule.dll"
|
||||||
|
"$ONI_PATH/0Harmony.dll"
|
||||||
|
)
|
||||||
|
|
||||||
|
for dll in "${GAME_DLLS[@]}"; do
|
||||||
|
if [ ! -f "$dll" ]; then
|
||||||
|
echo "[!] Required DLL not found: $dll"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[Build] Found all required DLLs"
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
|
# Compile
|
||||||
|
mcs -target:library \
|
||||||
|
-out:"$OUTPUT_DIR/ONIAgentBridge.dll" \
|
||||||
|
-reference:"$ONI_PATH/Assembly-CSharp.dll" \
|
||||||
|
-reference:"$ONI_PATH/Assembly-CSharp-firstpass.dll" \
|
||||||
|
-reference:"$ONI_PATH/UnityEngine.dll" \
|
||||||
|
-reference:"$ONI_PATH/UnityEngine.CoreModule.dll" \
|
||||||
|
-reference:"$ONI_PATH/0Harmony.dll" \
|
||||||
|
-recurse:"$MOD_DIR/*.cs"
|
||||||
|
|
||||||
|
echo "[Build] Compilation successful!"
|
||||||
|
echo "[Build] Output: $OUTPUT_DIR/ONIAgentBridge.dll"
|
||||||
|
echo ""
|
||||||
|
echo "To install: copy $OUTPUT_DIR/ONIAgentBridge.dll and $MOD_DIR/mod_info.yaml"
|
||||||
|
echo " to your ONI mods/local/ONIAgentBridge/ directory"
|
||||||
181
scripts/fix_csharp.py
Normal file
181
scripts/fix_csharp.py
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Convert C# 7/8 features in ONIAgentBridge.cs to C# 6 compatible code."""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
with open('mod/ONIAgentBridge.cs', 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# 1. Convert tuple switch at ProcessRequest to if-else chain
|
||||||
|
# Find the switch and replace it
|
||||||
|
old_switch_start = """ switch (path, method)
|
||||||
|
{"""
|
||||||
|
|
||||||
|
# Read the entire switch block and reconstruct
|
||||||
|
lines = content.split('\n')
|
||||||
|
new_lines = []
|
||||||
|
i = 0
|
||||||
|
while i < len(lines):
|
||||||
|
line = lines[i]
|
||||||
|
|
||||||
|
# Find the C# 7 tuple switch
|
||||||
|
if 'switch (path, method)' in line and '{' in lines[i+1]:
|
||||||
|
new_lines.append(' // --- C# 6 compatible dispatch ---')
|
||||||
|
new_lines.append(' bool _handled = false;')
|
||||||
|
i += 2 # skip "switch (path, method)" and "{"
|
||||||
|
|
||||||
|
while i < len(lines):
|
||||||
|
stripped = lines[i].strip()
|
||||||
|
|
||||||
|
# Check for case pattern: case ("...", "..."):
|
||||||
|
m = re.match(r'case \("([^"]+)", "([^"]+)"\):', stripped)
|
||||||
|
if m:
|
||||||
|
endpoint = m.group(1)
|
||||||
|
method = m.group(2)
|
||||||
|
indent = lines[i][:len(lines[i]) - len(lines[i].lstrip())]
|
||||||
|
new_lines.append(f'{indent}else if (path == "{endpoint}" && method == "{method}")')
|
||||||
|
new_lines.append(f'{indent}{{')
|
||||||
|
new_lines.append(f'{indent} _handled = true;')
|
||||||
|
i += 1
|
||||||
|
# Copy lines until "break;"
|
||||||
|
while i < len(lines) and lines[i].strip() != 'break;':
|
||||||
|
new_lines.append(lines[i])
|
||||||
|
i += 1
|
||||||
|
new_lines.append(f'{indent}}}')
|
||||||
|
i += 1 # skip "break;"
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for default case
|
||||||
|
if stripped == 'default:':
|
||||||
|
i += 1
|
||||||
|
# Skip the opening brace
|
||||||
|
if lines[i].strip() == '{':
|
||||||
|
i += 1
|
||||||
|
new_lines.append(' if (!_handled)')
|
||||||
|
new_lines.append(' {')
|
||||||
|
while i < len(lines):
|
||||||
|
if lines[i].strip() == '}' and not _is_end_of_method(lines, i):
|
||||||
|
# This could be the switch closing brace
|
||||||
|
# Check if next line is the method closing
|
||||||
|
break
|
||||||
|
new_lines.append(lines[i])
|
||||||
|
i += 1
|
||||||
|
new_lines.append(' }')
|
||||||
|
# Skip the closing brace of the switch
|
||||||
|
if lines[i].strip() == '}':
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for closing brace of switch
|
||||||
|
if stripped == '}':
|
||||||
|
i += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
# Any other content inside switch (shouldn't happen)
|
||||||
|
new_lines.append(lines[i])
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_lines.append(line)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
content = '\n'.join(new_lines)
|
||||||
|
|
||||||
|
def _is_end_of_method(lines, idx):
|
||||||
|
"""Check if this } ends a method (next non-blank is a method or class member)."""
|
||||||
|
for j in range(idx+1, min(idx+10, len(lines))):
|
||||||
|
s = lines[j].strip()
|
||||||
|
if s == '' or s.startswith('//') or s.startswith('/*'):
|
||||||
|
continue
|
||||||
|
if s.startswith('private ') or s.startswith('public ') or s.startswith('internal ') or s.startswith('static ') or s.startswith('}'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 2. Fix switch expressions (C# 8): `wireType switch { ... }` -> if-else
|
||||||
|
# Pattern: string buildingId = wireType switch { "heavy" => "HeaviWatWire", ... }
|
||||||
|
def fix_switch_expr(match):
|
||||||
|
full = match.group(0)
|
||||||
|
var_name = match.group(1)
|
||||||
|
# Parse the switch arms
|
||||||
|
# Extract the expression after "= "
|
||||||
|
body = match.group(2)
|
||||||
|
return full # placeholder, we'll handle below
|
||||||
|
|
||||||
|
# Fix: string buildingId = wireType switch { "heavy" => "HeaviWatWire", _ => "Wire" };
|
||||||
|
# Convert to: string buildingId; if (wireType == "heavy") buildingId = "HeaviWatWire"; else ...
|
||||||
|
for pattern in [
|
||||||
|
(r'wireType switch\s*\{([^}]+)\}', 'wireType'),
|
||||||
|
(r'error switch\s*\{([^}]+)\}', 'error'),
|
||||||
|
(r'i switch\s*\{([^}]+)\}', 'i'),
|
||||||
|
]:
|
||||||
|
pat, varname = pattern
|
||||||
|
matches = list(re.finditer(pat, content))
|
||||||
|
for m in reversed(matches):
|
||||||
|
body = m.group(1)
|
||||||
|
arms = re.findall(r'"([^"]*)"\s*=>\s*"([^"]*)"', body)
|
||||||
|
default = re.findall(r'_\s*=>\s*(null|"[^"]*")', body)
|
||||||
|
|
||||||
|
if varname == 'i':
|
||||||
|
# label assignment
|
||||||
|
replacements = []
|
||||||
|
for key, val in arms:
|
||||||
|
replacements.append(f' if ({varname} == {key}) label = "{val}";')
|
||||||
|
if default:
|
||||||
|
replacements.append(f' else label = {default[0]};')
|
||||||
|
new_code = '\n'.join(replacements)
|
||||||
|
else:
|
||||||
|
# Find the variable being assigned
|
||||||
|
start = m.start()
|
||||||
|
# Look backwards to find the variable name
|
||||||
|
line_start = content.rfind('\n', 0, start) + 1
|
||||||
|
line_before = content[line_start:start]
|
||||||
|
var_match = re.match(r'\s*(?:\w+\s+)?(\w+)\s*=\s*$', line_before)
|
||||||
|
|
||||||
|
indent = ' ' * 16
|
||||||
|
if varname == 'wireType':
|
||||||
|
# Multiple instances in wire building, find each by context
|
||||||
|
context_before = content[max(0,start-200):start]
|
||||||
|
if 'bridgeId' in context_before:
|
||||||
|
varname_full = 'bridgeId'
|
||||||
|
else:
|
||||||
|
varname_full = 'buildingId'
|
||||||
|
else:
|
||||||
|
varname_full = varname
|
||||||
|
|
||||||
|
lines_code = [f' string {varname_full};']
|
||||||
|
first = True
|
||||||
|
for key, val in arms:
|
||||||
|
prefix = 'if' if first else 'else if'
|
||||||
|
lines_code.append(f' {prefix} ({varname} == "{key}") {varname_full} = "{val}";')
|
||||||
|
first = False
|
||||||
|
if default:
|
||||||
|
dval = default[0]
|
||||||
|
lines_code.append(f' else {varname_full} = {dval};')
|
||||||
|
|
||||||
|
new_code = '\n'.join(lines_code)
|
||||||
|
|
||||||
|
# Replace the assignment line + switch expression
|
||||||
|
# Find the full assignment
|
||||||
|
assign_start = content.rfind('\n', 0, start)
|
||||||
|
assign_end = m.end()
|
||||||
|
while assign_end < len(content) and content[assign_end] != '\n':
|
||||||
|
assign_end += 1
|
||||||
|
old = content[assign_start:assign_end]
|
||||||
|
content = content[:assign_start] + '\n' + new_code + content[assign_end:]
|
||||||
|
|
||||||
|
# Write result
|
||||||
|
with open('mod/ONIAgentBridge.cs', 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
print('Done. Checking for remaining C# 7+ features...')
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
remaining = re.findall(r'\bswitch\b', content)
|
||||||
|
print(f'Remaining "switch" keywords: {len(remaining)}')
|
||||||
|
# Count them
|
||||||
|
for i, line in enumerate(content.split('\n')):
|
||||||
|
if 'switch' in line and not line.strip().startswith('//') and 'ProcessRequest' not in line:
|
||||||
|
sline = line.strip()
|
||||||
|
if 'if (' not in line and 'dictionary' not in line.lower() and 'dispatch' not in line:
|
||||||
|
print(f' Line ~{i}: {sline[:80]}')
|
||||||
Reference in New Issue
Block a user