private void AddModuleToStack(BombComponent component, TwitchComponentHandle handle, int priority = CameraInUse) { if (component == null || handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { return; } if (!moduleItems.TryGetValue(component, out ModuleItem item)) { item = new ModuleItem(component, handle, priority); moduleItems.Add(component, item); } else { item.priority = priority; } if (priority >= CameraPinned) { pinnedModuleStack.Push(item); } else if (priority >= CameraPrioritised) { priorityModuleStack.Push(item); } else { moduleStack.Push(item); } }
public static void HandleForcedSolve(MonoBehaviour bombComponent) { try { TwitchComponentHandle handle = null; KMBombModule module = bombComponent.GetComponent <KMBombModule>(); KMNeedyModule needyModule = bombComponent.GetComponent <KMNeedyModule>(); if (module != null) { handle = BombMessageResponder.Instance.ComponentHandles.Where(x => x.bombComponent.GetComponent <KMBombModule>() != null) .FirstOrDefault(x => x.bombComponent.GetComponent <KMBombModule>() == module); } else if (needyModule != null) { handle = BombMessageResponder.Instance.ComponentHandles.Where(x => x.bombComponent.GetComponent <KMBombModule>() != null) .FirstOrDefault(x => x.bombComponent.GetComponent <KMBombModule>() == needyModule); } if (handle != null) { HandleForcedSolve(handle); } else { CommonReflectedTypeInfo.HandlePassMethod.Invoke(bombComponent, null); foreach (MonoBehaviour behaviour in bombComponent.GetComponentsInChildren <MonoBehaviour>(true)) { behaviour.StopAllCoroutines(); } } } catch (Exception ex) { DebugHelper.LogException(ex, "An exception occured while silently soving a module:"); } }
public ModuleItem(BombComponent c, TwitchComponentHandle h, int p) { component = c; handle = h; priority = p; UpdateLayerData(); }
protected void SolveModule(string reason = "A module is being automatically solved.", bool removeSolveBasedModules = true) { IRCConnection.Instance.SendMessage("{0}{1}", reason, removeSolveBasedModules ? " Some other modules may also be solved to prevent problems." : ""); SolveSilently(); if (removeSolveBasedModules) { TwitchComponentHandle.RemoveSolveBasedModules(); } }
private Vector3 GetIdealPositionForHandle(TwitchComponentHandle thisHandle, IList bombComponents, out TwitchComponentHandle.Direction direction) { Rect handleBasicRect = new Rect(-0.155f, -0.1f, 0.31f, 0.2f); Rect bombComponentBasicRect = new Rect(-0.1f, -0.1f, 0.2f, 0.2f); float baseUp = (handleBasicRect.height + bombComponentBasicRect.height) * 0.55f; float baseRight = (handleBasicRect.width + bombComponentBasicRect.width) * 0.55f; Vector2 extentUp = new Vector2(0.0f, baseUp * 0.1f); Vector2 extentRight = new Vector2(baseRight * 0.2f, 0.0f); Vector2 extentResult = Vector2.zero; while (true) { Rect handleRect = handleBasicRect; handleRect.position += extentRight; if (!HasOverlap(thisHandle, handleRect, bombComponentBasicRect, bombComponents)) { extentResult = extentRight; direction = TwitchComponentHandle.Direction.Left; break; } handleRect = handleBasicRect; handleRect.position -= extentRight; if (!HasOverlap(thisHandle, handleRect, bombComponentBasicRect, bombComponents)) { extentResult = -extentRight; direction = TwitchComponentHandle.Direction.Right; break; } handleRect = handleBasicRect; handleRect.position += extentUp; if (!HasOverlap(thisHandle, handleRect, bombComponentBasicRect, bombComponents)) { extentResult = extentUp; direction = TwitchComponentHandle.Direction.Down; break; } handleRect = handleBasicRect; handleRect.position -= extentUp; if (!HasOverlap(thisHandle, handleRect, bombComponentBasicRect, bombComponents)) { extentResult = -extentUp; direction = TwitchComponentHandle.Direction.Up; break; } extentUp.y += baseUp * 0.1f; extentRight.x += baseRight * 0.1f; } return(new Vector3(extentResult.x, 0.0f, extentResult.y)); }
public static void DeactivateNeedyModule(TwitchComponentHandle handle) { handle.ircConnection.SendMessage(TwitchPlaySettings.data.UnsupportedNeedyWarning); KMNeedyModule needyModule = handle.bombComponent.GetComponent <KMNeedyModule>(); needyModule.OnNeedyActivation = () => { needyModule.StartCoroutine(KeepUnsupportedNeedySilent(needyModule)); }; needyModule.OnNeedyDeactivation = () => { needyModule.StopAllCoroutines(); needyModule.HandlePass(); }; needyModule.OnTimerExpired = () => { needyModule.StopAllCoroutines(); needyModule.HandlePass(); }; needyModule.WarnAtFiveSeconds = false; }
public static void HandleForcedSolve(TwitchComponentHandle handle) { try { if (!(handle?.Solver?.AttemptedForcedSolve ?? false) && (handle?.Solver?.HandleForcedSolve() ?? false)) { handle.Solver.AttemptedForcedSolve = true; return; } if (!(handle?.Solver?.AttemptedForcedSolve ?? false) && handle?.Solver?.ForcedSolveMethod != null) { handle.Solver.AttemptedForcedSolve = true; handle.Solver._delegatedSolveUserNickName = null; handle.Solver._currentUserNickName = null; handle.Solver._silentlySolve = true; try { handle.Solver.ForcedSolveMethod.Invoke(handle.Solver.CommandComponent, null); } catch (Exception ex) { DebugHelper.LogException(ex, "An exception occured while using the Forced Solve handler:"); CommonReflectedTypeInfo.HandlePassMethod.Invoke(handle.Solver.BombComponent, null); foreach (MonoBehaviour behavior in handle.bombComponent.GetComponentsInChildren <MonoBehaviour>(true)) { behavior.StopAllCoroutines(); } } } else if (handle?.Solver != null) { handle.Solver._delegatedSolveUserNickName = null; handle.Solver._currentUserNickName = null; handle.Solver._silentlySolve = true; CommonReflectedTypeInfo.HandlePassMethod.Invoke(handle.bombComponent, null); foreach (MonoBehaviour behavior in handle.bombComponent.GetComponentsInChildren <MonoBehaviour>(true)) { behavior.StopAllCoroutines(); } } else if (handle != null) { CommonReflectedTypeInfo.HandlePassMethod.Invoke(handle.bombComponent, null); foreach (MonoBehaviour behavior in handle.bombComponent.GetComponentsInChildren <MonoBehaviour>(true)) { behavior.StopAllCoroutines(); } } } catch (Exception ex) { DebugHelper.LogException(ex, "An exception occured while silently soving a module:"); } }
private bool CreateComponentHandlesForBomb(Bomb bomb) { bool foundComponents = false; List <BombComponent> bombComponents = bomb.BombComponents; var bombCommander = _bombCommanders[_bombCommanders.Count - 1]; if (bombComponents.Count > 12 || TwitchPlaySettings.data.ForceMultiDeckerMode) { bombCommander.multiDecker = true; } foreach (BombComponent bombComponent in bombComponents) { ComponentTypeEnum componentType = bombComponent.ComponentType; switch (componentType) { case ComponentTypeEnum.Empty: continue; case ComponentTypeEnum.Timer: _bombCommanders[_bombCommanders.Count - 1].timerComponent = (TimerComponent)bombComponent; continue; default: foundComponents = true; break; } TwitchComponentHandle handle = Instantiate <TwitchComponentHandle>(twitchComponentHandlePrefab, bombComponent.transform, false); handle.ircConnection = _ircConnection; handle.bombCommander = bombCommander; handle.bombComponent = bombComponent; handle.componentType = componentType; handle.coroutineQueue = _coroutineQueue; handle.coroutineCanceller = _coroutineCanceller; handle.leaderboard = leaderboard; handle.bombID = _currentBomb == -1 ? -1 : _bombCommanders.Count - 1; Vector3 idealOffset = handle.transform.TransformDirection(GetIdealPositionForHandle(handle, bombComponents, out handle.direction)); handle.transform.SetParent(bombComponent.transform.parent, true); handle.basePosition = handle.transform.localPosition; handle.idealHandlePositionOffset = bombComponent.transform.parent.InverseTransformDirection(idealOffset); bombCommander.bombSolvableModules++; _componentHandles.Add(handle); } return(foundComponents); }
private bool CreateComponentHandlesForBomb(MonoBehaviour bomb) { bool foundComponents = false; IList bombComponents = (IList)CommonReflectedTypeInfo.BombComponentsField.GetValue(bomb); if (bombComponents.Count > 12) { _bombCommanders[_bombCommanders.Count - 1]._multiDecker = true; } foreach (MonoBehaviour bombComponent in bombComponents) { object componentType = CommonReflectedTypeInfo.ComponentTypeField.GetValue(bombComponent); int componentTypeInt = (int)Convert.ChangeType(componentType, typeof(int)); ComponentTypeEnum componentTypeEnum = (ComponentTypeEnum)componentTypeInt; switch (componentTypeEnum) { case ComponentTypeEnum.Empty: continue; case ComponentTypeEnum.Timer: _bombCommanders[_bombCommanders.Count - 1]._timerComponent = bombComponent; continue; default: foundComponents = true; break; } TwitchComponentHandle handle = (TwitchComponentHandle)Instantiate(twitchComponentHandlePrefab, bombComponent.transform, false); handle.ircConnection = _ircConnection; handle.bombCommander = _bombCommanders[_bombCommanders.Count - 1]; handle.bombComponent = bombComponent; handle.componentType = componentTypeEnum; handle.coroutineQueue = _coroutineQueue; handle.coroutineCanceller = _coroutineCanceller; handle.leaderboard = leaderboard; handle.bombID = _currentBomb == -1 ? -1 : _bombCommanders.Count - 1; Vector3 idealOffset = handle.transform.TransformDirection(GetIdealPositionForHandle(handle, bombComponents, out handle.direction)); handle.transform.SetParent(bombComponent.transform.parent, true); handle.basePosition = handle.transform.localPosition; handle.idealHandlePositionOffset = bombComponent.transform.parent.InverseTransformDirection(idealOffset); handle.bombCommander._bombSolvableModules++; _componentHandles.Add(handle); } return(foundComponents); }
protected void SolveModule(string reason = "A module is being automatically solved.", bool removeSolveBasedModules = true) { IRCConnection.SendMessage("{0}{1}", reason, removeSolveBasedModules ? " Some other modules may also be solved to prevent problems." : ""); _currentUserNickName = null; _delegatedSolveUserNickName = null; if (removeSolveBasedModules) { TwitchComponentHandle.RemoveSolveBasedModules(); } CommonReflectedTypeInfo.HandlePassMethod.Invoke(BombComponent, null); }
private bool HasOverlap(TwitchComponentHandle thisHandle, Rect handleRect, Rect bombComponentBasicRect, IList bombComponents) { foreach (MonoBehaviour bombComponent in bombComponents) { Vector3 bombComponentCenter = thisHandle.transform.InverseTransformPoint(bombComponent.transform.position); Rect bombComponentRect = bombComponentBasicRect; bombComponentRect.position += new Vector2(bombComponentCenter.x, bombComponentCenter.z); if (bombComponentRect.Overlaps(handleRect)) { return(true); } } return(false); }
private void OnDisable() { _hideBombs = false; BombActive = false; EnableDisableInput(); TwitchComponentHandle.ClaimedList.Clear(); TwitchComponentHandle.ClearUnsupportedModules(); StopAllCoroutines(); Leaderboard.Instance.BombsAttempted++; parentService.GetComponent <KMGameInfo>().OnLightsChange -= OnLightsChange; LogUploader.Instance.Post(); parentService.StartCoroutine(SendDelayedMessage(1.0f, GetBombResult(), SendAnalysisLink)); moduleCameras?.gameObject.SetActive(false); foreach (TwitchBombHandle handle in BombHandles) { if (handle != null) { Destroy(handle.gameObject, 2.0f); } } BombHandles.Clear(); BombCommanders.Clear(); DestroyComponentHandles(); MusicPlayer.StopAllMusic(); GameRoom.Instance?.OnDisable(); OtherModes.RefreshModes(); try { string path = Path.Combine(Application.persistentDataPath, "TwitchPlaysLastClaimed.json"); File.WriteAllText(path, SettingsConverter.Serialize(LastClaimedModule)); } catch (Exception ex) { DebugHelper.LogException(ex, "Couldn't Write TwitchPlaysLastClaimed.json:"); } }
public void AttachToModule(BombComponent component, TwitchComponentHandle handle, int priority = CameraInUse) { if (handle != null && (handle.claimed) && (priority == CameraClaimed)) { priority = CameraClaimed; } int existingCamera = CurrentModulesContains(component); if (existingCamera > -1) { ModuleCamera cam = cameras[existingCamera]; if (cam.priority < priority) { cam.priority = priority; cam.module.priority = priority; } cam.index = ++index; cam.module.index = cam.index; return; } ModuleCamera camera = AvailableCamera(priority); try { // If the camera is in use, return its module to the appropriate stack if ((camera.priority > CameraNotInUse) && (camera.module.component != null)) { camera.module.index = camera.index; AddModuleToStack(camera.module.component, camera.module.handle, camera.priority); camera.priority = CameraNotInUse; } // Add the new module to the stack AddModuleToStack(component, handle, priority); // Refresh the camera camera.Refresh(); } catch (Exception e) { Debug.Log(LogPrefix + "Error: " + e.Message); } }
private IEnumerator CheckForBomb() { TwitchComponentHandle.ResetId(); UnityEngine.Object[] bombs; do { yield return(null); bombs = FindObjectsOfType(CommonReflectedTypeInfo.BombType); if (bombs.Length > 0) { yield return(new WaitForSeconds(0.1f)); bombs = FindObjectsOfType(CommonReflectedTypeInfo.BombType); } System.Random rand = new System.Random(); if (bombs.Length == 1) { _currentBomb = -1; SetBomb((MonoBehaviour)bombs[0], -1); if (rand.NextDouble() < specialNameProbability) { _bombHandles[0].nameText.text = singleNames[rand.Next(0, singleNames.Length - 1)]; } _coroutineQueue.AddToQueue(_bombHandles[0].OnMessageReceived(_bombHandles[0].nameText.text, "red", "!bomb hold"), -1); } else { _currentBomb = 0; int id = 0; for (var i = bombs.Length - 1; i >= 0; i--) { SetBomb((MonoBehaviour)bombs[i], id++); } if (rand.NextDouble() < specialNameProbability) { int nameIndex = rand.Next(0, doubleNames.Length - 1); string nameText = null; for (int i = 0; i < 2; i++) { nameText = doubleNames[nameIndex, i]; if (nameText != null) { _bombHandles[i].nameText.text = nameText; } } } else { _bombHandles[1].nameText.text = "The Other Bomb"; } _coroutineQueue.AddToQueue(_bombHandles[0].OnMessageReceived(_bombHandles[0].nameText.text, "red", "!bomb hold"), 0); } } while (bombs == null || bombs.Length == 0); moduleCameras = Instantiate <ModuleCameras>(moduleCamerasPrefab); }
private IEnumerator CheckForBomb() { yield return(new WaitUntil(() => (SceneManager.Instance.GameplayState.Bombs != null && SceneManager.Instance.GameplayState.Bombs.Count > 0))); List <Bomb> bombs = SceneManager.Instance.GameplayState.Bombs; for (int i = 0; i < GameRoom.GameRoomTypes.Length; i++) { if (GameRoom.GameRoomTypes[i]() != null && GameRoom.CreateRooms[i](FindObjectsOfType(GameRoom.GameRoomTypes[i]()), out GameRoom.Instance)) { GameRoom.Instance.InitializeBombs(bombs); break; } } try { GameRoom.Instance.InitializeBombNames(); } catch (Exception ex) { DebugHelper.LogException(ex, "An exception has occured while setting the bomb names"); } StartCoroutine(GameRoom.Instance.ReportBombStatus()); try { if (GameRoom.Instance.HoldBomb) { _coroutineQueue.AddToQueue(BombHandles[0].OnMessageReceived(BombHandles[0].nameText.text, "red", "bomb hold"), _currentBomb); } } catch (Exception ex) { DebugHelper.LogException(ex, "An exception has occured attempting to hold the bomb."); } try { moduleCameras = Instantiate <ModuleCameras>(moduleCamerasPrefab); } catch (Exception ex) { DebugHelper.LogException(ex, "Failed to Instantiate the module camera system due to an exception:"); moduleCameras = null; } moduleCameras?.ChangeBomb(BombCommanders[0]); for (int i = 0; i < 4; i++) { _notesDictionary[i] = (OtherModes.ZenModeOn && i == 3) ? TwitchPlaySettings.data.ZenModeFreeSpace : TwitchPlaySettings.data.NotesSpaceFree; moduleCameras?.SetNotes(i, _notesDictionary[i]); } if (EnableDisableInput()) { TwitchComponentHandle.SolveUnsupportedModules(true); } while (OtherModes.ZenModeOn) { foreach (BombCommander bomb in BombCommanders) { if (bomb.timerComponent == null || bomb.timerComponent.GetRate() < 0) { continue; } bomb.timerComponent.SetRateModifier(-bomb.timerComponent.GetRate()); } yield return(null); } }
protected override void OnMessageReceived(string userNickName, string userColorCode, string text) { Match match; int index; if (!text.StartsWith("!") || text.Equals("!")) { return; } text = text.Substring(1); if (IsAuthorizedDefuser(userNickName)) { if (text.RegexMatch(out match, "^notes(-?[0-9]+) (.+)$") && int.TryParse(match.Groups[1].Value, out index)) { string notes = match.Groups[2].Value; IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.NotesTaken, index--, notes); _notesDictionary[index] = notes; moduleCameras?.SetNotes(index, notes); return; } if (text.RegexMatch(out match, "^notes(-?[0-9]+)append (.+)", "^appendnotes(-?[0-9]+) (.+)") && int.TryParse(match.Groups[1].Value, out index)) { string notes = match.Groups[2].Value; IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.NotesAppended, index--, notes); if (!_notesDictionary.ContainsKey(index)) { _notesDictionary[index] = TwitchPlaySettings.data.NotesSpaceFree; } _notesDictionary[index] += " " + notes; moduleCameras?.AppendNotes(index, notes); return; } if (text.RegexMatch(out match, "^clearnotes(-?[0-9]+)$", "^notes(-?[0-9]+)clear$") && int.TryParse(match.Groups[1].Value, out index)) { IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.NoteSlotCleared, index--); _notesDictionary[index] = (OtherModes.ZenModeOn && index == 3) ? TwitchPlaySettings.data.ZenModeFreeSpace : TwitchPlaySettings.data.NotesSpaceFree; moduleCameras?.SetNotes(index, _notesDictionary[index]); return; } if (text.Equals("snooze", StringComparison.InvariantCultureIgnoreCase)) { if (GameRoom.Instance is ElevatorGameRoom) { return; //There is no alarm clock in the elevator room. } DropCurrentBomb(); _coroutineQueue.AddToQueue(AlarmClockHoldableHandler.Instance.RespondToCommand(userNickName, "alarmclock snooze")); return; } if (text.Equals("modules", StringComparison.InvariantCultureIgnoreCase)) { moduleCameras?.AttachToModules(ComponentHandles); return; } if (text.RegexMatch(out match, "^claims (.+)")) { OnMessageReceived(match.Groups[1].Value, userColorCode, "!claims"); return; } if (text.Equals("claims", StringComparison.InvariantCultureIgnoreCase)) { List <string> claimed = ( from handle in ComponentHandles where handle.PlayerName != null && handle.PlayerName.Equals(userNickName, StringComparison.InvariantCultureIgnoreCase) && !handle.Solved select string.Format(TwitchPlaySettings.data.OwnedModule, handle.Code, handle.HeaderText)).ToList(); if (claimed.Count > 0) { string message = string.Format(TwitchPlaySettings.data.OwnedModuleList, userNickName, string.Join(", ", claimed.ToArray(), 0, Math.Min(claimed.Count, 5))); if (claimed.Count > 5) { message += "..."; } IRCConnection.Instance.SendMessage(message); } else { IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.NoOwnedModules, userNickName); } return; } if (text.RegexMatch("^(?:claim ?|view ?|all ?){2,3}$")) { if (text.Contains("claim") && text.Contains("all")) { foreach (var handle in ComponentHandles) { if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.AddToClaimQueue(userNickName, text.Contains("view")); } return; } } if (text.StartsWith("claim ", StringComparison.InvariantCultureIgnoreCase)) { var split = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in split.Skip(1)) { TwitchComponentHandle handle = ComponentHandles.FirstOrDefault(x => x.Code.Equals(claim, StringComparison.InvariantCultureIgnoreCase)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.AddToClaimQueue(userNickName); } return; } if (text.RegexMatch("^(unclaim|release) ?all$")) { foreach (TwitchComponentHandle handle in ComponentHandles) { handle.RemoveFromClaimQueue(userNickName); } string[] moduleIDs = ComponentHandles.Where(x => !x.Solved && x.PlayerName != null && x.PlayerName.Equals(userNickName, StringComparison.InvariantCultureIgnoreCase)) .Select(x => x.Code).ToArray(); text = string.Format("unclaim {0}", string.Join(" ", moduleIDs)); } if (text.RegexMatch(out match, "^(?:unclaim|release) (.+)")) { var split = match.Groups[1].Value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in split) { TwitchComponentHandle handle = ComponentHandles.FirstOrDefault(x => x.Code.Equals(claim)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.OnMessageReceived(userNickName, userColorCode, "unclaim"); } return; } if (text.Equals("unclaimed", StringComparison.InvariantCultureIgnoreCase)) { IEnumerable <string> unclaimed = ComponentHandles.Where(handle => !handle.Claimed && !handle.Solved && GameRoom.Instance.IsCurrentBomb(handle.bombID)).Shuffle().Take(3) .Select(handle => string.Format($"{handle.HeaderText} ({handle.Code})")).ToList(); if (unclaimed.Any()) { IRCConnection.Instance.SendMessage("Unclaimed Modules: {0}", unclaimed.Join(", ")); } else { IRCConnection.Instance.SendMessage("There are no more unclaimed modules."); } return; } if (text.Equals("unsolved", StringComparison.InvariantCultureIgnoreCase)) { IEnumerable <string> unsolved = ComponentHandles.Where(handle => !handle.Solved && GameRoom.Instance.IsCurrentBomb(handle.bombID)).Shuffle().Take(3) .Select(handle => string.Format("{0} ({1}) - {2}", handle.HeaderText, handle.Code, handle.PlayerName == null ? "Unclaimed" : "Claimed by " + handle.PlayerName)).ToList(); if (unsolved.Any()) { IRCConnection.Instance.SendMessage("Unsolved Modules: {0}", unsolved.Join(", ")); } else { IRCConnection.Instance.SendMessage("There are no unsolved modules, something went wrong as this message should never be displayed."); //this should never happen } return; } if (text.RegexMatch(out match, "^(?:find|search) (.+)")) { string[] queries = match.Groups[1].Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (string query in queries) { string trimmed = query.Trim(); IEnumerable <string> modules = ComponentHandles.Where(handle => handle.HeaderText.ContainsIgnoreCase(trimmed) && GameRoom.Instance.IsCurrentBomb(handle.bombID)) .OrderByDescending(handle => handle.HeaderText.EqualsIgnoreCase(trimmed)).ThenBy(handle => handle.Solved).ThenBy(handle => handle.PlayerName != null).Take(3) .Select(handle => string.Format("{0} ({1}) - {2}", handle.HeaderText, handle.Code, handle.Solved ? "Solved" : (handle.PlayerName == null ? "Unclaimed" : "Claimed by " + handle.PlayerName) )).ToList(); if (modules.Any()) { IRCConnection.Instance.SendMessage("Modules: {0}", modules.Join(", ")); } else { IRCConnection.Instance.SendMessage($"Couldn't find any modules containing \"{trimmed}\"."); } } return; } if (text.RegexMatch(out match, "^(?:findplayer|playerfind|searchplayer|playersearch) (.+)")) { string[] queries = match.Groups[1].Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray(); foreach (string query in queries) { string trimmed = query.Trim(); IEnumerable <TwitchComponentHandle> modules = ComponentHandles.Where(handle => handle.HeaderText.ContainsIgnoreCase(trimmed) && GameRoom.Instance.IsCurrentBomb(handle.bombID)) .OrderByDescending(handle => handle.HeaderText.EqualsIgnoreCase(trimmed)).ThenBy(handle => handle.Solved).ToList(); IEnumerable <string> playerModules = modules.Where(handle => handle.PlayerName != null).OrderByDescending(handle => handle.HeaderText.EqualsIgnoreCase(trimmed)) .Select(handle => string.Format($"{handle.HeaderText} ({handle.Code}) - Claimed by {handle.PlayerName}")).ToList(); if (modules.Any()) { if (playerModules.Any()) { IRCConnection.Instance.SendMessage("Modules: {0}", playerModules.Join(", ")); } else { IRCConnection.Instance.SendMessage("None of the specified modules are claimed/have been solved."); } } else { IRCConnection.Instance.SendMessage($"Could not find any modules containing \"{trimmed}\"."); } } } if (text.RegexMatch(out match, "^(claim ?(?:any|van|mod) ?(?:view)?|view ?claim ?(?:any|van|mod))")) { var vanilla = match.Groups[1].Value.Contains("van"); var modded = match.Groups[1].Value.Contains("mod"); var view = match.Groups[1].Value.Contains("view"); var avoid = new[] { "Souvenir", "Forget Me Not", "Turn The Key", "Turn The Keys", "The Swan", "Forget Everything" }; var unclaimed = ComponentHandles .Where(handle => (vanilla ? !handle.IsMod : modded ? handle.IsMod : true) && !handle.Claimed && !handle.Solved && !avoid.Contains(handle.HeaderText) && GameRoom.Instance.IsCurrentBomb(handle.bombID)) .Shuffle().FirstOrDefault(); if (unclaimed != null) { text = unclaimed.Code + (view ? " claimview" : " claim"); } else { IRCConnection.Instance.SendMessage(string.Format("There are no more unclaimed{0} modules.", vanilla ? " vanilla" : modded ? " modded" : null)); } } if (text.RegexMatch(out match, "^(?:findsolved|solvedfind|searchsolved|solvedsearch) (.+)")) { string[] queries = match.Groups[1].Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray(); foreach (string query in queries) { string trimmed = query.Trim(); IEnumerable <BombCommander> commanders = BombCommanders.Where(handle => handle.SolvedModules.Keys.ToArray().Any(x => x.ContainsIgnoreCase(trimmed))).ToList(); IEnumerable <TwitchComponentHandle> modules = commanders.SelectMany(x => x.SolvedModules.Where(y => y.Key.ContainsIgnoreCase(trimmed))) .OrderByDescending(x => x.Key.EqualsIgnoreCase(trimmed)).SelectMany(x => x.Value).ToList(); IEnumerable <string> playerModules = modules.Where(handle => handle.PlayerName != null) .Select(handle => string.Format($"{handle.HeaderText} ({handle.Code}) - Claimed by {handle.PlayerName}", handle.HeaderText, handle.Code, "Claimed by " + handle.PlayerName)).ToList(); if (commanders.Any()) { if (playerModules.Any()) { IRCConnection.Instance.SendMessage("Modules: {0}", playerModules.Join(", ")); } else { IRCConnection.Instance.SendMessage("None of the specified modules have been solved."); } } else { IRCConnection.Instance.SendMessage($"Could not find any modules containing \"{trimmed}\"."); } } } if (text.RegexMatch(out match, "^((?:(?:find|search)|claim|view|all){2,4}) (.+)")) { bool validFind = match.Groups[1].Value.Contains("find") || match.Groups[1].Value.Contains("search"); bool validClaim = match.Groups[1].Value.Contains("claim"); if (!validFind || !validClaim) { return; } bool validView = match.Groups[1].Value.Contains("view"); bool validAll = match.Groups[1].Value.Contains("all"); string[] queries = match.Groups[2].Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries); int counter = 0; foreach (string query in queries) { if (counter == 2) { return; } string trimmed = query.Trim(); IEnumerable <string> modules = ComponentHandles.Where(handle => handle.HeaderText.ContainsIgnoreCase(trimmed) && GameRoom.Instance.IsCurrentBomb(handle.bombID) && !handle.Solved && !handle.Claimed) .OrderByDescending(handle => handle.HeaderText.EqualsIgnoreCase(trimmed)).Select(handle => $"{handle.Code}").ToList(); if (modules.Any()) { if (!validAll) { modules = modules.Take(1); } foreach (string module in modules) { TwitchComponentHandle handle = ComponentHandles.FirstOrDefault(x => x.Code.Equals(module)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.AddToClaimQueue(userNickName, validView); } if (validAll) { counter++; } } else { IRCConnection.Instance.SendMessage($"Couldn't find any modules containing \"{trimmed}\"."); } } return; } if (text.Equals("newbomb", StringComparison.InvariantCultureIgnoreCase) && OtherModes.ZenModeOn) { TwitchPlaySettings.SetRewardBonus(0); foreach (var handle in ComponentHandles.Where(x => GameRoom.Instance.IsCurrentBomb(x.bombID))) { if (!handle.Solved) { handle.SolveSilently(); } } return; } } if (text.RegexMatch(out match, "^notes(-?[0-9]+)$") && int.TryParse(match.Groups[1].Value, out index)) { if (!_notesDictionary.ContainsKey(index - 1)) { _notesDictionary[index - 1] = TwitchPlaySettings.data.NotesSpaceFree; } IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.Notes, index, _notesDictionary[index - 1]); return; } switch (UserAccess.HighestAccessLevel(userNickName)) { case AccessLevel.Streamer: case AccessLevel.SuperUser: if (text.RegexMatch(out match, @"^setmultiplier ([0-9]+(?:\.[0-9]+)*)$")) { OtherModes.SetMultiplier(float.Parse(match.Groups[1].Value)); return; } if (text.Equals("solvebomb", StringComparison.InvariantCultureIgnoreCase)) { foreach (var handle in ComponentHandles.Where(x => GameRoom.Instance.IsCurrentBomb(x.bombID))) { if (!handle.Solved) { handle.SolveSilently(); } } return; } goto case AccessLevel.Admin; case AccessLevel.Admin: if (text.Equals("enablecamerawall", StringComparison.InvariantCultureIgnoreCase) || text.Equals("enablemodulewall", StringComparison.InvariantCultureIgnoreCase)) { moduleCameras.EnableWallOfCameras(); StartCoroutine(HideBombs()); } if (text.Equals("disablecamerawall", StringComparison.InvariantCultureIgnoreCase) || text.Equals("disablemodulewall", StringComparison.InvariantCultureIgnoreCase)) { moduleCameras.DisableWallOfCameras(); _hideBombs = false; } goto case AccessLevel.Mod; case AccessLevel.Mod: if (text.RegexMatch(out match, @"^assign (\S+) (.+)")) { var split = match.Groups[2].Value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var assign in split) { TwitchComponentHandle handle = ComponentHandles.FirstOrDefault(x => x.Code.Equals(assign)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.OnMessageReceived(userNickName, userColorCode, string.Format("assign {0}", match.Groups[1].Value)); } return; } if (text.RegexMatch("^bot ?unclaim( ?all)?$")) { userNickName = IRCConnection.Instance.UserNickName; foreach (TwitchComponentHandle handle in ComponentHandles) { handle.RemoveFromClaimQueue(userNickName); } string[] moduleIDs = ComponentHandles.Where(x => !x.Solved && x.PlayerName != null && x.PlayerName.Equals(userNickName, StringComparison.InvariantCultureIgnoreCase)) .Select(x => x.Code).ToArray(); foreach (var claim in moduleIDs) { TwitchComponentHandle handle = ComponentHandles.FirstOrDefault(x => x.Code.Equals(claim)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.OnMessageReceived(userNickName, userColorCode, "unclaim"); } return; } if (text.Equals("filledgework", StringComparison.InvariantCultureIgnoreCase)) { foreach (var commander in BombCommanders) { commander.FillEdgework(_currentBomb != commander.twitchBombHandle.bombID); } return; } break; } GameRoom.Instance.RefreshBombID(ref _currentBomb); if (_currentBomb > -1) { //Check for !bomb messages, and pass them off to the currently held bomb. if (text.RegexMatch(out match, "^bomb (.+)")) { string internalCommand = match.Groups[1].Value; text = string.Format("bomb{0} {1}", _currentBomb + 1, internalCommand); } if (text.RegexMatch(out match, "^edgework$")) { text = string.Format("edgework{0}", _currentBomb + 1); } else { if (text.RegexMatch(out match, "^edgework (.+)")) { string internalCommand = match.Groups[1].Value; text = string.Format("edgework{0} {1}", _currentBomb + 1, internalCommand); } } } foreach (TwitchBombHandle handle in BombHandles) { if (handle == null) { continue; } IEnumerator onMessageReceived = handle.OnMessageReceived(userNickName, userColorCode, text); if (onMessageReceived == null) { continue; } if (_currentBomb != handle.bombID) { if (!GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } _coroutineQueue.AddToQueue(BombHandles[_currentBomb].HideMainUIWindow(), handle.bombID); _coroutineQueue.AddToQueue(handle.ShowMainUIWindow(), handle.bombID); _coroutineQueue.AddToQueue(BombCommanders[_currentBomb].LetGoBomb(), handle.bombID); _currentBomb = handle.bombID; } _coroutineQueue.AddToQueue(onMessageReceived, handle.bombID); } foreach (TwitchComponentHandle componentHandle in ComponentHandles) { if (!GameRoom.Instance.IsCurrentBomb(componentHandle.bombID)) { continue; } if (!text.StartsWith(componentHandle.Code + " ")) { continue; } IEnumerator onMessageReceived = componentHandle.OnMessageReceived(userNickName, userColorCode, text.Substring(componentHandle.Code.Length + 1)); if (onMessageReceived == null) { continue; } if (_currentBomb != componentHandle.bombID) { _coroutineQueue.AddToQueue(BombHandles[_currentBomb].HideMainUIWindow(), componentHandle.bombID); _coroutineQueue.AddToQueue(BombHandles[componentHandle.bombID].ShowMainUIWindow(), componentHandle.bombID); _coroutineQueue.AddToQueue(BombCommanders[_currentBomb].LetGoBomb(), componentHandle.bombID); _currentBomb = componentHandle.bombID; } _coroutineQueue.AddToQueue(onMessageReceived, componentHandle.bombID); } if (TwitchPlaySettings.data.BombCustomMessages.ContainsKey(text.ToLowerInvariant())) { IRCConnection.Instance.SendMessage(TwitchPlaySettings.data.BombCustomMessages[text.ToLowerInvariant()]); } }
private void OnDisable() { BombActive = false; EnableDisableInput(); TwitchComponentHandle.ClaimedList.Clear(); TwitchComponentHandle.ClearUnsupportedModules(); StopAllCoroutines(); leaderboard.BombsAttempted++; string bombMessage = null; bool HasDetonated = false; bool HasBeenSolved = true; var timeStarting = float.MaxValue; var timeRemaining = float.MaxValue; var timeRemainingFormatted = ""; TwitchPlaysService.logUploader.Post(); foreach (var commander in _bombCommanders) { HasDetonated |= commander.Bomb.HasDetonated; HasBeenSolved &= commander.IsSolved; if (timeRemaining > commander.CurrentTimer) { timeStarting = commander.bombStartingTimer; timeRemaining = commander.CurrentTimer; } if (!string.IsNullOrEmpty(timeRemainingFormatted)) { timeRemainingFormatted += ", " + commander.GetFullFormattedTime; } else { timeRemainingFormatted = commander.GetFullFormattedTime; } } if (HasDetonated) { bombMessage = string.Format(TwitchPlaySettings.data.BombExplodedMessage, timeRemainingFormatted); leaderboard.BombsExploded += _bombCommanders.Count; leaderboard.Success = false; TwitchPlaySettings.ClearPlayerLog(); } else if (HasBeenSolved) { bombMessage = string.Format(TwitchPlaySettings.data.BombDefusedMessage, timeRemainingFormatted); bombMessage += TwitchPlaySettings.GiveBonusPoints(leaderboard); leaderboard.BombsCleared += _bombCommanders.Count; leaderboard.Success = true; if (leaderboard.CurrentSolvers.Count == 1) { float previousRecord = 0.0f; float elapsedTime = timeStarting - timeRemaining; string userName = ""; foreach (string uName in leaderboard.CurrentSolvers.Keys) { userName = uName; break; } if (leaderboard.CurrentSolvers[userName] == (Leaderboard.RequiredSoloSolves * _bombCommanders.Count)) { leaderboard.AddSoloClear(userName, elapsedTime, out previousRecord); if (TwitchPlaySettings.data.EnableSoloPlayMode) { //Still record solo information, should the defuser be the only one to actually defuse a 11 * bomb-count bomb, but display normal leaderboards instead if //solo play is disabled. TimeSpan elapsedTimeSpan = TimeSpan.FromSeconds(elapsedTime); string soloMessage = string.Format(TwitchPlaySettings.data.BombSoloDefusalMessage, leaderboard.SoloSolver.UserName, (int)elapsedTimeSpan.TotalMinutes, elapsedTimeSpan.Seconds); if (elapsedTime < previousRecord) { TimeSpan previousTimeSpan = TimeSpan.FromSeconds(previousRecord); soloMessage += string.Format(TwitchPlaySettings.data.BombSoloDefusalNewRecordMessage, (int)previousTimeSpan.TotalMinutes, previousTimeSpan.Seconds); } soloMessage += TwitchPlaySettings.data.BombSoloDefusalFooter; parentService.StartCoroutine(SendDelayedMessage(1.0f, soloMessage)); } else { leaderboard.ClearSolo(); } } else { leaderboard.ClearSolo(); } } } else { bombMessage = string.Format(TwitchPlaySettings.data.BombAbortedMessage, timeRemainingFormatted); leaderboard.Success = false; TwitchPlaySettings.ClearPlayerLog(); } parentService.StartCoroutine(SendDelayedMessage(1.0f, bombMessage, SendAnalysisLink)); moduleCameras?.gameObject.SetActive(false); foreach (TwitchBombHandle handle in _bombHandles) { if (handle != null) { Destroy(handle.gameObject, 2.0f); } } _bombHandles.Clear(); _bombCommanders.Clear(); if (_componentHandles != null) { foreach (TwitchComponentHandle handle in _componentHandles) { Destroy(handle.gameObject, 2.0f); } _componentHandles.Clear(); } MusicPlayer.StopAllMusic(); }
public bool CreateComponentHandlesForBomb(Bomb bomb) { string[] keyModules = { "SouvenirModule", "MemoryV2", "TurnTheKey", "TurnTheKeyAdvanced", "theSwan", "HexiEvilFMN" }; bool foundComponents = false; List <BombComponent> bombComponents = bomb.BombComponents.Shuffle().ToList(); var bombCommander = BombCommanders[BombCommanders.Count - 1]; foreach (BombComponent bombComponent in bombComponents) { ComponentTypeEnum componentType = bombComponent.ComponentType; bool keyModule = false; string moduleName = ""; switch (componentType) { case ComponentTypeEnum.Empty: continue; case ComponentTypeEnum.Timer: BombCommanders[BombCommanders.Count - 1].timerComponent = (TimerComponent)bombComponent; continue; case ComponentTypeEnum.NeedyCapacitor: case ComponentTypeEnum.NeedyKnob: case ComponentTypeEnum.NeedyVentGas: case ComponentTypeEnum.NeedyMod: moduleName = bombComponent.GetModuleDisplayName(); keyModule = true; foundComponents = true; break; case ComponentTypeEnum.Mod: KMBombModule module = bombComponent.GetComponent <KMBombModule>(); keyModule = keyModules.Contains(module.ModuleType); goto default; default: moduleName = bombComponent.GetModuleDisplayName(); bombCommander.bombSolvableModules++; foundComponents = true; break; } if (!bombCommander.SolvedModules.ContainsKey(moduleName)) { bombCommander.SolvedModules[moduleName] = new List <TwitchComponentHandle>(); } TwitchComponentHandle handle = Instantiate <TwitchComponentHandle>(twitchComponentHandlePrefab, bombComponent.transform, false); handle.bombCommander = bombCommander; handle.bombComponent = bombComponent; handle.componentType = componentType; handle.coroutineQueue = _coroutineQueue; handle.bombID = _currentBomb == -1 ? -1 : BombCommanders.Count - 1; handle.IsKey = keyModule; handle.transform.SetParent(bombComponent.transform.parent, true); handle.basePosition = handle.transform.localPosition; ComponentHandles.Add(handle); } return(foundComponents); }
protected override void OnMessageReceived(string userNickName, string userColorCode, string text) { if (text.EqualsAny("!notes1", "!notes2", "!notes3", "!notes4")) { int index = "1234".IndexOf(text.Substring(6, 1), StringComparison.Ordinal); _ircConnection.SendMessage(TwitchPlaySettings.data.Notes, index + 1, _notes[index]); return; } if (text.StartsWith("!notes1 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes2 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes3 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes4 ", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } int index = "1234".IndexOf(text.Substring(6, 1), StringComparison.Ordinal); string notes = text.Substring(8); if (notes == "") { return; } _ircConnection.SendMessage(TwitchPlaySettings.data.NotesTaken, index + 1, notes); _notes[index] = notes; moduleCameras?.SetNotes(index, notes); return; } if (text.StartsWith("!appendnotes1 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!appendnotes2 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!appendnotes3 ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!appendnotes4 ", StringComparison.InvariantCultureIgnoreCase)) { text = text.Substring(0, 1) + text.Substring(7, 6) + text.Substring(1, 6) + text.Substring(13); } if (text.StartsWith("!notes1append ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes2append ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes3append ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!notes4append ", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } int index = "1234".IndexOf(text.Substring(6, 1), StringComparison.Ordinal); string notes = text.Substring(14); if (notes == "") { return; } _ircConnection.SendMessage(TwitchPlaySettings.data.NotesAppended, index + 1, notes); _notes[index] += " " + notes; moduleCameras?.AppendNotes(index, notes); return; } if (text.EqualsAny("!clearnotes1", "!clearnotes2", "!clearnotes3", "!clearnotes4")) { text = text.Substring(0, 1) + text.Substring(6, 6) + text.Substring(1, 5); } if (text.EqualsAny("!notes1clear", "!notes2clear", "!notes3clear", "!notes4clear")) { if (!IsAuthorizedDefuser(userNickName)) { return; } int index = "1234".IndexOf(text.Substring(6, 1), StringComparison.Ordinal); _notes[index] = TwitchPlaySettings.data.NotesSpaceFree; _ircConnection.SendMessage(TwitchPlaySettings.data.NoteSlotCleared, index + 1); moduleCameras?.SetNotes(index, TwitchPlaySettings.data.NotesSpaceFree); return; } if (text.Equals("!snooze", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } if (TwitchPlaySettings.data.AllowSnoozeOnly) { alarmClock.TurnOff(); } else { alarmClock.ButtonDown(0); } return; } if (text.Equals("!stop", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName, true)) { return; } _currentBomb = _coroutineQueue.CurrentBombID; return; } if (text.Equals("!modules", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } moduleCameras?.AttachToModules(_componentHandles); return; } if (text.StartsWith("!claims ", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } userNickName = text.Substring(8); text = "!claims"; if (userNickName == "") { return; } } if (text.Equals("!claims", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } List <string> claimed = (from handle in _componentHandles where handle.PlayerName != null && handle.PlayerName.Equals(userNickName, StringComparison.InvariantCultureIgnoreCase) && !handle.Solved select string.Format(TwitchPlaySettings.data.OwnedModule, handle.idText.text.Replace("!", ""), handle.headerText.text)).ToList(); if (claimed.Count > 0) { string message = string.Format(TwitchPlaySettings.data.OwnedModuleList, userNickName, string.Join(", ", claimed.ToArray(), 0, Math.Min(claimed.Count, 5))); if (claimed.Count > 5) { message += "..."; } _ircConnection.SendMessage(message); } else { _ircConnection.SendMessage(TwitchPlaySettings.data.NoOwnedModules, userNickName); } return; } if (text.StartsWith("!claim ", StringComparison.InvariantCultureIgnoreCase)) { var split = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in split.Skip(1)) { TwitchComponentHandle handle = _componentHandles.FirstOrDefault(x => x.Code.Equals(claim)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.OnMessageReceived(userNickName, userColorCode, string.Format("!{0} claim", claim)); } return; } if (text.EqualsAny("!unclaim all", "!release all", "!unclaimall", "!releaseall")) { string[] moduleIDs = _componentHandles.Where(x => x.PlayerName != null && x.PlayerName.Equals(userNickName, StringComparison.InvariantCultureIgnoreCase)) .Select(x => x.Code).ToArray(); text = string.Format("!unclaim {0}", string.Join(" ", moduleIDs)); } if (text.StartsWith("!unclaim ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!release ", StringComparison.InvariantCultureIgnoreCase)) { var split = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in split.Skip(1)) { TwitchComponentHandle handle = _componentHandles.FirstOrDefault(x => x.Code.Equals(claim)); if (handle == null || !GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } handle.OnMessageReceived(userNickName, userColorCode, string.Format("!{0} unclaim", claim)); } return; } if (text.Equals("!unclaimed", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } IEnumerable <string> unclaimed = _componentHandles.Where(handle => !handle.claimed && !handle.Solved && GameRoom.Instance.IsCurrentBomb(handle.bombID)).Shuffle().Take(3) .Select(handle => string.Format("{0} ({1})", handle.headerText.text, handle.Code)).ToList(); if (unclaimed.Any()) { _ircConnection.SendMessage("Unclaimed Modules: {0}", unclaimed.Join(", ")); } else { _ircConnection.SendMessage("There are no more unclaimed modules."); } return; } if (text.StartsWith("!find ", StringComparison.InvariantCultureIgnoreCase) || text.StartsWith("!search ", StringComparison.InvariantCultureIgnoreCase)) { if (!IsAuthorizedDefuser(userNickName)) { return; } var split = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string query = split.Skip(1).Join(" "); IEnumerable <string> modules = _componentHandles.Where(handle => handle.headerText.text.ContainsIgnoreCase(query) && GameRoom.Instance.IsCurrentBomb(handle.bombID)) .OrderByDescending(handle => handle.headerText.text.EqualsIgnoreCase(query)).ThenBy(handle => handle.Solved).ThenBy(handle => handle.PlayerName != null).Take(3) .Select(handle => string.Format("{0} ({1}) - {2}", handle.headerText.text, handle.Code, handle.Solved ? "Solved" : (handle.PlayerName == null ? "Unclaimed" : "Claimed by " + handle.PlayerName) )).ToList(); if (modules.Any()) { _ircConnection.SendMessage("Modules: {0}", modules.Join(", ")); } else { _ircConnection.SendMessage("Couldn't find any modules containing \"{0}\".", query); } return; } if (text.Equals("!filledgework", StringComparison.InvariantCultureIgnoreCase) && UserAccess.HasAccess(userNickName, AccessLevel.Mod, true)) { foreach (var commander in _bombCommanders) { commander.FillEdgework(_currentBomb != commander.twitchBombHandle.bombID); } return; } if (text.StartsWith("!setmultiplier", StringComparison.InvariantCultureIgnoreCase) && UserAccess.HasAccess(userNickName, AccessLevel.SuperUser, true)) { float tempNumber = float.Parse(text.Substring(15)); OtherModes.setMultiplier(tempNumber); } if (text.Equals("!solvebomb", StringComparison.InvariantCultureIgnoreCase) && UserAccess.HasAccess(userNickName, AccessLevel.SuperUser, true)) { foreach (var handle in _componentHandles.Where(x => GameRoom.Instance.IsCurrentBomb(x.bombID))) { if (!handle.Solved) { handle.SolveSilently(); } } return; } GameRoom.Instance.RefreshBombID(ref _currentBomb); if (_currentBomb > -1) { //Check for !bomb messages, and pass them off to the currently held bomb. Match match = Regex.Match(text, "^!bomb (.+)", RegexOptions.IgnoreCase); if (match.Success) { string internalCommand = match.Groups[1].Value; text = string.Format("!bomb{0} {1}", _currentBomb + 1, internalCommand); } match = Regex.Match(text, "^!edgework$"); if (match.Success) { text = string.Format("!edgework{0}", _currentBomb + 1); } else { match = Regex.Match(text, "^!edgework (.+)"); if (match.Success) { string internalCommand = match.Groups[1].Value; text = string.Format("!edgework{0} {1}", _currentBomb + 1, internalCommand); } } } foreach (TwitchBombHandle handle in _bombHandles) { if (handle == null) { continue; } IEnumerator onMessageReceived = handle.OnMessageReceived(userNickName, userColorCode, text); if (onMessageReceived == null) { continue; } if (_currentBomb != handle.bombID) { if (!GameRoom.Instance.IsCurrentBomb(handle.bombID)) { continue; } _coroutineQueue.AddToQueue(_bombHandles[_currentBomb].HideMainUIWindow(), handle.bombID); _coroutineQueue.AddToQueue(handle.ShowMainUIWindow(), handle.bombID); _coroutineQueue.AddToQueue(_bombCommanders[_currentBomb].LetGoBomb(), handle.bombID); _currentBomb = handle.bombID; } _coroutineQueue.AddToQueue(onMessageReceived, handle.bombID); } foreach (TwitchComponentHandle componentHandle in _componentHandles) { if (!GameRoom.Instance.IsCurrentBomb(componentHandle.bombID)) { continue; } IEnumerator onMessageReceived = componentHandle.OnMessageReceived(userNickName, userColorCode, text); if (onMessageReceived == null) { continue; } if (_currentBomb != componentHandle.bombID) { _coroutineQueue.AddToQueue(_bombHandles[_currentBomb].HideMainUIWindow(), componentHandle.bombID); _coroutineQueue.AddToQueue(_bombHandles[componentHandle.bombID].ShowMainUIWindow(), componentHandle.bombID); _coroutineQueue.AddToQueue(_bombCommanders[_currentBomb].LetGoBomb(), componentHandle.bombID); _currentBomb = componentHandle.bombID; } _coroutineQueue.AddToQueue(onMessageReceived, componentHandle.bombID); } }
private IEnumerator CheckForBomb() { TwitchComponentHandle.ResetId(); Bomb[] bombs; do { yield return(null); bombs = FindObjectsOfType <Bomb>(); if (bombs.Length > 0) { yield return(new WaitForSeconds(0.1f)); bombs = FindObjectsOfType <Bomb>(); } for (int i = 0; i < GameRoom.GameRoomTypes.Length; i++) { if (GameRoom.GameRoomTypes[i]() != null && GameRoom.CreateRooms[i](FindObjectsOfType(GameRoom.GameRoomTypes[i]()), out GameRoom.Instance)) { break; } } _currentBomb = bombs.Length == 1 ? -1 : 0; for (int i = 0; i < bombs.Length; i++) { SetBomb(bombs[i], _currentBomb == -1 ? -1 : i); } GameRoom.Instance.InitializeBombNames(_bombHandles); StartCoroutine(GameRoom.Instance.ReportBombStatus(_bombHandles)); if (GameRoom.Instance.HoldBomb) { _coroutineQueue.AddToQueue(_bombHandles[0].OnMessageReceived(_bombHandles[0].nameText.text, "red", "!bomb hold"), _currentBomb); } } while (bombs.Length == 0); AlarmClock[] clocks; do { yield return(null); clocks = FindObjectsOfType <AlarmClock>(); } while (clocks == null || clocks.Length == 0); alarmClock = clocks[0]; try { moduleCameras = Instantiate <ModuleCameras>(moduleCamerasPrefab); } catch (Exception ex) { DebugHelper.LogException(ex, "Failed to Instantiate the module Camera system due to an Exception: "); moduleCameras = null; } for (int i = 0; i < 4; i++) { _notes[i] = TwitchPlaySettings.data.NotesSpaceFree; moduleCameras?.SetNotes(i, TwitchPlaySettings.data.NotesSpaceFree); } if (EnableDisableInput()) { TwitchComponentHandle.SolveUnsupportedModules(); } }