コード例 #1
0
        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);
        }
コード例 #2
0
 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);
     }
 }
コード例 #3
0
        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));
        }
コード例 #4
0
 public static NetworkSession Join(AvailableNetworkSession availableSession)
 {
     try { return(EndJoin(BeginJoin(availableSession, null, null))); }
     catch { throw; }
 }