diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs index eccf1cf9..dc203abd 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/Program/Program.cs @@ -81,6 +81,9 @@ public async Task MainAsync() private async Task HeartbeatLoop() { + // default heartbeat data + byte[] heartbeat = new byte[] { 200 }; + while (true) { try @@ -100,7 +103,7 @@ private async Task HeartbeatLoop() _currentHeartbeatTimer = 0; for (int i = 0; i < _currentConnections.Count; i++) - transport.ServerSend(_currentConnections[i], 0, new ArraySegment(new byte[] { 200 })); + transport.ServerSend(_currentConnections[i], 0, new ArraySegment(heartbeat)); if (conf.UseLoadBalancer) { diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs index 58980510..5e800f2c 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandler.cs @@ -25,7 +25,7 @@ private string GenerateRoomID() const int LENGTH = 5; const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var randomID = ""; - var random = new Random(); + var random = _cachedRandom; do { diff --git a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerVariables.cs b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerVariables.cs index e7f3a177..ca364be4 100644 --- a/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerVariables.cs +++ b/ServerProject-DONT-IMPORT-INTO-UNITY/LRM/RelayHandler/RelayHandlerVariables.cs @@ -11,6 +11,8 @@ public partial class RelayHandler private int _maxPacketSize = 0; private Dictionary _cachedClientRooms = new(); private Dictionary _cachedRooms = new(); + + private System.Random _cachedRandom = new(); } public enum OpCodes diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs index 56a2d17a..225c75d5 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/Editor/LRMInspector.cs @@ -207,14 +207,6 @@ public override void OnInspectorGUI() } } } -#if !NET_4_6 - EditorGUILayout.BeginVertical("Box"); - EditorGUILayout.HelpBox("For LRM to function properly, it needs the API Compatibility to be at 4.x", MessageType.Error); - if (GUILayout.Button("Change to 4.x")) - PlayerSettings.SetApiCompatibilityLevel(BuildTargetGroup.Standalone, ApiCompatibilityLevel.NET_4_6); - EditorGUILayout.EndVertical(); - EditorGUILayout.Space(); -#endif currentTab = GUILayout.Toolbar(currentTab, tabs); EditorGUILayout.Space(); @@ -305,7 +297,8 @@ public override void OnInspectorGUI() EditorGUILayout.Space(); EditorGUILayout.Space(); - EditorGUILayout.PropertyField(serializedObject.FindProperty("diconnectedFromRelay")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("connectedToRelay")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("disconnectedFromRelay")); EditorGUILayout.PropertyField(serializedObject.FindProperty("serverListUpdated")); serializedObject.ApplyModifiedProperties(); break; diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs index a066ee2d..5ddd899a 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportRequests.cs @@ -95,13 +95,13 @@ IEnumerator JoinOtherRelayAndMatch(Room? roomValue, string ID) DisconnectFromRelay(); while (IsAuthenticated()) - yield return new WaitForEndOfFrame(); + yield return null; endpointServerPort = room.relayInfo.endpointPort; Connect(room.relayInfo.address, room.relayInfo.port); while (!IsAuthenticated()) - yield return new WaitForEndOfFrame(); + yield return null; int pos = 0; _directConnected = false; @@ -109,10 +109,9 @@ IEnumerator JoinOtherRelayAndMatch(Room? roomValue, string ID) _clientSendBuffer.WriteString(ref pos, room.serverId); _clientSendBuffer.WriteBool(ref pos, _directConnectModule != null); - if (GetLocalIp() == null) - _clientSendBuffer.WriteString(ref pos, "0.0.0.0"); - else - _clientSendBuffer.WriteString(ref pos, GetLocalIp()); + string local = GetLocalIp(); + + _clientSendBuffer.WriteString(ref pos, local ?? "0.0.0.0"); _isClient = true; diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportVariables.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportVariables.cs index 57cd7251..3e9b2079 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportVariables.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LRMTransportVariables.cs @@ -16,11 +16,14 @@ public partial class LightReflectiveMirrorTransport : Transport public float heartBeatInterval = 3; public bool connectOnAwake = true; public string authenticationKey = "Secret Auth Key"; - public UnityEvent diconnectedFromRelay; + + public UnityEvent disconnectedFromRelay; + public UnityEvent connectedToRelay; // NAT Puncher variables public bool useNATPunch = false; public int NATPunchtroughPort = -1; + private const int NAT_PUNCH_ATTEMPTS = 3; // LLB variables (LRM Load Balancer) public bool useLoadBalancer = false; @@ -33,6 +36,8 @@ public partial class LightReflectiveMirrorTransport : Transport public int maxServerPlayers = 10; public bool isPublicServer = true; + private const string LOCALHOST = "127.0.0.1"; + // Server list variables public UnityEvent serverListUpdated; public List relayServerList { private set; get; } = new List(); diff --git a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs index 1eaecdc3..5e9bab37 100644 --- a/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs +++ b/UnityProject/Assets/Mirror/Runtime/Transport/LRM/LRMTransport/LightReflectiveMirrorTransport.cs @@ -13,12 +13,9 @@ namespace LightReflectiveMirror public partial class LightReflectiveMirrorTransport : Transport { public bool IsAuthenticated() => _isAuthenticated; + private void Awake() { -#if !NET_4_6 - throw new Exception("LRM | Please switch to .NET 4.x for LRM to function properly!"); -#endif - if (Application.platform == RuntimePlatform.WebGLPlayer) useNATPunch = false; else @@ -56,17 +53,18 @@ private void SetupCallbacks() clientToServerTransport.OnClientError = (e) => Debug.LogException(e); } - void Disconnected() + private void Disconnected() { _connectedToRelay = false; _isAuthenticated = false; - diconnectedFromRelay?.Invoke(); + disconnectedFromRelay?.Invoke(); serverStatus = "Disconnected from relay."; } private void OnConnectedToRelay() { _connectedToRelay = true; + connectedToRelay?.Invoke(); } public void ConnectToRelay() @@ -121,7 +119,7 @@ public void DisconnectFromRelay() } } - void SendHeartbeat() + private void SendHeartbeat() { if (_connectedToRelay) { @@ -161,7 +159,7 @@ void SendHeartbeat() } } - void DataReceived(ArraySegment segmentData, int channel) + private void DataReceived(ArraySegment segmentData, int channel) { try { @@ -178,11 +176,13 @@ void DataReceived(ArraySegment segmentData, int channel) _isAuthenticated = true; RequestServerList(); break; + case OpCodes.AuthenticationRequest: // Server requested that we send an authentication request, lets send our auth key. serverStatus = "Sent authentication to relay..."; SendAuthKey(); break; + case OpCodes.GetData: // Someone sent us a packet from their mirror over the relay var recvData = data.ReadBytes(ref pos); @@ -198,6 +198,7 @@ void DataReceived(ArraySegment segmentData, int channel) if (_isClient) OnClientDataReceived?.Invoke(new ArraySegment(recvData), channel); break; + case OpCodes.ServerLeft: // Called when we were kicked, or server was closed. if (_isClient) @@ -206,6 +207,7 @@ void DataReceived(ArraySegment segmentData, int channel) OnClientDisconnected?.Invoke(); } break; + case OpCodes.PlayerDisconnected: // Called when another player left the room. if (_isServer) @@ -219,10 +221,12 @@ void DataReceived(ArraySegment segmentData, int channel) } } break; + case OpCodes.RoomCreated: // We successfully created the room, the server also gave us the serverId of the room! serverId = data.ReadString(ref pos); break; + case OpCodes.ServerJoined: // Called when a player joins the room or when we joined a room. int clientId = data.ReadInt(ref pos); @@ -239,6 +243,7 @@ void DataReceived(ArraySegment segmentData, int channel) _currentMemberId++; } break; + case OpCodes.DirectConnectIP: // Either a client is trying to join us via NAT Punch, or we are trying to join a host over NAT punch/Direct connect. var ip = data.ReadString(ref pos); @@ -264,16 +269,17 @@ void DataReceived(ArraySegment segmentData, int channel) if (useNATPunch && attemptNatPunch) { - if (ip == "127.0.0.1") - _directConnectModule.JoinServer("127.0.0.1", port + 1); + if (ip == LOCALHOST) + _directConnectModule.JoinServer(LOCALHOST, port + 1); else - _directConnectModule.JoinServer("127.0.0.1", _NATIP.Port - 1); + _directConnectModule.JoinServer(LOCALHOST, _NATIP.Port - 1); } else _directConnectModule.JoinServer(ip, port); } break; + case OpCodes.RequestNATConnection: // Called when the LRM node would like us to establish a NAT puncher connection. Its safe to ignore if NAT punch is disabled. if (useNATPunch && GetLocalIp() != null && _directConnectModule != null) @@ -297,20 +303,18 @@ void DataReceived(ArraySegment segmentData, int channel) _NATPuncher.Client.Bind(_NATIP); break; } - catch {} // Binding port is in use, keep trying :P + catch { } // Binding port is in use, keep trying :P } } - if (!IPAddress.TryParse(serverIP, out IPAddress serverAddr)) serverAddr = Dns.GetHostEntry(serverIP).AddressList[0]; _relayPuncherIP = new IPEndPoint(serverAddr, NATPunchtroughPort); - // Send 3 to lower chance of it being dropped or corrupted when received on server. - _NATPuncher.Send(initalData, sendPos, _relayPuncherIP); - _NATPuncher.Send(initalData, sendPos, _relayPuncherIP); - _NATPuncher.Send(initalData, sendPos, _relayPuncherIP); + for (int attempts = 0; attempts < NAT_PUNCH_ATTEMPTS; attempts++) + _NATPuncher.Send(initalData, sendPos, _relayPuncherIP); + _NATPuncher.BeginReceive(new AsyncCallback(RecvData), _NATPuncher); } break; @@ -414,18 +418,18 @@ public void UpdateRoomPlayerCount(int maxPlayers = 16) } } - Room? GetServerForID(string serverID) + private Room? GetServerForID(string serverID) { - for(int i = 0; i < relayServerList.Count; i++) + for (int i = 0; i < relayServerList.Count; i++) { - if(relayServerList[i].serverId == serverID) + if (relayServerList[i].serverId == serverID) return relayServerList[i]; } return null; } - void SendAuthKey() + private void SendAuthKey() { int pos = 0; _clientSendBuffer.WriteByte(ref pos, (byte)OpCodes.AuthenticationResponse); @@ -481,5 +485,4 @@ public struct RelayAddress public string address; public LRMRegions serverRegion; } - -} +} \ No newline at end of file