public void ConfirmAccount()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Confirming your account... Please wait!");

            if (!emailConfirmationView)
            {
                ViewsManager.NotifyNoViewFound("EmailConfirmationView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                string confirmationCode = emailConfirmationView.ConfirmationCode;

                Msf.Client.Auth.ConfirmEmail(confirmationCode, (isSuccessful, error) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        emailConfirmationView.Hide();
                        OnEmailConfirmedEvent?.Invoke();
                    }
                    else
                    {
                        outputMessage = $"An error occurred while confirming yor account: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
        protected virtual void OnClientConnectedToServer()
        {
            Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

            if (Msf.Client.Auth.IsSignedIn)
            {
                OnSignedInEvent?.Invoke();
            }
            else
            {
                if (Msf.Client.Auth.HasAuthToken())
                {
                    MsfTimer.WaitForSeconds(0.2f, () => {
                        SignInWithToken();
                    });
                }
                else
                {
                    if (!signinView)
                    {
                        ViewsManager.NotifyNoViewFound("SigninView");
                        return;
                    }

                    signinView.Show();
                }
            }
        }
        public void RequestConfirmationCode()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Sending confirmation code... Please wait!");

            if (!emailConfirmationView)
            {
                ViewsManager.NotifyNoViewFound("EmailConfirmationView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                Msf.Client.Auth.RequestEmailConfirmationCode((isSuccessful, error) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        emailConfirmationView.Show();
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage($"We have sent an email with confirmation code to your address '{Msf.Client.Auth.AccountInfo.Email}'", null));
                    }
                    else
                    {
                        outputMessage = $"An error occurred while requesting confirmation code: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
        public void CreateNewRoom()
        {
            if (!createNewRoomView)
            {
                ViewsManager.NotifyNoViewFound("CreateNewRoomView");
                return;
            }

            createNewRoomView.Hide();

            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Starting room... Please wait!");

            // Spawn options for spawner controller
            var spawnOptions = new DictionaryOptions();

            spawnOptions.Add(MsfDictKeys.maxPlayers, createNewRoomView.MaxConnections);
            spawnOptions.Add(MsfDictKeys.roomName, createNewRoomView.RoomName);
            spawnOptions.Add(MsfDictKeys.roomPassword, createNewRoomView.Password);

            // Custom options that will be given to room directly
            var customSpawnOptions = new DictionaryOptions();

            customSpawnOptions.Add(Msf.Args.Names.StartClientConnection, string.Empty);

            Msf.Client.Spawners.RequestSpawn(spawnOptions, customSpawnOptions, createNewRoomView.RegionName, (controller, error) =>
            {
                if (controller == null)
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);
                    Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(error, null));
                    return;
                }

                Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Room started. Finalizing... Please wait!");

                MsfTimer.WaitWhile(() =>
                {
                    return(controller.Status != SpawnStatus.Finalized);
                }, (isSuccess) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (!isSuccess)
                    {
                        Msf.Client.Spawners.AbortSpawn(controller.SpawnTaskId);
                        logger.Error("Failed spawn new room. Time is up!");
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage("Failed spawn new room. Time is up!", null));
                        return;
                    }

                    OnRoomStartedEvent?.Invoke();

                    logger.Info("You have successfully spawned new room");
                }, 60f);
            });
        }
        public void ResetPassword()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Changing password... Please wait!");

            if (!passwordResetCodeView)
            {
                ViewsManager.NotifyNoViewFound("PasswordResetCodeView");
                return;
            }

            if (!passwordResetView)
            {
                ViewsManager.NotifyNoViewFound("PasswordResetView");
                return;
            }

            if (!signinView)
            {
                ViewsManager.NotifyNoViewFound("SigninView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                Msf.Client.Auth.ChangePassword(new PasswordChangeData()
                {
                    Email       = passwordResetCodeView.Email,
                    Code        = passwordResetView.ResetCode,
                    NewPassword = passwordResetView.NewPassword
                },
                                               (isSuccessful, error) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        passwordResetView.Hide();
                        signinView.Show();

                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage("You have successfuly changed your password. Now you can sign in.", null));
                        OnPasswordChangedEvent?.Invoke();
                    }
                    else
                    {
                        outputMessage = $"An error occurred while changing password: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
        public void SignUp()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Signing up... Please wait!");

            if (!signinView)
            {
                ViewsManager.NotifyNoViewFound("SigninView");
                return;
            }

            if (!signupView)
            {
                ViewsManager.NotifyNoViewFound("SignUpView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                string username = signupView.Username;
                string email    = signupView.Email;
                string password = signupView.Password;

                var credentials = new Dictionary <string, string>
                {
                    { "username", username },
                    { "email", email },
                    { "password", password }
                };

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

                    if (isSuccessful)
                    {
                        signupView.Hide();
                        signinView.SetInputFieldsValues(username, password);
                        signinView.Show();

                        logger.Debug($"You have successfuly signed up. Now you may sign in");
                    }
                    else
                    {
                        outputMessage = $"An error occurred while signing up: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
        public void SignIn()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Signing in... Please wait!");

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

            if (!signinView)
            {
                ViewsManager.NotifyNoViewFound("SigninView");
                return;
            }

            if (!emailConfirmationView)
            {
                ViewsManager.NotifyNoViewFound("EmailConfirmationView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                Msf.Client.Auth.SignIn(signinView.Username, signinView.Password, (accountInfo, error) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (accountInfo != null)
                    {
                        signinView.Hide();

                        if (accountInfo.IsEmailConfirmed)
                        {
                            OnSignedInEvent?.Invoke();
                            logger.Debug($"You are successfully logged in as {Msf.Client.Auth.AccountInfo}");
                        }
                        else
                        {
                            emailConfirmationView.Show();
                        }
                    }
                    else
                    {
                        outputMessage = $"An error occurred while signing in: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }
        public void RequestResetPasswordCode()
        {
            Msf.Events.Invoke(MsfEventKeys.showLoadingInfo, "Sending reset password code... Please wait!");

            if (!passwordResetCodeView)
            {
                ViewsManager.NotifyNoViewFound("PasswordResetCodeView");
                return;
            }

            if (!passwordResetView)
            {
                ViewsManager.NotifyNoViewFound("PasswordResetView");
                return;
            }

            MsfTimer.WaitForSeconds(1f, () =>
            {
                Msf.Client.Auth.RequestPasswordReset(passwordResetCodeView.Email, (isSuccessful, error) =>
                {
                    Msf.Events.Invoke(MsfEventKeys.hideLoadingInfo);

                    if (isSuccessful)
                    {
                        passwordResetCodeView.Hide();
                        passwordResetView.Show();

                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage($"We have sent an email with reset code to your address '{passwordResetCodeView.Email}'", null));
                    }
                    else
                    {
                        outputMessage = $"An error occurred while password reset code: {error}";
                        Msf.Events.Invoke(MsfEventKeys.showOkDialogBox, new OkDialogBoxEventMessage(outputMessage, null));
                        logger.Error(outputMessage);
                    }
                });
            });
        }