private static ModComponentSolverDelegate GenerateModComponentSolverCreator(MonoBehaviour bombComponent, string moduleType) { ModCommandType commandType = ModCommandType.Simple; Type commandComponentType = null; MethodInfo method = FindProcessCommandMethod(bombComponent, out commandType, out commandComponentType); string help = FindHelpMessage(bombComponent); string manual = FindManualCode(bombComponent); bool statusBottom = false; float rotation = 0; bool statusLeft = FindStatusLightPosition(bombComponent, out statusBottom, out rotation); if (help == null && ModComponentSolverHelpMessages.ContainsKey(moduleType)) { help = ModComponentSolverHelpMessages[moduleType]; } if (manual == null && ModComponentSolverManualCodes.ContainsKey(moduleType)) { manual = ModComponentSolverManualCodes[moduleType]; } if (ModComponentSolverStatusLightLeft.ContainsKey(moduleType)) { statusLeft = ModComponentSolverStatusLightLeft[moduleType]; } if (ModComponentSolverStatusLightBottom.ContainsKey(moduleType)) { statusBottom = ModComponentSolverStatusLightBottom[moduleType]; } if (method != null) { switch (commandType) { case ModCommandType.Simple: return(delegate(BombCommander _bombCommander, MonoBehaviour _bombComponent, IRCConnection _ircConnection, CoroutineCanceller _canceller) { Component commandComponent = _bombComponent.GetComponentInChildren(commandComponentType); return new SimpleModComponentSolver(_bombCommander, _bombComponent, _ircConnection, _canceller, method, commandComponent, manual, help, statusLeft, statusBottom, rotation); }); case ModCommandType.Coroutine: FieldInfo cancelfield; Type canceltype; FindCancelBool(bombComponent, out cancelfield, out canceltype); return(delegate(BombCommander _bombCommander, MonoBehaviour _bombComponent, IRCConnection _ircConnection, CoroutineCanceller _canceller) { Component commandComponent = _bombComponent.GetComponentInChildren(commandComponentType); return new CoroutineModComponentSolver(_bombCommander, _bombComponent, _ircConnection, _canceller, method, commandComponent, manual, help, cancelfield, canceltype, statusLeft, statusBottom, rotation); }); default: break; } } return(null); }
private static MethodInfo FindProcessCommandMethod(MonoBehaviour bombComponent, out ModCommandType commandType, out Type commandComponentType) { Component[] allComponents = bombComponent.GetComponentsInChildren <Component>(true); foreach (Component component in allComponents) { Type type = component.GetType(); MethodInfo candidateMethod = type.GetMethod("ProcessTwitchCommand", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (candidateMethod == null) { continue; } if (ValidateMethodCommandMethod(type, candidateMethod, out commandType)) { commandComponentType = type; return(candidateMethod); } } commandType = ModCommandType.Simple; commandComponentType = null; return(null); }
private static bool ValidateMethodCommandMethod(Type type, MethodInfo candidateMethod, out ModCommandType commandType) { commandType = ModCommandType.Unsupported; ParameterInfo[] parameters = candidateMethod.GetParameters(); if (parameters == null || parameters.Length == 0) { DebugLog("Found a potential candidate ProcessCommand method in {0}, but the parameter list does not match the expected parameter list (too few parameters).", type.FullName); return(false); } if (parameters.Length > 1) { DebugLog("Found a potential candidate ProcessCommand method in {0}, but the parameter list does not match the expected parameter list (too many parameters).", type.FullName); return(false); } if (parameters[0].ParameterType != typeof(string)) { DebugLog("Found a potential candidate ProcessCommand method in {0}, but the parameter list does not match the expected parameter list (expected a single string parameter, got a single {1} parameter).", type.FullName, parameters[0].ParameterType.FullName); return(false); } if (candidateMethod.ReturnType == typeof(KMSelectable[])) { DebugLog("Found a valid candidate ProcessCommand method in {0} (using easy/simple API).", type.FullName); commandType = ModCommandType.Simple; return(true); } if (candidateMethod.ReturnType == typeof(IEnumerator)) { DebugLog("Found a valid candidate ProcessCommand method in {0} (using advanced/coroutine API).", type.FullName); commandType = ModCommandType.Coroutine; return(true); } return(false); }