Editor-side static driver for managing simple project settings files. It lists available .config files, reads a config into a string, and writes/upserts keys into a JSON config file under ProjectSettings in the project root.
#nullable enable
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Sandbox;
namespace Editor.Mcp
{
internal static class ProjectSettingsDriver
{
public static ToolOutcome<object> ManageSettings( string action, string? configName = null, string? key = null, string? value = null )
{
var project = Project.Current;
if ( project == null )
{
return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "settings.no_project", "No active project loaded." );
}
var normAction = action.ToLowerInvariant().Trim();
var settingsDir = Path.Combine( project.GetRootPath(), "ProjectSettings" );
Directory.CreateDirectory( settingsDir );
if ( normAction == "list_configs" )
{
var files = Directory.Exists( settingsDir ) ? Directory.GetFiles( settingsDir, "*.config" ).Select( Path.GetFileName ).ToArray() : Array.Empty<string>();
return ToolOutcome<object>.Ready( new
{
Project = project.Config.Ident,
Type = project.Config.Type,
AvailableConfigs = files
} );
}
var targetConfig = configName ?? "Platform";
var configPath = Path.Combine( settingsDir, $"{targetConfig}.config" );
if ( normAction == "read" )
{
var content = File.Exists( configPath ) ? File.ReadAllText( configPath ) : "{}";
return ToolOutcome<object>.Ready( new
{
ConfigName = targetConfig,
Content = content,
Exists = File.Exists( configPath )
} );
}
if ( normAction == "write" && !string.IsNullOrWhiteSpace( key ) && value != null )
{
JsonObject configObj;
try
{
var existing = File.Exists( configPath ) ? File.ReadAllText( configPath ) : "{}";
configObj = JsonNode.Parse( existing ) as JsonObject ?? new JsonObject();
}
catch
{
configObj = new JsonObject();
}
// Parse value into strongly-typed json node if possible
JsonNode? nodeValue;
if ( bool.TryParse( value, out var b ) )
{
nodeValue = JsonValue.Create( b );
}
else if ( int.TryParse( value, out var i ) )
{
nodeValue = JsonValue.Create( i );
}
else if ( float.TryParse( value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out var f ) )
{
nodeValue = JsonValue.Create( f );
}
else
{
try
{
nodeValue = JsonNode.Parse( value ) ?? JsonValue.Create( value );
}
catch
{
nodeValue = JsonValue.Create( value );
}
}
configObj[key] = nodeValue;
var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText( configPath, configObj.ToJsonString( options ) );
return ToolOutcome<object>.Ready( new
{
ConfigName = targetConfig,
UpdatedKey = key,
UpdatedValue = value,
Saved = true,
FilePath = configPath
} );
}
return ToolOutcome<object>.Ready( new { ConfigName = targetConfig, Status = "Ready" } );
}
}
}