ACR_ServerCommunicator.GameWorldManager.SynchronizeOnlineServers C# (CSharp) Method

SynchronizeOnlineServers() private method

This method synchronizes the online status of the server list.
private SynchronizeOnlineServers ( ) : void
return void
        private void SynchronizeOnlineServers()
        {
            IALFADatabase Database = DatabaseLinkQueryThread;

            //
            // Query the current server list and synchronize with our internal
            // state.
            //
            // There are several steps here:
            //
            // 1) Mark all online servers as "not visited".
            // 2) Retrieve the server list from the database.  For each server
            //    that wasn't already marked as online, mark it as online.
            //    Also, flag any server that is in the list from the database
            //    as "visited".
            // 3) Sweep the online server list for servers that are still
            //    flagged as "not visited".  These servers are those that have
            //    gone offline in the interim time.  Note that we don't yet
            //    update the player list, as that is handled by the player list
            //    synchronization tep.
            //

            //
            // First - query the database.  This query returns a list of all
            // servers that have checked in during the past ten minutes.  We
            // treat any server that has not checked in within at least that
            // long as being offline.
            //

            List<SynchronizeOnlineServersRow> Rowset = new List<SynchronizeOnlineServersRow>();

            Database.ACR_SQLQuery(
                "SELECT " +
                    "`servers`.`ID` AS server_id, " +
                    "`servers`.`IPAddress` as ip_address, " +
                    "`servers`.`IsPublic` as public_server " +
                "FROM `servers` " +
                "INNER JOIN `pwdata` ON `pwdata`.`Name` = `servers`.`Name` " +
                "WHERE pwdata.`Key` = 'ACR_TIME_SERVERTIME' " +
                "AND pwdata.`Last` >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 10 MINUTE) "
                );

            //
            // Clear visited.
            //
            // N.B.  The Visited flag is only managed on the query thread or
            //       prior to list insertion during initial server creation.
            //
            //       Thus, while we must lock to protect the integrity of the
            //       list, there's no need to worry about another thread
            //       altering the Visited state after we drop the lock.
            //

            lock (this)
            {
                foreach (GameServer Server in Servers)
                {
                    Server.Visited = false;
                }
            }

            //
            // Read each database row.
            //

            while (Database.ACR_SQLFetch())
            {
                SynchronizeOnlineServersRow Row;

                Row.ServerId = Convert.ToInt32(Database.ACR_SQLGetData(0));
                Row.AddressString = Database.ACR_SQLGetData(1);
                Row.PublicServer = ConvertToBoolean(Database.ACR_SQLGetData(2));

                Rowset.Add(Row);
            }

            lock (this)
            {
                //
                // Update entries.
                //

                foreach (SynchronizeOnlineServersRow Row in Rowset)
                {
                    int ServerId = Row.ServerId;
                    string AddressString = Row.AddressString;

                    GameServer Server = ReferenceServerById(ServerId, Database);

                    Server.Visited = true;

                    if (!Server.Online)
                    {
                        Server.Online = true;
                        Server.DatabaseOnline = true;
                        OnServerJoin(Server);
                    }

                    Server.SetHostnameAndPort(AddressString);
                    Server.Public = Row.PublicServer;
                }

                //
                // Sweep offline servers.
                //

                var NowOfflineServers = (from S in Servers
                                         where S.Visited == false &&
                                         S.Online == true
                                         select S);

                List<GameServer> ObjectsToRemove = new List<GameServer>(NowOfflineServers);

                foreach (GameServer Server in ObjectsToRemove)
                {
                    Server.Online = false;
                    Server.DatabaseOnline = false;
                    OnServerPart(Server);
                }
            }

        }