Browse Source

Command processor and command privilege levels implemented.

Beoran 8 years ago
parent
commit
c3e8fb3a3d
4 changed files with 94 additions and 15 deletions
  1. 66 7
      src/woe/server/action.go
  2. 3 0
      src/woe/server/ask.go
  3. 20 0
      src/woe/server/client.go
  4. 5 8
      src/woe/world/account.go

+ 66 - 7
src/woe/server/action.go

@@ -1,5 +1,7 @@
 package server
 
+import "bytes"
+import "errors"
 // import "github.com/beoran/woe/telnet"
 import "github.com/beoran/woe/world"
 import "github.com/beoran/woe/monolog"
@@ -11,9 +13,11 @@ type ActionData struct {
     Client * Client
     Server * Server
     World  * world.World
+    Account* world.Account
     Action * Action
-    Command  string
-    Argv   []string
+    Command  []byte
+    Rest     []byte
+    Argv     [][]byte
 }
 
 /* A handler for an action. */
@@ -36,21 +40,48 @@ func AddAction(name string, privilege world.Privilege, handler ActionHandler) {
     ActionMap[name] = action
 }
 
-func doShutdown(data * ActionData) (err error) {
+func doShout(data * ActionData) (err error) {
+      data.Server.Broadcast("Client said %s\r\n", data.Rest)
+      return nil  
+}
+
+func doShutdown(data * ActionData) (err error) {    
+    data.Server.Broadcast("Shutting down server NOW!\n")
+    data.Server.Restart();
     return nil
 }
 
 func doRestart(data * ActionData) (err error) {
+    data.Server.Broadcast("Restarting server NOW!\n")
+    data.Server.Restart();
     return nil
 }
 
-
-func doQuit(data * ActionData) (err error) {    
+func doQuit(data * ActionData) (err error) {  
+    data.Client.Printf("Byebye!\n")
+    data.Client.Disconnect()
     return nil
 }
 
-func ParseCommand(command string, data * ActionData) {
-    data.Command = command
+func ParseCommand(command []byte, data * ActionData) (err error) {
+    /* strip any leading blanks  */
+    trimmed    := bytes.TrimLeft(command, " \t")
+    parts      := bytes.SplitN(trimmed, []byte(" \t,"), 2)  
+    
+    if len(parts) < 1 {
+        data.Command = nil
+        return errors.New("Come again?")
+    }
+    data.Command = parts[0]
+    if len(parts) > 1 { 
+        data.Rest    = parts[1]
+        data.Argv    = bytes.Split(data.Rest, []byte(" \t,"))
+    } else {
+        data.Rest    = nil
+        data.Argv    = nil
+    }
+        
+    return nil
 } 
 
 func init() {
@@ -60,3 +91,31 @@ func init() {
     AddAction("/quit"       , world.PRIVILEGE_ZERO, doQuit)
 }
 
+func (client * Client) ProcessCommand(command []byte) {
+    ad := &ActionData{client, client.GetServer(), 
+        client.GetWorld(), client.GetAccount(), nil, nil, nil, nil }
+    _ = ad
+    err := ParseCommand(command, ad);
+    if err != nil {
+        client.Printf("%s", err)
+        return
+    }
+    
+    action, ok := ActionMap[string(ad.Command)]
+    ad.Action = &action
+    
+    if ad.Action == nil || (!ok) {
+        client.Printf("Unknown command %s.", ad.Command)
+        return
+    }
+    // Check if sufficient rights to perform the action
+    if (ad.Action.Privilege > client.GetAccount().Privilege) {
+        client.Printf("You lack the privilege to %s (%d vs %d).", 
+        ad.Command, ad.Action.Privilege, client.GetAccount().Privilege)
+        return
+    }
+    
+    // Finally run action
+    ad.Action.Handler(ad)
+} 
+

+ 3 - 0
src/woe/server/ask.go

@@ -130,6 +130,8 @@ func (me * Client) AskRepeatPassword() []byte {
 
 func (me * Client) HandleCommand() {
     command := me.ReadCommand()
+    me.ProcessCommand(command)
+    /*
     if bytes.HasPrefix(command, []byte("/quit")) {
       me.Printf("Byebye!\n")
       me.alive = false
@@ -142,6 +144,7 @@ func (me * Client) HandleCommand() {
     } else {
       me.server.Broadcast("Client %d said %s\r\n", me.id, command)  
     }
+    */
 }
  
 func (me * Client) ExistingAccountDialog() bool {

+ 20 - 0
src/woe/server/client.go

@@ -170,6 +170,10 @@ func (me * Client) Serve() (err error) {
     return nil
 }
 
+func (me * Client) Disconnect() {
+    me.alive = false
+}
+
 func (me * Client) IsAlive() bool {
     return me.alive
 }
@@ -177,3 +181,19 @@ func (me * Client) IsAlive() bool {
 func (me * Client) WriteString(str string) {
     me.conn.Write([]byte(str))
 }
+
+/** Accessor */
+func (me * Client) GetServer() (* Server) {
+    return me.server;
+}
+
+/** Accessor */
+func (me * Client) GetWorld() (* world.World) {
+    return me.server.World;
+}
+
+/** Accessor */
+func (me * Client) GetAccount() (* world.Account) {
+    return me.account;
+}
+

+ 5 - 8
src/woe/world/account.go

@@ -115,15 +115,12 @@ func LoadAccount(dirname string, name string) (account *Account, err error) {
     account.Hash            = record.Get("hash")
     account.Algo            = record.Get("algo")
     account.Email           = record.Get("email")
-    account.Points,  err    = record.GetInt("points")
-    if err != nil {
-        account.Points = 0
-    }
+    account.Points          = record.GetIntDefault("points", 0)
+    account.Privilege       = Privilege(record.GetIntDefault("privilege", 
+                                int(PRIVILEGE_NORMAL)))
+    
     var nchars int
-    nchars,  err            = record.GetInt("characters")
-    if err != nil {
-        nchars = 0
-    } 
+    nchars                  = record.GetIntDefault("characters", 0)
     _ = nchars
     /* Todo: load characters here... */    
     monolog.Info("Loaded Account: %s %v", path, record)