Exemple #1
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            // Find Assemblies Manually if necessary (Deprecate app.config)
            AppDomain.CurrentDomain.AssemblyResolve += AssemblyFinder.CurrentDomain_AssemblyResolve;

            /* - Initialization - */
            DoSquirrelStuff();

            // Initialize the console.
            ConsoleFunctions.Initialize();

            // Print startup information.
            Banner.PrintBanner();

            // Get Controller Order
            Controllers.PrintControllerOrder();

            // Unlock DLLs, Removes Zone Information which may prevent DLL injection if DLL was downloaded from e.g. Internet Explorer
            DllUnlocker.UnblockDlls();

            // Setup Server
            LoaderServer.SetupServer();

            // Setup libReloaded Debug Bindings
            SetuplibReloadedBindings();

            /* - Option Parsing, Linking - */

            // Parse Arguments
            ParseArguments(args);

            // Start game
            InjectByMethod(args);

            /* - Load and enter main close polling loop - */

            // Add to exited event
            _gameProcess.GetProcessFromReloadedProcess().EnableRaisingEvents = true;
            _gameProcess.GetProcessFromReloadedProcess().Exited += (sender, eventArgs) => ProcessSelfReattach(args);

            // Load modifications for the current game.
            ModLoader.LoadMods(_gameConfig, _gameProcess);

            // Stay alive in the background
            AppDomain.CurrentDomain.ProcessExit += Shutdown;
            Console.CancelKeyPress += Shutdown;

            // Sleep infinitely as much as it is necessary.
            while (true)
            {
                Console.ReadLine();
            }
        }
        /// <summary>
        /// Kicks off the individual mods running inside the target process
        /// specified by our <see cref="_gameProcess"/> variable.
        /// </summary>
        private static void InjectMods(string[] commandLineArguments)
        {
            // Do not reattach on exit for Steam Shims - they should not reboot if shimmed.
            if (commandLineArguments.Contains(Strings.Common.LoaderSettingSteamShim))
            {
                _gameProcess.GetProcessFromReloadedProcess().EnableRaisingEvents = true;
                _gameProcess.GetProcessFromReloadedProcess().Exited += (sender, eventArgs) => Shutdown(null, null);
            }
            else
            {
                _gameProcess.GetProcessFromReloadedProcess().EnableRaisingEvents = true;
                _gameProcess.GetProcessFromReloadedProcess().Exited += (sender, eventArgs) => ProcessSelfReattach(commandLineArguments);
            }


            ModLoader.LoadMods(_gameConfig, _gameProcess);
        }
        /// <summary>
        /// Checks whether to reattach Reloaded Mod Loader if the game process
        /// unexpectedly kills itself and then restarts (a standard for some games' launch procedures).
        /// </summary>
        private static void ProcessSelfReattach(string[] args)
        {
            // Use stopwatch for soft timing.
            Stopwatch timeoutStopWatch = new Stopwatch();

            timeoutStopWatch.Start();

            // Set attach name for reattaching.
            _attachTargetName = Path.GetFileNameWithoutExtension(_gameConfig.ExecutableLocation);

            // Spin trying to get game process until timeout.
            while (timeoutStopWatch.ElapsedMilliseconds < 6000)
            {
                // Grab current already running game, did we find it? Not? Try again.
                ReloadedProcess localGameProcess = ReloadedProcess.GetProcessByName(_attachTargetName);

                if (localGameProcess == null)
                {
                    continue;
                }

                // Ensure we didn't find some background process that was running all along.
                if (localGameProcess.GetProcessFromReloadedProcess().StartTime > _processStartTime)
                {
                    Bindings.PrintInfo($"// Game killed itself, probably due to Steam for restarting. Attempting reattach! | {_attachTargetName}");
                    Bindings.PrintInfo($"// Consider using the Steam shim.");
                    _gameProcess = localGameProcess;

                    // Disconnect all clients
                    foreach (NetPeer peer in LoaderServer.ReloadedServer.GetPeers())
                    {
                        LoaderServer.ReloadedServer.DisconnectPeer(peer);
                    }

                    InjectMods(args);

                    // Wait infinitely.
                    while (true)
                    {
                        Console.ReadLine();
                    }
                }
            }

            // Kill the process itself.
            Shutdown(null, null);
        }
Exemple #4
0
        /// <summary>
        /// Checks whether to reattach Reloaded Mod Loader if the game process
        /// unexpectedly kills itself and then restarts (a standard for some games' launch procedures).
        /// </summary>
        /// <param name="arguments">The commandline arguments originally passed to this process.</param>
        /// <returns>Returns true if another game instance is running, else false.</returns>
        private static void ProcessSelfReattach(string[] arguments)
        {
            // Decides whether
            bool buildArgumentsList = false;

            // Auto re-attach if there's another process instance that's up with matching name.
            // First set the attach name if not set and add to the arguments.
            if (_attachTargetName == null)
            {
                // Set attach name.
                _attachTargetName  = Path.GetFileNameWithoutExtension(_gameConfig.ExecutableLocation);
                buildArgumentsList = true;
            }

            // Use stopwatch for soft timing.
            Stopwatch timeoutStopWatch = new Stopwatch();

            timeoutStopWatch.Start();

            // Spin trying to get game process until timeout.
            while (timeoutStopWatch.ElapsedMilliseconds < 1000)
            {
                // Grab current already running game.
                ReloadedProcess localGameProcess = ReloadedProcess.GetProcessByName(_attachTargetName);

                // Did we find the process? If not, try again.
                if (localGameProcess == null)
                {
                    continue;
                }

                // Suspend the resurrected game.
                localGameProcess.SuspendAllThreads();

                // Check if process is newer than our original game process, if it is, restart self.
                if (localGameProcess.GetProcessFromReloadedProcess().StartTime > _processStartTime)
                {
                    // If the loader is lacking the "attach" flag.
                    // The reason this is done here is because we want to freeze the
                    // target process as soon as possible, such that we can hook onto it as early as possible.
                    if (buildArgumentsList)
                    {
                        // List of arguments.
                        List <string> argumentsList = arguments.ToList();

                        // Append attach argument.
                        argumentsList.Add($"{Strings.Common.LoaderSettingAttach}");

                        // Append attach name.
                        argumentsList.Add(_attachTargetName);

                        // Replace array.
                        arguments = argumentsList.ToArray();
                    }

                    _gameProcess = localGameProcess;
                    RestartSelf(arguments);
                    break;
                }

                // Resume the resurrected game.
                localGameProcess.ResumeAllThreads();
            }

            // Kill the process itself.
            Shutdown(null, null);
        }