Пример #1
0
        private static string GetModPath()
        {
            PluginManager.PluginInfo pluginInfo = PluginManager.instance.GetPluginsInfo()
                                                  .FirstOrDefault(pi => pi.publishedFileID.AsUInt64 == WorkshopId);

            return(pluginInfo?.modPath);
        }
Пример #2
0
        private bool MusicFileBelongsToInactiveMod(String file)
        {
            if (file.StartsWith(ConversionManager.ConvertedMusicPackMusicFolder))
            {
                String modid = Path.GetFileName(Path.GetDirectoryName(file));

                PluginManager.PluginInfo info = ModHelper.GetSourceModFromId(modid);

                if (info != null)
                {
                    return(!info.isEnabled);
                }
            }
            else
            {
                PluginManager.PluginInfo info = ModHelper.GetSourceModFromFolder(file);

                if (info != null)
                {
                    return(!info.isEnabled);
                }
            }

            return(false);
        }
Пример #3
0
 public override void Awake()
 {
     try {
         base.Awake();
         plugin_ = Plugin;
     } catch (Exception ex) { Log.Exception(ex); }
 }
Пример #4
0
        private static Type GetManagerType(ulong modId, string typeName)
        {
            PluginManager.PluginInfo mod = PluginManager.instance.GetPluginsInfo()
                                           .FirstOrDefault(pi => pi.publishedFileID.AsUInt64 == modId);

            if (mod?.isEnabled != true)
            {
                return(null);
            }

            Assembly assembly = mod.GetAssemblies()?.FirstOrDefault();

            if (assembly == null)
            {
                Log.Warning($"'Real Time' compatibility check: the mod {modId} has no assemblies.");
                return(null);
            }

            try
            {
                return(assembly.GetType(typeName));
            }
            catch (Exception ex)
            {
                Log.Warning($"'Real Time' compatibility check: the mod {modId} doesn't contain the '{typeName}' type: {ex}");
                return(null);
            }
        }
Пример #5
0
        public void OnDisabled()
        {
            if (Application.platform == RuntimePlatform.OSXPlayer)
            {
                Debug.Log("PatchLoader disabled");
                return;
            }

            if (_doorstopManager.IsInstalled() && !_pluginInfo.isEnabled)
            {
                _doorstopManager.Disable();
            }

            if (_doorstopManager.RequiresRestart)
            {
                ShowRestartGameModal($"The '{Name}' was uninstalled.\n{_doorstopManager.UninstallMessage}");
            }

            _doorstopManager           = null;
            _pluginInfo                = null;
            _logger                    = null;
            _patchLoaderConfigFilePath = null;
            _configManager             = null;

            Debug.Log("PatchLoader disabled");
        }
Пример #6
0
        // constructor gets instantiated before any extensions are called
        public ModCorral()
        {
            try
            {
                ModCorralConfig.SetInstance(ModCorralConfig.Deserialize("ModCorralConfig.xml"));

                // determine if we are enabled or not
                if (PluginManager.instance == null || PluginManager.instance.GetPluginsInfo() == null)
                {
                    Log.Message("ModCorral quitting, PluginManager.instance is null.");
                    return;
                }

                // the very first thing we need to do is check if we're enabled.  This constructor
                // is called even if we're marked as not to be loaded, so if not enabled, don't do anything
                PluginManager.PluginInfo myPluginInfo = null;
                foreach (PluginManager.PluginInfo info in PluginManager.instance.GetPluginsInfo())
                {
                    if (info.name == "ModCorral" || info.publishedFileID.AsUInt64 == 419090722)
                    {
                        myPluginInfo = info;
                        break;
                    }
                }

                if (myPluginInfo == null)
                {
                    Log.Error("ModCorral PluginInfo not found, exiting.");

                    return;
                }

                //// we need to be notified if our mod is enabled or disabled
                //PluginManager.instance.eventPluginsChanged += () => { this.EvaluateStatus(); };
                //PluginManager.instance.eventPluginsStateChanged += () => { this.EvaluateStatus(); };

                if (!myPluginInfo.isEnabled)
                {
                    Log.Warning("ModCorral is disabled.");
                    return;
                }

                Log.Message("ModCorral initializing.");

                // create our corral monobehaviour
                UIView uiv = UIView.GetAView();

                if (uiv != null && uiv.gameObject != null)
                {
                    CorralRegistration creg = CorralRegistration.instance;
                }
            }
            catch (Exception ex)
            {
                Log.Error("ModCorral() Exception: " + ex.Message);
            }
        }
        private static string GetModPath()
        {
            PluginManager.PluginInfo pluginInfo = PluginManager
                                                  .instance
                                                  .GetPluginsInfo()
                                                  .FirstOrDefault(info => info.modPath.Contains("real-time-nosteam"));

            return(pluginInfo?.modPath);
        }
Пример #8
0
        private void ConvertCustomMusic_AddConversionTasks(String folder, Dictionary <String, String> conversiontasks, bool mod)
        {
            Debug.Log("[CSLMusic] Conversion looking for files @ " + folder);

            if (Directory.Exists(folder))
            {
                PluginManager.PluginInfo modification = null;

                if (mod)
                {
                    modification = ModHelper.GetSourceModFromFolder(folder);

                    if (modification == null)
                    {
                        Debug.LogError("[CSLMusic] Cannot add folder " + folder + " as mod! Mod could not be identified");
                        return;
                    }

                    if (!modification.isEnabled)
                    {
                        //Don't convert if mod is not active
                        return;
                    }
                }

                //Get music in pack folder and look if the file has a corresponding *.raw file
                //If not, convert the file to raw
                foreach (String file in Directory.GetFiles(folder))
                {
                    if (ModOptions.SupportedNonRawFileFormats.Contains(Path.GetExtension(file)))
                    {
                        String srcfile = file;
                        String dstfile;

                        if (mod)
                        {
                            //We need to change the folder!
                            dstfile = Path.Combine(CreateModConvertedMusicFolder(modification), Path.GetFileNameWithoutExtension(srcfile) + ".raw");
                        }
                        else
                        {
                            dstfile = Path.ChangeExtension(file, ".raw");                             //We can work in out own folder
                        }

                        if (!File.Exists(dstfile))
                        {
                            //Add task
                            conversiontasks[srcfile] = dstfile;
                        }
                    }
                }
            }
            else
            {
                Debug.LogError("ERROR: " + folder + " is not existing!");
            }
        }
Пример #9
0
        /**
         * Creates and returns the folder containing the converted files for given mod
         * */
        public String CreateModConvertedMusicFolder(PluginManager.PluginInfo info)
        {
            String destinationpath = Path.Combine(ConvertedMusicPackMusicFolder, info.publishedFileID.AsUInt64.ToString());

            if (!Directory.Exists(destinationpath))
            {
                Directory.CreateDirectory(destinationpath);
            }

            return(destinationpath);
        }
Пример #10
0
        private static string GetModPath()
        {
            string assemblyName = typeof(RealTimeMod).Assembly.GetName().Name;

            PluginManager.PluginInfo pluginInfo = PluginManager.instance.GetPluginsInfo()
                                                  .FirstOrDefault(pi => pi.name == assemblyName || pi.publishedFileID.AsUInt64 == WorkshopId);

            return(pluginInfo == null
                ? Environment.CurrentDirectory
                : pluginInfo.modPath);
        }
Пример #11
0
        private bool AddUnknownMusicPackMusicFiles(ref bool mood_entries_not_found)
        {
            Debug.Log("[CSLMusic] Fetching unknown music pack music files ...");

            bool foundsomething = false;

            List <String> searchfolders = new List <string>();

            searchfolders.AddRange(ModOptions.ModdedMusicSourceFolders);
            if (Directory.Exists(ConversionManager.ConvertedMusicPackMusicFolder))
            {
                searchfolders.AddRange(Directory.GetDirectories(ConversionManager.ConvertedMusicPackMusicFolder));
            }

            /**
             * Add *.raw music from mod folders if somebody really wants to upload raw files
             * and music from converted
             * */
            foreach (String folder in searchfolders)
            {
                if (Directory.Exists(folder))
                {
                    var modid = Directory.GetParent(folder).Name;
                    Debug.Log("[CSLMusic] Looking for MusicPack songs in " + folder + ", mod-id " + modid);

                    //Does the plugin exist? Is it active
                    PluginManager.PluginInfo info = ModHelper.GetSourceModFromId(modid);

                    if (info == null)
                    {
                        Debug.LogWarning("[CSLMusic] Unknown mod in folder @ " + folder);
                        continue;
                    }

                    if (info.isEnabled)
                    {
                        Debug.Log("[CSLMusic] Adding mod conversion files from " + folder);
                        foundsomething |= AddUnknownMusicFiles(folder, ref mood_entries_not_found);
                    }
                    else
                    {
                        Debug.Log("[CSLMusic] Not adding mod conversion files from " + folder + ": Not enabled");
                        Debug.Log("-> Directory of this mod is " + info.modPath);
                    }
                }
                else
                {
                    Debug.LogError("ERROR: " + folder + " is not existing!");
                }
            }

            return(foundsomething);
        }
Пример #12
0
        static string FindModPath()
        {
            PluginManager.PluginInfo plugin = Singleton <PluginManager> .instance.GetPluginsInfo().FirstOrDefault(p => p.name == "Traffic++" || p.publishedFileID.AsUInt64 == TrafficMod.WORKSHOP_ID);

            if (plugin != null)
            {
                return(plugin.modPath);
            }
            else
            {
                Logger.LogInfo("Cannot find plugin path.");
            }

            return(null);
        }
Пример #13
0
        public void DisplayIncompatibleMods()
        {
            Dictionary <PublishedFileId, string> userIncompatibilities = CheckIncompatibilities();

            if (userIncompatibilities.Count > 0)
            {
                PluginManager pluginManager    = Singleton <PluginManager> .instance;
                var           plugins          = pluginManager.GetPluginsInfo();
                string        incompatibleList = "";

                foreach (KeyValuePair <PublishedFileId, string> incompatibility in userIncompatibilities)
                {
                    PluginManager.PluginInfo foundPlugin = null;
                    string pluginName = "Unknown mod (" + incompatibility.Key.AsUInt64.ToString() + ")";

                    foreach (PluginManager.PluginInfo plugin in plugins)
                    {
                        if (plugin.publishedFileID == incompatibility.Key)
                        {
                            foundPlugin = plugin;
                            break;
                        }
                    }

                    if (incompatibleList != "")
                    {
                        incompatibleList += "\n\n";
                    }

                    if (foundPlugin != null)
                    {
                        IUserMod[] instances = foundPlugin.GetInstances <IUserMod>();

                        if (instances.Length > 0)
                        {
                            pluginName = instances[0].Name;
                        }
                    }

                    incompatibleList += pluginName + " - " + string.Format(incompatibility.Value, pluginName);
                }

                incompatibleList += "\n\nYou can still run the game with th" + (userIncompatibilities.Count > 1 ? "ese mods" : "is mod") + ", but some things in Rush Hour might not work.";

                UIView.library.ShowModal <ExceptionPanel>("ExceptionPanel").SetMessage("Rush Hour has detected incompatible mods", incompatibleList, false);
            }
        }
Пример #14
0
        public void OnEnabled()
        {
            _pluginInfo = PluginManager.instance.FindPluginInfo(Assembly.GetExecutingAssembly());
            EnsureLogsDirectoryCreated();
            _logger = new Utils.Logger(Path.Combine(Path.Combine(Application.dataPath, "Logs"), "PatchLoaderMod.log"));
            _patchLoaderConfigFilePath = Path.Combine(DataLocation.applicationBase, "PatchLoader.Config.xml");
            _configManager             = new ConfigManager <Config>(_patchLoaderConfigFilePath, _logger);

            var expectedTargetAssemblyPath = PathExtensions.Combine(
                _pluginInfo.modPath,
                "PatchLoader",
                "PatchLoader.dll"
                );

            _doorstopManager = DoorstopManager.Create(expectedTargetAssemblyPath, _logger);

            if (Application.platform == RuntimePlatform.OSXPlayer)
            {
                ShowExceptionModal($"The '{Name}'\nMacOS platform is not supported yet.\n\n" +
                                   "Mod will disable itself.\n" +
                                   "Follow FPS Booster and PatchLoader mod development to stay informed about changes.\n" +
                                   "MacOS support will be added in one of the next major updates for PatchLoader mod.",
                                   () => {
                    _pluginInfo.isEnabled = false;
                });
                return;
            }

            if (!_doorstopManager.IsInstalled())
            {
                _doorstopManager.Install();
                SaveOrUpdateWorkshopPath();
            }

            if (_doorstopManager.CanEnable && !_doorstopManager.IsEnabled())
            {
                _doorstopManager.Enable();
            }

            if (_doorstopManager.RequiresRestart)
            {
                ShowRestartGameModal($"The '{Name}' was installed.\n{_doorstopManager.InstallMessage}");
            }

            Debug.Log("PatchLoader enabled");
        }
Пример #15
0
        private static TimeSpan GetPluginCreatedDelta(PluginManager.PluginInfo plugin)
        {
            DateTime created = DateTime.MinValue;

            foreach (var file in Directory.GetFiles(plugin.modPath))
            {
                if (Path.GetExtension(file) == ".dll")
                {
                    var tmp = File.GetCreationTime(file);
                    if (tmp > created)
                    {
                        created = tmp;
                    }
                }
            }

            return(DateTime.Now - created);
        }
Пример #16
0
        // event handler for plugin change
        public void EvaluateStatus()
        {
            try
            {
                PluginManager.PluginInfo myPluginInfo = null;
                foreach (PluginManager.PluginInfo info in PluginManager.instance.GetPluginsInfo())
                {
                    if (info.name == "BetterLoadPanel")
                    {
                        myPluginInfo = info;
                        break;
                    }
                }

                if (myPluginInfo == null || !myPluginInfo.isEnabled)
                {
                    // disable ourselves
                    if (IsMainMenuUpdated())
                    {
                        RemoveMainMenuButton();
                    }
                    if (IsPauseMenuUpdated())
                    {
                        RemovePauseMenuButton();
                    }
                }
                else
                {
                    // enable ourselves (if not already enabled)
                    if (!IsMainMenuUpdated())
                    {
                        AddMainMenuButton();
                    }
                    //if (!IsPauseMenuUpdated())
                    //{
                    //   AddPauseMenuButton();
                    //}
                }
            }
            catch (Exception ex)
            {
                DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Error, "evaluate: " + ex.Message);
            }
        }
        private static void TelemetryManagerCustomContentInfo(int buildingsCount, int propsCount, int treeCount, int vehicleCount)
        {
            UpdateActiveModCount();

            try
            {
                Telemetry        telemetry = new Telemetry();
                Telemetry.Pair[] infoPair  = new Telemetry.Pair[] { new Telemetry.Pair("buildings", buildingsCount), new Telemetry.Pair("props", propsCount), new Telemetry.Pair("trees", treeCount), new Telemetry.Pair("vehicles", vehicleCount) };
                telemetry.AddEvent("custom_content", infoPair);
                DebugUtils.Log("Sending telemetry with " + m_ActiveModCount + " mods active");
                Telemetry.Pair[] pairArray2 = new Telemetry.Pair[] { new Telemetry.Pair("enabledModCount", m_ActiveModCount), new Telemetry.Pair("modCount", Singleton <PluginManager> .instance.modCount) };
                telemetry.AddEvent("custom_mods", pairArray2);
                telemetry.Push();
                IEnumerator <PluginManager.PluginInfo> enumerator = Singleton <PluginManager> .instance.GetPluginsInfo().GetEnumerator();

                try
                {
                    while (enumerator.MoveNext())
                    {
                        PluginManager.PluginInfo current = enumerator.Current;
                        if (current.isEnabled)
                        {
                            Telemetry        telemetry2 = new Telemetry();
                            Telemetry.Pair[] pairArray3 = new Telemetry.Pair[] { new Telemetry.Pair("modName", current.name), new Telemetry.Pair("modWorkshopID", !(current.publishedFileID != PublishedFileId.invalid) ? "none" : current.publishedFileID.ToString()), new Telemetry.Pair("assemblyInfo", current.assembliesString) };
                            telemetry2.AddEvent("mod_used", pairArray3);
                            telemetry2.Push();
                        }
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
            }
            catch (Exception ex)
            {
                DebugUtils.Log(ex.Message);
                //CODebugBase<LogChannel>.Warn(LogChannel.HTTP, exception.GetType() + ": Telemetry event failed " + exception.Message);
            }
        }
Пример #18
0
 private void pluginsChanged()
 {
     try
     {
         PluginManager.PluginInfo pi = PluginManager.instance.GetPluginsInfo().Where(p => p.publishedFileID.AsUInt64 == 411769510L).FirstOrDefault();
         if (pi != null)
         {
             DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, string.Format("[NG+] This mod is {0}.", pi.isEnabled ? "enabled" : "disabled"));
             options.Show(pi.isEnabled);
         }
         else
         {
             DebugOutputPanel.AddMessage(PluginManager.MessageType.Message, "[NG+] Can't find self. No idea if this mod is enabled.");
         }
     }
     catch (Exception e)
     {
         Debug.LogException(e);
         DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "[NG+] " + e.GetType() + ": " + e.Message);
     }
 }
Пример #19
0
        public void OnDisabled()
        {
            if (_doorstopManager != null)
            {
                if (_doorstopManager.IsInstalled() && !_pluginInfo.isEnabled)
                {
                    _doorstopManager.Disable();
                }

                if (_doorstopManager.RequiresRestart)
                {
                    ShowRestartGameModal($"The '{Name}' was uninstalled.\n{_doorstopManager.UninstallMessage}", logger: _logger);
                    Debug.Log($"The '{Name}' was uninstalled \n{_doorstopManager.InstallMessage}");
                }

                _doorstopManager = null;
            }
            _pluginInfo = null;
            _logger     = null;
            _patchLoaderConfigFilePath = null;
            _configManager             = null;

            Debug.Log("PatchLoader disabled");
        }
Пример #20
0
 private void onWaitComplete(UIPanel roadOptionsPanel)
 {
     Logger.Info(nameof(onWaitComplete));
     using (IEnumerator <PluginManager.PluginInfo> enumerator = Singleton <PluginManager> .get_instance().GetPluginsInfo().GetEnumerator())
     {
         while (((IEnumerator)enumerator).MoveNext())
         {
             PluginManager.PluginInfo current         = enumerator.Current;
             PublishedFileId          publishedFileId = current.get_publishedFileID();
             bool flag = ((PublishedFileId) ref publishedFileId).get_AsUInt64() == 543722850UL;
             Logger.Info((flag && current.get_isEnabled()).ToString() ?? "");
             if (flag)
             {
                 break;
             }
         }
     }
     if (this.loading.get_currentMode() != null || LoadingExtension.Ui != null)
     {
         return;
     }
     LoadingExtension.Ui = new ZoningTogglesUI();
     LoadingExtension.Ui.CreateButtons(roadOptionsPanel);
 }
        private static bool VerifyModEnabled(ulong modId)
        {
            PluginManager.PluginInfo pluginInfo = Singleton <PluginManager> .instance.GetPluginsInfo().FirstOrDefault((PluginManager.PluginInfo pi) => pi.publishedFileID.AsUInt64 == modId);

            return(!(pluginInfo == null || !pluginInfo.isEnabled));
        }
Пример #22
0
        public void OnEnabled()
        {
            gameVersionSupported = true;
            _pluginInfo          = PluginManager.instance.FindPluginInfo(Assembly.GetExecutingAssembly());
            EnsureLogsDirectoryCreated();
            _logger = new Utils.Logger(Path.Combine(Path.Combine(Application.dataPath, "Logs"), "PatchLoaderMod.log"));
            Version gameVersion = GameVersionCheck.GetVersion(BuildConfig.applicationVersion);

            _logger.Info($"Detected game version {gameVersion} from string [{BuildConfig.applicationVersion}]");
            if (!GameVersionCheck.IsGameVersionSupported(gameVersion))
            {
                _logger.Error($"Game version is not supported! ({BuildConfig.applicationVersion})");
                gameVersionSupported = false;
                ShowExceptionModal($"The '{Name}'\nGame version is not supported!\n\n" +
                                   "Mod will disable itself.\n" +
                                   "Update game to the latest version and try again or remove/unsubscribe mod.\n",
                                   () => {
                    _pluginInfo.isEnabled = false;
                });
                return;
            }

            _patchLoaderConfigFilePath = Path.Combine(DataLocation.applicationBase, "PatchLoader.Config.xml");
            _configManager             = new ConfigManager <Config>(_patchLoaderConfigFilePath, _logger);
            _configManager.EnsureCreated(Config.InitialValues());

            var expectedTargetAssemblyPath = PathExtensions.Combine(
                _pluginInfo.modPath,
                "PatchLoader",
                "PatchLoader.dll"
                );

            _doorstopManager = DoorstopManager.Create(expectedTargetAssemblyPath, _logger, _configManager);

            if (!_doorstopManager.PlatformSupported)
            {
                ShowExceptionModal($"The '{Name}'\nPlatform(MacOS) is not supported yet.\n\n" +
                                   "Mod will disable itself.\n" +
                                   "Follow FPS Booster and PatchLoader mod development to stay informed about changes.\n" +
                                   "Platform(MacOS) support will be added in one of the next major updates for PatchLoader mod.",
                                   () => {
                    _pluginInfo.isEnabled = false;
                });
                return;
            }
            SaveOrUpdateWorkshopPath();

            var config = _configManager.Load();

            if (config.UpgradeInProgress)
            {
                Debug.Log("PatchLoader enabled. Upgrade in progress");
                UpdateUpgradeStage();
                return;
            }

            if (!_doorstopManager.IsInstalled())
            {
                _doorstopManager.Install();
                UpdateUpgradeStage();
            }
            else if (_doorstopManager.IsInstalled() &&
                     _doorstopManager.UpgradeManager.State == UpgradeState.Latest &&
                     _doorstopManager.CanEnable &&
                     !_doorstopManager.IsEnabled()
                     )
            {
                _doorstopManager.Enable();
            }
            else
            {
                UpdateUpgradeStage();
            }

            if (_doorstopManager.RequiresRestart)
            {
                ShowRestartGameModal($"The '{Name}' was installed.\n{_doorstopManager.InstallMessage}", logger: _logger);
                Debug.Log($"The '{Name}' was installed.\n{_doorstopManager.InstallMessage}");
            }
            Debug.Log("PatchLoader enabled");
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PluginInfoProxy"/> class.
 /// </summary>
 /// <param name="originalPluginInfo">The original plugin information.</param>
 public PluginInfoProxy(PluginManager.PluginInfo originalPluginInfo)
 {
     this.OriginalPluginInfo = originalPluginInfo;
 }
Пример #24
0
 public ModInfo()
 {
     this.pluginInfo = getPluginInfo();
 }
Пример #25
0
        public DataGridViewRow GetRow(PluginManager.PluginInfo pluginInfo)
        {
            int rowIndex = ModList.Filtered.IndexOf(pluginInfo);

            return(Rows[rowIndex]);
        }
Пример #26
0
 static bool IsUUIMod(this PluginManager.PluginInfo p) =>
 p.userModInstance.GetType().Assembly.GetType(UUI_NAME) != null;
 public ModInfo()
 {
     this.pluginInfo = getPluginInfo();
 }
Пример #28
0
        // default constructor
        public BetterLoadMod()
        {
            try
            {
                if (PluginManager.instance == null || PluginManager.instance.GetPluginsInfo() == null)
                {
                    //DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "BetterLoadPanel quitting, PluginManager.instance is null");
                    return;
                }

                DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "BetterLoadPanel initializing");

                // the very first thing we need to do is check if we're enabled.  This constructor
                // is called even if we're marked as not to be loaded, so if not enabled, don't do anything
                PluginManager.PluginInfo myPluginInfo = null;
                foreach (PluginManager.PluginInfo info in PluginManager.instance.GetPluginsInfo())
                {
                    //DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "pugins: " + info.name + ", id: " + info.publishedFileID.ToString());

                    if (info.name == "BetterLoadPanel" || info.publishedFileID.AsUInt64 == 413584409)
                    {
                        myPluginInfo = info;
                        break;
                    }
                }

                if (myPluginInfo == null)
                {
                    DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "BetterLoadPanel plugin not found");

                    return;
                }

                // we need to be notified if our mod is disabled, so we can remove our added buttons
                // this also handles being enabled, and re-adding buttons
                PluginManager.instance.eventPluginsChanged      += () => { this.EvaluateStatus(); };
                PluginManager.instance.eventPluginsStateChanged += () => { this.EvaluateStatus(); };

                // register for locale changes so we can updat button
                LocaleManager.eventLocaleChanged += () => { this.LocaleHasChanged(); };

                // create our panel now
                PanelWrapper = (BetterLoadPanelWrapper)UIView.GetAView().AddUIComponent(typeof(BetterLoadPanelWrapper));

                PanelWrapper.isVisible = false;
                PanelWrapper.Initialize();

                if (!myPluginInfo.isEnabled)
                {
                    DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "BetterLoadPanel disabled");
                    return;
                }

                DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Message, "BetterLoadPanel enabled");

                if (!IsMainMenuUpdated())
                {
                    AddMainMenuButton();
                }
            }
            catch (Exception ex)
            {
                DebugOutputPanel.AddMessage(ColossalFramework.Plugins.PluginManager.MessageType.Error, "BetterLoadPanel exception thrown in constructor: " + ex.Message);
            }
        }