GetProjectSettingSchemaCommand.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using LLM.Editor.Data;
  6. namespace LLM.Editor.Commands
  7. {
  8. [Serializable]
  9. public class GetProjectSettingSchemaCommand : ICommand
  10. {
  11. public string apiClassName;
  12. public CommandOutcome Execute(CommandContext context)
  13. {
  14. if (string.IsNullOrEmpty(apiClassName))
  15. {
  16. context.ErrorMessage = "Error: 'apiClassName' is required (e.g., 'UnityEngine.Time', 'UnityEngine.QualitySettings').";
  17. return CommandOutcome.Error;
  18. }
  19. var type = FindType(apiClassName);
  20. if (type == null)
  21. {
  22. context.ErrorMessage = $"Error: Could not find a class named '{apiClassName}'. Please ensure you are using the full, case-sensitive name.";
  23. return CommandOutcome.Error;
  24. }
  25. var schema = new Dictionary<string, object>();
  26. var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Static);
  27. foreach (var prop in properties)
  28. {
  29. if (!prop.CanRead) continue;
  30. try
  31. {
  32. schema[prop.Name] = new
  33. {
  34. type = prop.PropertyType.FullName,
  35. value = prop.GetValue(null),
  36. isReadOnly = !prop.CanWrite
  37. };
  38. }
  39. catch { /* Ignore properties that throw exceptions on read */ }
  40. }
  41. var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
  42. foreach (var field in fields)
  43. {
  44. try
  45. {
  46. schema[field.Name] = new
  47. {
  48. type = field.FieldType.FullName,
  49. value = field.GetValue(null),
  50. isReadOnly = field.IsInitOnly || field.IsLiteral
  51. };
  52. }
  53. catch { /* Ignore fields that throw exceptions on read */ }
  54. }
  55. context.CurrentSubject = schema;
  56. return CommandOutcome.Success;
  57. }
  58. private Type FindType(string typeName)
  59. {
  60. return AppDomain.CurrentDomain.GetAssemblies()
  61. .Where(a => a.FullName.StartsWith("UnityEngine"))
  62. .SelectMany(a => a.GetTypes())
  63. .FirstOrDefault(t => t.FullName != null && t.FullName.Equals(typeName, StringComparison.OrdinalIgnoreCase));
  64. }
  65. }
  66. }