Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated compatibility checker #699

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
57a03f3
wip - refactoring
originalfoo Feb 13, 2020
ca5b9af
use string builder for logging in loop
originalfoo Feb 13, 2020
d1fefff
Now compiles, showing signs of life
originalfoo Feb 13, 2020
e9a399d
cleaned some cruft
originalfoo Feb 14, 2020
2c64dbb
tinkering with assembly scanner
originalfoo Feb 14, 2020
a757c28
DLC scanner added
originalfoo Feb 14, 2020
f472130
Tidy up, also added Match Day to DLC scanner
originalfoo Feb 14, 2020
7d4ec20
Trying to extract version/branch info from assemblies
originalfoo Feb 15, 2020
680ed97
Partially working reflection
originalfoo Feb 15, 2020
b679300
Almost completely working reflection!
originalfoo Feb 15, 2020
70001e1
Retreiving version and branch, but very crufty code
originalfoo Feb 15, 2020
f1f8948
Version and branch inspection working nicely now
originalfoo Feb 15, 2020
a81d7e3
Missing variable declaration in example
originalfoo Feb 15, 2020
385ddfd
mid-way through a refactor
originalfoo Feb 18, 2020
ea093f9
mid-refactor
originalfoo Feb 20, 2020
2d2dfd8
Should be able to resume launcher auto-continue (not tested yet)
originalfoo Feb 20, 2020
963c434
Merge branch 'master' into 697-608-439-compatibility-checker
originalfoo Feb 21, 2020
8d6b87f
Tested the auto-continue feature - works great (thanks krzychu!)
originalfoo Feb 21, 2020
a287def
Refactor and cleanup
originalfoo Feb 21, 2020
0e31dc8
mid-refactor of UI (still horrible broken mess)
originalfoo Feb 21, 2020
a488325
more refactoring
originalfoo Feb 23, 2020
062c393
Tweaks to mod checker
originalfoo Feb 25, 2020
d31a3c1
Add error logging
originalfoo Feb 25, 2020
5046b24
Minor tweaks
originalfoo Feb 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion TLM/TLM/Compatibility/Check/DLCs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ public static void Verify() {
}

Log.Info(sb.ToString());
} catch { }
}
catch {
originalfoo marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
125 changes: 73 additions & 52 deletions TLM/TLM/Compatibility/CompatibilityManager.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
namespace TrafficManager.Compatibility {
using ColossalFramework;
using ColossalFramework.Plugins;
using static ColossalFramework.Plugins.PluginManager;
using ColossalFramework.UI;
using CSUtil.Commons;
using ICities;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using TrafficManager.Compatibility.Struct;
using UnityEngine;
using UnityEngine.SceneManagement;
using static ColossalFramework.Plugins.PluginManager;

/// <summary>
/// Manages pre-flight checks for known incompatible mods.
Expand All @@ -31,15 +30,25 @@ public static class CompatibilityManager {
/// <summary>
/// Is the compatibility checker paused? We pause it when active scene is not "MainMenu".
/// </summary>
internal static bool Paused = true;
private static bool paused_ = true;

/// <summary>
/// Tracks if a game restart is required (eg. after disabling/unsubscribing mods).
/// </summary>
private static bool restartRequired_ = false;

internal static bool RestartRequired = false;
/// <summary>
/// Stores the original value of <see cref="LauncherLoginData.instance.m_continue"/>.
/// </summary>
private static bool autoContinue_ = false;

/// <summary>
/// Initializes static members of the <see cref="CompatibilityManager"/> class.
/// </summary>
static CompatibilityManager() {
LauncherLoginData.instance.m_continue = false;
// Prevent vanilla autoloading last savegame
PreventAutoContinue();

// Translate current game verison in to Version instance
CurrentGameVersion = new Version(
Convert.ToInt32(BuildConfig.APPLICATION_VERSION_A),
Expand All @@ -55,22 +64,24 @@ static CompatibilityManager() {
/// checks when applicable.
/// </summary>
public static void Activate() {
// Pause the compatibility checker if scene changes to something other than "MainMenu"
SceneManager.activeSceneChanged += OnSceneChange;
// Abort if this is an in-game hotload
// todo

// todo: avoid checks when hotloading in-game
if (UIView.GetAView() != null) {
// TM:PE enabled via Main Menu > Content Manager so run now
Log.Info("CompatibilityManager.Activate()");
Paused = false;
paused_ = false;
PerformChecks();
} else {
// TM:PE was already enabled on game load, or via mod autoenabler;
// we must wait for main menu before doing anything else
Log.Info("CompatibilityManager.Activate(): Waiting for main menu...");
Paused = true;
paused_ = true;
LoadingManager.instance.m_introLoaded += OnIntroLoaded;
}

// Pause the compatibility checker if scene changes to something other than "MainMenu"
SceneManager.activeSceneChanged += OnSceneChange;
}

/// <summary>
Expand All @@ -88,15 +99,15 @@ public static void Deactivate() {
/// </summary>
private static void OnIntroLoaded() {
LoadingManager.instance.m_introLoaded -= OnIntroLoaded;
Paused = false;
paused_ = false;
PerformChecks();
}

/// <summary>
/// Triggered when plugins change.
/// </summary>
private static void OnPluginsChanged() {
if (!Paused) {
if (!paused_) {
PerformChecks();
}
}
Expand All @@ -110,43 +121,19 @@ private static void OnPluginsChanged() {
/// and first display of main menu.
/// </summary>
///
/// <param name="current">The current <see cref="Scene"/>.</param>
/// <param name="current">The current <see cref="Scene"/> (seems to always be empty).</param>
/// <param name="next">The <see cref="Scene"/> being transitioned to.</param>
private static void OnSceneChange(Scene current, Scene next) {
Log.InfoFormat(
"CompatibilityManager.OnSceneChange('{1}')",
next.name);
Paused = next.name != "MainMenu";
}

/// <summary>
/// Displays a panel allowing user to choose which assembly they want to use.
/// A game restart is required to make changes take effect.
/// </summary>
internal static void ShowAssemblyChooser() {
// todo
Log.Info("CompatibilityManager.ShowAssemblyChooser()");
}

/// <summary>
/// Displays a panel allowing users to remove/disable incompatible mods.
/// </summary>
///
/// <param name="critical">A dictionary of critical incompatibilities.</param>
/// <param name="major">A dictionary of major incompatibilities.</param>
/// <param name="minor">A dictionary of minor incompatibilities.</param>
internal static void ShowModRemoverDialog(
Dictionary<PluginInfo, string> critical,
Dictionary<PluginInfo, string> major,
Dictionary<PluginInfo, string> minor) {
// todo
Log.Info("CompatibilityManager.ShowModRemoverDialog()");
paused_ = next.name != "MainMenu";
}

/// <summary>
/// Adds listener for plugin manager subscription change event.
/// </summary>
internal static void ListenForSubscriptionChange() {
private static void ListenForSubscriptionChange() {
Log.Info("CompatibilityManager.ListenForSubscriptionChange()");
// clear old listener if present (is this necessary? don't know enough about C# events)
Singleton<PluginManager>.instance.eventPluginsChanged -= PerformChecks;
Expand All @@ -159,7 +146,7 @@ internal static void ListenForSubscriptionChange() {
/// </summary>
///
/// <returns>Returns <c>true</c> if safe to run tests, otherwise <c>false</c>.</returns>
internal static bool CanWeDoStuff() {
private static bool CanWeDoStuff() {
if (SceneManager.GetActiveScene().name == "MainMenu") {
Log.Info("CompatibilityManager.CanWeDoStuff()? Yes, 'MainMenu' scene");
return true;
Expand All @@ -177,34 +164,63 @@ internal static bool CanWeDoStuff() {
return false;
}

return !Paused;
return !paused_;
}

/// <summary>
/// Exits the game to desktop after a very short delay.
/// Exits the game to desktop.
/// </summary>
internal static void ExitToDesktop() {
private static void ExitToDesktop() {
// Don't exit to desktop if we're in-game!
if (!CanWeDoStuff()) {
if (paused_) {
return;
}
paused_ = true;

// Check we're not already quitting
if (Singleton<LoadingManager>.instance.m_applicationQuitting) {
return;
}

Singleton<LoadingManager>.instance.QuitApplication();
}

/// <summary>
/// Attempt to halt the Paradox Launcher autoload sequence.
/// Otherwise the user will not see any compatibility warnings.
/// </summary>
internal static void HaltAutoLoad() {
Log.Info("CompatibilityManager.HaltAutoLoad()");
private static void PreventAutoContinue() {
Log.Info("CompatibilityManager.PreventAutoContinue()");
try {
autoContinue_ = LauncherLoginData.instance.m_continue;
LauncherLoginData.instance.m_continue = false;
}
catch {
Log.Warning(" - Failed!");
}
}

/// <summary>
/// If tests pass with no issues, we can resume launcher auto-continue
/// if applicable.
/// </summary>
private static void ResumeAutoContinue() {
if (autoContinue_) {
Log.Info("CompatibilityManager.ResumeAutoContinue()");
autoContinue_ = false;

try {
MainMenu menu = GameObject.FindObjectOfType<MainMenu>();
if (menu != null) {
menu.m_BackgroundImage.zOrder = int.MaxValue;
menu.Invoke("AutoContinue", 2.5f);
}
}
catch {
}
}
}

/// <summary>
/// Runs through entire compatibility checker sequence
/// </summary>
Expand All @@ -228,23 +244,28 @@ private static void PerformChecks() {
out int critical,
out int candidate)) {

RestartRequired = major > 0 || critical > 0 || candidate > 1;
restartRequired_ = major > 0 || critical > 0 || candidate > 1;

// todo: deal with incompatibilities
}

// If a restart is not yet required, check for zombie assemblies
// which are the main cause of save/load issues.
if (!RestartRequired && !Check.Assemblies.Verify()) {
if (!restartRequired_ && !Check.Assemblies.Verify()) {

RestartRequired = true;
restartRequired_ = true;

// todo: show warning about settings loss
}


Check.DLCs.Verify();
ListenForSubscriptionChange();

if (restartRequired_) {
originalfoo marked this conversation as resolved.
Show resolved Hide resolved
} else {
autoContinue_ = false;
ListenForSubscriptionChange();
ResumeAutoContinue();
}
}
}
}
2 changes: 2 additions & 0 deletions TLM/TLM/Compatibility/GUI/ProcessIncompatibleMods.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*
originalfoo marked this conversation as resolved.
Show resolved Hide resolved
namespace TrafficManager.Compatibility.GUI {
using ColossalFramework.IO;
using ColossalFramework.PlatformServices;
Expand Down Expand Up @@ -345,3 +346,4 @@ private void TryPopModal() {
}
}
}
*/