예제 #1
0
        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);
        }
예제 #2
0
        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);
        }