public static void WriteDataToFile() { if (!DataHasChanged || ComponentSolverFactory.SilentMode) { return; } string path = Path.Combine(Application.persistentDataPath, usersSavePath); DebugHelper.Log($"ModuleData: Writing file {path}"); try { List <ModuleInformation> infoList = ComponentSolverFactory.GetModuleInformation().ToList(); infoList = infoList.OrderBy(info => info.moduleDisplayName).ThenBy(info => info.moduleID).ToList(); File.WriteAllText(path, SettingsConverter.Serialize(infoList)); //JsonConvert.SerializeObject(infoList, Formatting.Indented)); } catch (FileNotFoundException) { DebugHelper.LogWarning($"ModuleData: File {path} was not found."); return; } catch (Exception ex) { DebugHelper.LogException(ex); return; } DataHasChanged = false; DebugHelper.Log($"ModuleData: Writing of file {path} completed successfully."); }
public static void WriteDataToFile() { if (!DataHasChanged || ComponentSolverFactory.SilentMode) { return; } string path = Path.Combine(Application.persistentDataPath, usersSavePath); DebugHelper.Log($"ModuleData: Writing file {path}"); try { var infoList = ComponentSolverFactory .GetModuleInformation() .OrderBy(info => info.moduleDisplayName) .ThenBy(info => info.moduleID) .Select(info => { var fileInfo = lastRead.FirstOrDefault(file => file.moduleID == info.moduleID); var dictionary = new Dictionary <string, object>(); foreach (var field in infoFields) { if (!(info.CallMethod <bool?>($"ShouldSerialize{field.Name}") ?? true)) { continue; } var value = field.GetValue(info); if (field.Name == "moduleScore") { value = fileInfo?.moduleScore; } else if (field.Name == "moduleScoreIsDynamic") { value = fileInfo?.moduleScoreIsDynamic; } dictionary[field.Name] = value; } return(dictionary); }) .ToList(); File.WriteAllText(path, SettingsConverter.Serialize(infoList)); } catch (FileNotFoundException) { DebugHelper.LogWarning($"ModuleData: File {path} was not found."); return; } catch (Exception ex) { DebugHelper.LogException(ex); return; } DataHasChanged = false; DebugHelper.Log($"ModuleData: Writing of file {path} completed successfully."); }
private void OnDisable() { GameRoom.ShowCamera(); BombActive = false; EnableDisableInput(); bool claimsEnabled = TwitchModule.ClaimsEnabled; TwitchModule.ClearUnsupportedModules(); if (!claimsEnabled) { TwitchModule.ClaimsEnabled = true; } StopAllCoroutines(); Leaderboard.Instance.BombsAttempted++; // ReSharper disable once DelegateSubtraction ParentService.GetComponent <KMGameInfo>().OnLightsChange -= OnLightsChange; TwitchPlaysService.Instance.SetHeaderVisbility(false); LogUploader.Instance.GetBombUrl(); ParentService.StartCoroutine(SendDelayedMessage(1.0f, GetBombResult(), SendAnalysisLink)); if (!claimsEnabled) { ParentService.StartCoroutine(SendDelayedMessage(1.1f, "Claims have been enabled.")); } if (ModuleCameras != null) { ModuleCameras.gameObject.SetActive(false); } foreach (var bomb in Bombs.Where(x => x != null)) { Destroy(bomb.gameObject, 2.0f); } Bombs.Clear(); DestroyComponentHandles(); MusicPlayer.StopAllMusic(); GameRoom.Instance?.OnDisable(); 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:"); } }
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 static void WriteDataToFile() { string path = Path.Combine(Application.persistentDataPath, usersSavePath); DebugHelper.Log("TwitchPlayStrings: Writing file {0}", path); try { data.SettingsVersion = SettingsVersion; File.WriteAllText(path, SettingsConverter.Serialize(data)); //JsonConvert.SerializeObject(data, Formatting.Indented)); } catch (FileNotFoundException) { DebugHelper.LogWarning("TwitchPlayStrings: File {0} was not found.", path); return; } catch (Exception ex) { DebugHelper.LogException(ex); return; } DebugHelper.Log("TwitchPlayStrings: Writing of file {0} completed successfully", path); }
private void OnDisable() { GameRoom.ShowCamera(); BombActive = false; EnableDisableInput(); bool claimsEnabled = TwitchModule.ClaimsEnabled; TwitchModule.ClearUnsupportedModules(); if (!claimsEnabled) { TwitchModule.ClaimsEnabled = true; } StopAllCoroutines(); GoodPlayers.Clear(); EvilPlayers.Clear(); VSSetFlag = false; QueueEnabled = false; Leaderboard.Instance.BombsAttempted++; // ReSharper disable once DelegateSubtraction ParentService.GetComponent <KMGameInfo>().OnLightsChange -= OnLightsChange; ParentService.AddStateCoroutine(ParentService.AnimateHeaderVisibility(false)); LogUploader.Instance.GetBombUrl(); ParentService.AddStateCoroutine(DelayBombResult()); if (!claimsEnabled) { ParentService.AddStateCoroutine(SendDelayedMessage(1.1f, "Claims have been enabled.")); } if (ModuleCameras != null) { ModuleCameras.StartCoroutine(ModuleCameras.DisableCameras()); } // Award users who maintained modules. var methods = Modules.SelectMany(module => module.ScoreMethods); var awardedPoints = new Dictionary <string, int>(); foreach (var player in methods.SelectMany(method => method.Players).Distinct()) { int points = (methods.Sum(method => method.CalculateScore(player)) * OtherModes.ScoreMultiplier).RoundToInt(); if (points != 0) { awardedPoints[player] = points; Leaderboard.Instance.AddScore(player, points); } } if (awardedPoints.Count > 0) { IRCConnection.SendMessage($"These players have been awarded points for managing a needy: {awardedPoints.Select(pair => $"{pair.Key} ({pair.Value})").Join(", ")}"); } GameCommands.unclaimedModules = null; DestroyComponentHandles(); MusicPlayer.StopAllMusic(); GameRoom.Instance?.OnDisable(); 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:"); } }
private void OnDisable() { GameRoom.ShowCamera(); BombActive = false; EnableDisableInput(); bool claimsEnabled = TwitchModule.ClaimsEnabled; TwitchModule.ClearUnsupportedModules(); if (!claimsEnabled) { TwitchModule.ClaimsEnabled = true; } StopAllCoroutines(); Leaderboard.Instance.BombsAttempted++; // ReSharper disable once DelegateSubtraction ParentService.GetComponent <KMGameInfo>().OnLightsChange -= OnLightsChange; TwitchPlaysService.Instance.SetHeaderVisbility(false); LogUploader.Instance.GetBombUrl(); ParentService.StartCoroutine(DelayBombResult()); if (!claimsEnabled) { ParentService.StartCoroutine(SendDelayedMessage(1.1f, "Claims have been enabled.")); } if (ModuleCameras != null) { ModuleCameras.gameObject.SetActive(false); } // Award users who maintained needy modules. if (!OtherModes.ZenModeOn) { Dictionary <string, int> AwardedNeedyPoints = new Dictionary <string, int>(); foreach (TwitchModule twitchModule in Modules) { ModuleInformation ModInfo = twitchModule.Solver.ModInfo; ScoreMethod scoreMethod = ModInfo.scoreMethod; if (scoreMethod == ScoreMethod.Default) { continue; } foreach (var pair in twitchModule.PlayerNeedyStats) { string playerName = pair.Key; var needyStats = pair.Value; int points = Mathf.RoundToInt((scoreMethod == ScoreMethod.NeedySolves ? needyStats.Solves : needyStats.ActiveTime) * ModInfo.moduleScore); if (points != 0) { if (!AwardedNeedyPoints.ContainsKey(playerName)) { AwardedNeedyPoints[playerName] = 0; } AwardedNeedyPoints[playerName] += points; Leaderboard.Instance.AddScore(playerName, points); } } } if (AwardedNeedyPoints.Count > 0) { IRCConnection.SendMessage($"These players have been awarded points for managing a needy: {AwardedNeedyPoints.Select(pair => $"{pair.Key} ({pair.Value})").Join(", ")}"); } } GameCommands.unclaimedModules = null; DestroyComponentHandles(); MusicPlayer.StopAllMusic(); GameRoom.Instance?.OnDisable(); 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:"); } }
static IEnumerator TestComponents(List <KtaneModule> modules) { IEnumerable <BombComponent> untestedComponents = GetUntestedComponents(modules); Dictionary <string, string> nameMap = GetNameMap(modules); GameObject fakeModule = new GameObject(); gameObjects.Add(fakeModule); TwitchModule module = fakeModule.AddComponent <TwitchModule>(); module.enabled = false; HashSet <string> unsupportedModules = new HashSet <string>(); Dictionary <string, bool> supportStatus = new Dictionary <string, bool>(); ComponentSolverFactory.SilentMode = true; // Try to create a ComponentSolver for each module so we can see what modules are supported. foreach (BombComponent bombComponent in untestedComponents) { ComponentSolver solver = null; try { module.BombComponent = bombComponent.GetComponent <BombComponent>(); solver = ComponentSolverFactory.CreateSolver(module); module.StopAllCoroutines(); // Stop any coroutines to prevent any exceptions or from affecting the next module. } catch (Exception e) { DebugHelper.LogException(e, $"Couldn't create a component solver for \"{bombComponent.GetModuleDisplayName()}\" during startup for the following reason:"); } ModuleData.DataHasChanged |= solver != null; DebugHelper.Log(solver != null ? $"Found a solver of type \"{solver.GetType().FullName}\" for component \"{bombComponent.GetModuleDisplayName()}\". This module is {(solver.UnsupportedModule ? "not supported" : "supported")} by Twitch Plays." : $"No solver found for component \"{bombComponent.GetModuleDisplayName()}\". This module is not supported by Twitch Plays."); string moduleID = bombComponent.GetComponent <KMBombModule>()?.ModuleType ?? bombComponent.GetComponent <KMNeedyModule>()?.ModuleType; if (solver?.UnsupportedModule != false && moduleID != null) { unsupportedModules.Add(moduleID); } supportStatus[bombComponent.GetModuleDisplayName()] = !(solver?.UnsupportedModule != false && moduleID != null); yield return(null); } ComponentSolverFactory.SilentMode = false; ModuleData.WriteDataToFile(); Object.Destroy(fakeModule); // Always disable the modules from the spreadsheet var disabledSheet = new GoogleSheet("1G6hZW0RibjW7n72AkXZgDTHZ-LKj0usRkbAwxSPhcqA", "1849453757", "modulename"); yield return(disabledSheet); if (disabledSheet.Success && TwitchPlaySettings.data.AllowSheetDisabledModules) { foreach (var row in disabledSheet.GetRows()) { if (!nameMap.TryGetValue(row["modulename"], out string moduleID)) { DebugHelper.Log($"Couldn't map \"{row["modulename"]}\" to a module ID when disabling modules from the spreadsheet."); continue; } unsupportedModules.Add(moduleID); } } // Always disable modules that are marked as "Unplayable" foreach (var moduleInfo in modules) { if (moduleInfo.Compatibility != "Unplayable") { continue; } unsupportedModules.Add(moduleInfo.ModuleID); } // Using the list of unsupported module IDs stored in unsupportedModules, make a Mod Selector profile. string profilesPath = Path.Combine(Application.persistentDataPath, "ModProfiles"); if (Directory.Exists(profilesPath)) { Dictionary <string, object> profileData = new Dictionary <string, object>() { { "DisabledList", unsupportedModules }, { "Operation", 1 } }; File.WriteAllText(Path.Combine(profilesPath, "TP_Supported.json"), SettingsConverter.Serialize(profileData)); } alertProgressBar.localScale = Vector3.one; // Send a message to chat if any modules aren't marked as having support if (supportStatus.Values.Count(status => status) > 0) { var supportedList = supportStatus.Where(pair => pair.Value).Select(pair => pair.Key).Join(", "); IRCConnection.SendMessage($"These modules have TP support: {supportedList}"); alertText.text = $"These modules have TP support: {supportedList}"; yield return(new WaitForSeconds(4)); } else { alertText.text = "Support checks passed succesfully!"; yield return(new WaitForSeconds(2)); } // Log out the full results of the testing DebugHelper.Log($"Support testing results:\n{supportStatus.OrderByDescending(pair => pair.Value).Select(pair => $"{pair.Key} - {(pair.Value ? "" : "Not ")}Supported").Join("\n")}"); }
static IEnumerator TestComponents(IEnumerable <BombComponent> untestedComponents) { GameObject fakeModule = new GameObject(); gameObjects.Add(fakeModule); TwitchModule module = fakeModule.AddComponent <TwitchModule>(); module.enabled = false; List <string> unsupportedModules = new List <string>(); Dictionary <string, bool> supportStatus = new Dictionary <string, bool>(); ComponentSolverFactory.SilentMode = true; // Try to create a ComponentSolver for each module so we can see what modules are supported. foreach (BombComponent bombComponent in untestedComponents) { ComponentSolver solver = null; try { module.BombComponent = bombComponent.GetComponent <BombComponent>(); solver = ComponentSolverFactory.CreateSolver(module); module.StopAllCoroutines(); // Stop any coroutines to prevent any exceptions or from affecting the next module. } catch (Exception e) { DebugHelper.LogException(e, $"Couldn't create a component solver for \"{bombComponent.GetModuleDisplayName()}\" during startup for the following reason:"); } ModuleData.DataHasChanged |= solver != null; DebugHelper.Log(solver != null ? $"Found a solver of type \"{solver.GetType().FullName}\" for component \"{bombComponent.GetModuleDisplayName()}\". This module is {(solver.UnsupportedModule ? "not supported" : "supported")} by Twitch Plays." : $"No solver found for component \"{bombComponent.GetModuleDisplayName()}\". This module is not supported by Twitch Plays."); string moduleID = bombComponent.GetComponent <KMBombModule>()?.ModuleType ?? bombComponent.GetComponent <KMNeedyModule>()?.ModuleType; if (solver?.UnsupportedModule != false && moduleID != null) { unsupportedModules.Add(moduleID); } supportStatus[bombComponent.GetModuleDisplayName()] = !(solver?.UnsupportedModule != false && moduleID != null); yield return(null); } ComponentSolverFactory.SilentMode = false; ModuleData.WriteDataToFile(); Object.Destroy(fakeModule); // Using the list of unsupported module IDs stored in unsupportedModules, make a Mod Selector profile. string profilesPath = Path.Combine(Application.persistentDataPath, "ModProfiles"); if (Directory.Exists(profilesPath)) { Dictionary <string, object> profileData = new Dictionary <string, object>() { { "DisabledList", unsupportedModules }, { "Operation", 1 } }; File.WriteAllText(Path.Combine(profilesPath, "TP_Supported.json"), SettingsConverter.Serialize(profileData)); } alertProgressBar.localScale = Vector3.one; // Send a message to chat if any modules aren't marked as having support if (supportStatus.Values.Count(status => status) > 0) { var supportedList = supportStatus.Where(pair => pair.Value).Select(pair => pair.Key).Join(", "); IRCConnection.SendMessage($"Let the Scoring Team know that the following modules have TP support: {supportedList}"); alertText.text = $"These modules have TP support: {supportedList}"; yield return(new WaitForSeconds(4)); } else { alertText.text = "Support checks passed succesfully!"; yield return(new WaitForSeconds(2)); } // Log out the full results of the testing DebugHelper.Log($"Support testing results:\n{supportStatus.OrderByDescending(pair => pair.Value).Select(pair => $"{pair.Key} - {(pair.Value ? "" : "Not ")}Supported").Join("\n")}"); }