package main import ( "code.google.com/p/go.net/websocket" "errors" "log" ) 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) { var err error err = websocket.JSON.Send(ws, NewIdRequest(id)) if err != nil { return nil, errors.New("generic server error") } var clientid ClientID err = websocket.JSON.Receive(ws, &clientid) if err != nil { return nil, errors.New("could not parse id") } if v, msg := clientid.Valid(); !v { log.Printf("clientid is invalid: %+v", clientid) websocket.JSON.Send( ws, NewFailure(msg), ) return nil, errors.New(msg) } log.Printf("clientid: %+v", clientid) gameParam := NewGameParam(width, height) err = websocket.JSON.Send(ws, gameParam) if err != nil { websocket.JSON.Send(ws, NewFailure("generic server error")) return nil, err } log.Printf("gameparam: %+v", gameParam) switch clientid.Type { case "robot": var conf Config log.Printf("got here?") for { log.Printf("%s Waiting for client to send conf ...", id) err = websocket.JSON.Receive(ws, &conf) log.Printf("conf received: %+v", conf) if err != nil { return nil, err } // TODO: verify conf's type if conf.Stats.Valid() { _ = websocket.JSON.Send(ws, NewHandshake(id, true)) break } else { _ = websocket.JSON.Send(ws, NewHandshake(id, false)) } } conf.Name = clientid.Name return &conf, nil case "spectator": return nil, nil } return nil, nil }