Example #1
0
        /// <summary>
        ///     Calculates the bounding rectangle of the given zone based on a given world size and position.
        /// </summary>
        /// <param name="zone">Zone to calculate bounds for.</param>
        /// <param name="target_zone">Target zone to calculate bounds for.</param>
        /// <param name="world_x">X position of world.</param>
        /// <param name="world_y">Y position of world.</param>
        /// <param name="world_w">Width of world.</param>
        /// <param name="world_h">Height of world.</param>
        /// <param name="zone_x">Resulting zone boundry X position.</param>
        /// <param name="zone_y">Resulting zone boundry Y position.</param>
        /// <param name="zone_w">Resulting zone boundry width.</param>
        /// <param name="zone_h">Resulting zone boundry height.</param>
        private bool CalculateZoneBoundsInternal(Zone zone, Zone target_zone, int world_x, int world_y, int world_w, int world_h, out int zone_x, out int zone_y, out int zone_w, out int zone_h)
        {
            if (zone == target_zone)
            {
                zone_x = world_x;
                zone_y = world_y;
                zone_w = world_w;
                zone_h = world_h;
                return true;
            }

            // Is this split?
            if (zone.ChildZone1 != null || zone.ChildZone2 != null)
            {
                if (zone.SplitOrientation == ZoneSplitOrientation.Horizontal)
                {
                    if (CalculateZoneBoundsInternal(zone.ChildZone1, target_zone, world_x, world_y, world_w / 2, world_h, out zone_x, out zone_y, out zone_w, out zone_h) == true)
                    {
                        return true;
                    }
                    if (CalculateZoneBoundsInternal(zone.ChildZone2, target_zone, world_x + (world_w / 2), world_y, world_w / 2, world_h, out zone_x, out zone_y, out zone_w, out zone_h) == true)
                    {
                        return true;
                    }
                }
                else
                {
                    if (CalculateZoneBoundsInternal(zone.ChildZone1, target_zone, world_x, world_y, world_w, world_h / 2, out zone_x, out zone_y, out zone_w, out zone_h) == true)
                    {
                        return true;
                    }
                    if (CalculateZoneBoundsInternal(zone.ChildZone2, target_zone, world_x, world_y + (world_h / 2), world_w, world_h / 2, out zone_x, out zone_y, out zone_w, out zone_h) == true)
                    {
                        return true;
                    }
                }
            }

            zone_x = 0;
            zone_y = 0;
            zone_w = 0;
            zone_h = 0;
            return false;
        }
        /// <summary>
        ///     Returns true if connected to all super peers for the given zone.
        /// </summary>
        public bool ConnectedToAllZoneSuperPeers(Zone zone)
        {
            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                if (!RegisteredToZoneSuperPeer(peer))
                {
                    return false;
                }
                else
                {
                    bool found = false;

                    foreach (ClientToSuperPeerConnection c in m_superPeerConnections)
                    {
                        if (c.Connection.Connected == true &&
                            c.Connection.ConnectionEstablished == true &&
                            c.Connection.IPAddress == peer.ClientIPAddress &&
                            c.Connection.Port == peer.ClientListenPort)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found == false)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
Example #3
0
 /// <summary>
 ///     Invoked when a super-peer lose's control over a zone.
 /// </summary>
 /// <param name="zone">Zone that super peer lost control of.</param>
 /// <param name="superPeer">Super peer that lost control.</param>
 internal void SuperPeerLostControl(Zone zone, ZoneSuperPeer superPeer)
 {
     // Peer from same zone was lost, we should try and serialize our state now.
     if (superPeer.ZoneID == m_zone_id)
     {
         foreach (SuperPeerToClientConnection conn in m_registeredPeers)
         {
            conn.StoreAccount("SuperPeer In Zone Lost Control, SuperPeers="+zone.SuperPeers.Count+" Peers="+m_registeredPeers.Count);
         }
     }
 }
Example #4
0
        /// <summary>
        ///     Removes the given zone from this grid.
        /// </summary>
        /// <param name="zone">Zone to remove.</param>
        public void RemoveZone(Zone zone)
        {
            // Remove the zone.
            for (int i = 0; i < m_zones.Count; i++)
            {
                int key       = m_zones.Keys.ElementAt(i);
                Zone sub_zone = m_zones[key];

                if (sub_zone.ID == zone.ID)
                {
                    m_zones.Remove(key);
                }
            }

            // Remove references from all other zones.
            foreach (Zone z in m_zones.Values)
            {
                if (z.ChildZone1 == zone)
                {
                    z.ChildZone1 = null;
                    z.ChildZone1ID = 0;
                }
                if (z.ChildZone2 == zone)
                {
                    z.ChildZone2 = null;
                    z.ChildZone2ID = 0;
                }
                if (z.Parent == zone)
                {
                    z.Parent = null;
                    z.ParentID = 0;
                }
            }

            if (m_rootZone == zone)
            {
                m_rootZone = null;
            }
        }
        /// <summary>
        ///     Unregisters with all super peers that are not relevant to the new zone the player is moving ot.
        /// </summary>
        /// <param name="zone">Zone that player is moving to.</param>
        private void UnregisterWithOldSuperPeers(Zone zone)
        {
            foreach (ZoneSuperPeer peer in m_registeredSuperPeers)
            {
                bool found = false;
                bool alreadyUnregistering = false;

                foreach (ZoneSuperPeer target_peer in zone.SuperPeers)
                {
                    if (peer.ID == target_peer.ID)
                    {
                        found = true;
                        break;
                    }
                }
                foreach (ZoneSuperPeer target_peer in m_unregisteringSuperPeers)
                {
                    if (peer.ID == target_peer.ID)
                    {
                        alreadyUnregistering = true;
                        break;
                    }
                }

                if (found == false && alreadyUnregistering == false)
                {
                    bool foundConnection = false;

                    // Send unregister packets to the super peer.
                    foreach (ClientToSuperPeerConnection connection in m_superPeerConnections)
                    {
                        if (connection.Connection.IPAddress == peer.ClientIPAddress &&
                            connection.Connection.Port == peer.ClientListenPort)
                        {
                            Logger.Info("Unregistering with SuperPeer #{0}.", LoggerVerboseLevel.High, peer.ID);

                            SuperPeerUnregisterPacket packet = new SuperPeerUnregisterPacket();
                            packet.SuperPeerID = peer.ID;
                            packet.ChangeZoneSuperPeerCount = m_changeZoneSuperPeerCount;
                            connection.Connection.SendPacket(packet);

                            foundConnection = true;
                        }
                    }

                    // Add to unregistering list.                    
                    m_registerEventList.Add("Unregistering with " + peer.ID);
                    m_unregisteringSuperPeers.Add(peer);
                    m_superPeersDirty = true;

                    if (foundConnection == false)
                    {
                        throw new InvalidOperationException("Fialed to find connection to unregister.");
                    }
                }
            }
        }
        /// <summary>
        ///     Connects to superpeers that are required for the new zone.
        /// </summary>
        /// <param name="zone">Zone that player is moving to.</param>
        private void ConnectToNewSuperPeers(Zone zone)
        {
            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                bool connected = false;

                // Are we connected to the peer hosting this super peer?
                foreach (ClientToSuperPeerConnection c in m_superPeerConnections)
                {
                    if (c.ClientID == peer.ClientID)
                    {
                        connected = true;
                        break;
                    }
                }

                if (connected == false)
                {
                    Logger.Info("Connecting to peer hosting SuperPeer #{0} for zone #{1} on {2}:{3}.", LoggerVerboseLevel.High, peer.ID, peer.ZoneID, peer.ClientIPAddress, peer.ClientListenPort);

                    // Connect to super peer!
                    Connection connection = new Connection();
                    connection.ConnectOverTime(peer.ClientIPAddress, (ushort)peer.ClientListenPort);

                    m_superPeerConnections.Add(new ClientToSuperPeerConnection(this, connection, peer.ClientID));
                }
            }
        }
Example #7
0
        /// <summary>
        ///     Loads the zone map from the database.
        /// </summary>
        private void LoadZones()
        {
            DBConnection db = m_databaseConnection;
            DBResults results = null;

            results = db.Query("SELECT id, child_zone_1_id, child_zone_2_id, parent_id, split_orientation FROM {0}",
                                Settings.DB_TABLE_ZONES);

            // Clear out the zone grid.
            m_zoneGrid.Clear();

            // Add New Grids.
            for (int i = 0; i < results.RowsAffected; i++)
            {
                DBRow row = results[i];
                
                Zone zone = new Zone((int)row["id"],
                                     (int)row["parent_id"], 
                                     (int)row["child_zone_1_id"], 
                                     (int)row["child_zone_2_id"], 
                                     (ZoneSplitOrientation)((int)row["split_orientation"]));

                m_zoneGrid.AddZone(zone);
            }
        }
        /// <summary>
        ///     Gets a list of connections to super peers that are controlling
        ///     the given zone.
        /// </summary>
        /// <param name="zone">Zone that is being controlled.</param>
        /// <returns>List of connections to super peers of the zone.</returns>
        private List<ClientToSuperPeerConnection> GetZoneSuperPeerConnections(Zone zone)
        {
            List<ClientToSuperPeerConnection> connections = new List<ClientToSuperPeerConnection>();

            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                foreach (ClientToSuperPeerConnection c in m_superPeerConnections)
                {
                    if (c.Connection.Connected == true &&
                        c.Connection.ConnectionEstablished == true && 
                        c.Connection.IPAddress == peer.ClientIPAddress &&
                        c.Connection.Port == peer.ClientListenPort)
                    {
                        connections.Add(c);
                    }
                }
            }

            return connections;
        }
        /// <summary>
        ///     Invoked to given a client super-peer level control over a zone.
        /// </summary>
        /// <param name="zone">Zone to give control over.</param>
        /// <param name="client_id">ID of client to be given control.</param>
        internal void SuperPeerGainControl(Zone zone, int client_id)
        {
            if (m_isMaster == false)
            {
                return;
            }

            // Check zone is valid.
            if (zone == null)
            {
                return;
            }

            // See if we already have control.
            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                if (peer.ClientID == client_id)
                {
                    return;
                }
            }

            // Give client control.
            ZoneSuperPeer new_peer  = new ZoneSuperPeer();
            new_peer.ClientID       = client_id;
            new_peer.ZoneID         = zone.ID;

            // Get connection address for client.
            DBResults results = m_databaseConnection.Query(@"SELECT 
                                                            `ip_address`,
                                                            `listen_port`                    
                                                           FROM 
                                                            {0} 
                                                           WHERE
                                                            `id`={1}",
                                                          Settings.DB_TABLE_ACTIVE_CLIENTS,
                                                          client_id);

            if (results.RowsAffected > 0)
            {
                new_peer.ClientIPAddress  = results[0]["ip_address"].ToString();
                new_peer.ClientListenPort = (int)results[0]["listen_port"];
            }
            else
            {
                Logger.Error("Attempt to give control of zone (id={1}) to client that dosen't exist in database (id={0}).", LoggerVerboseLevel.Normal, client_id, zone.ID);
            }

            zone.SuperPeers.Add(new_peer);

            Logger.Info("Client #{0} has taken control of Zone #{1}. {2} SuperPeers now controlling zone.", LoggerVerboseLevel.High, client_id, zone.ID, zone.SuperPeers.Count);
        }
        /// <summary>
        ///     Invoked to take a clients super-peer level control over a zone.
        /// </summary>
        /// <param name="zone">Zone to have control.</param>
        /// <param name="client_id">ID of client to have control taken.</param>
        internal void SuperPeerLossControl(Zone zone, int client_id)
        {
            if (m_isMaster == false)
            {
                return;
            }

            // Check zone is valid.
            if (zone == null)
            {
                return;
            }

            // See if we already have control.
            bool found = false;
            foreach (ZoneSuperPeer peer in zone.SuperPeers.ToList())
            {
                if (peer.ClientID == client_id)
                {
                    zone.SuperPeers.Remove(peer);

                    found = true;
                }
            }

            if (found == true)
            {
                Logger.Warning("Client #{0} has lost control of Zone #{1}. {2} SuperPeers now controlling zone.", LoggerVerboseLevel.High, client_id, zone.ID, zone.SuperPeers.Count);
            }
        }
        /// <summary>
        ///     Removes a zone from the grid. Changes are applied immediately.
        /// </summary>
        /// <param name="zone">Zone to remove.</param>
        private void DeleteZone(Zone zone)
        {
            // Remove from zone grid.
            m_zoneGrid.RemoveZone(zone);

            // Loose control of all super peers.
            foreach (ZoneSuperPeer peer in zone.SuperPeers.ToList())
            {
                SuperPeerLossControl(zone, peer.ClientID);
            }
        }
        /// <summary>
        ///     Adds a new zone to the grid with the given settings. The zone
        ///     is not propogated until SaveZones() is called.
        /// </summary>
        /// <param name="child_1_zone">Child zone one if split, null if not split.</param>
        /// <param name="child_2_zone">Child zone two if split, null if not split.</param>
        /// <param name="split">Split type of zone.</param>
        /// <returns>Returns the zone that was added.</returns>
        private Zone AddZone(Zone parentZone, Zone child_1_zone, Zone child_2_zone, ZoneSplitOrientation split)
        {
            Zone zone = new Zone(0, 0, 0, 0, split);
            zone.ChildZone1 = child_1_zone;
            zone.ChildZone2 = child_2_zone;
            zone.Parent     = parentZone;

            if (zone.ChildZone1 != null)
            {
                zone.ChildZone1ID = zone.ChildZone1.ID;
            }
            if (zone.ChildZone2 != null)
            {
                zone.ChildZone2ID = zone.ChildZone2.ID;
            }
            if (zone.Parent != null)
            {
                zone.ParentID = zone.Parent.ID;
            }

            // We need to generate a unique ID for this zone.
            // This will get overriden when we commit to the database, but it allows us
            // to differentiate until then.
            int id = int.MinValue;
            while (true)
            {
                if (m_zoneGrid.GetZoneByID(id) == null)
                {
                    break;
                }
                id++;
            }
            zone.ID = id;

            m_zoneGrid.AddZone(zone);

            return zone;
        }
        /// <summary>
        ///     Gets the ID for the least burdended client (the one that has been assigned the least number of zones to control).
        /// </summary>
        /// <param name="zone">Zone capable of being overtaken by client.</param>
        /// <returns>Client ID of least burdended client, or below or equal to 0 if none found.</returns>
        private int GetLeastBurdenedClientID(Zone zone)
        {
            // Find lowest burdened client.
            DBResults results = m_databaseConnection.Query(@"SELECT 
                                                                a.id,
                                                                (
                                                                    SELECT 
                                                                        COUNT(*)
                                                                    FROM
                                                                        {0} AS c
                                                                    WHERE
                                                                        c.client_id = a.id
                                                                ) AS controlled_zone_count,
                                                                (
                                                                    SELECT 
                                                                        COUNT(*)
                                                                    FROM
                                                                        {0} AS c
                                                                    WHERE
                                                                        c.client_id = a.id &&
                                                                        c.zone_id   = {2}
                                                                ) AS this_zone_count,
                                                                listening,
                                                                account_id
                                                            FROM 
                                                                {1} AS a
                                                            ORDER BY
                                                                controlled_zone_count ASC,
                                                                last_active_timestamp DESC
                                                                ",
                                                Settings.DB_TABLE_ZONE_SUPERPEERS,
                                                Settings.DB_TABLE_ACTIVE_CLIENTS,
                                                zone.ID);

            if (results.RowsAffected > 0)
            {
                for (int i = 0; i < results.RowsAffected; i++)
                {
                    if ((long)results[i]["this_zone_count"] <= 0 &&
                        (results[i]["listening"] != null && (int)results[i]["listening"] > 0) &&
                        (results[i]["account_id"] != null && (int)results[i]["account_id"] > 0))
                    {
                        return (int)results[i]["id"];
                    }
                }
            }
            
            return 0;
        }
        /// <summary>
        ///     Invoked when a super-peer gains control over a zone.
        /// </summary>
        /// <param name="zone">Zone that super peer gained control of.</param>
        /// <param name="superPeer">Super peer that gained control.</param>
        private void SuperPeerGainedControl(Zone zone, ZoneSuperPeer superPeer)
        {
            // Is this us thats gained control of a zone?
            if (superPeer.ClientID == m_clientID)
            {
                SuperPeer peer  = new SuperPeer(this, superPeer.ID, superPeer.ZoneID);
                peer.Initialize();

                m_superPeers.Add(peer);

                Logger.Info("Gained control of zone #{0} as SuperPeer #{0}", LoggerVerboseLevel.High, zone.ID, superPeer.ID);
            }
            
            foreach (SuperPeer peer in m_superPeers)
            {
                peer.SuperPeerGainedControl(zone, superPeer);
            }
        }
        /// <summary>
        ///     Simulates movement of this client around the map.
        /// </summary>
        private void SimulateMovement()
        {
            bool forceMovementUpdate = (m_service.CurrentZone                                         != null &&
                                        m_lastMovementZone                                            != null &&
                                        m_service.CurrentZone.ID                                      != m_lastMovementZone.ID &&
                                        m_service.ConnectedToAllZoneSuperPeers(m_service.CurrentZone) == true ||
                                        m_service.SuperPeersDirty                                     == true);

            if (m_playerControlled == true)
            {
                int keyLeft  = (Keyboard.GetKeyStates(System.Windows.Input.Key.Left)  & KeyStates.Down) > 0 ? 1 : 0;
                int keyRight = (Keyboard.GetKeyStates(System.Windows.Input.Key.Right) & KeyStates.Down) > 0 ? 1 : 0;
                int keyUp    = (Keyboard.GetKeyStates(System.Windows.Input.Key.Up)    & KeyStates.Down) > 0 ? 1 : 0;
                int keyDown  = (Keyboard.GetKeyStates(System.Windows.Input.Key.Down)  & KeyStates.Down) > 0 ? 1 : 0;

                if ((keyLeft != m_keyLeft || keyRight != m_keyRight || keyUp != m_keyUp || keyDown != m_keyDown) ||
                    forceMovementUpdate == true)
                {
                    m_lastMovementZone = m_service.CurrentZone;
                    m_service.SetMovementVector(keyRight - keyLeft, keyDown - keyUp, m_settings.ClientMovementSpeedMax);
                }

                m_keyLeft = keyLeft;
                m_keyRight = keyRight;
                m_keyUp = keyUp;
                m_keyDown = keyDown;
            }
            else
            {
                if (Environment.TickCount > m_lastDirectionChange || forceMovementUpdate == true)
                {
                    m_lastDirectionChange = Environment.TickCount + (int)(m_settings.ClientDirectionChangeTimeMin + (RandomHelper.RandomInstance.NextDouble() * (m_settings.ClientDirectionChangeTimeMax - m_settings.ClientDirectionChangeTimeMin)));
                    m_direction = RandomHelper.RandomInstance.Next(0, 4);
                    m_speed = (float)(m_settings.ClientMovementSpeedMin + (RandomHelper.RandomInstance.NextDouble() * (m_settings.ClientMovementSpeedMax - m_settings.ClientMovementSpeedMin)));
                    m_lastMovementZone = m_service.CurrentZone;

                    switch (m_direction)
                    {
                        case 0: // Left
                            {
                                m_service.SetMovementVector(-1, 0, m_speed);
                                break;
                            }
                        case 1: // Right
                            {
                                m_service.SetMovementVector(1, 0, m_speed);
                                break;
                            }
                        case 2: // Up
                            {
                                m_service.SetMovementVector(0, -1, m_speed);
                                break;
                            }
                        case 3: // Down
                            {
                                m_service.SetMovementVector(0, 1, m_speed);
                                break;
                            }
                    }
                }
            }
        }
        /// <summary>
        ///     Invoked when a super-peer lose's control over a zone.
        /// </summary>
        /// <param name="zone">Zone that super peer lost control of.</param>
        /// <param name="superPeer">Super peer that lost control.</param>
        private void SuperPeerLostControl(Zone zone, ZoneSuperPeer superPeer)
        {
            // Is this us thats gained control of a zone?
            if (superPeer.ClientID == m_clientID)
            {
                foreach (SuperPeer peer in m_superPeers.ToList())
                {
                    if (peer.ID == superPeer.ID)
                    {
                        peer.Deinitialize();
                        break;
                    }
                }

                Logger.Info("Lost control of zone #{0} as SuperPeer #{0}", LoggerVerboseLevel.High, superPeer.ZoneID, superPeer.ID);
            }

            // Is this a superpeer for the zone we are inside of?
            // If so, any superpeers we are hosting, should start serializing now!
            foreach (SuperPeer peer in m_superPeers)
            {
                peer.SuperPeerLostControl(zone, superPeer);
            }
        }
Example #17
0
        /// <summary>
        ///     Adds the given zone to this zone grid.
        /// </summary>
        /// <param name="zone">Zone to add.</param>
        public void AddZone(Zone zone)
        {
            // Add to zones dictionary.
            if (m_zones.ContainsKey(zone.ID))
            {
                m_zones.Remove(zone.ID);
            }
            m_zones.Add(zone.ID, zone);

            // Add to all zones dictionary.
            if (m_allZones.ContainsKey(zone.ID))
            {
                m_allZones.Remove(zone.ID);
            }
            m_allZones.Add(zone.ID, zone);

            // Link up zones.
            int lowest_id = -1;
            foreach (int key in m_zones.Keys)
            {
                Zone z = m_zones[key];

                if (lowest_id == -1 || z.ID < lowest_id)
                {
                    lowest_id = z.ID;
                }

                if (z.ChildZone1ID != 0)
                {
                    if (m_zones.ContainsKey(z.ChildZone1ID))
                    {
                        z.ChildZone1 = m_zones[z.ChildZone1ID];
                    }
                    else
                    {
                        z.ChildZone1 = z;
                    }
                }
                if (z.ChildZone2ID != 0)
                {
                    if (m_zones.ContainsKey(z.ChildZone2ID))
                    {
                        z.ChildZone2 = m_zones[z.ChildZone2ID];
                    }
                    else
                    {
                        z.ChildZone2 = z;
                    }
                }
                if (z.ParentID != 0)
                {
                    if (m_zones.ContainsKey(z.ParentID))
                    {
                        z.Parent = m_zones[z.ParentID];
                    }
                    else
                    {
                        z.Parent = z;
                    }
                }
            }

            // Store root zone.
            if (lowest_id != -1)
            {
                if (m_zones.ContainsKey(lowest_id))
                {
                    m_rootZone = m_zones[lowest_id];
                }
                else
                {
                    m_rootZone = null;
                }
            }
            else
            {
                m_rootZone = null;
            }
        }
        /// <summary>
        ///     Sends a packet to all super peers looking after a zone and waits for their replies.
        /// </summary>
        /// <param name="zone">Zone to send packet to.</param>
        /// <param name="packet">Packet to send.</param>
        private void SendPacketToZoneSuperPeersWaitForReply(Zone zone, SuperPeerPacket packet)
        {
            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                if (!RegisteredToZoneSuperPeer(peer))
                {
                    continue;
                }

                foreach (ClientToSuperPeerConnection c in m_superPeerConnections)
                {
                    if (c.Connection.Connected == true &&
                        c.Connection.ConnectionEstablished == true && 
                        c.Connection.IPAddress == peer.ClientIPAddress &&
                        c.Connection.Port == peer.ClientListenPort)
                    {
                        packet.SuperPeerID = peer.ID;
                        c.Connection.SendPacketAndWaitAsync(packet).Wait();
                    }
                }
            }
        }
Example #19
0
        /// <summary>
        ///     Calculates the bounding rectangle of the given zone based on a given world size and position.
        /// </summary>
        /// <param name="zone">Zone to calculate bounds for.</param>
        /// <param name="world_x">X position of world.</param>
        /// <param name="world_y">Y position of world.</param>
        /// <param name="world_w">Width of world.</param>
        /// <param name="world_h">Height of world.</param>
        /// <param name="zone_x">Resulting zone boundry X position.</param>
        /// <param name="zone_y">Resulting zone boundry Y position.</param>
        /// <param name="zone_w">Resulting zone boundry width.</param>
        /// <param name="zone_h">Resulting zone boundry height.</param>
        public void CalculateZoneBounds(Zone zone, int world_x, int world_y, int world_w, int world_h, out int zone_x, out int zone_y, out int zone_w, out int zone_h)
        {
            zone_x = 0;
            zone_y = 0;
            zone_w = 0;
            zone_h = 0;

            CalculateZoneBoundsInternal(m_rootZone, zone, world_x, world_y, world_w, world_h, out zone_x, out zone_y, out zone_w, out zone_h);
        }
        /// <summary>
        ///     Registers with all super peers that are relevant to the new zone the player is moving ot.
        /// </summary>
        /// <param name="zone">Zone that player is moving to.</param>
        private void RegisterWithNewSuperPeers(Zone zone)
        {
            if (zone.SuperPeers.Count < m_settings.ZoneSuperPeerCount)
            {
                return;
            }

            foreach (ZoneSuperPeer peer in zone.SuperPeers)
            {
                bool alreadyRegistered = false;
                bool alreadyRegistering = false;

                foreach (ZoneSuperPeer target_peer in m_registeredSuperPeers)
                {
                    if (peer.ID == target_peer.ID)
                    {
                        alreadyRegistered = true;
                        break;
                    }
                }
                foreach (ZoneSuperPeer target_peer in m_registeringSuperPeers)
                {
                    if (peer.ID == target_peer.ID)
                    {
                        alreadyRegistering = true;
                        break;
                    }
                }

                if (alreadyRegistered == false && alreadyRegistering == false)
                {
                    bool found = false;

                    // Send register packets to the super peer.
                    foreach (ClientToSuperPeerConnection connection in m_superPeerConnections)
                    {
                        if (connection.Connection.Connected == true &&
                            connection.Connection.ConnectionEstablished == true &&
                            connection.Connection.IPAddress == peer.ClientIPAddress &&
                            connection.Connection.Port == peer.ClientListenPort)
                        {
                            Logger.Info("Registering with SuperPeer #{0}.", LoggerVerboseLevel.High, peer.ID);

                            SuperPeerRegisterPacket packet = new SuperPeerRegisterPacket();
                            packet.SuperPeerID = peer.ID;
                            packet.ClientID = m_clientID;

                            connection.Connection.SendPacket(packet);

                            found = true;
                        }
                    }

                    // Add to registering list.
                    if (found == true)
                    {
                        m_registeringSuperPeers.Add(peer);
                        m_superPeersDirty = true;
                        m_registerEventList.Add("Registering with " + peer.ID);
                    }
                }
            } 
        }
Example #21
0
        /// <summary>
        ///     Converts a packet representation of this zone grid into the zone grid.
        /// </summary>
        /// <param name="packet">Packet to convert.</param>
        public void FromPacket(ZoneGridPacket packet)
        {
            List<ZoneSuperPeer> old_superpeers = new List<ZoneSuperPeer>();
            List<ZoneSuperPeer> new_superpeers = new List<ZoneSuperPeer>();
            List<Zone> old_zones = new List<Zone>(m_zones.Values);

            // Make a full list of all super peers that currently exist.
            foreach (Zone zone in m_zones.Values)
            {
                old_superpeers.AddRange(zone.SuperPeers);
            }

            // Dispose of general stuff.
            m_zones.Clear();
            m_gained_superpeers.Clear();
            m_lost_superpeers.Clear();

            // Rebuild the zone grid.
            foreach (ZoneGridPacketZoneInfo zoneInfo in packet.Zones)
            {
                Zone zone = null;

                foreach (Zone z in old_zones)
                {
                    if (z.ID == zoneInfo.ID)
                    {
                        zone = z;
                        zone.ParentID = zoneInfo.ParentID;
                        zone.ChildZone1ID = zoneInfo.ChildZone1ID;
                        zone.ChildZone2ID = zoneInfo.ChildZone2ID;
                        zone.Parent = null;
                        zone.ChildZone1 = null;
                        zone.ChildZone2 = null;
                        zone.SplitOrientation = zoneInfo.SplitOrientation;
                        break;
                    }
                }

                if (zone == null)
                {
                    zone = new Zone(zoneInfo.ID, zoneInfo.ParentID, zoneInfo.ChildZone1ID, zoneInfo.ChildZone2ID, zoneInfo.SplitOrientation);
                }

                List<ZoneSuperPeer> oldZoneSuperPeers = new List<ZoneSuperPeer>(zone.SuperPeers);
                zone.SuperPeers.Clear();

                foreach (ZoneGridPacketSuperPeerInfo peerInfo in zoneInfo.SuperPeers)
                {
                    ZoneSuperPeer peer = null;

                    foreach (ZoneSuperPeer p in oldZoneSuperPeers)
                    {
                        if (p.ID == peerInfo.ID)
                        {
                            peer = p;
                            break;
                        }
                    }

                    if (peer == null)
                    {
                        peer = new ZoneSuperPeer();
                    }

                    peer.ID                 = peerInfo.ID;
                    peer.ZoneID             = peerInfo.ZoneID;
                    peer.ClientID           = peerInfo.ClientID;
                    peer.ClientIPAddress    = peerInfo.ClientIPAddress;
                    peer.ClientListenPort   = peerInfo.ClientListenPort;

                    zone.SuperPeers.Add(peer);
                }

                new_superpeers.AddRange(zone.SuperPeers);

                AddZone(zone);
            }

            // Calculate which super-peers are new.
            foreach (ZoneSuperPeer peer in old_superpeers)
            {
                bool found = false;
                foreach (ZoneSuperPeer peer2 in new_superpeers)
                {
                    if (peer.ZoneID == peer2.ZoneID &&
                        peer.ClientID == peer2.ClientID)
                    {
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    m_lost_superpeers.Add(peer);
                }
            }

            // Calculate which super-peers have been list.
            foreach (ZoneSuperPeer peer in new_superpeers)
            {
                bool found = false;
                foreach (ZoneSuperPeer peer2 in old_superpeers)
                {
                    if (peer.ZoneID == peer2.ZoneID &&
                        peer.ClientID == peer2.ClientID)
                    {
                        found = true;
                        break;
                    }
                }

                if (found == false)
                {
                    m_gained_superpeers.Add(peer);
                }
            }
        }
        /// <summary>
        ///     Updates our connection to the zone we are currently inside of.
        /// </summary>
        private void UpdateZoneConnection()
        {
            if (m_account == null)
            {
                return;
            }

            // Work out what zone we are currently inside.
            Zone zone = m_zoneGrid.GetZoneByPosition(0, 0, m_settings.WorldWidth, m_settings.WorldHeight, (int)m_account.PeristentState.X, (int)m_account.PeristentState.Y);
            if (zone == null)
            {
                return;
            }

            // Different from the zone we are currently in?
            if (m_currentZone == null || zone.ID != m_currentZone.ID)
            {
                // Send a message to arbitrator saying we have changed zone.
                ChangeZonePacket packet = new ChangeZonePacket();
                packet.ZoneID = zone.ID;
                m_arbitratorConnection.SendPacket(packet);

                Logger.Info("Changed zone from {0} to {1}.", LoggerVerboseLevel.High, m_currentZone == null ? "null" : m_currentZone.ID.ToString(), zone.ID);

                // Count up how many super peers we were connected to when we switched. This is important
                // for unregistering, as if we are not connected to enough we can't persist our position.
                if (m_registeredSuperPeers.Count > 0)
                {
                    m_changeZoneSuperPeerCount = (m_registeredSuperPeers.Count);// + m_registeringSuperPeers.Count);
                }
                else
                {
                    m_changeZoneSuperPeerCount = 0;
                }

                // Store the zone we are now in.
                m_currentZone = zone;
            }

            // Unregister with superpeers we are no longer intrested in.
            UnregisterWithOldSuperPeers(zone);     

            // Register with superpeers we are intrested in, but only
            // do this after we have unregistered all superpeers we are not intrested in.
            if (m_unregisteringSuperPeers.Count <= 0)
            {
                RegisterWithNewSuperPeers(zone);
            }

            // Are we not connected to zone super peers?
            ConnectToNewSuperPeers(zone);

            // Prune dead connections.
            PruneDeadConnections();
        }
Example #23
0
 /// <summary>
 ///     Invoked when a super-peer gains control over a zone.
 /// </summary>
 /// <param name="zone">Zone that super peer gained control of.</param>
 /// <param name="superPeer">Super peer that gained control.</param>
 internal void SuperPeerGainedControl(Zone zone, ZoneSuperPeer superPeer)
 {
 }