Advertisement
Guest User

Untitled

a guest
May 5th, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.63 KB | None | 0 0
  1. namespace MUD.Lib.Daemons
  2. {
  3.     /// <summary>
  4.     /// Handles the details of logging in and out. Yes, I'm playing enums-as-state-machines here. Leave me alone.
  5.     /// </summary>
  6.     internal class Login : VerbProcessor
  7.     {
  8.         private enum LoginState
  9.         {
  10.             Name,
  11.             NameExistsPass,
  12.             NameConfirm,
  13.             NewPassword1,
  14.             NewPassword2,
  15.             Email,
  16.             CharacterSequence
  17.         }
  18.  
  19.         private delegate bool LoginStateHandler(User user, string input);
  20.  
  21.         private Dictionary<LoginState, LoginStateHandler> LoginStateMachine;
  22.  
  23.         private User.ReceiveHandler Listener;
  24.  
  25.         private LoginState _currentState = LoginState.Name;
  26.  
  27.         private int InvalidLoginTries = 0;
  28.  
  29.         public Login(User user)
  30.         {
  31.             LoginStateMachine = new Dictionary<LoginState, LoginStateHandler>();
  32.             Listener = new User.ReceiveHandler(ReceiveInput);
  33.             user.OnExclusiveReceive += Listener;
  34.             InitializeSteps();
  35.         }
  36.  
  37.         private void InitializeSteps()
  38.         {
  39.             LoginStateMachine.Add(LoginState.Name, new LoginStateHandler(ProcessName));
  40.             LoginStateMachine.Add(LoginState.NameExistsPass, new LoginStateHandler(ValidatePassword));
  41.             LoginStateMachine.Add(LoginState.NameConfirm, new LoginStateHandler(NameConfirm));
  42.             LoginStateMachine.Add(LoginState.NewPassword1, new LoginStateHandler(NewPassword1));
  43.             LoginStateMachine.Add(LoginState.NewPassword2, new LoginStateHandler(NewPassword2));
  44.             LoginStateMachine.Add(LoginState.Email, new LoginStateHandler(EmailHandler));
  45.             LoginStateMachine.Add(LoginState.CharacterSequence, new LoginStateHandler(ToCharacterSequence));
  46.         }
  47.  
  48.         private bool ReceiveInput(User user, string command)
  49.         {
  50.             if (LoginStateMachine.Keys.Contains(_currentState))
  51.                 return LoginStateMachine[_currentState](user, command.TrimNewline());
  52.             else
  53.                 return false;
  54.         }
  55.  
  56.         // First thing we're going to see from the user.
  57.         private bool ProcessName(User user, string input)
  58.         {
  59.             user.Username = input;
  60.             // attempt to load the user;
  61.             user.Load();
  62.             if (!string.IsNullOrEmpty(user.Password))
  63.             {
  64.                 // ok, there is a user by this name.
  65.                 _currentState = LoginState.NameExistsPass;
  66.                 user.Write("Welcome back, " + user.Username + "! Please enter your password:\r\n");
  67.             }
  68.             else
  69.             {
  70.                 // this is a new user.
  71.                 _currentState = LoginState.NameConfirm;
  72.                 user.Write("Are you sure this is the account name you wish to use? (y/n)\r\n");
  73.             }
  74.             return true;
  75.         }
  76.  
  77.         private bool ValidatePassword(User user, string input)
  78.         {
  79.             MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  80.             if (user.Password == BitConverter.ToString(md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(input))))
  81.             {
  82.                 // password valid, continue to character selection
  83.                 // TODO: Move to character creation/selection
  84.                 _currentState = LoginState.CharacterSequence;
  85.                 ToCharacterSequence(user, "y");
  86.             }
  87.             else
  88.             {
  89.                 // password invalid, ask them to try again.
  90.                 InvalidLoginTries++;
  91.                 if (InvalidLoginTries < 3)
  92.                 {
  93.                     user.Write("Password invalid, please try again:\r\n ");
  94.                     return false;
  95.                 }
  96.                 else
  97.                 {
  98.                     user.Write("Maximum login attempts reached, disconnecting.\r\n");
  99.                     user.OnExclusiveReceive -= Listener;
  100.                     user.Disconnect();
  101.                 }
  102.             }
  103.             return true;
  104.         }
  105.  
  106.         private bool NameConfirm(User user, string input)
  107.         {
  108.             if (input.ToLower() == "y")
  109.             {
  110.                 // they want this name, move on.
  111.                 user.Write("Great! Please enter a password.\r\n");
  112.                 _currentState = LoginState.NewPassword1;
  113.             }
  114.             else
  115.             {
  116.                 user.Write("Ok, what name would you like to use?\r\n");
  117.                 _currentState = LoginState.Name;
  118.             }
  119.             return true;
  120.         }
  121.  
  122.         private bool NewPassword1(User user, string input)
  123.         {
  124.             MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  125.             user.Password = BitConverter.ToString(md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(input)));
  126.             _currentState = LoginState.NewPassword2;
  127.             user.Write("Please reenter your password:\r\n");
  128.             return true;
  129.         }
  130.  
  131.         private bool NewPassword2(User user, string input)
  132.         {
  133.             MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  134.             if (BitConverter.ToString(md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(input))) == user.Password)
  135.             {
  136.                 // Password accepted, move on.
  137.                 _currentState = LoginState.Email;
  138.                 user.Write("Please enter a valid email address.\r\n");
  139.             }
  140.             else
  141.             {
  142.                 // Passwords don't match, reenter.
  143.                 _currentState = LoginState.NewPassword1;
  144.                 user.Write("Passwords do not match, please choose a password:\r\n");
  145.             }
  146.             return true;
  147.         }
  148.  
  149.         private bool EmailHandler(User user, string input)
  150.         {
  151.             if (IsEmailValid(input))
  152.             {
  153.                 // store it and move on to character selection/creation!
  154.                 user.Email = input;
  155.                 user.Write("Ok, your new account with username " + user.Username + " and email address: " + user.Email + " is created. Please verify these details before continuing. (y/n)\r\n Warning: entering 'n' will cause the creation process to restart!\r\n");
  156.                 _currentState = LoginState.CharacterSequence;
  157.             }
  158.             else
  159.             {
  160.                 // oops, need to reenter.
  161.                 user.Write("Email invalid, please enter a valid email address.");
  162.             }
  163.             return true;
  164.         }
  165.  
  166.         private bool ToCharacterSequence(User user, string input)
  167.         {
  168.             if (input.ToLower() == "y")
  169.             {
  170.                 // TODO: load character select/creation sequence
  171.                 user.OnExclusiveReceive -= Listener;
  172.                 user.Save();
  173.                 user.Write("Welcome to MUD.Net!!\r\n");
  174.             }
  175.             else
  176.             {
  177.                 user.Write("Ok, starting over. Please enter desired username.\r\n");
  178.                 _currentState = LoginState.Name;
  179.             }
  180.             return true;
  181.         }
  182.  
  183.         private bool IsEmailValid(string email)
  184.         {
  185.             if (string.IsNullOrEmpty(email))
  186.                 return false;
  187.             // is there more than one "@"?
  188.             int First = email.IndexOf('@');
  189.             int Last = email.IndexOf('@');
  190.             if (First != Last && First < email.Length - 1)
  191.                 return false;
  192.             return true;
  193.         }
  194.  
  195.         // TODO: Should I assign a single Login instance to every user for the duration of their login sequence or handle it via daemon?
  196.         // TODO: Also, should I handle all character creation here as well?
  197.         // enum++ and -- work just fine, btw.
  198.  
  199.        
  200.  
  201.     }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement