예제 #1
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 = SteelFilter.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", 10);
                    // SteelFilter 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)
                {
                    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;
        }