Пример #1
0
        /// <summary>
        /// Sends request to get confirmation code
        /// </summary>
        public void RequestConfirmationCode()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Sending confirmation code... Please wait!");

            logger.Debug("Sending confirmation code... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.RequestEmailConfirmationCode((isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage($"We have sent an email with confirmation code to your address '{Mst.Client.Auth.AccountInfo.Email}'", null));
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while requesting confirmation code: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #2
0
        /// <summary>
        /// Sends request to master to generate rest password code and send it to user email
        /// </summary>
        /// <param name="userEmail"></param>
        public void RequestResetPasswordCode(string userEmail)
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Sending reset password code... Please wait!");

            logger.Debug("Sending reset password code... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.RequestPasswordReset(userEmail, (isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        Mst.Options.Set(MstDictKeys.resetPasswordEmail, userEmail);

                        Mst.Events.Invoke(MstEventKeys.hidePasswordResetCodeView);
                        Mst.Events.Invoke(MstEventKeys.showPasswordResetView);
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage($"We have sent an email with reset code to your address '{userEmail}'", null));
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while password reset code: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #3
0
        /// <summary>
        /// Send request to master server to change password
        /// </summary>
        /// <param name="userEmail"></param>
        /// <param name="resetCode"></param>
        /// <param name="newPassword"></param>
        public void ResetPassword(string userEmail, string resetCode, string newPassword)
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Changing password... Please wait!");

            logger.Debug("Changing password... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.ChangePassword(userEmail, resetCode, newPassword, (isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        Mst.Events.Invoke(MstEventKeys.hidePasswordResetView);
                        Mst.Events.Invoke(MstEventKeys.showSignInView);
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage("You have successfuly changed your password. Now you can sign in.", null));
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while changing password: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #4
0
        /// <summary>
        /// Sends sign up request to master server
        /// </summary>
        public void SignUp(string username, string useremail, string userpassword)
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Signing up... Please wait!");

            logger.Debug("Signing up... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                var credentials = new MstProperties();
                credentials.Set(MstDictKeys.userName, username);
                credentials.Set(MstDictKeys.userEmail, useremail);
                credentials.Set(MstDictKeys.userPassword, userpassword);

                Mst.Client.Auth.SignUp(credentials, (isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        Mst.Events.Invoke(MstEventKeys.hideSignUpView);
                        Mst.Events.Invoke(MstEventKeys.showSignInView);
                        Mst.Events.Invoke(MstEventKeys.setSignInDefaultCredentials, credentials);

                        logger.Debug($"You have successfuly signed up. Now you may sign in");
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while signing up: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #5
0
        /// <summary>
        /// Sends request to confirm account with confirmation code
        /// </summary>
        public void ConfirmAccount(string confirmationCode)
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Confirming your account... Please wait!");

            logger.Debug("Sending confirmation code... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.ConfirmEmail(confirmationCode, (isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        Mst.Events.Invoke(MstEventKeys.hideEmailConfirmationView);
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while confirming yor account: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #6
0
        /// <summary>
        /// Loads player profile
        /// </summary>
        /// <param name="successCallback"></param>
        public void LoadPlayerProfile(string username, SuccessCallback successCallback)
        {
            if (roomPlayersByUsername.ContainsKey(username))
            {
                RoomPlayer player = roomPlayersByUsername[username];

                Mst.Server.Profiles.FillProfileValues(player.Profile, (isSuccess, error) =>
                {
                    if (!isSuccess)
                    {
                        logger.Error("Room server cannot retrieve player profile from master server");
                        successCallback?.Invoke(false, "Room server cannot retrieve player profile from master server");

                        if (disconnectIfProfileFailed)
                        {
                            MstTimer.WaitForSeconds(1f, () => player.MirrorPeer.Disconnect());
                        }

                        return;
                    }

                    logger.Debug($"Profile of player {username} is successfully loaded. Player info: {player}");
                    successCallback?.Invoke(true, string.Empty);
                });
            }
        }
Пример #7
0
        /// <summary>
        /// Sends sign in as guest request to master server
        /// </summary>
        public void SignInAsGuest()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Signing in as guest... Please wait!");

            logger.Debug("Signing in as guest... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.SignInAsGuest((accountInfo, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (accountInfo != null)
                    {
                        Mst.Events.Invoke(MstEventKeys.hideSignInView);

                        logger.Debug($"You are successfully logged in as {Mst.Client.Auth.AccountInfo}");
                    }
                    else
                    {
                        string outputMessage = $"An error occurred while signing in: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #8
0
        /// <summary>
        /// This is called on the Server when a Mirror Client disconnects from the Server
        /// </summary>
        /// <param name="obj"></param>
        private void OnMirrorClientDisconnectedEvent(NetworkConnection connection)
        {
            MstTimer.WaitForSeconds(0.2f, () =>
            {
                // Try to find player in filtered list
                if (roomPlayersByMirrorPeerId.TryGetValue(connection.connectionId, out RoomPlayer player))
                {
                    logger.Debug($"Room server player {player.Username} with room client Id {connection.connectionId} left the room");

                    // Remove thisplayer from filtered list
                    roomPlayersByMirrorPeerId.Remove(player.MirrorPeer.connectionId);
                    roomPlayersByMsfPeerId.Remove(player.MasterPeerId);
                    roomPlayersByUsername.Remove(player.Username);

                    // Notify master server about disconnected player
                    if (RoomController.IsActive)
                    {
                        RoomController.NotifyPlayerLeft(player.MasterPeerId);
                    }

                    // Dispose profile
                    player.Profile?.Dispose();

                    // Inform subscribers about this bad guy
                    OnPlayerLeftRoomEvent?.Invoke(player);

                    // Calling termination conditions check
                    OnCheckTerminationConditionEvent?.Invoke();
                }
                else
                {
                    logger.Debug($"Room server client {connection.connectionId} left the room");
                }
            });
        }
Пример #9
0
        protected override void OnInitialize()
        {
            // If we hav offline scene in global options
            if (Mst.Options.Has(MstDictKeys.ROOM_OFFLINE_SCENE_NAME))
            {
                logger.Debug("Assigning offline scene to mirror network manager");
                RoomNetworkManager.offlineScene = Mst.Options.AsString(MstDictKeys.ROOM_OFFLINE_SCENE_NAME);
            }

            // Start listening to OnServerStartedEvent of our MirrorNetworkManager
            if (NetworkManager.singleton is RoomNetworkManager manager)
            {
                manager.OnClientStartedEvent += OnMirrorClientStartedEventHandler;
                manager.OnClientStoppedEvent += OnMirrorClientStoppedEventHandler;
            }
            else
            {
                logger.Error("Before using MirrorNetworkManager add it to scene");
            }

            // Add master server connection and disconnection listeners
            Connection.AddDisconnectionListener(OnDisconnectedFromMasterServerEventHandler, false);

            MstTimer.WaitForSeconds(0.5f, () =>
            {
                // If connection to master server is not established
                if (!Connection.IsConnected && !Connection.IsConnecting)
                {
                    Connection.UseSsl = MstApplicationConfig.Instance.UseSecure;
                    Connection.Connect(masterIp, masterPort);
                }
            });
        }
Пример #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="peer"></param>
        protected override void OnPeerDisconnected(IPeer peer)
        {
            MstTimer.WaitForSeconds(0.2f, () =>
            {
                // Try to find player in filtered list
                if (roomPlayersByRoomPeerId.TryGetValue(peer.Id, out IRoomPlayerPeerExtension player))
                {
                    logger.Debug($"Room server player {player.Username} with room client Id {peer.Id} left the room");

                    // Remove this player from filtered list
                    roomPlayersByRoomPeerId.Remove(player.Peer.Id);
                    roomPlayersByMsfPeerId.Remove(player.MasterPeerId);
                    roomPlayersByUsername.Remove(player.Username);

                    // Notify master server about disconnected player
                    if (RoomController.IsActive)
                    {
                        RoomController.NotifyPlayerLeft(player.MasterPeerId);
                    }

                    // Inform subscribers about this bad guy
                    OnPlayerLeftRoomEvent?.Invoke(player);

                    // Calling termination conditions check
                    OnCheckTerminationConditionEvent?.Invoke();
                }
                else
                {
                    logger.Debug($"Room server client {peer.Id} left the room");
                }
            });
        }
Пример #11
0
        /// <summary>
        /// Sends request to master server to signed in with token
        /// </summary>
        public void SignInWithToken()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Signing in... Please wait!");

            logger.Debug("Signing in... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                Mst.Client.Auth.SignInWithToken((accountInfo, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (accountInfo != null)
                    {
                        if (accountInfo.IsEmailConfirmed)
                        {
                            logger.Debug($"You are successfully logged in. {Mst.Client.Auth.AccountInfo}");
                        }
                        else
                        {
                            Mst.Events.Invoke(MstEventKeys.showEmailConfirmationView, Mst.Client.Auth.AccountInfo.Email);
                        }
                    }
                    else
                    {
                        outputMessage = $"An error occurred while signing in: {error}";
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
Пример #12
0
        /// <summary>
        /// Sends request to master server to find games list
        /// </summary>
        public void FindGames()
        {
            ClearGamesList();

            canvasGroup.interactable = false;

            if (statusInfoText)
            {
                statusInfoText.text = "Finding rooms... Please wait!";
                statusInfoText.gameObject.SetActive(true);
            }

            MstTimer.WaitForSeconds(0.2f, () =>
            {
                Mst.Client.Matchmaker.FindGames((games) =>
                {
                    canvasGroup.interactable = true;

                    if (games.Count == 0)
                    {
                        statusInfoText.text = "No games found! Try to create your own.";
                        return;
                    }

                    statusInfoText.gameObject.SetActive(false);
                    DrawGamesList(games);
                });
            });
        }
Пример #13
0
        protected override void OnInitialize()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Connecting to master... Please wait!");

            // If we want to use default credentials for signin or signup views
            if (useDefaultCredentials && Mst.Runtime.IsEditor)
            {
                var credentials = new MstProperties();
                credentials.Set(MstDictKeys.USER_NAME, defaultUsername);
                credentials.Set(MstDictKeys.USER_PASSWORD, defaultPassword);
                credentials.Set(MstDictKeys.USER_EMAIL, defaultEmail);

                Mst.Events.Invoke(MstEventKeys.setSignInDefaultCredentials, credentials);
                Mst.Events.Invoke(MstEventKeys.setSignUpDefaultCredentials, credentials);
            }

            Mst.Client.Auth.RememberMe = rememberUser;

            MstTimer.WaitForSeconds(0.5f, () =>
            {
                // Listen to connection events
                Connection.AddConnectionListener(OnClientConnectedToServer);
                Connection.AddDisconnectionListener(OnClientDisconnectedFromServer, false);

                if (!Connection.IsConnected && !Connection.IsConnecting)
                {
                    Connector.StartConnection();
                }
            });
        }
Пример #14
0
 /// <summary>
 /// This will start server in test mode
 /// </summary>
 protected virtual void StartServerInEditor()
 {
     if (startServerAsHost)
     {
         RoomNetworkManager.StopHost();
         MstTimer.WaitForSeconds(0.2f, () => RoomNetworkManager.StartHost());
     }
     else
     {
         RoomNetworkManager.StopServer();
         MstTimer.WaitForSeconds(0.2f, () => RoomNetworkManager.StartServer());
     }
 }
Пример #15
0
        /// <summary>
        /// Joins channel
        /// </summary>
        private void JoinPredefinedChannels()
        {
            canvasGroup.interactable = false;

            if (statusInfoText)
            {
                statusInfoText.text = "Finding rooms... Please wait!";
                statusInfoText.gameObject.SetActive(true);
            }

            MstTimer.WaitForSeconds(0.5f, () =>
            {
                // Join default chat
                Mst.Client.Chat.JoinChannel(defaultChannelName, (isSuccess, error) =>
                {
                    canvasGroup.interactable = true;
                    statusInfoText.gameObject.SetActive(false);

                    if (!isSuccess)
                    {
                        Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(error, () =>
                        {
                            Hide();
                            ViewsManager.Show("UsernamePickView");
                        }));

                        return;
                    }

                    // Get my channels
                    Mst.Client.Chat.GetMyChannels((channels, error) =>
                    {
                        statusInfoText.gameObject.SetActive(false);

                        if (!string.IsNullOrEmpty(error))
                        {
                            Mst.Events.Invoke(MstEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(error, () =>
                            {
                                Hide();
                                ViewsManager.Show("UsernamePickView");
                            }));

                            return;
                        }

                        DrawChannelsList(channels);
                    });
                });
            });
        }
Пример #16
0
        public void UpdateProfile()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Saving profile data... Please wait!");

            MstTimer.WaitForSeconds(1f, () =>
            {
                var data = new Dictionary<string, string>
                {
                    { "displayName", profileSettingsView.DisplayName },
                    { "avatarUrl", profileSettingsView.AvatarUrl }
                };

                Connection.SendMessage((short)MstMessageCodes.UpdateDisplayNameRequest, data.ToBytes(), OnSaveProfileResponseCallback);
            });
        }
Пример #17
0
        private void Rpc_NotifyDied()
        {
            if (isLocalPlayer)
            {
                characterController.enabled = false;

                IsAlive = false;
                OnDieEvent?.Invoke();
            }

            if (dieEffectPrefab)
            {
                MstTimer.WaitForSeconds(1f, () => {
                    Instantiate(dieEffectPrefab, transform.position, Quaternion.identity);
                });
            }
        }
Пример #18
0
        protected override void OnInitialize()
        {
            // Listen to disconnection from master
            masterConnection.AddDisconnectionListener(OnDisconnectedFromMasterEvent, false);

            MstTimer.WaitForSeconds(1f, () =>
            {
                if (IsInTestMode())
                {
                    StartRoomClient(true);
                }

                if (Mst.Options.Has(MstDictKeys.AUTOSTART_ROOM_CLIENT) || Mst.Args.StartClientConnection)
                {
                    StartRoomClient();
                }
            });
        }
Пример #19
0
        /// <summary>
        /// Get profile data from master
        /// </summary>
        public virtual void LoadProfile()
        {
            Mst.Events.Invoke(MstEventKeys.showLoadingInfo, "Loading profile... Please wait!");

            MstTimer.WaitForSeconds(0.2f, () =>
            {
                Mst.Client.Profiles.GetProfileValues(Profile, (isSuccessful, error) =>
                {
                    Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        OnProfileLoadedEvent?.Invoke();
                    }
                    else
                    {
                        logger.Error("Could not load user profile");
                        OnProfileLoadFailedEvent?.Invoke();
                    }
                });
            });
        }
Пример #20
0
        /// <summary>
        ///
        /// </summary>
        protected virtual void OnClientConnectedToServer()
        {
            Mst.Events.Invoke(MstEventKeys.hideLoadingInfo);

            if (Mst.Client.Auth.IsSignedIn)
            {
                OnSignedInEvent?.Invoke();
            }
            else
            {
                if (Mst.Client.Auth.HasAuthToken())
                {
                    MstTimer.WaitForSeconds(0.2f, () =>
                    {
                        SignInWithToken();
                    });
                }
                else
                {
                    Mst.Events.Invoke(MstEventKeys.showSignInView);
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Fires when client that wants to connect to this room made request to validate the access token
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="msg"></param>
        protected virtual void ValidateRoomAccessRequestHandler(NetworkConnection conn, ValidateRoomAccessRequestMessage msg)
        {
            logger.Debug($"Room client {conn.connectionId} asked to validate access token [{msg.Token}]");

            // Triying to validate given token
            Mst.Server.Rooms.ValidateAccess(RoomController.RoomId, msg.Token, (usernameAndPeerId, error) =>
            {
                // If token is not valid
                if (usernameAndPeerId == null)
                {
                    logger.Error(error);

                    conn.Send(new ValidateRoomAccessResultMessage()
                    {
                        Error  = error,
                        Status = ResponseStatus.Failed
                    });

                    MstTimer.WaitForSeconds(1f, () => conn.Disconnect());

                    return;
                }

                logger.Debug($"Client {conn.connectionId} is successfully validated");
                logger.Debug("Getting his account info...");

                Mst.Server.Auth.GetPeerAccountInfo(usernameAndPeerId.PeerId, (accountInfo, accountError) =>
                {
                    if (accountInfo == null)
                    {
                        logger.Error(accountError);

                        conn.Send(new ValidateRoomAccessResultMessage()
                        {
                            Error  = accountError,
                            Status = ResponseStatus.Error
                        });

                        MstTimer.WaitForSeconds(1f, () => conn.Disconnect());

                        return;
                    }

                    // If we do not want guest users to play in our room
                    if (!allowGuestUsers && accountInfo.Properties.Has(MstDictKeys.USER_IS_GUEST) && accountInfo.Properties.AsBool(MstDictKeys.USER_IS_GUEST))
                    {
                        logger.Error("Guest users cannot play this room. Hands off...");

                        conn.Send(new ValidateRoomAccessResultMessage()
                        {
                            Error  = "Guest users cannot play this room. Hands off...",
                            Status = ResponseStatus.Error
                        });

                        MstTimer.WaitForSeconds(1f, () => conn.Disconnect());

                        return;
                    }

                    // Create new room player
                    var player = new RoomPlayer(usernameAndPeerId.PeerId, conn, accountInfo.UserId, accountInfo.Username, accountInfo.Properties)
                    {
                        Profile = ProfileFactory(accountInfo.UserId)
                    };

                    // Add this player to filtered lists
                    roomPlayersByMsfPeerId.Add(usernameAndPeerId.PeerId, player);
                    roomPlayersByMirrorPeerId.Add(conn.connectionId, player);
                    roomPlayersByUsername.Add(accountInfo.Username, player);

                    // If server is required user profile
                    if (autoLoadUserProfile)
                    {
                        LoadPlayerProfile(accountInfo.Username, (isLoadProfileSuccess, loadProfileError) =>
                        {
                            if (isLoadProfileSuccess)
                            {
                                FinalizePlayerJoining(conn);
                            }
                        });
                    }
                    else
                    {
                        FinalizePlayerJoining(conn);
                    }
                });
            });
        }
Пример #22
0
        private void ProvideRoomAccessCheckHandler(IIncomingMessage message)
        {
            var provideRoomAccessCheckPacket = message.Deserialize(new ProvideRoomAccessCheckPacket());
            var roomController = Mst.Server.Rooms.GetRoomController(provideRoomAccessCheckPacket.RoomId);

            if (roomController == null)
            {
                message.Respond($"There's no room controller with room id {provideRoomAccessCheckPacket.RoomId}", ResponseStatus.NotHandled);
                return;
            }

            var isProviderDone = false;

            var requester = new UsernameAndPeerIdPacket()
            {
                PeerId   = provideRoomAccessCheckPacket.PeerId,
                Username = provideRoomAccessCheckPacket.Username
            };

            // Create access provider check options
            var roomAccessProviderCheck = new RoomAccessProviderCheck()
            {
                PeerId        = provideRoomAccessCheckPacket.PeerId,
                Username      = provideRoomAccessCheckPacket.Username,
                CustomOptions = provideRoomAccessCheckPacket.CustomOptions
            };

            // Invoke the access provider
            roomController.AccessProvider.Invoke(roomAccessProviderCheck, (access, error) =>
            {
                // In case provider timed out
                if (isProviderDone)
                {
                    return;
                }

                isProviderDone = true;

                if (access == null)
                {
                    // If access is not provided
                    message.Respond(string.IsNullOrEmpty(error) ? "" : error, ResponseStatus.Failed);
                    return;
                }

                message.Respond(access, ResponseStatus.Success);

                if (Logger.IsLogging(LogLevel.Trace))
                {
                    Logger.Trace("Room controller gave address to peer " + provideRoomAccessCheckPacket.PeerId + ":" + access);
                }
            });

            // Timeout the access provider
            MstTimer.WaitForSeconds(Mst.Server.Rooms.AccessProviderTimeout, () =>
            {
                if (!isProviderDone)
                {
                    isProviderDone = true;
                    message.Respond("Timed out", ResponseStatus.Timeout);
                    Logger.Error($"Access provider took longer than {Mst.Server.Rooms.AccessProviderTimeout} seconds to provide access. " +
                                 "If it's intended, increase the threshold at Msf.Server.Rooms.AccessProviderTimeout");
                }
            });
        }