SetProjectSettingValueCommand.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using LLM.Editor.Data;
  5. using Newtonsoft.Json.Linq;
  6. namespace LLM.Editor.Commands
  7. {
  8. [Serializable]
  9. public class SetProjectSettingValueCommand : ICommand
  10. {
  11. public string apiClassName;
  12. public string memberName;
  13. public object value;
  14. public CommandOutcome Execute(CommandContext context)
  15. {
  16. if (string.IsNullOrEmpty(apiClassName) || string.IsNullOrEmpty(memberName))
  17. {
  18. context.ErrorMessage = "Error: 'apiClassName' and 'memberName' are required.";
  19. return CommandOutcome.Error;
  20. }
  21. var type = FindType(apiClassName);
  22. if (type == null)
  23. {
  24. context.ErrorMessage = $"Error: Could not find a class named '{apiClassName}'.";
  25. return CommandOutcome.Error;
  26. }
  27. // Try to set a property
  28. var property = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.Static);
  29. if (property != null)
  30. {
  31. if (!property.CanWrite)
  32. {
  33. context.ErrorMessage = $"Error: Property '{memberName}' on '{apiClassName}' is read-only.";
  34. return CommandOutcome.Error;
  35. }
  36. try
  37. {
  38. var token = value is JToken ? (JToken)value : JToken.FromObject(value);
  39. var convertedValue = token.ToObject(property.PropertyType);
  40. property.SetValue(null, convertedValue);
  41. return CommandOutcome.Success;
  42. }
  43. catch (Exception e)
  44. {
  45. context.ErrorMessage = $"Error setting property '{memberName}': {e.Message}";
  46. return CommandOutcome.Error;
  47. }
  48. }
  49. // Try to set a field
  50. var field = type.GetField(memberName, BindingFlags.Public | BindingFlags.Static);
  51. if (field != null)
  52. {
  53. if (field.IsInitOnly || field.IsLiteral)
  54. {
  55. context.ErrorMessage = $"Error: Field '{memberName}' on '{apiClassName}' is read-only.";
  56. return CommandOutcome.Error;
  57. }
  58. try
  59. {
  60. var token = value is JToken ? (JToken)value : JToken.FromObject(value);
  61. var convertedValue = token.ToObject(field.FieldType);
  62. field.SetValue(null, convertedValue);
  63. return CommandOutcome.Success;
  64. }
  65. catch (Exception e)
  66. {
  67. context.ErrorMessage = $"Error setting field '{memberName}': {e.Message}";
  68. return CommandOutcome.Error;
  69. }
  70. }
  71. context.ErrorMessage = $"Error: Could not find a writable public static member named '{memberName}' on '{apiClassName}'.";
  72. return CommandOutcome.Error;
  73. }
  74. private Type FindType(string typeName)
  75. {
  76. return AppDomain.CurrentDomain.GetAssemblies()
  77. .Where(a => a.FullName.StartsWith("UnityEngine"))
  78. .SelectMany(a => a.GetTypes())
  79. .FirstOrDefault(t => t.FullName != null && t.FullName.Equals(typeName, StringComparison.OrdinalIgnoreCase));
  80. }
  81. }
  82. }