/// <summary> /// Creates a new instance of <see cref="GpcmServer"/> /// </summary> /// <param name="bindTo"></param> public GpcmServer(IPEndPoint bindTo) : base(bindTo, MaxConnections) { // Register for events GpcmClient.OnSuccessfulLogin += GpcmClient_OnSuccessfulLogin; GpcmClient.OnDisconnect += GpcmClient_OnDisconnect; // Setup timer. Every 15 seconds should be sufficient if (PollTimer == null || !PollTimer.Enabled) { PollTimer = new System.Timers.Timer(15000); PollTimer.Elapsed += (s, e) => { // Send keep alive to all connected clients if (Clients.Count > 0) { Parallel.ForEach(Clients.Values, client => client.SendKeepAlive()); } // Disconnect hanging connections if (Processing.Count > 0) { Parallel.ForEach(Processing.Values, client => CheckTimeout(client)); } }; PollTimer.Start(); } // Setup timer. Every 5 seconds should be sufficient if (StatusTimer == null || !StatusTimer.Enabled) { StatusTimer = new System.Timers.Timer(5000); StatusTimer.Elapsed += (s, e) => { // Return if we are empty if (PlayerStatusQueue.IsEmpty) { return; } // Open database connection using (Database.GamespyDatabase db = new Database.GamespyDatabase()) using (var transaction = db.BeginTransaction()) { try { var timestamp = DateTime.UtcNow.ToUnixTimestamp(); PlayerStatusUpdate result; while (PlayerStatusQueue.TryDequeue(out result)) { // Skip if this player never finished logging in if (!result.Client.CompletedLoginProcess) { continue; } // Only update record under these two status' if (result.Status != LoginStatus.Completed && result.Status != LoginStatus.Disconnected) { continue; } // Update player record db.Execute( "UPDATE player SET online=@P0, lastip=@P1, lastonline=@P2 WHERE id=@P3", (result.Status == LoginStatus.Disconnected) ? 0 : 1, result.Client.RemoteEndPoint.Address, timestamp, result.Client.PlayerId ); } transaction.Commit(); } catch (Exception ex) { ServerManager.Log("[Gpcm..ctor] StatusTimer: " + ex.Message); transaction.Rollback(); } } }; StatusTimer.Start(); } // Set connection handling base.ConnectionEnforceMode = EnforceMode.DuringPrepare; base.FullErrorMessage = Config.GetValue("Settings", "LoginServerFullMessage").Replace("\"", ""); // Begin accepting connections base.StartAcceptAsync(); }
/// <summary> /// Creates a new instance of <see cref="GPCMServer"/> /// </summary> public GPCMServer(DatabaseDriver databaseDriver) : base(databaseDriver) { GPCMClient.OnDisconnect += GpcmClient_OnDisconnect; GPCMClient.OnSuccessfulLogin += GpcmClient_OnSuccessfulLogin; // Setup timer. Every 15 seconds should be sufficient if (PollTimer == null || !PollTimer.Enabled) { PollTimer = new System.Timers.Timer(15000); PollTimer.Elapsed += (s, e) => { // Send keep alive to all connected clients if (Clients.Count > 0) { Parallel.ForEach(Clients.Values, client => client.SendKeepAlive()); } // Disconnect hanging connections if (Processing.Count > 0) { Parallel.ForEach(Processing.Values, client => CheckTimeout(client)); } }; PollTimer.Start(); } // Setup timer. Every 5 seconds should be sufficient if (StatusTimer == null || !StatusTimer.Enabled) { StatusTimer = new System.Timers.Timer(5000); StatusTimer.Elapsed += (s, e) => { // Return if we are empty if (PlayerStatusQueue.IsEmpty) { return; } // Open database connection using (var transaction = databaseDriver.BeginTransaction()) { try { long timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); GPCMClient result; while (PlayerStatusQueue.TryDequeue(out result)) { // Skip if this player never finished logging in if (result == null) { continue; } if (!result.CompletedLoginProcess) { continue; } // Only update record under these two status' { // Update player record databaseDriver.Execute( "UPDATE profiles SET status=@P3, lastip=@P0, lastonline=@P1 WHERE profileid=@P2", result.RemoteEndPoint.Address, timestamp, result.PlayerId, (uint)result.PlayerStatus ); } } transaction.Commit(); } catch (Exception ex) { LogWriter.Log.WriteException(ex); transaction.Rollback(); } } }; StatusTimer.Start(); } // Set connection handling ConnectionEnforceMode = EnforceMode.DuringPrepare; // TODO: Change this //FullErrorMessage = Config.GetValue("Settings", "LoginServerFullMessage").Replace("\"", ""); FullErrorMessage = ""; }
/// <summary> /// Creates a new instance of <see cref="GPCMClient"/> /// </summary> public GPCMServer(string serverName, DatabaseDriver driver, IPEndPoint bindTo, int maxConnections) : base(serverName, bindTo, maxConnections) { //GPCMHandler.DBQuery = new GPCMDBQuery(driver); DB = new DBQueryBase(driver); GPCMClient.OnDisconnect += ClientDisconnected; GPCMClient.OnSuccessfulLogin += ClientSuccessfulLogin; // Setup timer. Every 15 seconds should be sufficient if (PollTimer == null || !PollTimer.Enabled) { PollTimer = new System.Timers.Timer(15000); PollTimer.Elapsed += (s, e) => { // Send keep alive to all connected clients if (Clients.Count > 0) { Parallel.ForEach(Clients.Values, client => KAHandler.SendKeepAlive(client)); } // DisconnectByReason hanging connections if (Processing.Count > 0) { Parallel.ForEach(Processing.Values, client => CheckTimeout(client)); } }; PollTimer.Start(); } // Setup timer. Every 5 seconds should be sufficient if (StatusTimer == null || !StatusTimer.Enabled) { StatusTimer = new System.Timers.Timer(5000); StatusTimer.Elapsed += (s, e) => { // Return if we are empty if (PlayerStatusQueue.IsEmpty) { return; } //var transaction =DB.BeginTransaction(); try { long timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds(); GPCMClient result; while (PlayerStatusQueue.TryDequeue(out result)) { // Skip if this player never finished logging in if (result == null) { continue; } if (!result.CompletedLoginProcess) { continue; } LoginQuery.UpdateStatus(timestamp, result.RemoteEndPoint.Address, result.PlayerInfo.PlayerId, (uint)result.PlayerInfo.PlayerStatus); } //transaction.Commit(); } catch (Exception ex) { LogWriter.Log.WriteException(ex); // transaction.Rollback(); } }; StatusTimer.Start(); } // Set connection handling ConnectionEnforceMode = EnforceMode.DuringPrepare; // TODO: Change this //FullErrorMessage = Config.GetValue("Settings", "LoginServerFullMessage").Replace("\"", ""); FullErrorMessage = ""; StartAcceptAsync(); }