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 new CommandResultInfo { Message = String.Format("{0} is an invalid command", commandInput.Name.ToUpper()), Result = CommandResult.Fail }; 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 be a context 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; }
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 new CommandResultInfo { Message = String.Format("{0} is an invalid command", commandInput.Name.ToUpper()), Result = CommandResult.Fail } } ; 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 be a context 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); }