Няма описание

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package funmow
  2. import (
  3. "fmt"
  4. "sort"
  5. "strings"
  6. )
  7. const (
  8. MatchNone = iota
  9. MatchOne
  10. MatchMany
  11. )
  12. type PlayerMeta struct {
  13. ID DBRef `json:"id"`
  14. Password string `json:"password"`
  15. }
  16. type Object struct {
  17. ID DBRef `json:"id"`
  18. Type string `json:"type"`
  19. Owner DBRef `json:"owner"`
  20. Next DBRef `json:"next"`
  21. Name string `json:"name"`
  22. Description string `json:"description"`
  23. Flags map[string]bool `json:"flags"`
  24. Properties map[string]string `json:"properties"`
  25. db *DB
  26. }
  27. type ObjectFactory struct {
  28. db *DB
  29. }
  30. func NewObjectFactory(db *DB) *ObjectFactory {
  31. return &ObjectFactory{db: db}
  32. }
  33. func (f *ObjectFactory) NewObject() Object {
  34. o := Object{}
  35. o.ID, _ = f.db.Allocate()
  36. o.db = f.db
  37. return o
  38. }
  39. func (f *ObjectFactory) NewExit(name string, next DBRef, owner DBRef) Object {
  40. o := Object{
  41. Type: "exit",
  42. Name: name,
  43. Next: next,
  44. Owner: owner,
  45. db: f.db,
  46. }
  47. o.ID, _ = f.db.Allocate()
  48. return o
  49. }
  50. func (f *ObjectFactory) NewRoom() Object {
  51. o := Object{}
  52. o.ID, _ = f.db.Allocate()
  53. o.Type = "room"
  54. o.db = f.db
  55. return o
  56. }
  57. func (f *ObjectFactory) NewThing() Object {
  58. o := Object{}
  59. o.ID, _ = f.db.Allocate()
  60. o.Type = "thing"
  61. o.db = f.db
  62. return o
  63. }
  64. func (o *Object) Commit() error {
  65. return o.db.StoreObject(*o, o.ID)
  66. }
  67. func (o *Object) Refresh() bool {
  68. refreshed, found := o.db.RetrieveObject(o.ID)
  69. if found {
  70. *o = refreshed
  71. }
  72. return found
  73. }
  74. func (o Object) String() string {
  75. return fmt.Sprintf("id %d: %s", o.ID, o.Name)
  76. }
  77. func (o *Object) Remove(c *Object) error {
  78. return o.db.Unlink(o.ID, c.ID)
  79. }
  80. func (o *Object) Delete() error {
  81. err := o.db.Delete(o.ID)
  82. if err == nil {
  83. *o = Object{}
  84. }
  85. return err
  86. }
  87. func (o *Object) Contains(c *Object) error {
  88. return o.db.Link(o.ID, c.ID, c.Type)
  89. }
  90. func (o *Object) MatchExitNames(name string) ObjectList { // so much copypasta
  91. r := make(ObjectList, 0)
  92. children := o.db.GetChildren(o.ID) // map[DBRef]string
  93. for childID, childType := range children {
  94. if childType != "exit" {
  95. continue
  96. }
  97. o, found := o.db.Fetch(childID)
  98. if found {
  99. idName := fmt.Sprintf("#%d", childID)
  100. if strings.EqualFold(o.Name, name) || name == idName {
  101. r = append(r, o)
  102. break // have a match. Don't need to look for any more.
  103. }
  104. aliases := strings.Split(o.Name, ";")
  105. for _, v := range aliases {
  106. if v == name {
  107. r = append(r, o)
  108. break // no need to look at other aliases
  109. }
  110. }
  111. }
  112. }
  113. return r
  114. }
  115. func (o *Object) DetailedName() string {
  116. return fmt.Sprintf("%s <#%d>", o.Name, o.ID)
  117. }
  118. func (o *Object) GetContents(exclude DBRef) []string {
  119. r := make([]string, 0)
  120. children := o.db.GetChildren(o.ID)
  121. for childID, linkType := range children {
  122. if childID == exclude { continue }
  123. if !(linkType == "player" || linkType == "thing") { continue }
  124. o, found := o.db.Fetch(childID)
  125. if !found { continue }
  126. if linkType == "player" && !o.GetFlag("online") { continue }
  127. r = append(r, o.DetailedName())
  128. }
  129. sort.Strings(r)
  130. return r
  131. }
  132. func (o *Object) GetExits() []string {
  133. r := make([]string, 0)
  134. children := o.db.GetChildren(o.ID)
  135. for exitID, linkType := range children {
  136. if linkType != "exit" { continue }
  137. exit, found := o.db.Fetch(exitID)
  138. if !found { continue }
  139. aliases := strings.Split(exit.Name, ";")
  140. r = append(r, aliases[0])
  141. }
  142. sort.Strings(r)
  143. return r
  144. }
  145. func (o *Object) SetFlag(flag string, value bool) {
  146. if o.Flags == nil {
  147. o.Flags = make(map[string]bool)
  148. }
  149. o.Flags[flag]=value
  150. }
  151. func (o *Object) GetFlag(flag string) bool {
  152. if o.Flags == nil { return false }
  153. value, ok := o.Flags[flag]
  154. if !ok { return false }
  155. return value
  156. }
  157. func (o *Object) SetProp(key string, value string) {
  158. if o.Properties == nil {
  159. o.Properties = make(map[string]string)
  160. }
  161. o.Properties[key]=value
  162. }
  163. func (o *Object) GetProp(key string) string {
  164. if o.Properties == nil { return "" }
  165. value, ok := o.Properties[key]
  166. if !ok { return "" }
  167. return value
  168. }
  169. type ObjectList []Object
  170. func (l ObjectList) First() Object {
  171. if len(l) > 0 {
  172. return l[0]
  173. } else {
  174. return Object{}
  175. }
  176. }
  177. func (l ObjectList) ExactlyOne() (Object, int) {
  178. c := len(l)
  179. if c == 0 {
  180. return Object{}, MatchNone
  181. } else if c == 1 {
  182. return l[0], MatchOne
  183. } else {
  184. return Object{}, MatchMany
  185. }
  186. }