broadcasting death notifications

master
Jordan Orelli 5 years ago
parent 3202c30cb8
commit ca4015a4d4

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

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

@ -12,9 +12,11 @@ import (
type player struct {
*blammo.Log
conn *websocket.Conn
server *server
id int
conn *websocket.Conn
server *server
id int
username string
outbox chan string
}
func (p *player) run() {
@ -24,6 +26,7 @@ func (p *player) run() {
ctx, cancel := context.WithCancel(context.Background())
go p.writeMessages(ctx)
p.readMessages(cancel)
p.outbox = nil
p.conn.Close()
}
@ -52,7 +55,7 @@ func (p *player) readMessages(cancel func()) {
p.Child("rcv").Info(string(b))
}
p.server.inbox <- message{
from: p.id,
from: p,
text: string(b),
}
}
@ -76,12 +79,25 @@ func (p *player) writeMessages(ctx context.Context) {
return
}
fmt.Fprintf(w, "%d tick: %v", n, t)
fmt.Fprintf(w, "tick %d: %v", n, t)
if err := w.Close(); err != nil {
p.Error("close frame error: %v", err)
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():
return
}

@ -2,6 +2,7 @@ package main
import (
"encoding/json"
"fmt"
)
type request struct {
@ -31,7 +32,7 @@ type vector3 struct {
}
type command interface {
exec(*server)
exec(*server, *player)
}
type collectSoul struct {
@ -39,7 +40,7 @@ type collectSoul struct {
Position vector3 `json:"position"`
}
func (c *collectSoul) exec(s *server) {
func (c *collectSoul) exec(s *server, from *player) {
}
type login struct {
@ -47,12 +48,35 @@ type login struct {
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 {
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
join chan player
inbox chan message
souls map[string]soul
}
func (s *server) init() {
@ -42,6 +43,7 @@ func (s *server) play(w http.ResponseWriter, r *http.Request) {
s.join <- player{
conn: conn,
server: s,
outbox: make(chan string, 8),
}
}
@ -60,6 +62,7 @@ func (s *server) step(pc int) {
p.id = pc
p.Log = s.Child("players").Child(strconv.Itoa(p.id))
go p.run()
s.players[p.id] = &p
case m := <-s.inbox:
s.Info("received message: %v", m)
var req request
@ -69,5 +72,6 @@ func (s *server) step(pc int) {
}
cmd := req.parse(m.text)
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