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); }
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); }