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.

93 lines
1.7 KiB
Go

package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/jordanorelli/blammo"
"github.com/jordanorelli/kloam/db"
)
type server struct {
*blammo.Log
router *mux.Router
players map[int]*player
join chan player
leave chan *player
inbox chan message
souls map[string]soul
db *db.SQLite
}
func (s *server) init() {
r := mux.NewRouter()
r.HandleFunc("/kloam", s.play)
s.router = r
}
func (s *server) handler() http.Handler {
return s.router
}
func (s *server) play(w http.ResponseWriter, r *http.Request) {
u := websocket.Upgrader{}
conn, err := u.Upgrade(w, r, nil)
if err != nil {
s.Error("upgrade error: %s", err)
return
}
s.Info("client connected: %v", conn.RemoteAddr())
s.join <- player{
conn: conn,
server: s,
outbox: make(chan string, 8),
}
}
func (s *server) run() {
s.players = make(map[int]*player)
for pc := 0; true; pc++ {
s.step(pc)
}
}
func (s *server) step(pc int) {
select {
case p := <-s.join:
s.Info("received join: %#v", p)
p.id = pc
p.Log = s.Child("players").Child(strconv.Itoa(p.id))
go p.run()
s.players[p.id] = &p
for _, soul := range s.souls {
b, _ := json.Marshal(soul)
msg := fmt.Sprintf("spawn-soul %s", string(b))
select {
case p.outbox <- msg:
default:
}
}
case p := <-s.leave:
delete(s.players, p.id)
case m := <-s.inbox:
s.Info("received message: %v", m)
var req request
if err := json.Unmarshal([]byte(m.text), &req); err != nil {
s.Error("dunno how to read this message: %v", m.text)
return
}
cmd := req.parse(m.text)
s.Info("cmd: %#v", cmd)
cmd.exec(s, m.from)
}
}