server/protocol.go

145 lines
2.9 KiB
Go
Raw Normal View History

2013-08-21 07:53:34 -07:00
package main
import (
"code.google.com/p/go.net/websocket"
"errors"
2013-09-27 00:03:32 -07:00
"log"
2013-08-21 07:53:34 -07:00
)
2013-09-27 22:27:05 -07:00
type GameID struct {
Id string `json:"id"`
}
// > identify
type IdRequest struct {
Type string `json:"type"`
AssignedID string `json:"id"`
Failure
}
func NewIdRequest(id string) *IdRequest {
return &IdRequest{
Type: "idreq",
AssignedID: id,
}
}
// < [robot | spectator], name, client-type, game ID
type ClientID struct {
Type string `json:"type"`
Name string `json:"name"`
Useragent string `json:"useragent"`
}
func (c *ClientID) Valid() (bool, string) {
switch c.Type {
case "robot", "spectator":
return true, ""
}
return false, "usergent must be 'robot' or 'spectator'"
}
type BoardSize struct {
Width float64 `json:"width"`
Height float64 `json:"height"`
}
type GameParam struct {
BoardSize BoardSize `json:"boardsize"`
Type string `json:"type"`
}
// > [OK | FULL | NOT AUTH], board size, game params
func NewGameParam(w, h float64) *GameParam {
return &GameParam{
BoardSize: BoardSize{
Width: w,
Height: h,
},
Type: "gameparam",
}
}
type Handshake struct {
ID string `json:"id"`
Success bool `json:"success"`
Type string `json:"type"`
}
func NewHandshake(id string, success bool) *Handshake {
return &Handshake{
ID: id,
Success: success,
Type: "handshake",
}
}
type Failure struct {
Reason string `json:"reason"`
Type string `json:"type"`
}
func NewFailure(reason string) *Failure {
return &Failure{
Reason: reason,
Type: "failure",
}
}
func Negociate(ws *websocket.Conn, id string, width, height float64) (*Config, error) {
2013-08-21 07:53:34 -07:00
var err error
2013-09-27 22:27:05 -07:00
err = websocket.JSON.Send(ws, NewIdRequest(id))
2013-08-21 07:53:34 -07:00
if err != nil {
return nil, errors.New("generic server error")
2013-08-21 07:53:34 -07:00
}
2013-09-27 22:27:05 -07:00
var clientid ClientID
2013-08-21 07:53:34 -07:00
err = websocket.JSON.Receive(ws, &clientid)
if err != nil {
return nil, errors.New("could not parse id")
}
if v, msg := clientid.Valid(); !v {
2013-09-27 00:03:32 -07:00
log.Printf("clientid is invalid: %+v", clientid)
2013-08-21 07:53:34 -07:00
websocket.JSON.Send(
ws,
2013-09-27 22:27:05 -07:00
NewFailure(msg),
2013-08-21 07:53:34 -07:00
)
return nil, errors.New(msg)
}
2013-09-27 00:03:32 -07:00
log.Printf("clientid: %+v", clientid)
2013-08-21 07:53:34 -07:00
2013-09-27 22:27:05 -07:00
gameParam := NewGameParam(width, height)
2013-08-21 07:53:34 -07:00
err = websocket.JSON.Send(ws, gameParam)
if err != nil {
2013-09-27 22:27:05 -07:00
websocket.JSON.Send(ws, NewFailure("generic server error"))
2013-08-21 07:53:34 -07:00
return nil, err
}
2013-09-27 00:03:32 -07:00
log.Printf("gameparam: %+v", gameParam)
2013-08-21 07:53:34 -07:00
switch clientid.Type {
case "robot":
2013-09-27 22:27:05 -07:00
var conf Config
2013-09-27 00:03:32 -07:00
log.Printf("got here?")
2013-08-21 07:53:34 -07:00
for {
2013-09-27 00:03:32 -07:00
log.Printf("%s Waiting for client to send conf ...", id)
2013-08-21 07:53:34 -07:00
err = websocket.JSON.Receive(ws, &conf)
2013-09-27 00:03:32 -07:00
log.Printf("conf received: %+v", conf)
2013-08-21 07:53:34 -07:00
if err != nil {
return nil, err
}
// TODO: verify conf's type
2013-09-03 23:26:40 -07:00
if conf.Stats.Valid() {
2013-09-27 22:27:05 -07:00
_ = websocket.JSON.Send(ws, NewHandshake(id, true))
2013-08-21 07:53:34 -07:00
break
} else {
2013-09-27 22:27:05 -07:00
_ = websocket.JSON.Send(ws, NewHandshake(id, false))
2013-08-21 07:53:34 -07:00
}
}
conf.Name = clientid.Name
2013-08-21 07:53:34 -07:00
return &conf, nil
case "spectator":
return nil, nil
}
return nil, nil
}