You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.1 KiB
Go

package main
import (
"encoding/json"
"fmt"
)
type request struct {
Cmd string `json:"cmd"`
}
func (r request) parse(msg string) command {
var c command
switch r.Cmd {
case "login":
c = new(login)
case "death":
c = new(death)
case "collect-soul":
c = new(collectSoul)
default:
return nil
}
json.Unmarshal([]byte(msg), &c)
return c
}
type vector3 struct {
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
}
type command interface {
exec(*server, *player)
}
type collectSoul struct {
PlayerName string `json:"playerName"`
Position vector3 `json:"position"`
}
func (c *collectSoul) exec(s *server, from *player) {
soul, ok := s.souls[c.PlayerName]
if !ok {
return
}
delete(s.souls, c.PlayerName)
b, err := json.Marshal(soul)
if err != nil {
s.Error("unable to serialize soul: %v", err)
return
}
msg := fmt.Sprintf("soul-collected %s", string(b))
for _, player := range s.players {
select {
case player.outbox <- msg:
default:
s.Error("can't write to player %s's outbox", player.username)
}
}
}
type login struct {
Username string `json:"username"`
Password string `json:"password"`
}
type loginResult struct {
Passed bool `json:"passed"`
Error string `json:"error,omitempty"`
}
func (l *login) exec(s *server, from *player) {
res := loginResult{}
if err := s.db.CheckPassword(l.Username, l.Password); err != nil {
res.Error = err.Error()
} else {
res.Passed = true
from.username = l.Username
}
b, _ := json.Marshal(res)
msg := fmt.Sprintf("login-result %s", string(b))
from.outbox <- msg
}
type death struct {
Position vector3 `json:"position"`
}
func (d *death) exec(s *server, from *player) {
s.Info("executing a death: %#v", d)
_soul := soul{
PlayerName: from.username,
Position: d.Position,
}
s.souls[from.username] = _soul
b, err := json.Marshal(_soul)
if err != nil {
s.Error("unable to serialize soul: %v", err)
return
}
msg := fmt.Sprintf("spawn-soul %s", string(b))
for _, player := range s.players {
select {
case player.outbox <- msg:
default:
s.Error("can't write to player %s's outbox", player.username)
}
}
}