Exemplo n.º 1
0
        private bool ExecuteCommand(MethodInfo method, User user, Chat chat, string[] args, Message messageData, out object result)
        {
            Core.Log.Info($"Execute command {method}");

            result = new object();
            CommandContext context = new CommandContext(Core, user, chat, messageData);

            var parameters = method.GetParameters();

            int addLenght = 0;

            if (parameters.Length > 0 && typeof(CommandContext).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(CommandContext).IsAssignableFrom(parameter.ParameterType))
                        {
                            objectArgs[k] = context;
                            continue;
                        }
                        Core.Log.Warn(chat, $"Command method {method.Name} missing Player as first argument.");
                        return(false);
                    }

                    bool isStringParam = IsParams(parameter) && parameter.ParameterType == typeof(string[]);

                    if ((parameter.IsOptional || isStringParam) && args.Length <= i)
                    {
                        if (isStringParam)
                        {
                            objectArgs[k] = new string[0];
                        }
                        else
                        {
                            objectArgs[k] = parameter.DefaultValue;
                        }
                        continue;
                    }

                    if (args.Length < k)
                    {
                        Core.Log.Error(chat, $"No math {k} arguments");
                        return(false);
                    }

                    if (typeof(IParameterSerializer).IsAssignableFrom(parameter.ParameterType))
                    {
                        var ctor = parameter.ParameterType.GetConstructor(Type.EmptyTypes);
                        IParameterSerializer defaultValue = ctor.Invoke(null) as IParameterSerializer;
                        defaultValue?.Deserialize(user, args[i++]);

                        objectArgs[k] = defaultValue;

                        continue;
                    }

                    if (parameter.ParameterType == typeof(User))
                    {
                        long   id;
                        string _id = args[i++].Split(' ', '|').First();
                        if (_id.Length < 4 || !long.TryParse(_id.Substring(3), out id))
                        {
                            return(false);
                        }
                        objectArgs[k] = new User(user.VkApi, id);
                        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(long))
                    {
                        long value;
                        if (!long.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++];
                        if (!Enum.TryParse(parameter.ParameterType, val, true, out object value) || value as Enum == null)
                        {
                            Core.Log.Warn($"Could not convert to valid enum value: {val}");
                            return(false);
                        }

                        objectArgs[k] = value;
                        continue;
                    }

                    if (isStringParam)
                    {
                        List <string> strings = new List <string>();
                        for (; i < args.Length; i++)
                        {
                            strings.Add(args[i]);
                        }
                        objectArgs[k] = strings.ToArray();
                        continue;
                    }

                    return(false);
                }

                if (i < args.Length)
                {
                    return(false);
                }
            }
            catch (Exception e)
            {
                //if (Log.IsDebugEnabled)
                //{
                //	Log.Error("Trying to execute command overload", e);
                //}
                //chat.SendMessage(e);
                Core.Log.Error(chat, e.ToString());

                return(false);
            }

            try
            {
                object pluginInstance = _plugins.FirstOrDefault(plugin => method.DeclaringType.IsInstanceOfType(plugin)) ?? method.DeclaringType;
                if (pluginInstance == null)
                {
                    return(false);
                }

                ICommandFilter filter = pluginInstance as ICommandFilter;
                if (filter != null)
                {
                    filter.OnCommandExecuting(user);
                }

                if (method.IsStatic)
                {
                    result = method.Invoke(null, objectArgs);
                }
                else
                {
                    if (method.DeclaringType == null)
                    {
                        return(false);
                    }

                    Plugin.CurrentContext = context; // Setting thread local for call
                    result = method.Invoke(pluginInstance, objectArgs);
                    Plugin.CurrentContext = null;    // Done with thread local, we using pool to make sure it's reset.
                }

                if (filter != null)
                {
                    filter.OnCommandExecuted();
                }

                return(true);
            }
            catch (Exception e)
            {
                Core.Log.Error(chat, e.ToString());
                //Log.Error($"Error while executing command {method}", e);
                //chat.SendMessage(e);
            }

            return(false);
        }
Exemplo n.º 2
0
        private object ExecuteCommand(MethodInfo method, Player player, string[] args)
        {
            Log.Info($"Execute command {method}");

            var parameters = method.GetParameters();

            int addLenght = 0;

            if (parameters.Length > 0 && typeof(Player).IsAssignableFrom(parameters[0].ParameterType))
            {
                addLenght = 1;
            }

            object[] objectArgs = new object[parameters.Length];

            for (int k = 0; k < parameters.Length; k++)
            {
                var parameter = parameters[k];
                int i         = k - addLenght;
                if (k == 0 && addLenght == 1)
                {
                    if (typeof(Player).IsAssignableFrom(parameter.ParameterType))
                    {
                        objectArgs[k] = player;
                        continue;
                    }
                    Log.WarnFormat("Command method {0} missing Player as first argument.", method.Name);
                    return(null);
                }

                if (parameter.IsOptional && args.Length <= i)
                {
                    objectArgs[k] = parameter.DefaultValue;
                    continue;
                }

                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 (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 = JsonConvert.DeserializeObject <Target>(args[i]);
                    target        = FillTargets(player, player.Level, target);
                    objectArgs[k] = target;
                    continue;
                }

                if (parameter.ParameterType == typeof(BlockPos))
                {
                    var blockpos = JsonConvert.DeserializeObject <BlockPos>(args[i]);
                    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(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType == typeof(short))
                {
                    short value;
                    if (!short.TryParse(args[i], out value))
                    {
                        return(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType == typeof(int))
                {
                    int value;
                    if (!int.TryParse(args[i], out value))
                    {
                        return(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType == typeof(bool))
                {
                    bool value;
                    if (!bool.TryParse(args[i], out value))
                    {
                        return(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType == typeof(float))
                {
                    float value;
                    if (!float.TryParse(args[i], out value))
                    {
                        return(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType == typeof(double))
                {
                    double value;
                    if (!double.TryParse(args[i], out value))
                    {
                        return(null);
                    }
                    objectArgs[k] = value;
                    continue;
                }
                if (parameter.ParameterType.IsEnum)
                {
                    Enum value = Enum.Parse(parameter.ParameterType, args[i], true) as Enum;
                    if (value == null)
                    {
                        Log.Error($"Could not convert to valid enum value: {args[i]}");
                        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(null);
            }

            object result = null;

            try
            {
                object pluginInstance = _plugins.FirstOrDefault(plugin => plugin.GetType() == method.DeclaringType);
                if (pluginInstance == null)
                {
                    return(null);
                }

                ICommandFilter filter = pluginInstance as ICommandFilter;
                if (filter != null)
                {
                    filter.OnCommandExecuting(player);
                }

                if (method.IsStatic)
                {
                    result = method.Invoke(null, objectArgs);
                }
                else
                {
                    if (method.DeclaringType == null)
                    {
                        return(false);
                    }

                    Plugin.CurrentPlayer = player;                   // Setting thread local for call
                    result = method.Invoke(pluginInstance, objectArgs);
                    Plugin.CurrentPlayer = null;                     // Done with thread local, we using pool to make sure it's reset.
                }

                if (filter != null)
                {
                    filter.OnCommandExecuted();
                }
            }
            catch (Exception e)
            {
                Log.Error($"Error while executing command {method}", e);
            }
            return(result);
        }