using System; using System.Linq; using System.Reflection; using LLM.Editor.Data; using Newtonsoft.Json.Linq; namespace LLM.Editor.Commands { [Serializable] public class SetProjectSettingValueCommand : ICommand { public string apiClassName; public string memberName; public object value; public CommandOutcome Execute(CommandContext context) { if (string.IsNullOrEmpty(apiClassName) || string.IsNullOrEmpty(memberName)) { context.ErrorMessage = "Error: 'apiClassName' and 'memberName' are required."; return CommandOutcome.Error; } var type = FindType(apiClassName); if (type == null) { context.ErrorMessage = $"Error: Could not find a class named '{apiClassName}'."; return CommandOutcome.Error; } // Try to set a property var property = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.Static); if (property != null) { if (!property.CanWrite) { context.ErrorMessage = $"Error: Property '{memberName}' on '{apiClassName}' is read-only."; return CommandOutcome.Error; } try { var token = value is JToken ? (JToken)value : JToken.FromObject(value); var convertedValue = token.ToObject(property.PropertyType); property.SetValue(null, convertedValue); return CommandOutcome.Success; } catch (Exception e) { context.ErrorMessage = $"Error setting property '{memberName}': {e.Message}"; return CommandOutcome.Error; } } // Try to set a field var field = type.GetField(memberName, BindingFlags.Public | BindingFlags.Static); if (field != null) { if (field.IsInitOnly || field.IsLiteral) { context.ErrorMessage = $"Error: Field '{memberName}' on '{apiClassName}' is read-only."; return CommandOutcome.Error; } try { var token = value is JToken ? (JToken)value : JToken.FromObject(value); var convertedValue = token.ToObject(field.FieldType); field.SetValue(null, convertedValue); return CommandOutcome.Success; } catch (Exception e) { context.ErrorMessage = $"Error setting field '{memberName}': {e.Message}"; return CommandOutcome.Error; } } context.ErrorMessage = $"Error: Could not find a writable public static member named '{memberName}' on '{apiClassName}'."; return CommandOutcome.Error; } private Type FindType(string typeName) { return AppDomain.CurrentDomain.GetAssemblies() .Where(a => a.FullName.StartsWith("UnityEngine")) .SelectMany(a => a.GetTypes()) .FirstOrDefault(t => t.FullName != null && t.FullName.Equals(typeName, StringComparison.OrdinalIgnoreCase)); } } }