write-field and read-field commands similar to call-static

Issue #128 new
Yusuf Ismail repo owner created an issue

Commands for reading and writing fields on static and instance variables similar to call-static and call-instance

Comments (1)

  1. Grant Oganyan

    While we wait for official support, here my solution if anyone needs it. This only works for the first instance of an object, so no support for different MonoTargetType types.

    The Commands:

    [Command("call-field", "Get or set specified field in a specified class.")]
    static string CallVariable ([CommandParameterDescription("Class containing the field.")] Type classType, [CommandParameterDescription("Field name")] string variable, [CommandParameterDescription("Set value for the field.")] string value = null) {
        if (value == null) return ReadVariable(classType, variable);
        else return SetVariable(classType, variable, value);
    }
    
    static string ReadVariable (Type classType, string variable) {
        Object target = CommandsHelper.FindObject(classType);
        FieldInfo field = CommandsHelper.FindField(classType, variable);
    
        string value = field.GetValue(target).ToString().ColorText(QuantumConsole.Instance.Theme.DefaultReturnValueColor);
    
        return $"[{target.name} - {classType}] {field.Name}: {value.ColorText(QuantumConsole.Instance.Theme.DefaultReturnValueColor)}";
    }
    
    static string SetVariable (Type classType, string variable, string value) {
        Object target = CommandsHelper.FindObject(classType);
        FieldInfo field = CommandsHelper.FindField(classType, variable);
    
        object setValue = CommandsHelper.Parser.Parse(value, field.FieldType);
    
        field.SetValue(target, setValue);
    
        return $"[{target.name} - {classType}] Set {field.Name} to {field.GetValue(target).ToString().ColorText(QuantumConsole.Instance.Theme.DefaultReturnValueColor)}";        
    }
    
    [Command("call-variable-static")]
    static string CallStaticVariable (Type classType, string variable, string value = null) {
        if (value == null) return ReadStaticVariable(classType, variable);
        else return SetStaticVariable(classType, variable, value);
    }
    
    static string ReadStaticVariable (Type classType, string variable) {
        FieldInfo field = CommandsHelper.FindField(classType, variable);
    
        return $"[{classType}] {field.Name}: {field.GetValue(null).ToString().ColorText(QuantumConsole.Instance.Theme.DefaultReturnValueColor)}";
    }
    
    static string SetStaticVariable (Type classType, string variable, string value) {
        FieldInfo field = CommandsHelper.FindField(classType, variable);
    
        object setValue = CommandsHelper.Parser.Parse(value, field.FieldType);
    
        field.SetValue(null, setValue);
    
        return $"[{classType}] Set {field.Name} to {field.GetValue(null).ToString().ColorText(QuantumConsole.Instance.Theme.DefaultReturnValueColor)}";        
    }
    

    CommandsHelper class:

    public static class CommandsHelper {
    
      public static readonly QuantumParser Parser = new QuantumParser();
    
      public static FieldInfo FindField (Type type, string variable) {
    
          const BindingFlags flags =  BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod |
                                          BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
    
    
          FieldInfo field = type.GetField(variable, flags);
    
          if (field == null) throw new Exception($"Could not find variable \"{variable}\" inside \"{type}\".");
    
          return field;
      }
    
      public static FieldInfo[] FindAllFields (Type type) {
          const BindingFlags flags =  BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod |
                                          BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
    
    
          FieldInfo[] fields = type.GetFields(flags);
    
          if (fields.Length <= 0) throw new Exception($"Could not find any fields in \"{type}\".");
    
          return fields;
      }
    
      public static Object FindObject (Type type) {
          Object target = Object.FindObjectOfType(type);
          if (!target) throw new Exception($"No target of type \"{type}\" was found."); 
    
          return target;
      }
    }
    

  2. Log in to comment