예제 #1
0
        /// <summary>
        /// Callback for a successful login
        /// </summary>
        /// <param name="sender">The GpcmClient that is logged in</param>
        private void GpcmClient_OnSuccessfulLogin(object sender)
        {
            // Wrap this in a try/catch
            try
            {
                GPCMClient oldC;
                GPCMClient client = sender as GPCMClient;

                // Remove connection from processing
                Processing.TryRemove(client.ConnectionId, out oldC);

                // Check to see if the client is already logged in, if so disconnect the old user
                if (Clients.TryRemove(client.PlayerId, out oldC))
                {
                    oldC.Disconnect(DisconnectReason.NewLoginDetected);
                    LogWriter.Log.Write("Login Clash:   {0} - {1} - {2}", LogLevel.Information, client.PlayerNick, client.PlayerId, client.RemoteEndPoint);
                }

                // Add current client to the dictionary
                if (!Clients.TryAdd(client.PlayerId, client))
                {
                    LogWriter.Log.Write("ERROR: [GpcmServer._OnSuccessfulLogin] Unable to add client to HashSet.", LogLevel.Error);
                }

                // Add player to database queue
                PlayerStatusQueue.Enqueue(client);
            }
            catch (Exception E)
            {
                LogWriter.Log.WriteException(E);
            }
        }
예제 #2
0
        /// <summary>
        /// Callback for when a connection had disconnected
        /// </summary>
        /// <param name="client">The client object whom is disconnecting</param>
        private void GpcmClient_OnDisconnect(GPCMClient client)
        {
            // If we are exiting, don't do anything here.
            if (Exiting)
            {
                return;
            }

            // Remove client, and call OnUpdate Event
            try
            {
                // Remove client from online list
                if (Clients.TryRemove(client.PlayerId, out client) && !client.Disposed)
                {
                    client.Dispose();
                }

                // Add player to database queue
                PlayerStatusQueue.Enqueue(client);
            }
            catch (Exception e)
            {
                LogWriter.Log.Write("An Error occured at [GpcmServer._OnDisconnect] : Generating Exception Log {0}", LogLevel.Error, e.ToString());
            }
        }
예제 #3
0
        /// <summary>
        /// Callback for a successful login
        /// </summary>
        /// <param name="sender">The GpcmClient that is logged in</param>
        private void GpcmClient_OnSuccessfulLogin(object sender)
        {
            // Wrap this in a try/catch
            try
            {
                GpcmClient oldC;
                GpcmClient client = sender as GpcmClient;

                // Remove connection from processing
                Processing.TryRemove(client.ConnectionId, out oldC);

                // Check to see if the client is already logged in, if so disconnect the old user
                if (Clients.TryRemove(client.PlayerId, out oldC))
                {
                    oldC.Disconnect(DisconnectReason.NewLoginDetected);
                    ServerManager.Log("Login Clash:   {0} - {1} - {2}", client.PlayerNick, client.PlayerId, client.RemoteEndPoint);
                }

                // Add current client to the dictionary
                if (!Clients.TryAdd(client.PlayerId, client))
                {
                    Program.ErrorLog.Write("ERROR: [GpcmServer._OnSuccessfulLogin] Unable to add client to HashSet.");
                }

                // Add player to database queue
                var status = new PlayerStatusUpdate(client, LoginStatus.Completed);
                PlayerStatusQueue.Enqueue(status);
            }
            catch (Exception E)
            {
                Program.ErrorLog.Write("ERROR: [GpcmServer._OnSuccessfulLogin] Exception was thrown, Generating exception log.");
                ExceptionHandler.GenerateExceptionLog(E);
            }
        }
예제 #4
0
        /// <summary>
        /// Callback for when a connection had disconnected
        /// </summary>
        /// <param name="client">The client object whom is disconnecting</param>
        private void GpcmClient_OnDisconnect(GpcmClient client)
        {
            // If we are exiting, don't do anything here.
            if (Exiting)
            {
                return;
            }

            // Remove client, and call OnUpdate Event
            try
            {
                // Remove client from online list
                if (Clients.TryRemove(client.PlayerId, out client) && !client.Disposed)
                {
                    client.Dispose();
                }

                // Add player to database queue
                var status = new PlayerStatusUpdate(client, LoginStatus.Disconnected);
                PlayerStatusQueue.Enqueue(status);
            }
            catch (Exception e)
            {
                Program.ErrorLog.Write("An Error occured at [GpcmServer._OnDisconnect] : Generating Exception Log");
                ExceptionHandler.GenerateExceptionLog(e);
            }
        }
예제 #5
0
        public async Task <bool> PlayerStatusQueueConsumer(PlayerStatusQueue message)
        {
            _logger.LogDebug($"Consumer Get Queue {JsonConvert.SerializeObject(message)} ready");

            await _playerStatusHandler.Execute(message.Status);

            if (await Commit())
            {
                //await _bus.RaiseEvent(new ReceivedEmailEvent(playerId)).ConfigureAwait(false);
            }

            return(true);
        }
예제 #6
0
        /// <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 = "";
        }
예제 #7
0
        /// <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();
        }
예제 #8
0
        /// <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();
        }