Beispiel #1
0
 /// <summary>
 /// Check to see if the <see cref="MissionSession"/> is cached
 /// </summary>
 /// <param name="cachedMissionSession">The current cached <see cref="MissionSession"/></param>
 /// <param name="lookupMissionSession">The current <see cref="MissionSession"/> to check</param>
 /// <returns>True if the cached <see cref="MissionSession"/> matches the lookup <see cref="MissionSession"/></returns>
 private bool IsMissionSessionCached(MissionSession cachedMissionSession, MissionSession lookupMissionSession)
 {
     return(cachedMissionSession != null && cachedMissionSession.Mission != null &&
            cachedMissionSession.Session != null && cachedMissionSession.Mission.Map != null &&
            cachedMissionSession.Mission.Name == lookupMissionSession.Mission.Name &&
            cachedMissionSession.Session.Id == lookupMissionSession.Session.Id &&
            cachedMissionSession.Mission.Map.Name == lookupMissionSession.Mission.Map.Name);
 }
Beispiel #2
0
        /// <summary>
        /// Update the database with the modified <see cref="MissionSession"/> object
        /// </summary>
        /// <param name="missionSession"><see cref="MissionSession"/> object to update</param>
        public void UpdateMissionSession(MissionSession missionSession)
        {
            _updateMissionSession.Parameters[DatabaseUtil.MISSION_TO_SESSION_ID_KEY].Value = missionSession.Id;
            _updateMissionSession.Parameters[DatabaseUtil.LENGTH_KEY].Value = missionSession.Length;
            _updateMissionSession.Parameters[DatabaseUtil.PLAYED_KEY].Value = missionSession.Played;
            _updateMissionSession.ExecuteNonQuery();

            _logger.DebugFormat("Mission session updated on the database with ID: {0}", missionSession.Id);
        }
Beispiel #3
0
        /// <summary>
        /// Helper method to create a <see cref="MissionSession"/> in the database
        /// </summary>
        /// <param name="missionSession"><see cref="MissionSession"/> to create</param>
        /// <returns><see cref="MissionSession"/> with added database id</returns>
        private MissionSession CreateMissionSession(MissionSession missionSession)
        {
            _addMissionSession.Parameters[DatabaseUtil.MISSION_ID_KEY].Value = missionSession.Mission.Id;
            _addMissionSession.Parameters[DatabaseUtil.SESSION_ID_KEY].Value = missionSession.Session.Id;
            _addMissionSession.ExecuteNonQuery();

            missionSession.Id = GetLastInsertedId();
            _logger.DebugFormat("Mission session added to the database with ID: {0}", missionSession.Id);

            return(missionSession);
        }
Beispiel #4
0
        /// <summary>
        /// Gets, or creates a mission session with the provided map name, mission name, and <see cref="Session"/>.
        /// Caches the return value to reduce MySQL interactions and decrease run time
        /// </summary>
        /// <param name="mapName">Name of the map that the server is on</param>
        /// <param name="mission">Name of the mission that the server is on</param>
        /// <param name="session">Current <see cref="Session"/> object</param>
        /// <returns>A full <see cref="MissionSession"/> object with information from the database</returns>
        public MissionSession GetOrCreateMissionSession(string mapName, string mission, Session session)
        {
            MissionSession missionSession = new MissionSession();

            missionSession.Mission     = new Mission(mission);
            missionSession.Mission.Map = new Map(mapName);
            missionSession.Session     = session;

            if (IsMissionSessionCached(_cachedMissionSession, missionSession))
            {
                missionSession = _cachedMissionSession;
                _logger.DebugFormat("Retrieved mission session from cache with ID: {0}", missionSession.Id);
            }
            else
            {
                _getMissionSession.Parameters[DatabaseUtil.NAME_KEY].Value       = missionSession.Mission.Name;
                _getMissionSession.Parameters[DatabaseUtil.SESSION_ID_KEY].Value = session.Id;

                MySqlDataReader getMissionResult = _getMissionSession.ExecuteReader();

                if (getMissionResult.HasRows)
                {
                    bool relinkMap = false;

                    getMissionResult.Read();
                    missionSession.Mission.Id = getMissionResult.GetInt32(0);

                    if (missionSession.Mission.Map.Name.Equals(getMissionResult.GetString(5)))
                    {
                        missionSession.Mission.Map.Id = getMissionResult.GetInt32(4);
                    }
                    else
                    {
                        relinkMap = true;
                    }

                    if (getMissionResult.IsDBNull(1))
                    {
                        getMissionResult.Close();
                        CreateMissionSession(missionSession);
                    }
                    else
                    {
                        missionSession.Id     = getMissionResult.GetInt32(1);
                        missionSession.Length = getMissionResult.GetInt32(2);
                        missionSession.Played = getMissionResult.GetBoolean(3);
                        _logger.DebugFormat("Retrieved mission session from database with ID: {0}", missionSession.Id);

                        getMissionResult.Close();
                    }

                    if (relinkMap)
                    {
                        missionSession.Mission.Map.Id = GetMapId(missionSession.Mission.Map.Name);
                        _updateMission.Parameters[DatabaseUtil.MISSION_ID_KEY].Value = missionSession.Mission.Id;
                        _updateMission.Parameters[DatabaseUtil.MAP_ID_KEY].Value     = missionSession.Mission.Map.Id;

                        _updateMission.ExecuteNonQuery();
                    }
                }
                else
                {
                    getMissionResult.Close();

                    missionSession.Mission.Map.Id = GetMapId(missionSession.Mission.Map.Name);

                    _addMission.Parameters[DatabaseUtil.NAME_KEY].Value   = missionSession.Mission.Name;
                    _addMission.Parameters[DatabaseUtil.MAP_ID_KEY].Value = missionSession.Mission.Map.Id;
                    _addMission.ExecuteNonQuery();

                    missionSession.Mission.Id = GetLastInsertedId();

                    CreateMissionSession(missionSession);
                }
                _cachedMissionSession = missionSession;
            }

            return(missionSession);
        }
Beispiel #5
0
        /// <summary>
        /// Begins reporting on a session, should handle DAOs here
        /// </summary>
        public void StartReporting()
        {
            // define DAO objects to interact with databases
            MySqlConnection connection = null;
            PlayerDAO       playerDAO  = null;
            MissionDAO      missionDAO = null;
            SessionDAO      sessionDAO = null;

            try {
                // create DAO objects to interact with databases
                BuildDAOsIfNeeded(ref connection, ref playerDAO, ref missionDAO, ref sessionDAO);

                ServerInfoService serverInfoService = new ServerInfoService();

                // variables needed to track session playthough
                Session        session = null;
                MissionSession currentMissionSession = null;
                ISet <PlayerMissionSession> currentPlayersToMissionSession = new HashSet <PlayerMissionSession>();
                int  missionCount = 0;
                bool inGame       = false;

                Stopwatch runTime = new Stopwatch();
                runTime.Start();
                try {
                    while (session == null && CheckTimeThreshold(runTime.ElapsedMilliseconds))
                    {
                        try {
                            _logger.Debug("Trying to set up session");
                            session = SetUpSession(serverInfoService, sessionDAO, Settings.Default.armaServerAddress,
                                                   Settings.Default.armaServerPort, ref inGame);
                        } catch (MySqlException e) {
                            _logger.Error("Problem setting up session: ", e);
                            BuildDAOsIfNeeded(ref connection, ref playerDAO, ref missionDAO, ref sessionDAO);
                        }
                        Thread.Sleep(Settings.Default.pollRate);
                    }

                    while (CheckMissionThreshold(missionCount, inGame) && CheckTimeThreshold(runTime.ElapsedMilliseconds))
                    {
                        try {
                            _logger.Debug("Trying to update session details");
                            ServerInfo serverInfo = serverInfoService.GetServerInfo(Settings.Default.armaServerAddress, Settings.Default.armaServerPort);
                            inGame = CheckServerRunningState(serverInfo.ServerState);

                            if (inGame)
                            {
                                if (session.MaxPing < serverInfo.Ping)
                                {
                                    session.MaxPing = serverInfo.Ping;
                                }
                                else if (session.MinPing > serverInfo.Ping)
                                {
                                    session.MinPing = serverInfo.Ping;
                                }

                                if (session.MaxPlayers < serverInfo.Players.Count)
                                {
                                    session.MaxPlayers = serverInfo.Players.Count;
                                }

                                MissionSession missionSession = missionDAO.GetOrCreateMissionSession(serverInfo.MapName, serverInfo.Mission, session);
                                if (currentMissionSession != null && currentMissionSession.Id != missionSession.Id)   // handle case where missions changed between polls
                                {
                                    sessionDAO.UpdateSession(session);
                                    missionDAO.UpdateMissionSession(currentMissionSession);
                                    playerDAO.UpdatePlayerMissionSessions(currentPlayersToMissionSession);

                                    currentPlayersToMissionSession.Clear();
                                }

                                missionSession.Length += (Settings.Default.pollRate / 1000);
                                if (missionSession.Played == false && CheckPlayedThreshold(missionSession.Length))
                                {
                                    missionSession.Played = true;
                                    missionCount++;
                                }

                                currentMissionSession = missionSession;

                                ISet <PlayerMissionSession> playersToMissionSession = playerDAO.GetOrCreatePlayerMissionSessions(serverInfo.Players, missionSession);

                                foreach (PlayerMissionSession playerToMissionSession in playersToMissionSession)
                                {
                                    playerToMissionSession.Length += (Settings.Default.pollRate / 1000);
                                    if (playerToMissionSession.Played == false && CheckPlayedThreshold(playerToMissionSession.Length))
                                    {
                                        playerToMissionSession.Played = true;
                                    }
                                }

                                currentPlayersToMissionSession.UnionWith(playersToMissionSession);
                            }
                            else if (currentMissionSession != null)
                            {
                                sessionDAO.UpdateSession(session);
                                missionDAO.UpdateMissionSession(currentMissionSession);
                                playerDAO.UpdatePlayerMissionSessions(currentPlayersToMissionSession);

                                currentMissionSession = null;
                                currentPlayersToMissionSession.Clear();
                            }
                        } catch (MySqlException e) {
                            _logger.Error("Problem updating session details: ", e);
                            BuildDAOsIfNeeded(ref connection, ref playerDAO, ref missionDAO, ref sessionDAO);
                        }
                        Thread.Sleep(Settings.Default.pollRate);
                    }
                } catch (NoServerInfoException nsie) {
                    _logger.Error("Error reporting", nsie);
                }
            }
            finally {
                // Ensure disposable objects are disposed
                if (playerDAO != null)
                {
                    playerDAO.Dispose();
                }
                if (missionDAO != null)
                {
                    missionDAO.Dispose();
                }
                if (sessionDAO != null)
                {
                    sessionDAO.Dispose();
                }
                if (connection != null)
                {
                    connection.Dispose();
                }
            }
        }
        /// <summary>
        /// Gets or creates a set of <see cref="PlayerMissionSession"/>s from the given list of <see cref="Player"/>s and the current <see cref="Session"/>.
        /// Using caching to reduce MySQL calls and speed up runtime
        /// </summary>
        /// <param name="players">List of <see cref="Player"/>s to get/create</param>
        /// <param name="missionSession">Current <see cref="MissionSession"/></param>
        /// <returns>A set of <see cref="PlayerMissionSession"/> objects, from the database.</returns>
        public ISet <PlayerMissionSession> GetOrCreatePlayerMissionSessions(IList <Player> players, MissionSession missionSession)
        {
            ISet <PlayerMissionSession> playerMissionSessions = new HashSet <PlayerMissionSession>();

            foreach (Player player in players)
            {
                PlayerMissionSession playerToMissionSession = new PlayerMissionSession();
                playerToMissionSession.Player         = player;
                playerToMissionSession.MissionSession = missionSession;

                string key = player.Name + missionSession.Id;
                if (_cachedPlayerMissionSessions.ContainsKey(key))
                {
                    _cachedPlayerMissionSessions.TryGetValue(key, out playerToMissionSession);
                    _logger.DebugFormat("Retrieved player mission session from the cache with ID: {0}", playerToMissionSession.Id);
                }
                else
                {
                    _getPlayerMissionSession.Parameters[DatabaseUtil.NAME_KEY].Value = player.Name;
                    _getPlayerMissionSession.Parameters[DatabaseUtil.MISSION_TO_SESSION_ID_KEY].Value = missionSession.Id;

                    MySqlDataReader getPlayerResult = _getPlayerMissionSession.ExecuteReader();

                    if (getPlayerResult.HasRows)
                    {
                        getPlayerResult.Read();
                        playerToMissionSession.Player.Id = getPlayerResult.GetInt32(0);

                        if (getPlayerResult.GetBoolean(1) != playerToMissionSession.Player.HasClanTag)
                        {
                            playerToMissionSession.Player.Updated = true;
                        }

                        if (getPlayerResult.IsDBNull(2))
                        {
                            getPlayerResult.Close();
                            CreatePlayerMissionSession(playerToMissionSession);
                        }
                        else
                        {
                            playerToMissionSession.Id     = getPlayerResult.GetInt32(2);
                            playerToMissionSession.Length = getPlayerResult.GetInt32(3);
                            playerToMissionSession.Played = getPlayerResult.GetBoolean(4);
                            _logger.DebugFormat("Retrieved player mission session from the database with ID: {0}", playerToMissionSession.Id);

                            getPlayerResult.Close();
                        }
                    }
                    else
                    {
                        getPlayerResult.Close();
                        _addPlayer.Parameters[DatabaseUtil.NAME_KEY].Value         = player.Name;
                        _addPlayer.Parameters[DatabaseUtil.HAS_CLAN_TAG_KEY].Value = player.HasClanTag;
                        _addPlayer.ExecuteNonQuery();

                        playerToMissionSession.Player.Id = GetLastInsertedId();

                        CreatePlayerMissionSession(playerToMissionSession);
                    }
                    _cachedPlayerMissionSessions.Add(key, playerToMissionSession);
                }
                playerMissionSessions.Add(playerToMissionSession);
            }

            return(playerMissionSessions);
        }