/// <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; }
/// <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); } } }
/// <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)); } } }
/// <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); } }
/// <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(); } } } }
/// <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); } } } }
/// <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(); }
/// <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) { }