public CommandResultInfo ExecuteCommand(CommandExecutionInfo commandInput) { //TODO: This should handle errors //TODO: Pretty complex, maybe could use some commenting ICommand commandInstance = GetCommandInstance(commandInput.Name); if (commandInstance == null) { return(CommandResultInfo.Fail(String.Format("{0} is an invalid command", commandInput.Name.ToUpper()))); } MethodInfo[] commandMethods = commandInstance.GetType().GetMethods() .Where(o => o.Name == "Execute") .Where(o => o.GetParameters()[0].ParameterType.BaseType == typeof(MessageContext)).ToArray(); //Sort descending by number of parameters so the more "specific" methods are given priority Array.Sort(commandMethods, (m1, m2) => - m1.GetParameters().Length.CompareTo(m2.GetParameters().Length)); foreach (MethodInfo methodInfo in commandMethods) { ParameterInfo[] methodParameters = methodInfo.GetParameters(); int parameterCount = methodParameters.Length - 1; //Loop throught the method's parameters for (int p = 0; p < methodParameters.Length; p++) { ParameterInfo methodParameter = methodParameters[p]; if (commandInput.ParameterList.Count < parameterCount) { break; } if (p == 0) { //First parameter must match the current context type if (methodParameter.ParameterType != commandInput.Context.GetType()) { break; } //Handle parameterless command if (commandInput.ParameterList.Count == 0) { if (parameterCount != 0) { break; } commandInput.ParameterList.Insert(0, commandInput.Context); return((CommandResultInfo)methodInfo.Invoke(commandInstance, commandInput.ParameterList.ToArray())); } continue; } // If it's a channel, convert the string into a ChannelInfo object if (FlamingIRC.Rfc2812Util.IsValidChannelName(commandInput.ParameterList[p - 1] as string)) { commandInput.ParameterList[p - 1] = new ChannelInfo(commandInput.ParameterList[p - 1] as string); } var sp = (commandInput.ParameterList[p - 1] as string); if (sp != null && sp.StartsWith("-")) // Check for switches { sp = sp.Remove(0, 1); commandInput.ParameterList[p - 1] = sp.ToCharArray(); } if (methodParameter.ParameterType != commandInput.ParameterList[p - 1].GetType()) { break; //Parameter mismatch. Break parameter loop and go the the next method } if (p != parameterCount) { continue; //If this isn't the last parameter then keep looping } //Checks for an "open-ended" string parameter. if (methodParameter.ParameterType == typeof(string)) { bool allStrings = true; var openString = new System.Text.StringBuilder(); int numberOpenEnded = 0; for (int k = p - 1; k < commandInput.ParameterList.Count; k++) { if (commandInput.ParameterList[k].GetType() != typeof(string)) { allStrings = false; break; } openString.Append(commandInput.ParameterList[k] + " "); numberOpenEnded++; } if (allStrings && p != commandInput.ParameterList.Count) { openString.Remove(openString.Length - 1, 1); commandInput.ParameterList.RemoveRange(p - 1, numberOpenEnded); commandInput.ParameterList.Add(openString.ToString()); } } commandInput.ParameterList.Insert(0, commandInput.Context); return((CommandResultInfo)methodInfo.Invoke(commandInstance, commandInput.ParameterList.ToArray())); //TODO: Should maybe log or something before returning } } return(null); }
private void commandTextBox_CommandEntered(object sender, Common.DataEventArgs<string> e) { CommandResultInfo result = new CommandResultInfo(); try { result = _pluginManager.ExecuteCommand(_pluginManager.ParseCommand(Server, e.Data)); } catch (TargetInvocationException ex) { serverOutputBox.AppendLine(ex.InnerException.Message, Color.Red); } if (result != null && result.Result == CommandResult.Fail) serverOutputBox.AppendLine(result.Message, Color.Red); }