コード例 #1
0
ファイル: NetworkSession.cs プロジェクト: gustavolsson/BoxNet
        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;
        }
コード例 #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 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));
        }
コード例 #4
0
        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; }
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        // 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);
        }
コード例 #7
0
 public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, int maxLocalGamers, NetworkSessionProperties searchProperties)
 {
     try { return(EndFind(BeginFind(sessionType, maxLocalGamers, searchProperties, null, null))); }
     catch { throw; }
 }
コード例 #8
0
 public static AvailableNetworkSessionCollection Find(NetworkSessionType sessionType, IEnumerable <SignedInGamer> localGamers, NetworkSessionProperties searchProperties)
 {
     try { return(EndFind(BeginFind(sessionType, localGamers, searchProperties, null, null))); }
     catch { throw; }
 }
コード例 #9
0
 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; }
 }
コード例 #10
0
        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);
        }