public static IAsyncResult BeginJoin(AvailableNetworkSession availableSession, AsyncCallback callback, Object asyncState) { if (Session != null || AsyncCreateCaller != null || AsyncFindCaller != null || AsyncJoinCaller != null) { throw new InvalidOperationException("Only one NetworkSession allowed"); } if (availableSession == null) { throw new ArgumentNullException("availableSession"); } AsyncJoinCaller = new AsyncJoin(InternalJoin); IAsyncResult result = null; try { result = AsyncJoinCaller.BeginInvoke(availableSession, callback, asyncState); } catch { AsyncJoinCaller = null; throw; } return(result); }
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 NetworkSession InternalJoin(AvailableNetworkSession availableSession) { var config = new NetPeerConfiguration(NetworkSettings.GameAppId) { Port = 0, // Use any port AcceptIncomingConnections = false, AutoFlushSendQueue = true, }; config.EnableMessageType(NetIncomingMessageType.VerboseDebugMessage); config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); config.EnableMessageType(NetIncomingMessageType.UnconnectedData); var clientPeer = new NetPeer(config); try { clientPeer.Start(); } catch (Exception e) { throw new NetworkException("Could not start client peer", e); } Debug.WriteLine("Client peer started."); if (availableSession.SessionType == NetworkSessionType.SystemLink) { clientPeer.Connect((IPEndPoint)availableSession.Tag); } else if (availableSession.SessionType == NetworkSessionType.PlayerMatch || availableSession.SessionType == NetworkSessionType.Ranked) { clientPeer.Configuration.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess); NetworkMasterServer.RequestIntroduction(clientPeer, availableSession.HostGuid, GetInternalIp(clientPeer)); } else { clientPeer.Shutdown("Failed to connect"); throw new InvalidOperationException(); } bool triedConnect = false; bool success = false; byte machineId = 255; var joinError = NetworkSessionJoinError.SessionNotFound; var startTime = DateTime.Now; while (DateTime.Now - startTime <= JoinTimeOut) { var msg = clientPeer.ReadMessage(); if (msg == null) { Thread.Sleep((int)NoMessageSleep.TotalMilliseconds); continue; } if (msg.MessageType == NetIncomingMessageType.NatIntroductionSuccess) { if (!triedConnect) { clientPeer.Connect(msg.SenderEndPoint); triedConnect = true; } } else if (msg.MessageType == NetIncomingMessageType.StatusChanged) { var status = (NetConnectionStatus)msg.ReadByte(); var reason = msg.ReadString(); if (status == NetConnectionStatus.Connected) { if (msg.SenderConnection.RemoteHailMessage != null && msg.SenderConnection.RemoteHailMessage.LengthBytes >= 1) { success = true; machineId = msg.SenderConnection.RemoteHailMessage.ReadByte(); } break; } else if (status == NetConnectionStatus.Disconnected) { NetworkSessionJoinError error; if (Enum.TryParse(reason, out error)) { joinError = error; } } } else { HandleLidgrenMessage(msg); } clientPeer.Recycle(msg); } if (!success || machineId == 255) { clientPeer.Shutdown("Failed to connect"); throw new NetworkSessionJoinException("Could not connect to host", joinError); } // Setup client if (availableSession.SessionType == NetworkSessionType.PlayerMatch || availableSession.SessionType == NetworkSessionType.Ranked) { clientPeer.Configuration.DisableMessageType(NetIncomingMessageType.NatIntroductionSuccess); } clientPeer.Configuration.AutoFlushSendQueue = false; return(new NetworkSession(clientPeer, false, machineId, availableSession.SessionType, availableSession.SessionProperties, availableSession.MaxGamers, availableSession.PrivateGamerSlots, availableSession.LocalGamers, availableSession.HostGamertag, // TODO: Store real display name here instead of gamertag availableSession.HostGamertag)); }
public static NetworkSession Join(AvailableNetworkSession availableSession) { try { return(EndJoin(BeginJoin(availableSession, null, null))); } catch { throw; } }