Example #1
0
        public LaunchManagerResult LaunchGameHandlingDelaysAndTitles(BackgroundWorker worker)
        {
            var result = new LaunchManagerResult();

            if (worker.CancellationPending)
            {
                return(result);
            }
            DateTime lastLaunchUtc = (_accountLaunchTimes.ContainsKey(_launchItem.AccountName)
                                       ? _accountLaunchTimes[_launchItem.AccountName]
                                       : DateTime.MinValue);
            // Add a 5 second delay before launching the same account. EMU servers won't have cross-server timouts like Live servers did.
            TimeSpan         delay            = new TimeSpan(0, 0, 5) - (DateTime.UtcNow - lastLaunchUtc);
            GameLaunchResult gameLaunchResult = null;

            while (delay.TotalMilliseconds > 0)
            {
                if (worker.CancellationPending)
                {
                    return(result);
                }
                string context = string.Format("Waiting {0} sec", (int)delay.TotalSeconds + 1);
                ReportStatus(context, _launchItem);

                System.Threading.Thread.Sleep(1000);
                delay = new TimeSpan(0, 0, 5) - (DateTime.UtcNow - lastLaunchUtc);
            }

            ReportStatus("Launching", _launchItem);
            _accountLaunchTimes[_launchItem.AccountName] = DateTime.UtcNow;

            var launcher = new GameLauncher();

            launcher.ReportGameStatusEvent += (o) => { ReportStatus(o, _launchItem); };
            launcher.StopLaunchEvent       += (o, eventArgs) => { return(worker.CancellationPending); };
            try
            {
                var finder = new ThwargUtils.WindowFinder();
                finder.RecordExistingWindows();
                string launcherPath = GetLaunchItemLauncherLocation(_launchItem);
                OverridePreferenceFile(_launchItem.CustomPreferencePath);
                gameLaunchResult = launcher.LaunchGameClient(
                    launcherPath,
                    _launchItem.ServerName,
                    accountName: _launchItem.AccountName,
                    password: _launchItem.Password,
                    ipAddress: _launchItem.IpAndPort,
                    emu: _launchItem.EMU,
                    desiredCharacter: _launchItem.CharacterSelected,
                    rodatSetting: _launchItem.RodatSetting,
                    simpleLaunch: _launchItem.IsSimpleLaunch
                    );
                if (!gameLaunchResult.Success)
                {
                    return(result);
                }
                string gameCaptionPattern = ConfigSettings.GetConfigString("GameCaptionPattern", null);
                if (gameCaptionPattern != null)
                {
                    var    regex = new System.Text.RegularExpressions.Regex(gameCaptionPattern);
                    IntPtr hwnd  = finder.FindNewWindow(regex);
                    if (hwnd != IntPtr.Zero)
                    {
                        string newGameTitle = GetNewGameTitle(_launchItem);
                        if (!string.IsNullOrEmpty(newGameTitle))
                        {
                            finder.SetWindowTitle(hwnd, newGameTitle);
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                ReportStatus("Exception launching game launcher: " + exc.Message, _launchItem);
                return(result);
            }
            if (gameLaunchResult != null && gameLaunchResult.Success)
            {
                result.Success   = true;
                result.ProcessId = gameLaunchResult.ProcessId;
            }
            return(result);
        }
Example #2
0
        /// <summary>
        /// Read all process files
        ///  Check if any characters have changed
        /// </summary>
        private void PerformReadProcessFiles()
        {
            foreach (var gameSession in _map.GetAllGameSessions())
            {
                string heartbeatFile = gameSession.ProcessStatusFilepath;
                if (string.IsNullOrEmpty(heartbeatFile))
                {
                    // This occurs when launching game session
                    continue;
                }
                var response = ThwargFilter.LaunchControl.GetHeartbeatStatus(heartbeatFile);
                if (!response.IsValid)
                {
                    Logger.WriteError(string.Format("Invalid contents in heartbeat file: {0}", heartbeatFile));
                    continue;
                }
                var status = GetStatusFromHeartbeatFileTime(gameSession);

                if (!response.Status.IsOnline)
                {
                    int gameInteractionTimeoutSeconds = ConfigSettings.GetConfigInt("GameInteractionTimeoutSeconds", 120);
                    // ThwargFilter reports !IsOnline if server dispatch quits firing
                    // but that isn't reliable, as it doesn't fire when not logged in to a character
                    if (response.Status.LastServerDispatchSecondsAgo > gameInteractionTimeoutSeconds)
                    {
                        status = ServerAccountStatusEnum.None;
                        Logger.WriteInfo("Killing offline/character screen game");
                    }
                }
                else
                {
                    _lastOnlineTimeUtc = DateTime.UtcNow;
                }

                if (status == ServerAccountStatusEnum.None)
                {
                    if (!Globals.NeverKillClients)
                    {
                        Process p = TryGetProcessFromId(response.Status.ProcessId);
                        if (p != null)
                        {
                            p.Kill();
                            File.Delete(heartbeatFile);
                            _map.RemoveGameSessionByProcessId(p.Id);
                            Logger.WriteDebug("Killing process: " + p.Id.ToString());
                            OnGameDied(new EventArgs());
                        }
                    }
                }

                bool newGame       = false;
                bool changedGame   = false;
                bool changedStatus = false;
                if (gameSession.AccountName == null)
                {
                    newGame = true;
                }
                else if (gameSession.AccountName != response.Status.AccountName ||
                         gameSession.ServerName != response.Status.ServerName)
                {
                    // This doesn't make sense and shouldn't happen
                    // Account & Server should be fixed for the life of a game session
                    Logger.WriteError(string.Format("Account/Server change in heartbeat file!: {0}", heartbeatFile));
                    changedGame = true;
                }
                else if (gameSession.CharacterName != response.Status.CharacterName)
                {
                    changedGame = true;
                }
                else if (gameSession.Status != status)
                {
                    changedStatus      = true;
                    gameSession.Status = status;
                }
                UpdateGameSessionFromHeartbeatStatus(gameSession, heartbeatFile, response);
                if (newGame)
                {
                    NotifyGameChange(gameSession, GameChangeType.StartGame);
                }
                else if (changedGame)
                {
                    NotifyGameChange(gameSession, GameChangeType.ChangeGame);
                }
                else if (changedStatus)
                {
                    NotifyGameChange(gameSession, GameChangeType.ChangeStatus);
                }
            }
            _lastReadProcesFilesUtc = DateTime.UtcNow;
        }