const double hostMigrationGraceTime = 40; // seconds void ValidateHostMigration() { if (clientDisconnections == null) { return; // Already host-migrated } owner.Log("Host migration validated"); clientDisconnections = null; OpenToConnections(owner.GameInfo.IsInternetGame, owner.GameInfo.SideChannelAuth); }
/// <summary>Construct for host migration only!</summary> internal P2PServer(P2PNetwork owner, bool hostMigrationValidatedByServer, int maxConnectionId) { this.owner = owner; owner.Log("Becoming P2P Server (host migration)"); hostMigrationTime = NetTime.Now; clientDisconnections = new ClientDisconnections(); if (hostMigrationValidatedByServer) { ValidateHostMigration(); } owner.LocalPeerInfo.IsServer = true; // Recover information from application-connected peer list: var leavingPeers = new List <RemotePeer>(); foreach (var remotePeer in owner.RemotePeers) { Debug.Assert(remotePeer.PeerInfo.IsApplicationConnected); Debug.Assert(remotePeer.PeerInfo.ConnectionId <= maxConnectionId); Debug.Assert(remotePeer.PeerInfo.InputAssignment != 0); Debug.Assert((assignedInputs & remotePeer.PeerInfo.InputAssignment) == 0); assignedInputs |= remotePeer.PeerInfo.InputAssignment; Debug.Assert(!(remotePeer.PeerInfo.IsServer && remotePeer.IsConnected)); // old server should not still be connected if (remotePeer.IsConnected) { locallyConnected.Add(remotePeer.Connection); } // Anyone not connected will get removed from the game in CompleteHostMigration remotePeer.PeerInfo.IsServer = false; // Un-server-ify the original server } // And also from ourself: Debug.Assert(owner.LocalPeerInfo.IsApplicationConnected); Debug.Assert(owner.LocalPeerInfo.ConnectionId <= maxConnectionId); Debug.Assert(owner.LocalPeerInfo.InputAssignment != 0); Debug.Assert((assignedInputs & owner.LocalPeerInfo.InputAssignment) == 0); assignedInputs |= owner.LocalPeerInfo.InputAssignment; // This should be safe, as host migration should remove all traces peers beyond this point (including in the app layer) and is atomic nextConnectionId = maxConnectionId + 1; }