account.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package world
  2. import "path/filepath"
  3. import "os"
  4. import "encoding/xml"
  5. import "github.com/beoran/woe/sitef"
  6. import "github.com/beoran/woe/monolog"
  7. import "fmt"
  8. import "errors"
  9. type Privilege int
  10. const (
  11. PRIVILEGE_ZERO = Privilege(iota * 100)
  12. PRIVILEGE_NORMAL
  13. PRIVILEGE_MASTER
  14. PRIVILEGE_LORD
  15. PRIVILEGE_IMPLEMENTOR
  16. )
  17. type Named struct {
  18. Name string
  19. }
  20. type Account struct {
  21. Name string
  22. Hash string
  23. Algo string
  24. Email string
  25. Points int
  26. Privilege Privilege
  27. CharacterNames []string
  28. characters [] * Character
  29. }
  30. func SavePathForXML(dirname string, typename string, name string) string {
  31. return filepath.Join(dirname, typename, name + ".xml")
  32. }
  33. func SavePathFor(dirname string, typename string, name string) string {
  34. return filepath.Join(dirname, typename, name + ".sitef")
  35. }
  36. func NewAccount(name string, pass string, email string, points int) (*Account) {
  37. return &Account{name, pass, "plain", email, points, PRIVILEGE_NORMAL, nil, nil}
  38. }
  39. // Password Challenge for an account.
  40. func (me * Account) Challenge(challenge string) bool {
  41. if me.Algo == "plain" {
  42. return me.Hash == challenge
  43. }
  44. // XXX implement encryption later
  45. return false
  46. }
  47. // Helpers for use with sitef records
  48. func SitefStoreString(rec sitef.Record, key string, val string) {
  49. rec[key] = val
  50. }
  51. func SitefStoreInt(rec sitef.Record, key string, val int) {
  52. rec[key] = fmt.Sprintf("%d", val)
  53. }
  54. func SitefStoreArray(rec sitef.Record, key string, val LabeledList) {
  55. }
  56. // Save an account as a sitef file.
  57. func (me * Account) Save(dirname string) (err error) {
  58. path := SavePathFor(dirname, "account", me.Name)
  59. rec := make(sitef.Record)
  60. rec.Put("name", me.Name)
  61. rec.Put("hash", me.Hash)
  62. rec.Put("algo", me.Algo)
  63. rec.Put("email", me.Email)
  64. rec.PutInt("points", me.Points)
  65. rec.PutInt("privilege", int(me.Privilege))
  66. rec.PutInt("characters",len(me.characters))
  67. for i, chara := range me.characters {
  68. key := fmt.Sprintf("characters[%d]", i)
  69. rec.Put(key, chara.Name)
  70. }
  71. monolog.Debug("Saving Acccount record: %s %v", path, rec)
  72. return sitef.SaveRecord(path, rec)
  73. }
  74. // Load an account from a sitef file.
  75. func LoadAccount(dirname string, name string) (account *Account, err error) {
  76. path := SavePathFor(dirname, "account", name)
  77. records, err := sitef.ParseFilename(path)
  78. if err != nil {
  79. return nil, err
  80. }
  81. if len(records) < 1 {
  82. return nil, errors.New("No record found!")
  83. }
  84. record := records[0]
  85. monolog.Info("Loading Account record: %s %v", path, record)
  86. account = new(Account)
  87. account.Name = record.Get("name")
  88. account.Hash = record.Get("hash")
  89. account.Algo = record.Get("algo")
  90. account.Email = record.Get("email")
  91. account.Points, err = record.GetInt("points")
  92. if err != nil {
  93. account.Points = 0
  94. }
  95. var nchars int
  96. nchars, err = record.GetInt("characters")
  97. if err != nil {
  98. nchars = 0
  99. }
  100. _ = nchars
  101. /* Todo: load characters here... */
  102. monolog.Info("Loaded Account: %s %v", path, record)
  103. return account, nil
  104. }
  105. func (me * Account) SaveXML(dirname string) (err error) {
  106. path := SavePathForXML(dirname, "account", me.Name)
  107. file, err := os.Create(path)
  108. if err != nil {
  109. return err
  110. }
  111. enc := xml.NewEncoder(file)
  112. enc.Indent(" ", " ")
  113. return enc.Encode(me)
  114. }
  115. func LoadAccountXML(dirname string, name string) (account *Account, err error) {
  116. path := SavePathForXML(dirname, "account", name)
  117. file, err := os.Open(path)
  118. if err != nil {
  119. return nil, err
  120. }
  121. dec := xml.NewDecoder(file)
  122. account = new(Account)
  123. err = dec.Decode(account)
  124. return account, nil
  125. }