private bool ExecuteCommand(MethodInfo method, OpenPlayer player, string[] args, out object result) { Log.Info($"Execute command {method}"); result = null; var parameters = method.GetParameters(); int addLenght = 0; if (parameters.Length > 0 && typeof(OpenPlayer).IsAssignableFrom(parameters[0].ParameterType)) { addLenght = 1; } object[] objectArgs = new object[parameters.Length]; try { int i = 0; for (int k = 0; k < parameters.Length; k++) { var parameter = parameters[k]; if (k == 0 && addLenght == 1) { if (typeof(OpenPlayer).IsAssignableFrom(parameter.ParameterType)) { objectArgs[k] = player; continue; } Log.WarnFormat("Command method {0} missing Player as first argument.", method.Name); return(false); } if (PluginManager.Services.TryResolve(parameter.ParameterType, out var param)) { objectArgs[k] = param; continue; } if (parameter.IsOptional && args.Length <= i) { objectArgs[k] = parameter.DefaultValue; continue; } if (args.Length < k) { return(false); } if (typeof(IParameterSerializer).IsAssignableFrom(parameter.ParameterType)) { var ctor = parameter.ParameterType.GetConstructor(Type.EmptyTypes); IParameterSerializer defaultValue = ctor.Invoke(null) as IParameterSerializer; defaultValue?.Deserialize(player, args[i++]); objectArgs[k] = defaultValue; continue; } if (typeof(CustomEnum).IsAssignableFrom(parameter.ParameterType)) { var ctor = parameter.ParameterType.GetConstructor(Type.EmptyTypes); CustomEnum c = ctor.Invoke(null) as CustomEnum; if (!c.SetValue(args[i++])) { return(false); } objectArgs[k] = c; continue; //param.EnumType = c. } if (parameter.ParameterType.BaseType == typeof(EnumBase)) { var ctor = parameter.ParameterType.GetConstructor(Type.EmptyTypes); EnumBase instance = (EnumBase)ctor.Invoke(null); instance.Value = args[i++]; objectArgs[k] = instance; continue; } if (parameter.ParameterType == typeof(Target)) { var target = FillTargets(player, player.Level, args[i++]); objectArgs[k] = target; continue; } if (parameter.ParameterType == typeof(BlockPos)) { if (args.Length < i + 3) { return(false); } BlockPos blockPos = new BlockPos(); string val = args[i++]; if (val.StartsWith("~")) { val = val.Substring(1); blockPos.XRelative = true; } int.TryParse(val, out var x); blockPos.X = x; val = args[i++]; if (val.StartsWith("~")) { val = val.Substring(1); blockPos.YRelative = true; } int.TryParse(val, out var y); blockPos.Y = y; val = args[i++]; if (val.StartsWith("~")) { val = val.Substring(1); blockPos.ZRelative = true; } int.TryParse(val, out var z); blockPos.Z = z; objectArgs[k] = blockPos; continue; } if (parameter.ParameterType == typeof(string)) { objectArgs[k] = args[i++]; continue; } if (parameter.ParameterType == typeof(byte)) { byte value; if (!byte.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType == typeof(short)) { short value; if (!short.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType == typeof(int)) { int value; if (!int.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType == typeof(bool)) { bool value; if (!bool.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType == typeof(float)) { float value; if (!float.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType == typeof(double)) { double value; if (!double.TryParse(args[i++], out value)) { return(false); } objectArgs[k] = value; continue; } if (parameter.ParameterType.IsEnum) { string val = args[i++]; Enum value = Enum.Parse(parameter.ParameterType, val, true) as Enum; if (value == null) { Log.Error($"Could not convert to valid enum value: {val}"); continue; } objectArgs[k] = value; continue; } if (IsParams(parameter) && parameter.ParameterType == typeof(string[])) { List <string> strings = new List <string>(); for (int j = i++; j < args.Length; j++) { strings.Add(args[j]); } objectArgs[k] = strings.ToArray(); continue; } return(false); } } catch (Exception e) { // if (Log.IsDebugEnabled) { Log.Error("Trying to execute command overload", e); } return(false); } try { if (method.IsStatic) { result = method.Invoke(null, objectArgs); } else { if (_pluginCommands.TryGetValue(method, out CommandData data)) { object instance = data.Instance; Plugin.CurrentPlayer = player; // Setting thread local for call result = method.Invoke(instance, objectArgs); Plugin.CurrentPlayer = null; } else { Log.Warn($"Could not find instance of command's declaringtype!"); return(false); } } return(true); } catch (Exception e) { Log.Error($"Error while executing command {method}", e); } return(false); }
private CommandSet GenerateCommandSet(MethodInfo[] methods) { CommandSet commands = new CommandSet(); foreach (MethodInfo method in methods) { CommandAttribute commandAttribute = Attribute.GetCustomAttribute(method, typeof(CommandAttribute), false) as CommandAttribute; if (commandAttribute == null) { continue; } // TODO: Do we need the authorize attribute with the new permission system? AuthorizeAttribute authorizeAttribute = Attribute.GetCustomAttribute(method, typeof(AuthorizeAttribute), false) as AuthorizeAttribute ?? new AuthorizeAttribute(); if (string.IsNullOrEmpty(commandAttribute.Name)) { commandAttribute.Name = method.Name; } var overload = new Overload { Description = commandAttribute.Description ?? "Bullshit", Method = method, Input = new Input(), }; string commandName = commandAttribute.Name.ToLowerInvariant(); var split = commandName.Split(' '); Parameter subCommmandParam = null; if (split.Length > 1) { subCommmandParam = new Parameter(); subCommmandParam.Name = "subcommand"; subCommmandParam.Type = "stringenum"; subCommmandParam.EnumType = "SubCommand" + commandName.Replace(" ", "-"); subCommmandParam.EnumValues = new[] { split[1] }; commandName = split[0]; } if (commands.ContainsKey(commandName)) { Command command = commands[commandName]; command.Versions.First().Overloads.Add(commandAttribute.Overload ?? Guid.NewGuid().ToString(), overload); } else { commands.Add(commandName, new Command { Name = commandName, Versions = new[] { new MiNET.Plugins.Version() { Permission = authorizeAttribute.Permission.ToString().ToLowerInvariant(), CommandPermission = authorizeAttribute.Permission, ErrorMessage = authorizeAttribute.ErrorMessage, Aliases = commandAttribute.Aliases ?? new string[0], Description = commandAttribute.Description ?? "", Overloads = new Dictionary <string, Overload> { { "default", overload }, } }, } }); } List <Parameter> inputParams = new List <Parameter>(); if (subCommmandParam != null) { inputParams.Add(subCommmandParam); } var parameters = method.GetParameters(); bool isFirstParam = true; foreach (var parameter in parameters) { if (isFirstParam && typeof(OpenPlayer).IsAssignableFrom(parameter.ParameterType)) { continue; } isFirstParam = false; if (PluginManager.Services.TryResolve(parameter.ParameterType, out _)) { //This is a depencency injected param continue; } Parameter param = new Parameter(); param.Name = ToCamelCase(parameter.Name); param.Type = GetParameterType(parameter); param.Optional = parameter.IsOptional; if (param.Type.Equals("bool")) { param.Type = "stringenum"; param.EnumType = "bool"; param.EnumValues = new string[] { "false", "true" }; } else if (param.Type.Equals("stringenum")) { if (parameter.ParameterType.IsEnum) { param.EnumValues = parameter.ParameterType.GetEnumNames().Select(s => s.ToLowerInvariant()).ToArray(); string typeName = parameter.ParameterType.Name; typeName = typeName.Replace("Enum", ""); typeName = typeName.ToLowerInvariant()[0] + typeName.Substring(1); param.EnumType = typeName; } else { param.EnumValues = null; string typeName = parameter.ParameterType.Name; typeName = typeName.Replace("Enum", ""); typeName = typeName.ToLowerInvariant()[0] + typeName.Substring(1); param.EnumType = typeName; if (parameter.ParameterType == typeof(ItemTypeEnum)) { param.EnumValues = new string[] { }; param.EnumType = "Item"; } else if (parameter.ParameterType == typeof(BlockTypeEnum)) { param.EnumValues = new string[] { }; param.EnumType = "Block"; } else if (parameter.ParameterType == typeof(EntityTypeEnum)) { param.EnumValues = new string[] { }; param.EnumType = "EntityType"; } else if (parameter.ParameterType == typeof(CommandNameEnum)) { param.EnumValues = new string[] { }; param.EnumType = "CommandName"; } else if (parameter.ParameterType == typeof(EnchantEnum)) { param.EnumValues = new string[] { "enchant_test" }; param.EnumType = "Enchant"; } else if (parameter.ParameterType == typeof(EffectEnum)) { param.EnumValues = new string[] { "effect_test" }; param.EnumType = "Effect"; } else if (typeof(CustomEnum).IsAssignableFrom(parameter.ParameterType)) { CustomEnum c = parameter.ParameterType.GetConstructor(Type.EmptyTypes).Invoke(null) as CustomEnum; if (c != null) { param.EnumValues = c.GetValues(); param.EnumType = c.EnumType; //param.EnumType = c. } } } } inputParams.Add(param); } if (inputParams.Count == 0) { overload.Input.Parameters = null; } else { overload.Input.Parameters = inputParams.ToArray(); } } return(commands); }