/// <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> /// 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> /// 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> /// Returns true if we are registered to the given zone super peer. /// </summary> /// <param name="id">ID of zone super peer to check.</param> /// <returns>True if we are registered to it.</returns> public bool RegisteredToZoneSuperPeer(ZoneSuperPeer peer) { foreach (ZoneSuperPeer p in m_registeredSuperPeers) { if (p.ID == peer.ID) { return true; } } return false; }
/// <summary> /// Loads zoen super-peers from the database. /// </summary> private void LoadZoneSuperPeers() { DBConnection db = m_databaseConnection; DBResults results = null; results = db.Query("SELECT id, zone_id, client_id FROM {0}", Settings.DB_TABLE_ZONE_SUPERPEERS); // Clear out the zone grid. foreach (Zone zone in m_zoneGrid.Zones) { zone.SuperPeers.Clear(); } // Add new super peers. for (int i = 0; i < results.RowsAffected; i++) { DBRow row = results[i]; ZoneSuperPeer superPeer = new ZoneSuperPeer(); superPeer.ID = (int)row["id"]; superPeer.ZoneID = (int)row["zone_id"]; superPeer.ClientID = (int)row["client_id"]; Zone zone = m_zoneGrid.GetZoneByID(superPeer.ZoneID); if (zone != null) { zone.SuperPeers.Add(superPeer); } } }
/// <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> /// Loads information about which super peers control which zones. /// </summary> private void LoadZoneSuperPeers() { DBResults results = null; results = m_databaseConnection.Query(@"SELECT peers.`id`, peers.`zone_id`, peers.`client_id`, clients.`ip_address`, clients.`listen_port` FROM {0} AS peers JOIN {1} AS clients ON peers.`client_id` = clients.`id`", Settings.DB_TABLE_ZONE_SUPERPEERS, Settings.DB_TABLE_ACTIVE_CLIENTS); for (int i = 0; i < results.RowsAffected; i++) { int id = (int)results[i]["id"]; int zone_id = (int)results[i]["zone_id"]; int client_id = (int)results[i]["client_id"]; string ip_address = results[i]["ip_address"].ToString(); int listen_port = (int)results[i]["listen_port"]; Zone zone = m_zoneGrid.GetZoneByID(zone_id); if (zone == null) { continue; } ZoneSuperPeer superPeer = new ZoneSuperPeer(); superPeer.ID = id; superPeer.ZoneID = zone_id; superPeer.ClientID = client_id; superPeer.ClientIPAddress = ip_address; superPeer.ClientListenPort = listen_port; //SuperPeerGainControl(zone, superPeer); zone.SuperPeers.Add(superPeer); } }
/// <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> /// 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) { }