using Mirror; using Mirror.Examples.Chat; using System.Collections; using System.Collections.Generic; using UnityEngine; public class ChatAuthenticator : NetworkAuthenticator { readonly HashSet connectionsPendingDisconnect = new HashSet(); internal static readonly HashSet playerNames = new HashSet(); [Header("Client Username")] public string playerName; #region Messages; public struct AuthRequestMessage : NetworkMessage { public string authUsername; } public struct AuthResponseMessage : NetworkMessage { public byte code; public string message; } #endregion #region Server [UnityEngine.RuntimeInitializeOnLoadMethod] static void ResetStatics() { playerNames.Clear(); } public override void OnStartServer() { NetworkServer.RegisterHandler(OnAuthRequestMessage, false); } public override void OnStopServer() { NetworkServer.UnregisterHandler(); } public override void OnServerAuthenticate(NetworkConnectionToClient conn) { } public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg) { Debug.Log($"Authentication Request Username: {msg.authUsername}"); if (connectionsPendingDisconnect.Contains(conn)) return; if (!playerNames.Contains(msg.authUsername)) { playerNames.Add(msg.authUsername); conn.authenticationData = msg.authUsername; AuthResponseMessage authResponseMessage = new AuthResponseMessage { code = 100, message = "Success" }; conn.Send(authResponseMessage); ServerAccept(conn); } else { connectionsPendingDisconnect.Add(conn); AuthResponseMessage authResponseMessage = new AuthResponseMessage { code = 200, message = "Username already in use... try again" }; conn.Send(authResponseMessage); conn.isAuthenticated = false; StartCoroutine(DelayedDisconnect(conn, 1f)); } } IEnumerator DelayedDisconnect(NetworkConnectionToClient conn, float waitTime) { yield return new WaitForSeconds(waitTime); ServerReject(conn); yield return null; connectionsPendingDisconnect.Remove(conn); } #endregion #region Client public void SetPlayerName(string username) { playerName = username; if (LoginUI.instance != null && LoginUI.instance.errorText != null) { LoginUI.instance.errorText.text = string.Empty; LoginUI.instance.errorText.gameObject.SetActive(false); } } public override void OnStartClient() { NetworkClient.RegisterHandler(OnAuthResponseMessage, false); } public override void OnStopClient() { NetworkClient.UnregisterHandler(); } public override void OnClientAuthenticate() { NetworkClient.Send(new AuthRequestMessage { authUsername = playerName }); } public void OnAuthResponseMessage(AuthResponseMessage msg) { if (msg.code == 100) { Debug.Log($"Authentication Response: {msg.code} {msg.message}"); ClientAccept(); } else { Debug.LogError($"Authentication Response: {msg.code} {msg.message}"); NetworkManager.singleton.StopHost(); LoginUI.instance.errorText.text = msg.message; LoginUI.instance.errorText.gameObject.SetActive(true); } } #endregion // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { } // Update is called once per frame void Update() { } }