/// <summary> /// Every 10 seconds check if the coroutine is still active. /// If not, try to restart it. /// It is checked by two values - ticks and lastTick /// Ticks are added by coroutine. If the value is different than the lastTick, everything is okay. /// If the ticks and lastTick is the same, that means coroutine stopped. /// </summary> /// <returns></returns> IEnumerator ControlCoroutine() { while (MopSettings.IsModActive) { yield return(new WaitForSeconds(10)); if (lastTick == ticks) { if (retries >= MaxRetries) { ModConsole.LogError("[MOP] Restart attempt failed. Enabling Safe Mode."); ModConsole.LogError("[MOP] Please contact mod developer. Make sure you send output_log and last MOP crash log!"); try { ToggleAll(true); } catch { } MopSettings.EnableSafeMode(); yield break; } retries++; restartSucceedMessaged = false; ModConsole.LogWarning($"[MOP] MOP has stopped working! Restart attempt {retries}/{MaxRetries}..."); StopCoroutine(currentLoop); currentLoop = LoopRoutine(); StartCoroutine(currentLoop); } else { lastTick = ticks; } } }
/// <summary> /// Creates then new error dump file /// </summary> /// <param name="ex"></param> public static void New(Exception ex, bool isCritical, string message) { // Don't save errors that already occured. if (erorrsContainer.Contains(message)) { return; } string fileName = $"{DefaultErrorLogName}_{DateTime.Now:yyyy-MM-dd-HH-mm}"; if (File.Exists($"{LogFolder}/{fileName}.txt")) { int crashesInFolder = 0; while (File.Exists($"{LogFolder}/{fileName}_{crashesInFolder}.txt")) { crashesInFolder++; } fileName += $"_{crashesInFolder}"; } string logFilePath = $"{LogFolder}/{fileName}.txt"; string gameInfo = GetGameInfo(); string errorInfo = $"{ex.Message}\n{ex.StackTrace}\nTarget Site: {ex.TargetSite}"; using (StreamWriter sw = new StreamWriter(logFilePath)) { sw.Write($"{gameInfo}\n=== ERROR ===\n\n// " + $"{WittyComments.GetErrorWittyText()}\n\n" + $"{message}{(message.Length > 0 ? "\n\n" : "")}" + $"{errorInfo}"); } string errorMessage = $"[MOP] An error has occured. Log has been saved into My Summer Car folder into:\n\n{logFilePath}.\n\n" + $"Please go into MOP Settings and click \"<b>I found a bug</b>\" button, in order to generate bug report and then follow the instructions.\n"; if (isCritical) { ModConsole.LogError(errorMessage); } else { ModConsole.LogWarning(errorMessage + "\nYou can continue playing."); } erorrsContainer.Add(message); }
/// <summary> /// Seeks for rule files (.mopconfig) in MOP config folder. /// </summary> void GetAndReadRules() { overrideUpdateCheck = false; try { // Find and .mopconfig files. DirectoryInfo dir = new DirectoryInfo(MOP.ModConfigPath); List <FileInfo> files = dir.GetFiles().Where(d => d.Name.EndsWith(RuleExtension)).ToList(); // Load custom rule file. if (File.Exists($"{dir}/{CustomFile}")) { files.Add(new FileInfo($"{dir}/{CustomFile}")); ModConsole.Log("[MOP] User custom rule file found!"); } if (files.Count == 0) { ModConsole.Log($"[MOP] No rule files found."); NewMessage(""); return; } string message = $"[MOP] Found {files.Count} rule file{(files.Count > 1 ? "s" : "")}!"; if (files.Count == 69) { message = message.Rainbowmize(); } ModConsole.Log(message); int removed = 0; // Read rule files. foreach (FileInfo file in files) { // Delete rules for mods that don't exist. if (ModLoader.LoadedMods.Find(m => m.ID == Path.GetFileNameWithoutExtension(file.Name)) == null && file.Name != CustomFile) { removed++; if (MOP.DeleteUnusedRules.Value) { File.Delete(file.FullName); ModConsole.Log($"<color=yellow>[MOP] Rule file {file.Name} has been deleted, " + $"because corresponding mod is not present.</color>"); removed++; continue; } ModConsole.Log($"<color=yellow>[MOP] Skipped {file.Name} rule, " + $"because the corresponding mod is not present.</color>"); RulesManager.Instance.UnusedRules.Add(file.Name); continue; } // Verify if the servercontent has that rule file. // Some mod makers may include poorly configured rule files, // that's why they have to be only provided by the server. if (serverContent != null && MOP.VerifyRuleFiles.Value && file.Name != CustomFile) { if (serverContent.Find(m => m.ID == Path.GetFileNameWithoutExtension(file.Name)) == null) { ModConsole.LogWarning($"[MOP] Rule file {file.Name} has been skipped, because it couldn't be verified."); removed++; continue; } } RulesManager.Instance.RuleFileNames.Add(file.Name); ReadRulesFromFile(file.FullName); } int loaded = files.Count - removed; ModConsole.Log($"<color=green>[MOP] Loading {loaded}/{files.Count} rule files done!</color>"); if (loaded == 0) { NewMessage($"MOP: No rules have been loaded ({removed} rule{(removed == 1 ? "" : "s")} skipped)."); } else { NewMessage($"MOP: Succesfully loaded {loaded} rule file{(loaded == 1 ? "" : "s")}! {(removed > 0 ? $"({removed} rule{(removed == 1 ? "" : "s")} skipped)" : "" )}"); } } catch (Exception ex) { ExceptionManager.New(ex, false, "RULE_FILES_READ_ERROR"); } }