暂无描述

object.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 {
  123. continue
  124. }
  125. if !(linkType == "player" || linkType == "thing") {
  126. continue
  127. }
  128. o, found := o.db.Fetch(childID)
  129. if !found {
  130. continue
  131. }
  132. if linkType == "player" && !o.GetFlag("online") {
  133. continue
  134. }
  135. r = append(r, o.DetailedName())
  136. }
  137. sort.Strings(r)
  138. return r
  139. }
  140. func (o *Object) GetExits() []string {
  141. r := make([]string, 0)
  142. children := o.db.GetChildren(o.ID)
  143. for exitID, linkType := range children {
  144. if linkType != "exit" {
  145. continue
  146. }
  147. exit, found := o.db.Fetch(exitID)
  148. if !found {
  149. continue
  150. }
  151. aliases := strings.Split(exit.Name, ";")
  152. r = append(r, aliases[0])
  153. }
  154. sort.Strings(r)
  155. return r
  156. }
  157. func (o *Object) SetFlag(flag string, value bool) {
  158. if o.Flags == nil {
  159. o.Flags = make(map[string]bool)
  160. }
  161. o.Flags[flag] = value
  162. }
  163. func (o *Object) GetFlag(flag string) bool {
  164. if o.Flags == nil {
  165. return false
  166. }
  167. value, ok := o.Flags[flag]
  168. if !ok {
  169. return false
  170. }
  171. return value
  172. }
  173. func (o *Object) SetProp(key string, value string) {
  174. if o.Properties == nil {
  175. o.Properties = make(map[string]string)
  176. }
  177. o.Properties[key] = value
  178. }
  179. func (o *Object) GetProp(key string) string {
  180. if o.Properties == nil {
  181. return ""
  182. }
  183. value, ok := o.Properties[key]
  184. if !ok {
  185. return ""
  186. }
  187. return value
  188. }
  189. type ObjectList []Object
  190. func (l ObjectList) First() Object {
  191. if len(l) > 0 {
  192. return l[0]
  193. } else {
  194. return Object{}
  195. }
  196. }
  197. func (l ObjectList) ExactlyOne() (Object, int) {
  198. c := len(l)
  199. if c == 0 {
  200. return Object{}, MatchNone
  201. } else if c == 1 {
  202. return l[0], MatchOne
  203. } else {
  204. return Object{}, MatchMany
  205. }
  206. }