/// <summary> /// Method to pull data from an A3 server /// </summary> /// <param name="host">Host name/IP of the A3 server</param> /// <param name="port">Port of the A3 server steam query point (+1 game port)</param> /// <returns>Filled in <see cref="ServerInfo"/> object</returns> public ServerInfo GetServerInfo(string host, int port) { Stopwatch retry = new Stopwatch(); retry.Start(); while (retry.ElapsedMilliseconds < Properties.Settings.Default.retryTimeLimit) { try { using (UdpClient client = new UdpClient(56800)) { IPAddress[] hostEntry = Dns.GetHostAddresses(host); IPEndPoint remoteIpEndpoint = null; if (hostEntry.Length > 0) { remoteIpEndpoint = new IPEndPoint(hostEntry[0], port); } else { remoteIpEndpoint = new IPEndPoint(IPAddress.Parse(host), port); } client.Client.ReceiveTimeout = 20000; client.Connect(remoteIpEndpoint); //Server Info //request general info client.Send(REQUEST_INFO, REQUEST_INFO.Length); Stopwatch ping = new Stopwatch(); ping.Start(); byte[] response = client.Receive(ref remoteIpEndpoint); ping.Stop(); ServerInfo serverInfo = new ServerInfo(response); serverInfo.Ping = ping.ElapsedMilliseconds; //get player info serverInfo.AddPlayers(GetChallengeResponse(PLAYER_BYTE, client, remoteIpEndpoint)); return serverInfo; } } catch (Exception e) { _logger.Warn("Trouble connecting to the server: ", e); if (retry.ElapsedMilliseconds > Properties.Settings.Default.retryTimeLimit) { throw new NoServerInfoException("Trouble connecting to the server"); } else { System.Threading.Thread.Sleep(Properties.Settings.Default.pollRate); } } } return null; }
/// <summary> /// Helper method to update <see cref="Player"/> data in the database /// </summary> /// <param name="playerDAO">DAO for <see cref="Player"/>s</param> /// <param name="session">The current game <see cref="Session"/></param> /// <param name="serverInfo">The current <see cref="ServerInfo"/></param> /// <param name="missionSession">The current <see cref="MissionSession"/></param> /// <returns>The current set of <see cref="PlayerSession"/>s</returns> private ISet<PlayerSession> UpdatePlayerData(PlayerDAO playerDAO, Session session, ServerInfo serverInfo, MissionSession missionSession) { ISet<PlayerSession> playerSessions = playerDAO.GetOrCreatePlayerSessions(serverInfo.Players, session); foreach (PlayerSession playerSession in playerSessions) { playerSession.Updated = true; playerSession.Length += (Settings.Default.pollRate / 1000); if (playerSession.Played == false && CheckPlayedThreshold(playerSession.Length)) { playerSession.Played = true; } } playerDAO.UpdatePlayerSessions(playerSessions); return playerSessions; }
/// <summary> /// Helper method to update <see cref="Mission"/> data in the database /// </summary> /// <param name="missionDAO">DAO for <see cref="Mission"/>s</param> /// <param name="session">The current game <see cref="Session"/></param> /// <param name="serverInfo">The current <see cref="ServerInfo"/></param> /// <param name="missionCount">The number of missions played</param> /// <returns>The current <see cref="MissionSession"/></returns> private MissionSession UpdateMissionData(MissionDAO missionDAO, Session session, ServerInfo serverInfo, ref int missionCount) { MissionSession missionSession = missionDAO.GetOrCreateMissionSession(serverInfo.MapName, serverInfo.Mission, session); missionSession.Updated = true; missionSession.Length += (Settings.Default.pollRate / 1000); if (missionSession.Played == false && CheckPlayedThreshold(missionSession.Length)) { missionSession.Played = true; missionCount++; } missionDAO.UpdateMissionSession(missionSession); return missionSession; }
/// <summary> /// Helper method to update <see cref="Session"/> data in the database /// </summary> /// <param name="sessionDAO">DAO for <see cref="Session"/>s</param> /// <param name="session">The current game <see cref="Session"/></param> /// <param name="serverInfo">The current <see cref="ServerInfo"/></param> private void UpdateSessionData(SessionDAO sessionDAO, Session session, ServerInfo serverInfo) { bool updateSession = false; if (session.MaxPing < serverInfo.Ping) { session.MaxPing = serverInfo.Ping; updateSession = true; } else if (session.MinPing > serverInfo.Ping) { session.MinPing = serverInfo.Ping; updateSession = true; } if (session.MaxPlayers < serverInfo.Players.Count) { session.MaxPlayers = serverInfo.Players.Count; updateSession = true; } if (updateSession) { sessionDAO.UpdateSession(session); } }