public void StopQueue() { if (_activeCoroutine != null) { StopCoroutine(_activeCoroutine); _activeCoroutine = null; } _processing = false; coroutineCanceller.ResetCancel(); }
private IEnumerator ProcessQueueCoroutine() { CoroutineCanceller.ResetCancel(); while (_coroutineQueue.Count > 0) { IEnumerator coroutine = _coroutineQueue.Dequeue(); if (_bombIDProcessed.Count > 0) { CurrentBombID = _bombIDProcessed.Dequeue(); } bool result = true; while (result) { try { result = coroutine.MoveNext(); } catch { result = false; } if (result) { yield return(coroutine.Current); } } } _processing = false; _activeCoroutine = null; CoroutineCanceller.ResetCancel(); }
protected internal override IEnumerator RespondToCommandInternal(string inputCommand) { inputCommand = inputCommand.Trim(); if (!inputCommand.StartsWith("press ", StringComparison.InvariantCultureIgnoreCase)) { yield break; } inputCommand = inputCommand.Substring(6); string sequence = "pressing "; foreach (Match move in Regex.Matches(inputCommand, @"(\b(red|blue|green|yellow)\b|[rbgy])", RegexOptions.IgnoreCase)) { SimonButton button = _buttons[buttonIndex[move.Value.Substring(0, 1).ToLowerInvariant()]]; if (button != null) { yield return(move.Value); sequence += move.Value + " "; if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); yield break; } yield return(DoInteractionClick(button, sequence)); } } }
private IEnumerator ProcessQueueCoroutine() { CoroutineCanceller.ResetCancel(); while (_coroutineQueue.Count > 0) { IEnumerator coroutine = _coroutineQueue.Dequeue(); if (_bombIDProcessed.Count > 0) { CurrentBombID = _bombIDProcessed.Dequeue(); } bool result = true; while (result) { try { result = coroutine.MoveNext(); } catch (Exception e) { DebugHelper.LogException(e, "An exception occurred while executing a queued coroutine:"); result = false; } if (result) { yield return(coroutine.Current); } } } _processing = false; _activeCoroutine = null; CoroutineCanceller.ResetCancel(); }
public static IEnumerator DefaultCommand(TwitchModule module, string user, string cmd) { if (cmd.RegexMatch(out Match match, @"(?<zoom>zoom *(?<time>\d*\.?\d+)?)? *(?<tilt>tilt *(?<direction>[uptobmdwnlefrigh]+|-?\d+)?)? *(?:send *to *module)? *(?<command>.+)?")) { var groups = match.Groups; var timed = groups["time"].Success; var zoom = groups["zoom"].Success; var tilt = groups["tilt"].Success; var command = groups["command"].Success; // Both a time and a command can't be entered. And either a zoom or tilt needs to take place otherwise, we should let the command run normally. if ((!timed || !command) && (zoom || tilt)) { MusicPlayer musicPlayer = null; int delay = 2; if (timed) { delay = groups["time"].Value.TryParseInt() ?? 2; delay = Math.Max(2, delay); if (delay >= 15) { musicPlayer = MusicPlayer.StartRandomMusic(); } } object toYield = command ? (object)RunModuleCommand(module, user, groups["command"].Value) : delay; IEnumerator routine = null; if (tilt) { routine = Tilt(module, toYield, groups["direction"].Value); } if (zoom) { routine = Zoom(module, user, routine ?? toYield); } yield return(routine); if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); IRCConnection.SendMessage($"Sorry @{user}, your request to hold up the bomb for {delay} seconds has been cut short."); } if (musicPlayer != null) { musicPlayer.StopMusic(); } yield break; } } yield return(RunModuleCommand(module, user, cmd)); }
public static IEnumerator Zoom(TwitchModule module, string user, [Group(1)] float?duration) { MusicPlayer musicPlayer = null; var delay = duration ?? 2; delay = Math.Max(2, delay); module.Solver._zoom = true; if (delay >= 15) { musicPlayer = MusicPlayer.StartRandomMusic(); } var zoomCoroutine = TwitchGame.ModuleCameras?.ZoomCamera(module, 1); if (zoomCoroutine != null) { while (zoomCoroutine.MoveNext()) { yield return(zoomCoroutine.Current); } } yield return(new WaitForSecondsWithCancel(delay, false, module.Solver)); if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); IRCConnection.SendMessage($"Sorry @{user}, your request to hold up the bomb for {delay} seconds has been cut short."); } if (musicPlayer != null) { musicPlayer.StopMusic(); } var unzoomCoroutine = TwitchGame.ModuleCameras?.UnzoomCamera(module, 1); if (unzoomCoroutine != null) { while (unzoomCoroutine.MoveNext()) { yield return(unzoomCoroutine.Current); } } }
private IEnumerator ProcessQueueCoroutine() { while (_coroutineQueue.Count > 0) { CoroutineCanceller.ResetCancel(); IEnumerator coroutine = _coroutineQueue.First.Value; if (_bombIDProcessed.Count > 0) { CurrentBombID = _bombIDProcessed.Dequeue(); } yield return(ProcessCoroutine(coroutine)); _coroutineQueue.RemoveFirst(); } _processing = false; _activeCoroutine = null; CoroutineCanceller.ResetCancel(); }
public static IEnumerator DefaultCommand(TwitchModule module, string user, string cmd) { if ((Votes.Active && Votes.CurrentVoteType == VoteTypes.Solve && Votes.voteModule == module) || module.Votesolving) { IRCConnection.SendMessage($"Sorry @{user}, the module you are trying to interact with is being votesolved."); yield break; } if (cmd.RegexMatch(out Match match, @"(?:(?<zoom>zoom *(?<time>\d*\.?\d+)?)|(?<superzoom>superzoom *(?<factor>\d*\.?\d+) *(?<x>\d*\.?\d+)? *(?<y>\d*\.?\d+)? *(?<stime>\d*\.?\d+)?))? *(?:(?<tilt>tilt *(?<direction>[uptobmdwnlefrigh]+|-?\d+)?)|(?<show>show)?)? *(?:send *to *module)? *(?<command>.+)?")) { var groups = match.Groups; var timed = groups["time"].Success || groups["stime"].Success; var zooming = groups["zoom"].Success || groups["superzoom"].Success; var tilt = groups["tilt"].Success; var show = groups["show"].Success; var command = groups["command"].Success; if (!timed && !zooming && !command && show) { yield return(Show(module, 0.5)); yield break; } // Both a time and a command can't be entered. And either a zoom, show or tilt needs to take place otherwise, we should let the command run normally. if ((!timed || !command) && (zooming || tilt || show)) { MusicPlayer musicPlayer = null; float delay = 2; if (timed) { delay = groups["time"].Value.TryParseInt() ?? groups["stime"].Value.TryParseInt() ?? 2; delay = Math.Max(2, delay); } object toYield = command ? (object)RunModuleCommand(module, user, groups["command"].Value) : delay; IEnumerator routine = null; if (show) { routine = Show(module, toYield); } if (tilt) { routine = Tilt(module, toYield, groups["direction"].Value.ToLowerInvariant()); } if (zooming) { var zoomData = new SuperZoomData( groups["factor"].Value.TryParseFloat() ?? 1, groups["x"].Value.TryParseFloat() ?? 0.5f, groups["y"].Value.TryParseFloat() ?? 0.5f ); routine = Zoom(module, zoomData, routine ?? toYield); } if (delay >= 15) { musicPlayer = MusicPlayer.StartRandomMusic(); } yield return(routine); if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); IRCConnection.SendMessage($"Sorry @{user}, your request to hold up the bomb for {delay} seconds has been cut short."); } if (musicPlayer != null) { musicPlayer.StopMusic(); } yield break; } } yield return(RunModuleCommand(module, user, cmd)); }
public IEnumerator RespondToCommand(string userNickName, string message) { DisableOnStrike = false; Strike = false; StrikeCount = 0; _currentUserNickName = userNickName; FloatingHoldable.HoldStateEnum holdState = Holdable.HoldState; if (holdState == FloatingHoldable.HoldStateEnum.Held) { } else { IEnumerator holdCoroutine = HoldableCommander.Hold(); while (holdCoroutine.MoveNext() && !Strike) { yield return(holdCoroutine.Current); } } IEnumerator processCommand = RespondToCommandCommon(message); if (processCommand == null || !processCommand.MoveNext()) { DebugHelper.Log("Running RespondToCommandInternal()"); processCommand = RespondToCommandInternal(message); bool cancelled = false; bool parseError = false; bool cancelling = false; if (processCommand == null || !processCommand.MoveNext()) { if (!Strike) { SendToChat(null, userNickName, ref parseError); } } else { processIEnumerators.Push(processCommand); processIEnumerators.Push(FirstItem(processCommand.Current)); } do { try { bool result = false; while (!result && !Strike) { if (processIEnumerators.Count > 0) { processCommand = processIEnumerators.Pop(); result = processCommand.MoveNext(); if (result) { processIEnumerators.Push(processCommand); } } else { break; } } if (Strike) { DebugHelper.Log("A strike was caused by the command. Invocation will not continue."); } if (!result || Strike) { break; } } catch (Exception ex) { DebugHelper.LogException(ex, "Error Processing command due to an exception. Invocation will not continue.:"); break; } switch (processCommand.Current) { case IEnumerator iEnumerator: if (iEnumerator != null) { processIEnumerators.Push(iEnumerator); } continue; case KMSelectable kmSelectable when kmSelectable != null: if (heldSelectables.Contains(kmSelectable)) { DoInteractionEnd(kmSelectable); heldSelectables.Remove(kmSelectable); } else { DoInteractionStart(kmSelectable); heldSelectables.Add(kmSelectable); } break; case KMSelectable[] kmSelectables: foreach (KMSelectable selectable in kmSelectables) { if (selectable != null) { yield return(DoInteractionClick(selectable)); if (Strike) { break; } } else { yield return(new WaitForSeconds(0.1f)); } } break; case Quaternion quaternion: HoldableCommander.RotateByLocalQuaternion(quaternion); break; case string currentString when !string.IsNullOrEmpty(currentString): if (currentString.Equals("trycancel", StringComparison.InvariantCultureIgnoreCase) && CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); cancelled = true; } else if (currentString.ToLowerInvariant().EqualsAny("elevator music", "hold music", "waiting music")) { if (_musicPlayer == null) { _musicPlayer = MusicPlayer.StartRandomMusic(); } } else if (currentString.ToLowerInvariant().Equals("cancelled") && cancelling) { CancelBool?.SetValue(CommandComponent, false); CoroutineCanceller.ResetCancel(); cancelled = true; } else if (currentString.StartsWith("strikemessage ", StringComparison.InvariantCultureIgnoreCase) && currentString.Substring(14).Trim() != string.Empty) { StrikeMessage = currentString.Substring(14); } else if (currentString.Equals("strike", StringComparison.InvariantCultureIgnoreCase)) { _delegatedStrikeUserNickName = _currentUserNickName; } else if (currentString.Equals("multiple strikes", StringComparison.InvariantCultureIgnoreCase)) { DisableOnStrike = true; } else if (currentString.ToLowerInvariant().EqualsAny("detonate", "explode") && BombMessageResponder.BombActive) { BombCommander BombCommander = BombMessageResponder.Instance.BombCommanders[0]; AwardStrikes(_currentUserNickName, BombCommander.StrikeLimit - BombCommander.StrikeCount); BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(string.Empty, HoldableCommander.ID); Strike = true; } else if (currentString.ToLowerInvariant().Equals("show front")) { processIEnumerators.Push(HoldableCommander.Hold(true)); } else if (currentString.ToLowerInvariant().Equals("show back")) { processIEnumerators.Push(HoldableCommander.Hold(false)); } else { SendToChat(currentString, userNickName, ref parseError); } break; case string[] currentStrings: if (currentStrings.Length >= 1) { if (currentStrings[0].ToLowerInvariant().EqualsAny("detonate", "explode") && BombMessageResponder.BombActive) { BombCommander BombCommander = BombMessageResponder.Instance.BombCommanders[0]; AwardStrikes(_currentUserNickName, BombCommander.StrikeLimit - BombCommander.StrikeCount); switch (currentStrings.Length) { case 2: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(currentStrings[1], HoldableCommander.ID); break; case 3: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(currentStrings[1], currentStrings[2]); break; default: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(string.Empty, HoldableCommander.ID); break; } break; } } break; case Dictionary <string, bool> permissions: foreach (KeyValuePair <string, bool> pair in permissions) { if (TwitchPlaySettings.data.ModPermissions.ContainsKey(pair.Key)) { continue; } TwitchPlaySettings.data.ModPermissions.Add(pair.Key, pair.Value); TwitchPlaySettings.WriteDataToFile(); } break; case KMMission mission: MiscellaneousMessageResponder.Instance.RunMission(mission); break; case object[] objects: if (objects == null) { break; } switch (objects.Length) { case 3 when objects[0] is string objstr: if (IsAskingPermission(objstr, userNickName, out bool permissionGranted)) { if (permissionGranted) { switch (objects[1]) { case Action actionTrue: actionTrue.Invoke(); break; case IEnumerator iEnumerator when iEnumerator != null: processIEnumerators.Push(iEnumerator); yield return(null); continue; } } else { switch (objects[2]) { case Action actionFalse: actionFalse.Invoke(); break; case string objStr2 when !string.IsNullOrEmpty(objStr2): SendToChat(objStr2, userNickName, ref parseError); break; case IEnumerator iEnumerator when iEnumerator != null: processIEnumerators.Push(iEnumerator); yield return(null); continue; } } } break; } break;
public IEnumerator RespondToCommand(string userNickName, string message) { TryCancel = false; _responded = false; _zoom = false; _processingTwitchCommand = true; if (Solved) { _processingTwitchCommand = false; yield break; } _currentUserNickName = userNickName; int beforeStrikeCount = StrikeCount; IEnumerator subcoroutine = null; if (message.StartsWith("send to module ", StringComparison.InvariantCultureIgnoreCase)) { message = message.Substring(15); } else { subcoroutine = RespondToCommandCommon(message, userNickName); } if (subcoroutine == null || !subcoroutine.MoveNext()) { if (_responded) { yield break; } if (_zoom) { message = message.Substring(4).Trim(); } try { subcoroutine = RespondToCommandInternal(message); } catch (Exception e) { HandleModuleException(e); yield break; } bool moved = false; if (subcoroutine != null) { try { moved = subcoroutine.MoveNext(); if (moved && modInfo.DoesTheRightThing) { //Handle No-focus API commands. In order to focus the module, the first thing yielded cannot be one of the things handled here, as the solver will yield break if //it is one of these API commands returned. switch (subcoroutine.Current) { case string currentString: if (SendToTwitchChat(currentString, userNickName) && !currentString.StartsWith("strikemessage", StringComparison.InvariantCultureIgnoreCase)) { yield break; } break; } _responded = true; } } catch (Exception e) { HandleModuleException(e); yield break; } } if (subcoroutine == null || !moved || Solved || beforeStrikeCount != StrikeCount) { if (Solved || beforeStrikeCount != StrikeCount) { IRCConnection.Instance.SendMessage("Please submit an issue at https://github.com/samfun123/KtaneTwitchPlays/issues regarding module !{0} ({1}) attempting to solve prematurely.", ComponentHandle.Code, ComponentHandle.HeaderText); if (modInfo != null) { modInfo.DoesTheRightThing = false; ModuleData.DataHasChanged = true; ModuleData.WriteDataToFile(); } IEnumerator focusDefocus = BombCommander.Focus(Selectable, FocusDistance, FrontFace); while (focusDefocus.MoveNext()) { yield return(focusDefocus.Current); } yield return(new WaitForSeconds(0.5f)); focusDefocus = BombCommander.Defocus(Selectable, FrontFace); while (focusDefocus.MoveNext()) { yield return(focusDefocus.Current); } yield return(new WaitForSeconds(0.5f)); } else if (!_responded) { ComponentHandle.CommandInvalid(userNickName); } _currentUserNickName = null; _processingTwitchCommand = false; yield break; } } IEnumerator focusCoroutine = BombCommander.Focus(Selectable, FocusDistance, FrontFace); while (focusCoroutine.MoveNext()) { yield return(focusCoroutine.Current); } yield return(new WaitForSeconds(0.5f)); IEnumerator unzoom = null; if (_zoom) { IEnumerator zoom = BombMessageResponder.moduleCameras?.ZoomCamera(BombComponent, 1); unzoom = BombMessageResponder.moduleCameras?.UnzoomCamera(BombComponent, 1); if (zoom == null || unzoom == null) { _zoom = false; } else { while (zoom.MoveNext()) { yield return(zoom.Current); } } } int previousStrikeCount = StrikeCount; bool parseError = false; bool needQuaternionReset = false; bool hideCamera = false; bool exceptionThrown = false; bool trycancelsequence = false; while ((previousStrikeCount == StrikeCount && !Solved) || DisableOnStrike) { try { if (!subcoroutine.MoveNext()) { break; } else { _responded = true; } } catch (Exception e) { exceptionThrown = true; HandleModuleException(e); break; } object currentValue = subcoroutine.Current; if (currentValue is string currentString) { if (currentString.Equals("strike", StringComparison.InvariantCultureIgnoreCase)) { _delegatedStrikeUserNickName = userNickName; } else if (currentString.Equals("solve", StringComparison.InvariantCultureIgnoreCase)) { _delegatedSolveUserNickName = userNickName; } else if (currentString.Equals("unsubmittablepenalty", StringComparison.InvariantCultureIgnoreCase)) { if (TwitchPlaySettings.data.UnsubmittablePenaltyPercent <= 0) { continue; } int penalty = Math.Max((int)(modInfo.moduleScore * TwitchPlaySettings.data.UnsubmittablePenaltyPercent), 1); Leaderboard.Instance.AddScore(_currentUserNickName, -penalty); IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.UnsubmittableAnswerPenalty, _currentUserNickName, Code, modInfo.moduleDisplayName, penalty, penalty > 1 ? "s" : ""); } else if (currentString.Equals("parseerror", StringComparison.InvariantCultureIgnoreCase)) { parseError = true; break; } else if (currentString.RegexMatch(out Match match, "^trycancel((?: (?:.|\\n)+)?)$")) { if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); if (!string.IsNullOrEmpty(match.Groups[1].Value)) { IRCConnection.Instance.SendMessage($"Sorry @{userNickName}, {match.Groups[1].Value.Trim()}"); } break; } } else if (currentString.RegexMatch(out match, "^trycancelsequence((?: (?:.|\\n)+)?)$")) { trycancelsequence = true; yield return(currentValue); continue; } else if (currentString.RegexMatch(out match, "^trywaitcancel ([0-9]+(?:\\.[0-9])?)((?: (?:.|\\n)+)?)$") && float.TryParse(match.Groups[1].Value, out float waitCancelTime)) { yield return(new WaitForSecondsWithCancel(waitCancelTime, false)); if (CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); if (!string.IsNullOrEmpty(match.Groups[2].Value)) { IRCConnection.Instance.SendMessage($"Sorry @{userNickName}, {match.Groups[2].Value.Trim()}"); } break; } } // Commands that allow messages to be sent to the chat. else if (SendToTwitchChat(currentString, userNickName)) { //handled } else if (currentString.StartsWith("add strike", StringComparison.InvariantCultureIgnoreCase)) { OnStrike(null); } else if (currentString.Equals("multiple strikes", StringComparison.InvariantCultureIgnoreCase)) { DisableOnStrike = true; } else if (currentString.Equals("end multiple strikes", StringComparison.InvariantCultureIgnoreCase)) { if (previousStrikeCount == StrikeCount) { DisableOnStrike = false; if (Solved) { OnPass(null); } } else { break; } } else if (currentString.StartsWith("autosolve", StringComparison.InvariantCultureIgnoreCase)) { HandleModuleException(new Exception(currentString)); break; } else if (currentString.ToLowerInvariant().EqualsAny("detonate", "explode")) { AwardStrikes(_currentUserNickName, BombCommander.StrikeLimit - BombCommander.StrikeCount); BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(string.Empty, modInfo.moduleDisplayName); break; } else if (currentString.RegexMatch(out match, "^(end |toggle )?(?:elevator|hold|waiting) music$")) { if (match.Groups.Count > 1 && _musicPlayer != null) { _musicPlayer.StopMusic(); _musicPlayer = null; } else if (!currentString.StartsWith("end ", StringComparison.InvariantCultureIgnoreCase) && _musicPlayer == null) { _musicPlayer = MusicPlayer.StartRandomMusic(); } } else if (currentString.ToLowerInvariant().Equals("hide camera")) { if (!hideCamera) { BombMessageResponder.moduleCameras?.Hide(); BombMessageResponder.moduleCameras?.HideHUD(); IEnumerator hideUI = BombCommander.twitchBombHandle.HideMainUIWindow(); while (hideUI.MoveNext()) { yield return(hideUI.Current); } } hideCamera = true; } else if (currentString.Equals("cancelled", StringComparison.InvariantCultureIgnoreCase) && CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); TryCancel = false; break; } else { if (TwitchPlaySettings.data.EnableDebuggingCommands) { DebugHelper.Log($"Unprocessed string: {currentString}"); } } } else if (currentValue is KMSelectable selectable1) { if (HeldSelectables.Contains(selectable1)) { DoInteractionEnd(selectable1); HeldSelectables.Remove(selectable1); } else { DoInteractionStart(selectable1); HeldSelectables.Add(selectable1); } } else if (currentValue is IList <KMSelectable> selectables) { foreach (KMSelectable selectable in selectables) { yield return(DoInteractionClick(selectable)); if ((previousStrikeCount != StrikeCount && !DisableOnStrike) || Solved || (trycancelsequence && CoroutineCanceller.ShouldCancel)) { break; } } if (trycancelsequence && CoroutineCanceller.ShouldCancel) { CoroutineCanceller.ResetCancel(); break; } } else if (currentValue is Quaternion localQuaternion) { BombCommander.RotateByLocalQuaternion(localQuaternion); //Whitelist perspective pegs as it only returns Quaternion.Euler(x, 0, 0), which is compatible with the RotateCamaraByQuaternion. if (BombComponent.GetComponent <KMBombModule>()?.ModuleType.Equals("spwizPerspectivePegs") ?? false) { BombCommander.RotateCameraByLocalQuaternion(BombComponent, localQuaternion); } needQuaternionReset = true; } else if (currentValue is Quaternion[] localQuaternions) { if (localQuaternions.Length == 2) { BombCommander.RotateByLocalQuaternion(localQuaternions[0]); BombCommander.RotateCameraByLocalQuaternion(BombComponent, localQuaternions[1]); needQuaternionReset = true; } } else if (currentValue is string[] currentStrings) { if (currentStrings.Length >= 1) { if (currentStrings[0].ToLowerInvariant().EqualsAny("detonate", "explode")) { AwardStrikes(_currentUserNickName, BombCommander.StrikeLimit - BombCommander.StrikeCount); switch (currentStrings.Length) { case 2: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(currentStrings[1], modInfo.moduleDisplayName); break; case 3: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(currentStrings[1], currentStrings[2]); break; default: BombCommander.twitchBombHandle.CauseExplosionByModuleCommand(string.Empty, modInfo.moduleDisplayName); break; } break; } } } yield return(currentValue); if (CoroutineCanceller.ShouldCancel) { TryCancel = true; } trycancelsequence = false; } if (!_responded && !exceptionThrown) { ComponentHandle.CommandInvalid(userNickName); } if (needQuaternionReset) { BombCommander.RotateByLocalQuaternion(Quaternion.identity); BombCommander.RotateCameraByLocalQuaternion(BombComponent, Quaternion.identity); } if (hideCamera) { BombMessageResponder.moduleCameras?.Show(); BombMessageResponder.moduleCameras?.ShowHUD(); IEnumerator showUI = BombCommander.twitchBombHandle.ShowMainUIWindow(); while (showUI.MoveNext()) { yield return(showUI.Current); } } if (_musicPlayer != null) { _musicPlayer.StopMusic(); _musicPlayer = null; } if (DisableOnStrike) { DisableOnStrike = false; BombMessageResponder.moduleCameras?.UpdateStrikes(true); if (Solved) { OnPass(null); } AwardStrikes(_currentUserNickName, StrikeCount - previousStrikeCount); } if (!parseError) { yield return(new WaitForSeconds(0.5f)); } if (_zoom) { while (unzoom?.MoveNext() ?? false) { yield return(unzoom.Current); } } IEnumerator defocusCoroutine = BombCommander.Defocus(Selectable, FrontFace); while (defocusCoroutine.MoveNext()) { yield return(defocusCoroutine.Current); } yield return(new WaitForSeconds(0.5f)); _currentUserNickName = null; _processingTwitchCommand = false; }