private void UnregisterWithMasterServer() { if (!isHost || type == NetworkSessionType.Local || type == NetworkSessionType.SystemLink) { return; } NetworkMasterServer.UnregisterHost(peer, guid); }
/// <summary> /// Request a general info string from the master server. Only applicable to the PlayerMatch and Ranked /// session types. See summary for the MasterServerGeneralInfo property.This is a MonoGame-only extension. /// </summary> public void RequestMasterServerGeneralInfo() { if (IsDisposed) { throw new ObjectDisposedException("NetworkSession"); } if (type != NetworkSessionType.PlayerMatch && type != NetworkSessionType.Ranked) { throw new InvalidOperationException("Can only be invoked on a session of type PlayerMarch or Ranked"); } NetworkMasterServer.RequestGeneralInfo(peer); }
private void RegisterWithMasterServer() { if (!isHost || type == NetworkSessionType.Local || type == NetworkSessionType.SystemLink) { return; } var currentTime = DateTime.Now; if (currentTime - lastMasterServerReport < NetworkSettings.MasterServerRegistrationInterval) { return; } lastMasterServerReport = currentTime; UpdatePublicInfo(); NetworkMasterServer.RegisterHost(peer, guid, GetInternalIp(peer), publicInfo); }
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)); }
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)); }
private void ReceiveMessages() { NetIncomingMessage msg; while ((msg = peer.ReadMessage()) != null) { if (msg.MessageType == NetIncomingMessageType.DiscoveryRequest) { Debug.WriteLine("Local discovery request received"); if (isHost) { UpdatePublicInfo(); NetworkMasterServer.SendRequestHostsResponse(peer, msg.SenderEndPoint, true, guid, publicInfo); } } else if (msg.MessageType == NetIncomingMessageType.ConnectionApproval) { if (!isHost) { throw new InvalidOperationException(); } if (allowJoinInProgress || state == NetworkSessionState.Lobby) { byte machineId; if (GetOpenPublicGamerSlots() > 0 && GetUniqueId(machineFromId, out machineId)) { // Approved, create network machine var machine = new NetworkMachine(this, false, false, machineId); msg.SenderConnection.Tag = machine; AddMachine(machine, msg.SenderConnection); // Send approval to client containing unique machine id var hailMsg = peer.CreateMessage(); hailMsg.Write(machineId); msg.SenderConnection.Approve(hailMsg); } else { msg.SenderConnection.Deny(NetworkSessionJoinError.SessionFull.ToString()); } } else { msg.SenderConnection.Deny(NetworkSessionJoinError.SessionNotJoinable.ToString()); } } else if (msg.MessageType == NetIncomingMessageType.StatusChanged) { var status = (NetConnectionStatus)msg.ReadByte(); Debug.WriteLine("Connection status updated: " + status + " (Reason: " + msg.ReadString() + ")"); if (status == NetConnectionStatus.Connected) { if (!isHost) { throw new InvalidOperationException("A client cannot accept new connections"); } if (msg.SenderConnection.Tag == null) { throw new InvalidOperationException(); } var machine = (NetworkMachine)msg.SenderConnection.Tag; SendMachineConnectedMessage(machine, null); } else if (status == NetConnectionStatus.Disconnected) { if (msg.SenderConnection != null) { if (msg.SenderConnection.Tag == null) { throw new InvalidOperationException(); } var machine = (NetworkMachine)msg.SenderConnection.Tag; RemoveMachine(machine); if (isHost) { SendMachineDisconnectedMessage(machine); } else { string reasonString; NetworkSessionEndReason reason; if (msg.ReadString(out reasonString) && Enum.TryParse(reasonString, out reason)) { End(reason); } else { End(NetworkSessionEndReason.Disconnected); } } } } } else if (msg.MessageType == NetIncomingMessageType.Data) { if (msg.SenderConnection.Tag == null) { throw new InvalidOperationException(); } ReceiveMessage(msg, msg.DeliveryMethod, (NetworkMachine)msg.SenderConnection.Tag); } else if (msg.MessageType == NetIncomingMessageType.UnconnectedData) { if (msg.SenderEndPoint.Equals(NetworkMasterServer.ResolveEndPoint())) { MasterServerMessageType responseType; MasterServerMessageResult responseResult; if (NetworkMasterServer.ParseResponseHeader(msg, out responseType, out responseResult)) { if (responseResult == MasterServerMessageResult.Ok) { if (responseType == MasterServerMessageType.RequestGeneralInfo) { string generalInfo; if (NetworkMasterServer.ParseRequestGeneralInfoResponse(msg, out generalInfo)) { masterServerGeneralInfo = generalInfo; } } else if (responseType == MasterServerMessageType.RegisterHost) { isRegisteredAsHostWithMasterServer = true; } else if (responseType == MasterServerMessageType.UnregisterHost) { isRegisteredAsHostWithMasterServer = false; } } else { hasFailedMasterServerValidation = true; } } } else { Debug.WriteLine("Unconnected data not from master server recieved from " + msg.SenderEndPoint + ", ignoring..."); } } else { HandleLidgrenMessage(msg); } peer.Recycle(msg); if (IsDisposed) { break; } } }