Beispiel #1
0
        /// <summary>
        ///     Polls the simulator, this is where new threads are spun up to simulate different parts of the architecture.
        /// </summary>
        public void Poll()
        {
            // While polling threads, we count them as well
            // so we can decide if we want to spawn any more later.
            int arbitratorThreadCount           = 0;
            int listeningArbitratorThreadCount  = 0;
            int clientThreadCount               = 0;

            // Lost database connection? Reconnect it.
            if (m_running == true && m_aborting == false)
            {
                if (m_databaseConnection == null || m_databaseConnection.Connected == false)
                {
                    SetupDBConnection().Wait();
                    if (m_databaseConnection == null || m_databaseConnection.Connected == false)
                    {
                        return;
                    }
                }
            }

            // Poll simulation threads.
            foreach (SimulatorThread thread in m_threads.ToArray())
            {
                if (thread.IsRunning == false)
                {
                    Logger.Info("Simulator thread #{0} has now finished.", LoggerVerboseLevel.High, thread.ThreadID);
                    m_threads.Remove(thread);
                }
                else if (thread.IsAborting == false)
                {
                    if (thread is ArbitratorSimulatorThread)
                    {
                        ArbitratorSimulatorThread arbitrator = thread as ArbitratorSimulatorThread;
                        if (arbitrator.Service != null && arbitrator.Service.IsListening == true)
                        {
                            listeningArbitratorThreadCount++;
                        }
                        arbitratorThreadCount++;
                    }
                    else if (thread is ClientSimulatorThread)
                    {
                        clientThreadCount++;
                    }
                }
            }

            // Have we stopped running or are we trying to abort?
            if (m_aborting == true || m_running == false)
            {
                if (m_threads.Count <= 0)
                {
                    if (m_aborting == true)
                    {
                        // Dispose of database connection.
                        if (m_databaseConnection != null)
                        {
                            m_databaseConnection.DisconnectAsync().Wait();
                            m_databaseConnection = null;
                        }

                        Logger.Info("All simulator threads have now terminated.", LoggerVerboseLevel.Normal);
                    }

                    m_running  = false;
                    m_aborting = false;
                    return;
                }

                return;
            }

            // Paused?
            if (m_paused == true)
            {
                return;
            }

            // Spawn off new arbitrators.
            if (arbitratorThreadCount < m_settings.ArbitratorCount)
            {
                if (SpawnArbitrator() == true)
                {
                    Logger.Info("Spawned new arbitrator thread ({0}/{1} arbitrators running).", LoggerVerboseLevel.High, arbitratorThreadCount + 1, m_settings.ArbitratorCount);
                }
            }

            // Spawn off new game clients.
            if (clientThreadCount < m_settings.ClientCount && listeningArbitratorThreadCount > 0)
            {
                if (Environment.TickCount > m_clientSpawnTimer)
                {
                    if (SpawnClient() == true)
                    {
                        Logger.Info("Spawned new client thread ({0}/{1} clients running).", LoggerVerboseLevel.High, clientThreadCount + 1, m_settings.ClientCount);
                    }

                    m_clientSpawnTimer = Environment.TickCount + RandomHelper.RandomInstance.Next(m_settings.ClientConnectIntervalMin, m_settings.ClientConnectIntervalMax);
                }
            }

            // Load current network state.
            if (Environment.TickCount > m_loadNetworkStateTimer)
            {
                LoadNetworkState();
                m_loadNetworkStateTimer = Environment.TickCount + m_settings.SimulatorReloadClientInterval;
            }
        }
        /// <summary>
        ///     Validates database settings to make sure we can connect to it and its setup correctly.
        /// </summary>
        private bool ValidateDatabase()
        {
            DBConnection conn = new DBConnection();

            Logger.Info("Attempting to connect to database on " + m_simulationSettings.DatabaseHostname + ":" + m_simulationSettings.DatabasePort, LoggerVerboseLevel.Normal);

            Task<bool> task = conn.ConnectAsync(m_simulationSettings.DatabaseHostname, m_simulationSettings.DatabasePort, m_simulationSettings.DatabaseName, m_simulationSettings.DatabaseUsername, m_simulationSettings.DatabasePassword);
            task.Wait();

            if (task.Result == true)
            {
                Logger.Info("Connected successfully, database information is valid.", LoggerVerboseLevel.Normal);

                conn.DisconnectAsync().Wait();
                return true;
            }
            else
            {
                Logger.Error("Failed to connect to database.", LoggerVerboseLevel.Normal);

                return false;
            }
        }
Beispiel #3
0
        /// <summary>
        ///     Sets up the database connection.
        /// </summary>
        /// <returns>Returns true if successful, else false.</returns>
        private async Task<bool> SetupDBConnection()
        {
            bool result = false;

            if (m_databaseConnection == null)
            {
                Logger.Info("Attempting to connect to database on " + m_settings.DatabaseHostname + ":" + m_settings.DatabasePort + " ...", LoggerVerboseLevel.High);
                m_databaseConnection = new DBConnection();

                result = await m_databaseConnection.ConnectAsync(m_settings.DatabaseHostname, m_settings.DatabasePort, m_settings.DatabaseName, m_settings.DatabaseUsername, m_settings.DatabasePassword);
            }
            else
            {
                Logger.Error("Lost database connection, attempting to setup connection again ...", LoggerVerboseLevel.Normal);
                result = await m_databaseConnection.ReconnectAsync();
            }

            if (result == false)
            {
                Logger.Error("Failed to connect to database on " + m_settings.DatabaseHostname + ":" + m_settings.DatabasePort, LoggerVerboseLevel.Normal);
            }
            else
            {
                Logger.Info("Successfully connected to database.", LoggerVerboseLevel.High);
            }

            return result;
        }
Beispiel #4
0
        /// <summary>
        ///     Serializes this user account into the database.
        /// </summary>
        /// <param name="database">Database to serialize into.</param>
        public void Serialize(DBConnection database)
        {
            DBResults results = null;

            results = database.Query(@"SELECT id FROM {0} WHERE username='******'",
                                                  Settings.DB_TABLE_ACCOUNTS,
                                                  StringHelper.Escape(m_username));

            byte[] persistentState = m_persistent_state.Serialize();

            // Already exists?
            if (results.RowsAffected > 0)
            {
                results = database.QueryParameterized(@"UPDATE {0} SET
                                                            username='******',
                                                            password='******',
                                                            email='{3}',
                                                            last_login_timestamp=UNIX_TIMESTAMP(),
                                                            persistent_state=@parameter_1
                                                       WHERE
                                                            username='******'",
                                        new object[] { persistentState },
                                        Settings.DB_TABLE_ACCOUNTS,
                                        StringHelper.Escape(m_username.ToLower()),
                                        StringHelper.Escape(m_password.ToLower()),
                                        StringHelper.Escape(m_email.ToLower()),
                                        StringHelper.Escape(m_username.ToLower()));
            }

            // New account?
            else
            {
                results = database.QueryParameterized(@"INSERT INTO {0}
                                                            (username, password, email, last_login_timestamp, persistent_state)
                                                        VALUES
                                                            ('{1}', '{2}', '{3}', UNIX_TIMESTAMP(), @parameter_1)",
                                            new object [] { persistentState },
                                            Settings.DB_TABLE_ACCOUNTS,
                                            StringHelper.Escape(m_username.ToLower()),
                                            StringHelper.Escape(m_password.ToLower()),
                                            StringHelper.Escape(m_email.ToLower()));
            }
        }
Beispiel #5
0
        /// <summary>
        ///     Loads a user account that has the given username from the database.
        /// </summary>
        /// <param name="database">Database to load username from.</param>
        /// <param name="username">Username of account to load.</param>
        /// <returns>Account loaded, or null if one dosen't exist.</returns>
        public static UserAccount LoadByUsername(DBConnection database, string username)
        {
            DBResults results = database.Query(@"SELECT id, username, password, email, last_login_timestamp, persistent_state FROM {0} WHERE LOWER(`username`)='{1}'",
                                                Settings.DB_TABLE_ACCOUNTS,
                                                StringHelper.Escape(username.ToLower()));

            if (results.RowsAffected > 0)
            {
                DBRow row = results[0];

                UserAccount account = new UserAccount();
                account.m_id                    = (int)row["id"];
                account.m_username              = row["username"].ToString();
                account.m_password              = row["password"].ToString();
                account.m_email                 = row["email"].ToString();
                account.m_last_login_timestamp  = row["last_login_timestamp"] == null ? 0 : (int)row["last_login_timestamp"];
                account.m_persistent_state      = new UserAccountPersistentState((byte[])row["persistent_state"]);

                return account;
            }
            else
            {
                return null;
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Create a user account with the given information.
        /// </summary>
        /// <param name="settings">Settings used to initialize this account.</param>
        /// <param name="database">Database to load username from.</param>
        /// <param name="username">Username of account to load.</param>
        /// <returns>Account loaded, or null if one dosen't exist.</returns>
        public static UserAccount CreateAccount(Settings settings, DBConnection database, string username, string password, string email)
        {
            DBResults results = database.Query(@"SELECT id FROM {0} WHERE LOWER(`username`)='{1}'",
                                                Settings.DB_TABLE_ACCOUNTS,
                                                StringHelper.Escape(username.ToLower()));

            if (results.RowsAffected <= 0)
            {
                UserAccount account = new UserAccount();
                account.m_id                    = (int)results.LastInsertID;
                account.m_username              = username;
                account.m_password              = password;
                account.m_email                 = email;
                account.m_last_login_timestamp  = 0;
                account.m_persistent_state      = new UserAccountPersistentState();

                account.LoadDefaults(settings);

                account.Serialize(database);

                return account;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        ///     Initializes this arbitrator, making initial connections to database and getting ready
        ///     to begin accepting connections.
        /// </summary>
        /// <returns>True if successful, otherwise false. If false is returned then the Run/Deinit methods are never called.</returns>
        public bool Initialize()
        {
            Logger.Info("Begining setup of arbitrator server ...", LoggerVerboseLevel.High);

            m_listenConnection      = null;
            m_databaseConnection    = null;

            // Setup database connection.
            SetupDBConnection().Wait();
            if (m_databaseConnection == null || m_databaseConnection.Connected == false)
            {
                Logger.Error("Failed to setup arbitrator, could not initialize database connection.", LoggerVerboseLevel.Normal);
                return false;
            }

            // Setup listening connection.
            SetupConnection().Wait();
            if (m_listenConnection == null || m_listenConnection.Listening == false)
            {
                Logger.Error("Failed to setup arbitrator, could not initialize listen connection.", LoggerVerboseLevel.Normal);
                return false;
            }

            // Register arbitrator in database.
            RegisterArbitrator();

            Logger.Info("Setup arbitrator server successfully.", LoggerVerboseLevel.High);

            return true;
        }