This class enables communication between different instance of the mod manager.
Only one instance of the client can be running per game mode. This class listens for messages sent from other instances of the mod manager to be processed.
상속: System.MarshalByRefObject, IMessager
예제 #1
0
		/// <summary>
		/// Starts up the IPC listner channel to wait for message from other instances.
		/// </summary>
		/// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param>
		/// <param name="p_gmdGameModeInfo">The descriptor of the game mode for which mods are being managed.</param>
		/// <param name="p_mmgModManager">The mod manager to use to manage mods.</param>
		/// <param name="p_frmMainForm">The main application form.</param>
		public static IMessager InitializeListener(EnvironmentInfo p_eifEnvironmentInfo, IGameModeDescriptor p_gmdGameModeInfo, ModManager p_mmgModManager, MainForm p_frmMainForm)
		{
			if (m_schMessagerChannel != null)
				throw new InvalidOperationException("The IPC Channel has already been created as a SERVER.");

			string strUri = String.Format("{0}-{1}IpcServer", p_eifEnvironmentInfo.Settings.ModManagerName, p_gmdGameModeInfo.ModeId);
			m_schMessagerChannel = new IpcServerChannel(strUri);
			ChannelServices.RegisterChannel(m_schMessagerChannel, true);
			MessagerServer msgMessager = new MessagerServer(p_mmgModManager, p_frmMainForm);
			string strEndpoint = String.Format("{0}Listener", p_gmdGameModeInfo.ModeId);
			RemotingServices.Marshal(msgMessager, strEndpoint, typeof(IMessager));

			strUri += "/" + strEndpoint;
			string strTraceInfo = String.Format("Setting up listener on {0} at {1}", strUri, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			Trace.TraceInformation(strTraceInfo);

			return msgMessager;
		}
예제 #2
0
        /// <summary>
        /// Starts up the IPC listner channel to wait for message from other instances.
        /// </summary>
        /// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param>
        /// <param name="p_gmdGameModeInfo">The descriptor of the game mode for which mods are being managed.</param>
        /// <param name="p_mmgModManager">The mod manager to use to manage mods.</param>
        /// <param name="p_frmMainForm">The main application form.</param>
        public static IMessager InitializeListener(EnvironmentInfo p_eifEnvironmentInfo, IGameModeDescriptor p_gmdGameModeInfo, ModManager p_mmgModManager, MainForm p_frmMainForm)
        {
            if (m_schMessagerChannel != null)
            {
                throw new InvalidOperationException("The IPC Channel has already been created as a SERVER.");
            }

            string strUri = String.Format("{0}-{1}IpcServer", CommonData.ModManagerName, p_gmdGameModeInfo.ModeId);

            m_schMessagerChannel = new IpcServerChannel(strUri);
            ChannelServices.RegisterChannel(m_schMessagerChannel, true);
            MessagerServer msgMessager = new MessagerServer(p_mmgModManager, p_frmMainForm);
            string         strEndpoint = String.Format("{0}Listener", p_gmdGameModeInfo.ModeId);

            RemotingServices.Marshal(msgMessager, strEndpoint, typeof(IMessager));

            strUri += "/" + strEndpoint;
            string strTraceInfo = String.Format("Setting up listener on {0} at {1}", strUri, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            Trace.TraceInformation(strTraceInfo);

            return(msgMessager);
        }
예제 #3
0
        /// <summary>
        /// Runs the applications
        /// </summary>
        /// <remarks>
        /// This method makes sure the environment is sane. If so, it creates the required services
        /// and launches the main form.
        /// </remarks>
        /// <param name="args">The command line arguments passed to the application.</param>
        /// <returns><c>true</c> if the application started as expected;
        /// <c>false</c> otherwise.</returns>
        public bool RunMainForm(string[] args)
        {
            if (!SandboxCheck(_environmentInfo))
            {
                return(false);
            }

            SetCompressorPath(_environmentInfo);

            var deletedDll = CheckModScriptDLL();

            string requestedGameMode = null;

            Uri modToAdd = null;

            if (args.Length > 0 && !args[0].StartsWith("-"))
            {
                if (Uri.TryCreate(args[0], UriKind.Absolute, out modToAdd) && modToAdd.Scheme.Equals("nxm", StringComparison.OrdinalIgnoreCase))
                {
                    requestedGameMode = DetermineRequestedGameMode(modToAdd.Host);
                }
            }
            else
            {
                for (var i = 0; i < args.Length; i++)
                {
                    var strArg = args[i];

                    if (strArg == "-game")
                    {
                        requestedGameMode = args[i + 1];
                        Trace.Write("Game Specified On Command line: " + requestedGameMode + ") ");
                    }
                }
            }

            var changeDefaultGameMode = false;
            var supportedGames        = GetSupportedGameModes();

            do
            {
                var fontSetResolver = SetUpFonts();

                var installedGames = GetInstalledGameModes(supportedGames);

                if (installedGames == null)
                {
                    Trace.TraceInformation("No installed games.");
                    MessageBox.Show($"No games were detected! {_environmentInfo.Settings.ModManagerName} will now close.", "No Games", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(false);
                }

                CheckIfDefaultGameModeIsInstalled(installedGames);

                var selector        = new GameModeSelector(supportedGames, installedGames, _environmentInfo);
                var gameModeFactory = selector.SelectGameMode(requestedGameMode, changeDefaultGameMode);

                if (selector.RescanRequested)
                {
                    _environmentInfo.Settings.InstalledGamesDetected = false;
                    _environmentInfo.Settings.Save();
                    changeDefaultGameMode = true;
                    continue;
                }

                if (gameModeFactory == null)
                {
                    return(false);
                }

                Trace.TraceInformation($"Game Mode Factory Selected: {gameModeFactory.GameModeDescriptor.Name} ({gameModeFactory.GameModeDescriptor.ModeId})");

                Mutex gameModeMutex = null;
                var   ownsMutex     = false;

                try
                {
                    for (var attemptCount = 0; attemptCount < 3; attemptCount++)
                    {
                        Trace.TraceInformation($"Creating Game Mode mutex (Attempt: {attemptCount})");
                        gameModeMutex = new Mutex(true, $"{_environmentInfo.Settings.ModManagerName}-{gameModeFactory.GameModeDescriptor.ModeId}-GameModeMutex", out ownsMutex);

                        //If the mutex is owned, you are the first instance of the mod manager for game mode, so break out of loop.
                        if (ownsMutex)
                        {
                            break;
                        }

                        try
                        {
                            //If the mutex isn't owned, attempt to talk across the messager.
                            using (var messager = MessagerClient.GetMessager(_environmentInfo, gameModeFactory.GameModeDescriptor))
                            {
                                if (messager != null)
                                {
                                    //Messenger was created OK, send download request, or bring to front.
                                    if (modToAdd != null)
                                    {
                                        Trace.TraceInformation($"Messaging to add: {modToAdd}");
                                        messager.AddMod(modToAdd.ToString());
                                    }
                                    else
                                    {
                                        Trace.TraceInformation("Messaging to bring to front.");
                                        messager.BringToFront();
                                    }

                                    return(true);
                                }
                            }

                            gameModeMutex.Close();
                            gameModeMutex = null;
                        }
                        catch (InvalidOperationException)
                        {
                            var stbPromptMessage = new StringBuilder();
                            stbPromptMessage.AppendLine($"{_environmentInfo.Settings.ModManagerName} was unable to start. It appears another instance of {_environmentInfo.Settings.ModManagerName} is already running.");
                            stbPromptMessage.AppendLine($"If you were trying to download multiple files, wait for {_environmentInfo.Settings.ModManagerName} to start before clicking on a new file download.");
                            MessageBox.Show(stbPromptMessage.ToString(), "Already running", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return(false);
                        }

                        //Messenger couldn't be created, so sleep for a few seconds to give time for opening
                        // the running copy of the mod manager to start up/shut down
                        Thread.Sleep(TimeSpan.FromSeconds(5.0d));
                    }

                    if (!ownsMutex)
                    {
                        var htlListener = (HeaderlessTextWriterTraceListener)Trace.Listeners["DefaultListener"];
                        htlListener.ChangeFilePath(Path.Combine(Path.GetDirectoryName(htlListener.FilePath), "Messager" + Path.GetFileName(htlListener.FilePath)));

                        Trace.TraceInformation("THIS IS A MESSAGER TRACE LOG.");

                        if (!htlListener.TraceIsForced)
                        {
                            htlListener.SaveToFile();
                        }

                        var stbPromptMessage = new StringBuilder();
                        stbPromptMessage.AppendLine($"{_environmentInfo.Settings.ModManagerName} was unable to start. It appears another instance of {_environmentInfo.Settings.ModManagerName} is already running.");
                        stbPromptMessage.AppendLine("A Trace Log file was created at:");
                        stbPromptMessage.AppendLine(htlListener.FilePath);
                        stbPromptMessage.AppendLine("Before reporting the issue, don't close this window and check for a fix here (you can close it afterwards):");
                        stbPromptMessage.AppendLine(NexusLinks.FAQs);
                        stbPromptMessage.AppendLine("If you can't find a solution, please make a bug report and attach the TraceLog file here:");
                        stbPromptMessage.AppendLine(NexusLinks.Issues);
                        MessageBox.Show(stbPromptMessage.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        return(false);
                    }

                    ApplicationInitializer appInitializer = null;

                    while ((appInitializer == null) || (appInitializer.Status == TaskStatus.Retrying))
                    {
                        appInitializer = new ApplicationInitializer(_environmentInfo, fontSetResolver, deletedDll);
                        var appInitializerForm = new ApplicationInitializationForm(appInitializer);
                        appInitializer.Initialize(gameModeFactory, SynchronizationContext.Current);
                        appInitializerForm.ShowDialog();
                    }

                    if (appInitializer.Status != TaskStatus.Complete)
                    {
                        if (appInitializer.Status == TaskStatus.Error)
                        {
                            return(false);
                        }

                        changeDefaultGameMode = true;
                        DisposeServices(appInitializer.Services);

                        continue;
                    }

                    var gameMode = appInitializer.GameMode;
                    var services = appInitializer.Services;

                    var mainFormViewModel = new MainFormVM(_environmentInfo, installedGames, gameMode, services.ModRepository, services.DownloadMonitor, services.ModActivationMonitor, services.ModManager, services.PluginManager);
                    var mainForm          = new MainForm(mainFormViewModel);

                    using (var msgMessager = MessagerServer.InitializeListener(_environmentInfo, gameMode, services.ModManager, mainForm))
                    {
                        if (modToAdd != null)
                        {
                            Trace.TraceInformation("Adding mod: " + modToAdd);
                            msgMessager.AddMod(modToAdd.ToString());
                            modToAdd = null;
                        }

                        Trace.TraceInformation("Running Application.");

                        try
                        {
                            Application.Run(mainForm);
                            services.ModInstallLog.Backup();
                            requestedGameMode     = mainFormViewModel.RequestedGameMode;
                            changeDefaultGameMode = mainFormViewModel.DefaultGameModeChangeRequested;
                        }
                        finally
                        {
                            DisposeServices(services);
                            gameMode.Dispose();
                        }
                    }
                }
                finally
                {
                    if (gameModeMutex != null)
                    {
                        if (ownsMutex)
                        {
                            gameModeMutex.ReleaseMutex();
                        }

                        gameModeMutex.Close();
                    }

                    FileUtil.ForceDelete(_environmentInfo.TemporaryPath);

                    //Clean up created font's.
                    FontManager.Dispose();
                }
            } while (!string.IsNullOrEmpty(requestedGameMode) || changeDefaultGameMode);

            return(true);
        }
        /// <summary>
        /// Runs the applications
        /// </summary>
        /// <remarks>
        /// This method makes sure the environment is sane. If so, it creates the required services
        /// and launches the main form.
        /// </remarks>
        /// <param name="p_strArgs">The command line arguments passed to the application.</param>
        /// <returns><c>true</c> if the application started as expected;
        /// <c>false</c> otherwise.</returns>
        public bool RunMainForm(string[] p_strArgs)
        {
            if (!SandboxCheck(m_eifEnvironmentInfo))
                return false;
            SetCompressorPath(m_eifEnvironmentInfo);

            string strRequestedGameMode = null;
            string[] strArgs = p_strArgs;
            Uri uriModToAdd = null;
            if ((p_strArgs.Length > 0) && !p_strArgs[0].StartsWith("-"))
            {
                if (Uri.TryCreate(p_strArgs[0], UriKind.Absolute, out uriModToAdd) && uriModToAdd.Scheme.Equals("nxm", StringComparison.OrdinalIgnoreCase))
                    strRequestedGameMode = uriModToAdd.Host;
            }
            else
                for (Int32 i = 0; i < p_strArgs.Length; i++)
                {
                    string strArg = p_strArgs[i];
                    if (strArg.StartsWith("-"))
                    {
                        switch (strArg)
                        {
                            case "-game":
                                strRequestedGameMode = p_strArgs[i + 1];
                                Trace.Write("Game Specified On Command line: " + strRequestedGameMode + ") ");
                                break;
                        }
                    }
                }

            bool booChangeDefaultGameMode = false;
            GameModeRegistry gmrSupportedGames = GetSupportedGameModes();
            do
            {
                NexusFontSetResolver nfrResolver = SetUpFonts();

                GameModeRegistry gmrInstalledGames = GetInstalledGameModes(gmrSupportedGames);
                if (gmrInstalledGames == null)
                {
                    Trace.TraceInformation("No installed games.");
                    MessageBox.Show(String.Format("No games were detected! {0} will now close.", m_eifEnvironmentInfo.Settings.ModManagerName), "No Games", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }

                GameModeSelector gmsSelector = new GameModeSelector(gmrSupportedGames, gmrInstalledGames, m_eifEnvironmentInfo);
                IGameModeFactory gmfGameModeFactory = gmsSelector.SelectGameMode(strRequestedGameMode, booChangeDefaultGameMode);
                if (gmsSelector.RescanRequested)
                {
                    m_eifEnvironmentInfo.Settings.InstalledGamesDetected = false;
                    m_eifEnvironmentInfo.Settings.Save();
                    booChangeDefaultGameMode = true;
                    continue;
                }
                if (gmfGameModeFactory == null)
                    return false;

                Trace.TraceInformation(String.Format("Game Mode Factory Selected: {0} ({1})", gmfGameModeFactory.GameModeDescriptor.Name, gmfGameModeFactory.GameModeDescriptor.ModeId));

                Mutex mtxGameModeMutex = null;
                bool booOwnsMutex = false;
                try
                {
                    for (Int32 intAttemptCount = 0; intAttemptCount < 3; intAttemptCount++)
                    {
                        Trace.TraceInformation("Creating Game Mode mutex (Attempt: {0})", intAttemptCount);
                        mtxGameModeMutex = new Mutex(true, String.Format("{0}-{1}-GameModeMutex", m_eifEnvironmentInfo.Settings.ModManagerName, gmfGameModeFactory.GameModeDescriptor.ModeId), out booOwnsMutex);

                        //If the mutex is owned, you are the first instance of the mod manager for game mode, so break out of loop.
                        if (booOwnsMutex)
                            break;

                        try
                        {
                            //If the mutex isn't owned, attempt to talk across the messager.
                            using (IMessager msgMessager = MessagerClient.GetMessager(m_eifEnvironmentInfo, gmfGameModeFactory.GameModeDescriptor))
                            {
                                if (msgMessager != null)
                                {
                                    //Messenger was created OK, send download request, or bring to front.
                                    if (uriModToAdd != null)
                                    {
                                        Trace.TraceInformation(String.Format("Messaging to add: {0}", uriModToAdd));
                                        msgMessager.AddMod(uriModToAdd.ToString());
                                    }
                                    else
                                    {
                                        Trace.TraceInformation(String.Format("Messaging to bring to front."));
                                        msgMessager.BringToFront();
                                    }
                                    return true;
                                }
                            }
                            mtxGameModeMutex.Close();
                            mtxGameModeMutex = null;
                        }
                        catch (InvalidOperationException)
                        {
                            StringBuilder stbPromptMessage = new StringBuilder();
                            stbPromptMessage.AppendFormat("{0} was unable to start. It appears another instance of {0} is already running.", m_eifEnvironmentInfo.Settings.ModManagerName).AppendLine();
                            stbPromptMessage.AppendFormat("If you were trying to download multiple files, wait for {0} to start before clicking on a new file download.", m_eifEnvironmentInfo.Settings.ModManagerName).AppendLine();
                            MessageBox.Show(stbPromptMessage.ToString(), "Already running", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return false;
                        }
                        //Messenger couldn't be created, so sleep for a few seconds to give time for opening
                        // the running copy of the mod manager to start up/shut down
                        Thread.Sleep(TimeSpan.FromSeconds(5.0d));
                    }
                    if (!booOwnsMutex)
                    {
                        HeaderlessTextWriterTraceListener htlListener = (HeaderlessTextWriterTraceListener)Trace.Listeners["DefaultListener"];
                        htlListener.ChangeFilePath(Path.Combine(Path.GetDirectoryName(htlListener.FilePath), "Messager" + Path.GetFileName(htlListener.FilePath)));
                        Trace.TraceInformation("THIS IS A MESSAGER TRACE LOG.");
                        if (!htlListener.TraceIsForced)
                            htlListener.SaveToFile();

                        StringBuilder stbPromptMessage = new StringBuilder();
                        stbPromptMessage.AppendFormat("{0} was unable to start. It appears another instance of {0} is already running.", m_eifEnvironmentInfo.Settings.ModManagerName).AppendLine();
                        stbPromptMessage.AppendLine("A Trace Log file was created at:");
                        stbPromptMessage.AppendLine(htlListener.FilePath);
                        stbPromptMessage.AppendLine("Before reporting the issue, don't close this window and check for a fix here (you can close it afterwards):");
                        stbPromptMessage.AppendLine(NexusLinks.FAQs);
                        stbPromptMessage.AppendLine("If you can't find a solution, please make a bug report and attach the TraceLog file here:");
                        stbPromptMessage.AppendLine(NexusLinks.Issues);
                        MessageBox.Show(stbPromptMessage.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return false;
                    }

                    //ApplicationInitializer ainInitializer = new ApplicationInitializer(m_eifEnvironmentInfo, nfrResolver);
                    //ApplicationInitializationForm frmAppInitilizer = new ApplicationInitializationForm(ainInitializer);
                    //ainInitializer.Initialize(gmfGameModeFactory, SynchronizationContext.Current);
                    //frmAppInitilizer.ShowDialog();
                    ApplicationInitializer ainInitializer = null;
                    ApplicationInitializationForm frmAppInitilizer = null;
                    while ((ainInitializer == null) || (ainInitializer.Status == TaskStatus.Retrying))
                    {
                        ainInitializer = new ApplicationInitializer(m_eifEnvironmentInfo, nfrResolver);
                        frmAppInitilizer = new ApplicationInitializationForm(ainInitializer);
                        ainInitializer.Initialize(gmfGameModeFactory, SynchronizationContext.Current);
                        frmAppInitilizer.ShowDialog();
                    }

                    if (ainInitializer.Status != TaskStatus.Complete)
                    {
                        if (ainInitializer.Status == TaskStatus.Error)
                            return false;
                        booChangeDefaultGameMode = true;
                        DisposeServices(ainInitializer.Services);
                        continue;
                    }

                    IGameMode gmdGameMode = ainInitializer.GameMode;
                    ServiceManager svmServices = ainInitializer.Services;

                    MainFormVM vmlMainForm = new MainFormVM(m_eifEnvironmentInfo, gmrInstalledGames, gmdGameMode, svmServices.ModRepository, svmServices.DownloadMonitor, svmServices.ActivateModsMonitor, svmServices.UpdateManager, svmServices.ModManager, svmServices.PluginManager);
                    MainForm frmMain = new MainForm(vmlMainForm);

                    using (IMessager msgMessager = MessagerServer.InitializeListener(m_eifEnvironmentInfo, gmdGameMode, svmServices.ModManager, frmMain))
                    {
                        if (uriModToAdd != null)
                        {
                            Trace.TraceInformation("Adding mod: " + uriModToAdd.ToString());
                            msgMessager.AddMod(uriModToAdd.ToString());
                            uriModToAdd = null;
                        }

                        Trace.TraceInformation("Running Application.");
                        try
                        {
                            Application.Run(frmMain);
                            svmServices.ModInstallLog.Backup();
                            strRequestedGameMode = vmlMainForm.RequestedGameMode;
                            booChangeDefaultGameMode = vmlMainForm.DefaultGameModeChangeRequested;
                        }
                        finally
                        {
                            DisposeServices(svmServices);
                            gmdGameMode.Dispose();
                        }
                    }
                }
                finally
                {
                    if (mtxGameModeMutex != null)
                    {
                        if (booOwnsMutex)
                            mtxGameModeMutex.ReleaseMutex();
                        mtxGameModeMutex.Close();
                    }
                    FileUtil.ForceDelete(m_eifEnvironmentInfo.TemporaryPath);

                    //Clean up created font's.
                    FontManager.Dispose();
                }
            } while (!String.IsNullOrEmpty(strRequestedGameMode) || booChangeDefaultGameMode);
            return true;
        }