Browse Source

Cleaned up object resolution, cleaned up lots of stuff. Changed flages to be strictly booleans and added properties. Added 'give x to y' and 'put x into y' commands.

Keelan Lightfoot 8 years ago
parent
commit
41ee2f825a
5 changed files with 463 additions and 465 deletions
  1. 12
    15
      client.go
  2. 29
    6
      cmd/funmow/main.go
  3. 36
    8
      db.go
  4. 332
    363
      execution_context.go
  5. 54
    73
      object.go

+ 12
- 15
client.go View File

129
 		}
129
 		}
130
 	case "create":
130
 	case "create":
131
 		if len(fields) == 3 {
131
 		if len(fields) == 3 {
132
-			player, found := c.db.GetPlayer(fields[1])
133
-			if !found || (found && player.Password != fields[2]) {
134
-				c.write("Bad username or password.\n")
132
+			_, found := c.db.GetPlayer(fields[1])
133
+			if found {
134
+				c.write("That name is already taken.\n")
135
 				break
135
 				break
136
 			}
136
 			}
137
 			
137
 			
138
-			c.playerID = player.ID
139
-			c.authenticated = true
140
-
141
-			// when a player authenticates, the ipc channels get turned on
142
-			subReq := EventSubscribeRequest{
143
-				connectionID: c.connectionID,
144
-				playerID:     c.playerID,
145
-				inbound:      c.inbound,
146
-				outbound:     make(chan chan PlayerEvent),
138
+			playerID, _ := c.db.CreatePlayer(strings.TrimSpace(fields[1]), strings.TrimSpace(fields[2]), nil)
139
+			
140
+			_, found = c.db.Fetch(playerID)
141
+			if !found {
142
+				c.write("I can't even.\n")
143
+				break
147
 			}
144
 			}
148
-
149
-			c.outbound = c.eventDistributor.Subscribe(subReq)
150
-			c.sendCommand("look")
145
+			
146
+			c.write("You have been created. Now you can connect!\n")
147
+			
151
 		} else {
148
 		} else {
152
 			c.write("What?\n")
149
 			c.write("What?\n")
153
 		}
150
 		}

+ 29
- 6
cmd/funmow/main.go View File

4
 	"github.com/naleek/funmow"
4
 	"github.com/naleek/funmow"
5
 	"log"
5
 	"log"
6
 	"net"
6
 	"net"
7
+	"flag"
7
 )
8
 )
8
 
9
 
9
 const (
10
 const (
10
 	FunMOWVersion   = "0.2"
11
 	FunMOWVersion   = "0.2"
11
 	FunMOWDefaultDB = "funmow.db"
12
 	FunMOWDefaultDB = "funmow.db"
12
-	FunMOWListen    = ":4201"
13
+	FunMOWDefaultListen    = ":4201"
13
 )
14
 )
14
 
15
 
15
 func main() {
16
 func main() {
16
 
17
 
18
+	var seed bool
19
+	var listen string
20
+	var dbPath string
21
+
22
+	flag.BoolVar(&seed, "seed", false, "Seed the world DB")
23
+	flag.StringVar(&listen, "listen", FunMOWDefaultListen, "Listen Address:Port of game server.")
24
+	flag.StringVar(&dbPath, "db", FunMOWDefaultDB, "Path to FunMOW database.")
25
+
26
+	help := flag.Bool("h", false, "Show usage")
27
+
28
+	flag.Parse()
29
+
30
+	if *help {
31
+		flag.PrintDefaults()
32
+		return
33
+	}
34
+
35
+
36
+
17
 	log.Print("Starting FunMOW Version ", FunMOWVersion)
37
 	log.Print("Starting FunMOW Version ", FunMOWVersion)
18
 
38
 
19
 	log.Print("Using database ", FunMOWDefaultDB)
39
 	log.Print("Using database ", FunMOWDefaultDB)
22
 
42
 
23
 	defer db.Close()
43
 	defer db.Close()
24
 
44
 
25
-	seedDB(db)
45
+	if seed {
46
+		log.Print("Seeding database...")
47
+		seedDB(db)
48
+	}
26
 
49
 
27
-	log.Print("Listening for connections on ", FunMOWListen)
28
-	ln, err := net.Listen("tcp", FunMOWListen)
50
+	log.Print("Listening for connections on ", listen)
51
+	ln, err := net.Listen("tcp", listen)
29
 	if err != nil {
52
 	if err != nil {
30
 		log.Fatal(err)
53
 		log.Fatal(err)
31
 	}
54
 	}
50
 
73
 
51
 	f := funmow.NewObjectFactory(db)
74
 	f := funmow.NewObjectFactory(db)
52
 
75
 
53
-	keelan, _ := db.CreatePlayer("keelan", map[string]string{"wizard":"true"})
54
-	dan, _ := db.CreatePlayer("dan", nil)
76
+	keelan, _ := db.CreatePlayer("keelan", "123", map[string]bool{"wizard":true})
77
+	dan, _ := db.CreatePlayer("dan", "123", nil)
55
 
78
 
56
 	outside := f.NewObject()
79
 	outside := f.NewObject()
57
 	outside.Type = "room"
80
 	outside.Type = "room"

+ 36
- 8
db.go View File

7
 	"fmt"
7
 	"fmt"
8
 	"github.com/boltdb/bolt"
8
 	"github.com/boltdb/bolt"
9
 	"strconv"
9
 	"strconv"
10
+	"errors"
11
+	"regexp"
10
 )
12
 )
11
 
13
 
12
 const (
14
 const (
15
 
17
 
16
 type DBRef int
18
 type DBRef int
17
 
19
 
18
-func NewDBRefFromHashRef(v string) (DBRef, error) {
20
+func NewDBRefFromHashRef(v string) (DBRef, bool) {
19
 	var destInt int
21
 	var destInt int
22
+	
23
+	if matched, _ := regexp.MatchString(`^\pZ*#[0-9]+\pZ*?`, v); !matched {
24
+		return 0, false
25
+	}
26
+
20
 	n, err := fmt.Sscanf(v, "#%d", &destInt)
27
 	n, err := fmt.Sscanf(v, "#%d", &destInt)
21
 
28
 
22
 	if err != nil || n == 0 {
29
 	if err != nil || n == 0 {
23
-		return 0, err
30
+		return 0, false
24
 	}
31
 	}
25
 
32
 
26
-	return DBRef(destInt), nil
33
+	return DBRef(destInt), true
27
 }
34
 }
28
 
35
 
29
 func NewDBRefFromString(v string) (DBRef, error) {
36
 func NewDBRefFromString(v string) (DBRef, error) {
249
 
256
 
250
 }
257
 }
251
 
258
 
252
-
253
-
254
-
255
 func (s *DB) GetPlayer(name string) (PlayerMeta, bool) {
259
 func (s *DB) GetPlayer(name string) (PlayerMeta, bool) {
256
 	var player PlayerMeta
260
 	var player PlayerMeta
257
 	found := false
261
 	found := false
270
 	return player, found
274
 	return player, found
271
 }
275
 }
272
 
276
 
273
-func (s *DB) CreatePlayer(name string, flags map[string]string) (DBRef, error) {
277
+func (s *DB) DeletePlayer(name string) error {
278
+	return s.db.Update(func(tx *bolt.Tx) error {
279
+		playerBucket := tx.Bucket([]byte("player"))
280
+		err := playerBucket.Delete([]byte(name))
281
+		return err
282
+	})
283
+}
284
+
285
+func (s *DB) RenamePlayer(oldName string, newName string) error {
286
+	// doing it this way accomplishes the change as a single transasction
287
+	// and saves a bunch of marshalling and unmarshalling
288
+	return s.db.Update(func(tx *bolt.Tx) error {
289
+		playerBucket := tx.Bucket([]byte("player"))
290
+		buf := playerBucket.Get([]byte(oldName))
291
+		if buf == nil {
292
+			return errors.New("Can't find player")
293
+		}
294
+		err := playerBucket.Delete([]byte(oldName))
295
+		if err != nil { return err }
296
+		return playerBucket.Put([]byte(newName), buf)
297
+	})
298
+}
299
+
300
+
301
+func (s *DB) CreatePlayer(name string, password string, flags map[string]bool) (DBRef, error) {
274
 
302
 
275
 	var playerID DBRef
303
 	var playerID DBRef
276
 
304
 
283
 		}
311
 		}
284
 		playerID = DBRef(seq)
312
 		playerID = DBRef(seq)
285
 		s.txStoreObject(objectBucket, Object{ID: playerID, Name: name, Type: "player", Flags: flags}, playerID)
313
 		s.txStoreObject(objectBucket, Object{ID: playerID, Name: name, Type: "player", Flags: flags}, playerID)
286
-		playerMeta := PlayerMeta{ID: playerID, Password: "password"}
314
+		playerMeta := PlayerMeta{ID: playerID, Password: password}
287
 		buf, err := json.Marshal(playerMeta)
315
 		buf, err := json.Marshal(playerMeta)
288
 		if err != nil {
316
 		if err != nil {
289
 			return err
317
 			return err

+ 332
- 363
execution_context.go
File diff suppressed because it is too large
View File


+ 54
- 73
object.go View File

18
 }
18
 }
19
 
19
 
20
 type Object struct {
20
 type Object struct {
21
-	ID          DBRef  `json:"id"`
22
-	Next        DBRef  `json:"next"`
23
-	Type        string `json:"type"`
24
-	Name        string `json:"name"`
25
-	Description string `json:"description"`
26
-	Flags		map[string]string `json:"flags"`
27
-	Owner DBRef `json:"owner"`
21
+
22
+	ID          DBRef             `json:"id"`
23
+	Type        string            `json:"type"`
24
+	Owner       DBRef             `json:"owner"`
25
+	Next        DBRef             `json:"next"`
26
+	Name        string            `json:"name"`
27
+	Description string            `json:"description"`
28
+	Flags		map[string]bool   `json:"flags"`
29
+	Properties  map[string]string `json:"properties"`
30
+	
28
 	db    *DB
31
 	db    *DB
32
+	
29
 }
33
 }
30
 
34
 
31
 type ObjectFactory struct {
35
 type ObjectFactory struct {
103
 	return o.db.Link(o.ID, c.ID, c.Type)
107
 	return o.db.Link(o.ID, c.ID, c.Type)
104
 }
108
 }
105
 
109
 
106
-func (o *Object) MatchLinkNames(matchName string, player DBRef) ObjectList {
107
-	if matchName == "here" {
108
-		return ObjectList{*o}
109
-	}
110
-	if matchName == "me" {
111
-		p, found := o.db.Fetch(player)
112
-		if !found {
113
-			return ObjectList{}
114
-		} else {
115
-			return ObjectList{p}
116
-		}
117
-	}
118
-	r := make(ObjectList, 0)
119
-
120
-	children := o.db.GetChildren(o.ID) // map[DBRef]string
121
-
122
-	for childID, _ := range children {
123
-		o, found := o.db.Fetch(childID)
124
-		if found {
125
-			idName := fmt.Sprintf("#%d", o.ID)
126
-			lowerObjectName := strings.ToLower(o.Name)
127
-			lowerMatchName := strings.ToLower(matchName)
128
-			if strings.HasPrefix(lowerObjectName, lowerMatchName) || matchName == idName {
129
-				r = append(r, o)
130
-			}
131
-		}
132
-	}
133
-
134
-	return r
135
-}
136
-
137
 func (o *Object) MatchExitNames(name string) ObjectList { // so much copypasta
110
 func (o *Object) MatchExitNames(name string) ObjectList { // so much copypasta
138
 	r := make(ObjectList, 0)
111
 	r := make(ObjectList, 0)
139
 
112
 
160
 					break // no need to look at other aliases
133
 					break // no need to look at other aliases
161
 				}
134
 				}
162
 			}
135
 			}
163
-
164
 		}
136
 		}
165
 	}
137
 	}
166
 
138
 
168
 }
140
 }
169
 
141
 
170
 func (o *Object) DetailedName() string {
142
 func (o *Object) DetailedName() string {
171
-	return fmt.Sprintf("%s (#%d)", o.Name, o.ID)
143
+	return fmt.Sprintf("%s <#%d>", o.Name, o.ID)
172
 }
144
 }
173
 
145
 
174
-func (o *Object) GetLinkNames(matchType string, exclude DBRefList) []string {
146
+func (o *Object) GetContents(exclude DBRef) []string {
175
 	r := make([]string, 0)
147
 	r := make([]string, 0)
176
-
177
-	children := o.db.GetChildren(o.ID) // map[DBRef]string
178
-
179
-childLoop:
148
+	children := o.db.GetChildren(o.ID)
180
 	for childID, linkType := range children {
149
 	for childID, linkType := range children {
181
-		if matchType != "*" && matchType != linkType {
182
-			continue
183
-		}
184
-		for _, excludeID := range exclude {
185
-			if excludeID == childID {
186
-				continue childLoop
187
-			}
188
-		}
150
+		if childID == exclude { continue }
151
+		if !(linkType == "player" || linkType == "thing") { continue }
189
 		o, found := o.db.Fetch(childID)
152
 		o, found := o.db.Fetch(childID)
190
-		if found {
191
-			if linkType == "player" {
192
-				if o.GetFlag("online","false") == "true" {
193
-					r = append(r, o.DetailedName())
194
-				}
195
-			} else if linkType == "exit" {
196
-				r = append(r, o.Name)
197
-			} else {
198
-				r = append(r, o.DetailedName())
199
-			}
200
-		}
153
+		if !found { continue }
154
+		if linkType == "player" && !o.GetFlag("online") { continue }
155
+		r = append(r, o.DetailedName())
201
 	}
156
 	}
157
+	sort.Strings(r)
158
+	return r
159
+}
202
 
160
 
161
+func (o *Object) GetExits() []string {
162
+	r := make([]string, 0)
163
+	children := o.db.GetChildren(o.ID)
164
+	for exitID, linkType := range children {
165
+		if linkType != "exit" { continue }
166
+		exit, found := o.db.Fetch(exitID)
167
+		if !found { continue }
168
+		aliases := strings.Split(exit.Name, ";")
169
+		r = append(r, aliases[0])
170
+	}
171
+	
203
 	sort.Strings(r)
172
 	sort.Strings(r)
204
 	return r
173
 	return r
205
 }
174
 }
206
 
175
 
207
-func (o *Object) SetFlag(flag string, value string) {
176
+func (o *Object) SetFlag(flag string, value bool) {
208
 	if o.Flags == nil {
177
 	if o.Flags == nil {
209
-		o.Flags = make(map[string]string)
178
+		o.Flags = make(map[string]bool)
210
 	}
179
 	}
211
 	o.Flags[flag]=value
180
 	o.Flags[flag]=value
212
 }
181
 }
213
 
182
 
214
-func (o *Object) GetFlag(flag string, defaultValue string) (string) {
215
-	
216
-	if o.Flags == nil {
217
-		return defaultValue
218
-	}
183
+func (o *Object) GetFlag(flag string) bool {
219
 	
184
 	
185
+	if o.Flags == nil { return false }
220
 	value, ok := o.Flags[flag]
186
 	value, ok := o.Flags[flag]
187
+	if !ok { return false }
221
 	
188
 	
222
-	if !ok {
223
-		return defaultValue
189
+	return value
190
+}
191
+
192
+func (o *Object) SetProp(key string, value string) {
193
+	if o.Properties == nil {
194
+		o.Properties = make(map[string]string)
224
 	}
195
 	}
196
+	o.Properties[key]=value
197
+}
198
+
199
+func (o *Object) GetProp(key string) string {
200
+	
201
+	if o.Properties == nil { return "" }
202
+	value, ok := o.Properties[key]
203
+	if !ok { return "" }
225
 	
204
 	
226
 	return value
205
 	return value
227
 }
206
 }
228
 
207
 
229
 
208
 
209
+
210
+
230
 type ObjectList []Object
211
 type ObjectList []Object
231
 
212
 
232
 func (l ObjectList) First() Object {
213
 func (l ObjectList) First() Object {