action.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package server
  2. import "bytes"
  3. import "errors"
  4. // import "github.com/beoran/woe/telnet"
  5. import "github.com/beoran/woe/world"
  6. import "github.com/beoran/woe/monolog"
  7. /* Actiondata are the params passed to an Actin, neatly wrapped in
  8. * a struct */
  9. type ActionData struct {
  10. Client * Client
  11. Server * Server
  12. World * world.World
  13. Account* world.Account
  14. Action * Action
  15. Command []byte
  16. Rest []byte
  17. Argv [][]byte
  18. }
  19. /* A handler for an action. */
  20. type ActionHandler func(data * ActionData) (err error)
  21. /* Actions that a client can perform on a server or in
  22. * the server's world. */
  23. type Action struct {
  24. Name string
  25. Privilege world.Privilege
  26. Handler ActionHandler
  27. }
  28. var ActionMap map[string] Action
  29. func AddAction(name string, privilege world.Privilege, handler ActionHandler) {
  30. monolog.Info("Adding new action %s with privilege %d", name, privilege)
  31. action := Action{name, privilege, handler}
  32. ActionMap[name] = action
  33. }
  34. func doShout(data * ActionData) (err error) {
  35. data.Server.Broadcast("Client said %s\r\n", data.Rest)
  36. return nil
  37. }
  38. func doShutdown(data * ActionData) (err error) {
  39. data.Server.Broadcast("Shutting down server NOW!\n")
  40. data.Server.Restart();
  41. return nil
  42. }
  43. func doRestart(data * ActionData) (err error) {
  44. data.Server.Broadcast("Restarting server NOW!\n")
  45. data.Server.Restart();
  46. return nil
  47. }
  48. func doQuit(data * ActionData) (err error) {
  49. data.Client.Printf("Byebye!\n")
  50. data.Client.Disconnect()
  51. return nil
  52. }
  53. func ParseCommand(command []byte, data * ActionData) (err error) {
  54. /* strip any leading blanks */
  55. trimmed := bytes.TrimLeft(command, " \t")
  56. parts := bytes.SplitN(trimmed, []byte(" \t,"), 2)
  57. if len(parts) < 1 {
  58. data.Command = nil
  59. return errors.New("Come again?")
  60. }
  61. data.Command = parts[0]
  62. if len(parts) > 1 {
  63. data.Rest = parts[1]
  64. data.Argv = bytes.Split(data.Rest, []byte(" \t,"))
  65. } else {
  66. data.Rest = nil
  67. data.Argv = nil
  68. }
  69. return nil
  70. }
  71. func init() {
  72. ActionMap = make(map[string] Action)
  73. AddAction("/shutdown" , world.PRIVILEGE_LORD, doShutdown)
  74. AddAction("/restart" , world.PRIVILEGE_LORD, doRestart)
  75. AddAction("/quit" , world.PRIVILEGE_ZERO, doQuit)
  76. }
  77. func (client * Client) ProcessCommand(command []byte) {
  78. ad := &ActionData{client, client.GetServer(),
  79. client.GetWorld(), client.GetAccount(), nil, nil, nil, nil }
  80. _ = ad
  81. err := ParseCommand(command, ad);
  82. if err != nil {
  83. client.Printf("%s", err)
  84. return
  85. }
  86. action, ok := ActionMap[string(ad.Command)]
  87. ad.Action = &action
  88. if ad.Action == nil || (!ok) {
  89. client.Printf("Unknown command %s.", ad.Command)
  90. return
  91. }
  92. // Check if sufficient rights to perform the action
  93. if (ad.Action.Privilege > client.GetAccount().Privilege) {
  94. client.Printf("You lack the privilege to %s (%d vs %d).",
  95. ad.Command, ad.Action.Privilege, client.GetAccount().Privilege)
  96. return
  97. }
  98. // Finally run action
  99. ad.Action.Handler(ad)
  100. }