broadcasting death notifications

master
Jordan Orelli 5 years ago
parent 3202c30cb8
commit ca4015a4d4

@ -17,6 +17,7 @@ func main() {
Log: log, Log: log,
join: make(chan player), join: make(chan player),
inbox: make(chan message), inbox: make(chan message),
souls: make(map[string]soul),
} }
s.init() s.init()
go s.run() go s.run()

@ -1,6 +1,6 @@
package main package main
type message struct { type message struct {
from int from *player
text string text string
} }

@ -15,6 +15,8 @@ type player struct {
conn *websocket.Conn conn *websocket.Conn
server *server server *server
id int id int
username string
outbox chan string
} }
func (p *player) run() { func (p *player) run() {
@ -24,6 +26,7 @@ func (p *player) run() {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
go p.writeMessages(ctx) go p.writeMessages(ctx)
p.readMessages(cancel) p.readMessages(cancel)
p.outbox = nil
p.conn.Close() p.conn.Close()
} }
@ -52,7 +55,7 @@ func (p *player) readMessages(cancel func()) {
p.Child("rcv").Info(string(b)) p.Child("rcv").Info(string(b))
} }
p.server.inbox <- message{ p.server.inbox <- message{
from: p.id, from: p,
text: string(b), text: string(b),
} }
} }
@ -76,12 +79,25 @@ func (p *player) writeMessages(ctx context.Context) {
return return
} }
fmt.Fprintf(w, "%d tick: %v", n, t) fmt.Fprintf(w, "tick %d: %v", n, t)
if err := w.Close(); err != nil { if err := w.Close(); err != nil {
p.Error("close frame error: %v", err) p.Error("close frame error: %v", err)
return return
} }
p.Info("wrote a tick") case msg := <-p.outbox:
p.Info("writing message from outbox: %s", msg)
w, err := p.conn.NextWriter(websocket.TextMessage)
if err != nil {
p.Error("error getting writer: %v", err)
return
}
w.Write([]byte(msg))
if err := w.Close(); err != nil {
p.Error("close frame error: %v", err)
return
}
case <-ctx.Done(): case <-ctx.Done():
return return
} }

@ -2,6 +2,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt"
) )
type request struct { type request struct {
@ -31,7 +32,7 @@ type vector3 struct {
} }
type command interface { type command interface {
exec(*server) exec(*server, *player)
} }
type collectSoul struct { type collectSoul struct {
@ -39,7 +40,7 @@ type collectSoul struct {
Position vector3 `json:"position"` Position vector3 `json:"position"`
} }
func (c *collectSoul) exec(s *server) { func (c *collectSoul) exec(s *server, from *player) {
} }
type login struct { type login struct {
@ -47,12 +48,35 @@ type login struct {
Password string `json:"password"` Password string `json:"password"`
} }
func (l *login) exec(s *server) { func (l *login) exec(s *server, from *player) {
from.username = l.Username
} }
type death struct { type death struct {
Position vector3 `json:"position"` Position vector3 `json:"position"`
} }
func (d *death) exec(s *server) { 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)
}
}
} }

@ -16,6 +16,7 @@ type server struct {
players map[int]*player players map[int]*player
join chan player join chan player
inbox chan message inbox chan message
souls map[string]soul
} }
func (s *server) init() { func (s *server) init() {
@ -42,6 +43,7 @@ func (s *server) play(w http.ResponseWriter, r *http.Request) {
s.join <- player{ s.join <- player{
conn: conn, conn: conn,
server: s, server: s,
outbox: make(chan string, 8),
} }
} }
@ -60,6 +62,7 @@ func (s *server) step(pc int) {
p.id = pc p.id = pc
p.Log = s.Child("players").Child(strconv.Itoa(p.id)) p.Log = s.Child("players").Child(strconv.Itoa(p.id))
go p.run() go p.run()
s.players[p.id] = &p
case m := <-s.inbox: case m := <-s.inbox:
s.Info("received message: %v", m) s.Info("received message: %v", m)
var req request var req request
@ -69,5 +72,6 @@ func (s *server) step(pc int) {
} }
cmd := req.parse(m.text) cmd := req.parse(m.text)
s.Info("cmd: %#v", cmd) s.Info("cmd: %#v", cmd)
cmd.exec(s, m.from)
} }
} }

@ -0,0 +1,6 @@
package main
type soul struct {
PlayerName string `json:"playerName"`
Position vector3 `json:"position"`
}
Loading…
Cancel
Save