internal NetworkSession(NetPeer peer, bool isHost, byte machineId, NetworkSessionType type, NetworkSessionProperties properties, int maxGamers, int privateGamerSlots, IEnumerable <SignedInGamer> localGamers, string hostDisplayName, string hostGamertag) { if (peer.Configuration.AutoFlushSendQueue) { throw new InvalidOperationException("Peer must not flush send queue automatically"); } if (isHost && machineId != 0) { throw new InvalidOperationException("Host must have machine id 0"); } if (!isHost && machineId == 0) { throw new InvalidOperationException("Client cannot have machine id 0"); } this.peer = peer; this.isHost = isHost; this.machineId = machineId; this.type = type; this.guid = Guid.NewGuid(); this.properties = properties; this.localMachine = new NetworkMachine(this, true, isHost, machineId); this.hostMachine = isHost ? this.localMachine : new NetworkMachine(this, false, true, 0); AddMachine(this.localMachine, null); if (!isHost) { if (peer.ConnectionsCount != 1 || peer.Connections[0].Status != NetConnectionStatus.Connected) { throw new InvalidOperationException("Client peer must be connected to host before NetworkSession can be instantiated"); } hostConnection = peer.Connections[0]; hostConnection.Tag = this.hostMachine; AddMachine(this.hostMachine, hostConnection); // Add host gamer with id 0, important for NetworkSession.Host property AddGamer(new NetworkGamer(this.hostMachine, 0, privateGamerSlots > 0, false, hostDisplayName, hostGamertag)); } this.maxGamers = maxGamers; this.privateGamerSlots = privateGamerSlots; if (isHost) { // Add local gamers directly to make sure that there is always at least one gamer in the session byte id = 0; foreach (var gamer in localGamers) { AddGamer(new LocalNetworkGamer(gamer, this.localMachine, id++, GetOpenPrivateGamerSlots() > 0)); } if (allGamers.Count == 0) { throw new InvalidOperationException(); } } else { foreach (var gamer in localGamers) { AddLocalGamer(gamer); } } this.AllGamers = new GamerCollection <NetworkGamer>(new List <NetworkGamer>(), this.allGamers); this.PreviousGamers = new GamerCollection <NetworkGamer>(new List <NetworkGamer>(), this.previousGamers); this.RemoteGamers = new GamerCollection <NetworkGamer>(new List <NetworkGamer>(), this.remoteGamers); this.LocalGamers = new GamerCollection <LocalNetworkGamer>(new List <LocalNetworkGamer>(), this.localGamers); this.BytesPerSecondReceived = 0; this.BytesPerSecondSent = 0; this.SimulatedLatency = TimeSpan.Zero; this.SimulatedPacketLoss = 0.0f; SignedInGamer.SignedOut += LocalGamerSignedOut; }
private static void AddAvailableNetworkSession(Guid hostGuid, NetworkSessionPublicInfo publicInfo, IEnumerable <SignedInGamer> localGamers, NetworkSessionType searchType, NetworkSessionProperties searchProperties, IList <AvailableNetworkSession> availableSessions, object tag = null) { if (searchType == publicInfo.sessionType && searchProperties.SearchMatch(publicInfo.sessionProperties)) { var availableSession = new AvailableNetworkSession( hostGuid, localGamers, publicInfo.maxGamers, publicInfo.privateGamerSlots, publicInfo.sessionType, publicInfo.currentGamerCount, publicInfo.hostGamertag, publicInfo.openPrivateGamerSlots, publicInfo.openPublicGamerSlots, publicInfo.sessionProperties) { Tag = tag, }; availableSessions.Add(availableSession); } }
private static AvailableNetworkSessionCollection InternalFind(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, NetworkSessionProperties searchProperties) { var config = new NetPeerConfiguration(NetworkSettings.GameAppId) { Port = 0, // Use any port AcceptIncomingConnections = false, }; config.EnableMessageType(NetIncomingMessageType.VerboseDebugMessage); config.EnableMessageType(NetIncomingMessageType.UnconnectedData); config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse); var discoverPeer = new NetPeer(config); try { discoverPeer.Start(); } catch (Exception e) { throw new InvalidOperationException("Could not start discover peer", e); } Debug.WriteLine("Discover peer started."); // Discover hosts if (sessionType == NetworkSessionType.SystemLink) { Debug.WriteLine("Sending local discovery request..."); discoverPeer.DiscoverLocalPeers(NetworkSettings.Port); } else if (sessionType == NetworkSessionType.PlayerMatch || sessionType == NetworkSessionType.Ranked) { Debug.WriteLine("Sending discovery request to master server..."); NetworkMasterServer.RequestHosts(discoverPeer); } else { throw new InvalidOperationException(); } // Get list of answers var availableSessions = new List <AvailableNetworkSession>(); var startTime = DateTime.Now; while (DateTime.Now - startTime <= DiscoveryTimeOut) { var msg = discoverPeer.ReadMessage(); if (msg == null) { Thread.Sleep((int)NoMessageSleep.TotalMilliseconds); continue; } if (msg.MessageType == NetIncomingMessageType.DiscoveryResponse) { Guid guid; NetworkSessionPublicInfo publicInfo; if (NetworkMasterServer.ParseExpectedResponseHeader(msg, MasterServerMessageType.RequestHosts) && NetworkMasterServer.ParseRequestHostsResponse(msg, out guid, out publicInfo)) { AddAvailableNetworkSession(guid, publicInfo, localGamers, sessionType, searchProperties, availableSessions, tag: msg.SenderEndPoint); } else { Debug.WriteLine("Failed to parse local discovery response from " + msg.SenderEndPoint + ", ignoring..."); } } else if (msg.MessageType == NetIncomingMessageType.UnconnectedData) { if (!msg.SenderEndPoint.Equals(NetworkMasterServer.ResolveEndPoint())) { Debug.WriteLine("Unconnected data not from master server recieved from " + msg.SenderEndPoint + ", ignoring..."); } else { Guid guid; NetworkSessionPublicInfo publicInfo; if (NetworkMasterServer.ParseExpectedResponseHeader(msg, MasterServerMessageType.RequestHosts) && NetworkMasterServer.ParseRequestHostsResponse(msg, out guid, out publicInfo)) { AddAvailableNetworkSession(guid, publicInfo, localGamers, sessionType, searchProperties, availableSessions); } else { Debug.WriteLine("Failed to parse master server discovery response from " + msg.SenderEndPoint + ", ignoring..."); } } } else { HandleLidgrenMessage(msg); } discoverPeer.Recycle(msg); } discoverPeer.Shutdown(string.Empty); Debug.WriteLine("Discovery peer shut down."); return(new AvailableNetworkSessionCollection(availableSessions)); }
public static IAsyncResult BeginCreate(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties, AsyncCallback callback, Object asyncState) { if (maxLocalGamers < MinSupportedLocalGamers || maxLocalGamers > MaxSupportedLocalGamers) { throw new ArgumentOutOfRangeException("maxLocalGamers must be in the range [" + MinSupportedLocalGamers + ", " + MaxSupportedLocalGamers + "]"); } var localGamers = GetLocalGamers(maxLocalGamers); try { return(BeginCreate(sessionType, localGamers, maxGamers, privateGamerSlots, sessionProperties, callback, asyncState)); } catch { throw; } }
private static NetworkSession InternalCreate(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties) { var config = new NetPeerConfiguration(NetworkSettings.GameAppId) { Port = NetworkSettings.Port, AcceptIncomingConnections = true, AutoFlushSendQueue = false, }; config.EnableMessageType(NetIncomingMessageType.VerboseDebugMessage); config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); config.EnableMessageType(NetIncomingMessageType.UnconnectedData); if (sessionType == NetworkSessionType.SystemLink) { config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest); } if (sessionType == NetworkSessionType.PlayerMatch || sessionType == NetworkSessionType.Ranked) { config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess); } var serverPeer = new NetPeer(config); try { serverPeer.Start(); } catch (Exception e) { throw new NetworkException("Could not start server peer", e); } Debug.WriteLine("Server peer started."); var firstGamer = localGamers.First(); return(new NetworkSession(serverPeer, true, 0, sessionType, sessionProperties, maxGamers, privateGamerSlots, localGamers, firstGamer.DisplayName, firstGamer.Gamertag)); }
// Asynchronous session creation public static IAsyncResult BeginCreate(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties, AsyncCallback callback, Object asyncState) { if (Session != null || AsyncCreateCaller != null || AsyncFindCaller != null || AsyncJoinCaller != null) { throw new InvalidOperationException("Only one NetworkSession allowed"); } if (localGamers == null) { throw new ArgumentNullException("localGamers"); } foreach (var localGamer in localGamers) { if (localGamer == null) { throw new ArgumentNullException("Element of localGamers"); } } if (maxGamers < MinSupportedGamers || maxGamers > MaxSupportedGamers) { throw new ArgumentOutOfRangeException("maxGamers must be in the range [" + MinSupportedGamers + ", " + MaxSupportedGamers + "]"); } if (privateGamerSlots < 0 || privateGamerSlots > maxGamers) { throw new ArgumentOutOfRangeException("privateGamerSlots must be in the range [0, maxGamers]"); } if (sessionProperties == null) { sessionProperties = new NetworkSessionProperties(); } AsyncCreateCaller = new AsyncCreate(InternalCreate); IAsyncResult result = null; try { result = AsyncCreateCaller.BeginInvoke(sessionType, localGamers, maxGamers, privateGamerSlots, sessionProperties, callback, asyncState); } catch { AsyncCreateCaller = null; throw; } return(result); }
public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, int maxLocalGamers, NetworkSessionProperties searchProperties) { try { return(EndFind(BeginFind(sessionType, maxLocalGamers, searchProperties, null, null))); } catch { throw; } }
public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, NetworkSessionProperties searchProperties) { try { return(EndFind(BeginFind(sessionType, localGamers, searchProperties, null, null))); } catch { throw; } }
public static NetworkSession Create(NetworkSessionType sessionType, int maxLocalGamers, int maxGamers, int privateGamerSlots, NetworkSessionProperties sessionProperties) { try { return(EndCreate(BeginCreate(sessionType, maxLocalGamers, maxGamers, privateGamerSlots, sessionProperties, null, null))); } catch { throw; } }
public static IAsyncResult BeginFind(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, NetworkSessionProperties searchProperties, AsyncCallback callback, Object asyncState) { if (Session != null || AsyncCreateCaller != null || AsyncFindCaller != null || AsyncJoinCaller != null) { throw new InvalidOperationException("Only one NetworkSession allowed"); } if (sessionType == NetworkSessionType.Local) { throw new ArgumentException("Find cannot be used with NetworkSessionType.Local"); } if (localGamers == null) { throw new ArgumentNullException("localGamers"); } foreach (var localGamer in localGamers) { if (localGamer == null) { throw new ArgumentNullException("Element of localGamers"); } } if (searchProperties == null) { searchProperties = new NetworkSessionProperties(); } AsyncFindCaller = new AsyncFind(InternalFind); IAsyncResult result = null; try { result = AsyncFindCaller.BeginInvoke(sessionType, localGamers, searchProperties, callback, asyncState); } catch { AsyncFindCaller = null; throw; } return(result); }