Browse Source

Working on character creation.

Beoran 8 years ago
parent
commit
39971a8b5b
7 changed files with 236 additions and 50 deletions
  1. 26 0
      lib/security.rb
  2. 5 5
      lib/telnet.rb
  3. 8 6
      lib/woe/account.rb
  4. 133 0
      lib/woe/being.rb
  5. 0 0
      lib/woe/character.rb
  6. 64 39
      lib/woe/client.rb
  7. 0 0
      lib/woe/mobile.rb

+ 26 - 0
lib/security.rb

@@ -0,0 +1,26 @@
+#
+# Woe security related helper functions. 
+#
+
+
+CRYPT_MAKE_SALT_AID = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"
+
+# Generates salt for use by crypt.
+def crypt_make_salt  
+  c1 = CRYPT_MAKE_SALT_AID[rand(CRYPT_MAKE_SALT_AID.length)] 
+  c2 = CRYPT_MAKE_SALT_AID[rand(CRYPT_MAKE_SALT_AID.length)] 
+  return c1 + c2
+end
+
+# Crypt with salt generation.
+def crypt(pass, salt = nil) 
+  salt = crypt_make_salt unless salt
+  return pass.to_s.crypt(salt)
+end
+
+# Challenge crypt password trypass against the hash hash
+def crypt_challenge?(trypass, hash) 
+  salt = hash[0, 2]
+  tryhash = trypass.to_s.crypt(salt)
+  return tryhash == hash
+end

+ 5 - 5
lib/telnet.rb

@@ -559,14 +559,14 @@ end
     telnet_send(buf)
   end
 
-
+  CRLF  = "\r\n"
+  CRNUL = "\r\0"
+  
   # send formatted data with \r and \n translation in addition to IAC IAC 
   def telnet_printf(fmt, *args)
-    crlf  = "\r\n"
-    clnul = "\r\0"
     buf   = sprintf(fmt, *args)
-    buf.gsub!("\r", crnul)
-    buf.gsub!("\n", crlf)
+    buf.gsub!("\r", CRNUL)
+    buf.gsub!("\n", CRLF)
     telnet_send(buf)
   end
 

+ 8 - 6
lib/woe/account.rb

@@ -1,6 +1,8 @@
 require_relative "../sitef.rb"
 require_relative "../serdes.rb"
 require_relative "../monolog.rb"
+require_relative "../security.rb"
+
 
 
 module Woe
@@ -8,11 +10,11 @@ class Account
   include Serdes
   include Monolog
 
-  serdes_reader :id
-  serdes_reader :pass
-  serdes_reader :algo
-  serdes_reader :email
-  serdes_reader :woe_points
+  serdes_reader   :id
+  serdes_reader   :pass
+  serdes_reader   :algo
+  serdes_reader   :email
+  serdes_accessor :woe_points
   
   
   def inspect
@@ -29,7 +31,7 @@ class Account
     if algo == "plain"
       return @pass == trypass
     elsif algo == "crypt"
-      return crypt_challenge(trypass, @pass)
+      return crypt_challenge?(trypass, @pass)
     else
       return false
     end

+ 133 - 0
lib/woe/being.rb

@@ -0,0 +1,133 @@
+module Woe
+  module Being
+    include Serdes
+    include Monolog
+
+    serdes_reader   :id
+    serdes_reader   :account
+    
+    # Essentials
+    serdes_reader   :kind         # AKA "race"
+    serdes_reader   :level
+    serdes_reader   :profession   # AKA "class"
+    
+    # Talents
+    serdes_reader   :strength
+    serdes_reader   :toughness
+    serdes_reader   :agility
+    serdes_reader   :dexterity
+    serdes_reader   :intelligence
+    serdes_reader   :wisdom
+    serdes_reader   :charisma
+    serdes_reader   :essence
+    
+    # Vitals
+    serdes_reader   :hp
+    serdes_reader   :hp_max
+    serdes_reader   :mp
+    serdes_reader   :mp_max
+    serdes_reader   :jp
+    serdes_reader   :jp_max
+    serdes_reader   :lp
+    serdes_reader   :lp_max
+        
+    # Equipment values
+    serdes_reader   :offense
+    serdes_reader   :protection
+    serdes_reader   :block
+    serdes_reader   :rapidity
+    serdes_reader   :yield
+
+
+    # Skills array
+    serdes_reader   :skills
+    
+    # Affects array
+    serdes_reader   :affects
+    
+    # Derived stats 
+    def force
+      return (strength * 2 + wisdom) / 3
+    end
+    
+    def vitality
+      return (toughness * 2 + charisma) / 3
+    end
+    
+    def quickness
+      return (agilty * 2 + intelligence) / 3
+    end
+    
+    def knack
+      return (dexterity * 2 + essence) / 3
+    end
+    
+    def understanding
+      return (intelligence * 2 + toughness) / 3
+    end
+    
+    def grace 
+      return (charisma * 2 + agility) / 3
+    end
+    
+    def zeal
+      return (wisdom * 2 + strength) / 3
+    end
+    
+    def numen
+      return (essence * 2 + DEX) / 3
+    end
+
+    # Generates a prompt for use with the being
+    def to_prompt
+      if essence > 0
+        "HP:#{hp}/#{hp_max} MP:#{mp}/#{mp_max} JP:#{jp}/#{jp_max} LP:#{lp}/#{lp_max}>"
+      else
+        "HP:#{hp}/#{hp_max} MP:#{mp}/#{mp_max} LP:#{lp}/#{lp_max}>"
+      end
+    end
+  
+    # Generates an overview of the status of the being.
+    def to_status
+      status <<- STATUS_END
+      ********************************
+        Status
+        
+        #{id} level #{level} #{kind} #{profession}
+        
+        Talents
+        
+        STR #{strength}
+        TOU #{toughness}
+        AGI #{agility}
+        DEX #{dexterity}
+        INT #{intelligence}
+        WIS #{wisdom}
+        CHA #{charisma}
+        ESS #{essence}
+        
+        Equipment
+        
+        OFF #{offense}
+        PRO #{protection}
+        BLO #{block}
+        RAP #{rapidity}
+        YIE #{self.yield}
+        
+        "HP:#{hp}/#{hp_max} MP:#{mp}/#{mp_max} JP:#{jp}/#{jp_max} LP:#{lp}/#{lp_max}>"
+
+      ********************************
+      STATUS_END
+      return status
+    end
+    
+    # Sets up the being based on the talents
+    def setup_on_birth
+      
+    end 
+    
+  
+  end
+end
+    
+

+ 0 - 0
lib/woe/character.rb


+ 64 - 39
lib/woe/client.rb

@@ -66,7 +66,7 @@ class Client
   end
   
   def printf(fmt, *args)
-    @telnet.printf(fmt, *args)
+    @telnet.telnet_printf(fmt, *args)
   end
   
   def on_start
@@ -363,9 +363,13 @@ class Client
  
   LOGIN_RE = /\A[A-Za-z][A-Za-z0-9]*\Z/
   
-  def ask_something(prompt, re, nomatch_prompt)
+  def ask_something(prompt, re, nomatch_prompt, noecho=false)
     something = nil
     
+    if noecho
+      password_mode
+    end
+
     while  something.nil? || something.empty? 
       write("#{prompt}:")
       something = wait_for_command
@@ -377,8 +381,13 @@ class Client
         end
       end
     end
+    
+    if noecho
+      normal_mode
+    end
+    
     something.chomp!
-    true
+    return something
   end
   
   
@@ -390,20 +399,12 @@ class Client
   EMAIL_RE = /@/
 
   def ask_email
-    return ask_something("E-mail:", EMAIL_RE, "Email must have at least an @ in there somewhere.")
+    return ask_something("E-mail", EMAIL_RE, "Email must have at least an @ in there somewhere.")
   end
 
 
   def ask_password(prompt = "Password")
-    password = nil
-    password_mode
-    while  password.nil? || password.empty?
-      write("\r\n#{prompt}:")
-      password = wait_for_command
-    end
-    password.chomp!
-    normal_mode
-    true
+    return ask_something(prompt, nil, "", true) 
   end
   
   def handle_command
@@ -413,41 +414,65 @@ class Client
       write("Byebye!\r\n")
       @busy = false
     else
-      @server.broadcast("#@login said #{order}\r\n")
+      @server.broadcast("#{@account.id} said #{order}\r\n")
     end
   end
- 
-  def serve()
-    setup_telnet
+  
+  def existing_account_dialog
+    pass  = ask_password
+    return false unless pass
+    unless @account.challenge?(pass)
+      printf("Password not correct!\n")
+      return false
+    end
+    return true
+  end
+  
+  def new_account_dialog(login)
+    while !@account 
+      printf("\nWelcome, %s! Creating new account...\n", login)
+      pass1  = ask_password
+      return false unless pass1
+      pass2 = ask_password("Repeat Password")
+      return false unless pass2
+      if pass1 != pass2
+        printf("\nPasswords do not match! Please try again!\n")
+        next
+      end
+      email = ask_email
+      return false unless email
+      @account = Woe::Account.new(:id => login, :email => email )
+      @account.password   = pass1
+      @account.woe_points = 7
+      unless @account.save_one
+        printf("\nFailed to save your account! Please contact a WOE administrator!\n")
+        return false
+      end
+      printf("\nSaved your account.\n")
+      return true
+    end
+  end
+  
+  def account_dialog
     login  = ask_login
     return false unless login
     @account = Account.fetch(login)
     if @account
-      pass  = ask_password
-      return false unless pass
-      
+      return existing_account_dialog
     else
-      while !@account 
-        printf("\nWelcome, %s! Creating new account...\n", login)
-        pass1  = ask_password
-        return false unless pass
-        pass2 = ask_password("Repeat Password:")
-        return false unless pass
-        if pass1 != pass2
-          printf("\nPasswords do not match.\n")
-          next
-        end
-        email = ask_email
-        return false unless email
-        
-        
-      
-      end
-      
-      
+      return new_account_dialog(login)
+    end
+  end
+ 
+  def serve()
+    setup_telnet
+    aok = account_dialog  
+    unless aok
+      printf "\nLogin failed. Breaking connection.\n"
+      return false
     end
     
-    write("\r\nWelcome #{@login} #{@password}!\r\n")
+    write("\r\nWelcome #{@account.id}!\r\n")
     while @busy do
       handle_command
     end

+ 0 - 0
lib/woe/mobile.rb