func socketListen(port string) { ln, err := net.Listen("tcp", port) if err != nil { logger.Errorf("Could not open socket for listening") } for { conn, err := ln.Accept() if err != nil { logger.Errorf("Could not accept connection from client") continue } sconn := connection.NewSocketConn(conn) gamehub.connRegister <- sconn } }
func (pc *clientConnection) wsReadPump() { defer func() { pc.conn.Close() }() for { msg, err := pc.conn.Read() if err != nil { if err == io.EOF || err == io.ErrUnexpectedEOF { // the client ID here is redundant... kc := killClient{pc.info.id} killcconn := CommandMarshal("killClient", kc) pc.currentHandler.handleWebsocket([]byte(killcconn), pc) } else { logger.Errorf("Error while reading from websocket: %s", err) } break } logger.Debugf("Received %s from websocket", msg) select { case newHandler := <-pc.handlers: pc.currentHandler = newHandler default: } pc.currentHandler.handleWebsocket(msg, pc) } }
func (pc *clientConnection) wsWritePump() { for msg := range pc.toClient { logger.Debugf("Writing %s to websocket", msg) err := pc.conn.Write(msg) if err != nil { logger.Errorf("Error while writing to websocket: %s", err) break } } }
func chatHandler(data []byte, cconn *clientConnection, proxy *proxy) { var request ChatPacket err := json.Unmarshal(data, &request) if err != nil { logger.Errorf("Malformed chat json: %s", data) return } resp := response{0, request} out := CommandMarshal("chat", resp) proxy.broadcast(out) }
func (gh *game_hub) handleWebsocket(message []byte, cconn *clientConnection) { cmds := strings.SplitN(string(message), ":", 2) if len(cmds) == 2 { if fun, ok := gh.localHandlers[cmds[0]]; ok { fun(cmds[1], cconn) } else { logger.Warnf("Unrecognized command: %s", cmds[0]) cconn.toClient <- []byte("unrecognized:") } } else { logger.Errorf("Malformed command: %s", cmds) } }
func (p *proxy) serverReadPump() { defer func() { p.server.conn.Close() }() for { msg, err := p.server.conn.Read() if err != nil { logger.Errorf("Error while reading from socket: %s", err) break } logger.Debugf("Received %s from socket", msg) p.broadcast(msg) } }
func (p *proxy) handleWebsocket(message []byte, cconn *clientConnection) { splitMsg := strings.SplitN(string(message), ":", 2) command := splitMsg[0] data := splitMsg[1] localHandler, ok := p.localHandlers[command] if ok { localHandler([]byte(data), cconn, p) return } logger.Infof("Proxying message from client: %s", message) message = appendClientInfo(command, data, cconn.info) err := p.server.conn.Write(message) if err != nil { logger.Errorf("Error while writing to socket: %s", err) } }
func (gh *game_hub) commitGame(game *game) { delete(gh.uncommittedGames, game.numPlayers) // make connection to server conn, err := connectToServer() if err != nil { logger.Errorf("Could not connect to server, this game is going to hang...") return } game.proxy.server = &serverConnection{conn: conn} game.channelInHandler(game.proxy) go game.proxy.serverReadPump() game.proxy.sendInitialGameInfo() logger.Info("Committed a game, proxying its messages") gh.committedGames.PushBack(game) }
func (gh *game_hub) handleClientInfo(message string, cconn *clientConnection) { ci := clientInfo{} resp := response{0, nil} // I hate repeating this unmarshalling code, does Go allow something more general? err := json.Unmarshal([]byte(message), &ci) if err != nil { logger.Warnf("Error unmarshalling json: %s", err) return } userid, err := getClientIdFromToken(ci.Token) if err != nil { logger.Errorf("Error querying database: %s", err) resp.Status = -1 cconn.toClient <- CommandMarshal("clientInfo", resp) return } ci.id = userid cconn.info = ci cconn.toClient <- CommandMarshal("clientInfo", resp) }
func serveWs(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { http.Error(w, "Method not allowed", 405) return } if strings.Split(r.Header.Get("Origin"), ":")[1] != strings.Split("http://"+r.Host, ":")[1] { logger.Warnf("Cross origin problem: %s", r.Host) http.Error(w, "Origin not allowed", 403) return } ws, err := websocket.Upgrade(w, r, nil, 1024, 1024) if _, ok := err.(websocket.HandshakeError); ok { http.Error(w, "Not a websocket handshake", 400) return } else if err != nil { logger.Errorf("Websocket upgrade error: %s", err) return } ws.SetReadLimit(RECV_BUF_LEN) conn := NewWebsocketConn(ws) gamehub.connRegister <- conn }
func (gameWrapper *GameWrapper) Attack(playerId int, request api.AttackRequest) (*api.AttackResponse, error) { player, err := gameWrapper.world.GetAndVerifyTurnOwner(playerId) if err != nil { return nil, err } attackingUnit, err := gameWrapper.world.GetAndVerifyOwnedUnit(player, request.Attacker) if err != nil { return nil, err } defendingUnit, err := gameWrapper.world.GetUnitAtLocation(game.LocationFromRequest(request.Target)) if err != nil { return nil, err } alive, err := game.DamageUnit(attackingUnit, request.AttackIndex, defendingUnit) // TODO When a unit is dead mark is as such logger.Errorf("unit is %s (alive)", alive) if err != nil { return nil, err } return &api.AttackResponse{ Attacker: request.Attacker, AttackIndex: request.AttackIndex, Target: request.Target}, nil }
func NewWorld(playerIds []int, worldId int) (*World, error) { db, err := newDatabase() if err != nil { logger.Errorf("DB is open and cannot be used (%s)", err.Error()) return nil, err } defer db.Close() terrains, err := loadTerrains(db) if err != nil { return nil, err } nations, err := loadNations(db) if err != nil { return nil, err } numPlayers := len(playerIds) if numPlayers > 4 || numPlayers < 1 { logger.Warnf("Must have between 1 and 4 players, got %d", numPlayers) return nil, errors.New("must have between 1 and 4 players") } if len(nations) < numPlayers { logger.Errorf("Not enough nations were loaded, must have at least 2, got %s", nations) return nil, errors.New("Not enough nations were loaded, must have at least 2") } players := make([]*Player, numPlayers) for i, playerId := range playerIds { players[i] = NewPlayer(playerId, nations[i], team(i)) } if len(terrains) < 2 { return nil, errors.New("No terrains were loadable") } plains := terrains[0] roads := terrains[1] ret_world := &World{ terrain: [][]Terrain{ []Terrain{plains, roads, plains, plains, plains, plains, plains, plains}, []Terrain{plains, roads, plains, plains, plains, plains, plains, plains}, []Terrain{roads, roads, roads, plains, plains, plains, plains, plains}, []Terrain{plains, plains, roads, plains, plains, plains, plains, plains}, []Terrain{plains, plains, roads, plains, plains, plains, plains, plains}, []Terrain{plains, plains, plains, plains, plains, plains, plains, plains}}, unitMap: make(map[Location]*Unit), units: make(map[int]*Unit), players: players, numPlayers: numPlayers, turnOwner: 0, nextUnitId: 0} if worldId == 0 { name := "warrior" dbHealth, dbAttacks, dbArmor, dbMovement, err := loadUnit(db, name) if err != nil { return nil, err } ret_world.AddUnit(NewLocation(0, 0), name, nations[0], dbHealth, dbAttacks, dbArmor, dbMovement) name = "mage" dbHealth, dbAttacks, dbArmor, dbMovement, err = loadUnit(db, name) if err != nil { return nil, err } ret_world.AddUnit(NewLocation(3, 3), name, nations[0], dbHealth, dbAttacks, dbArmor, dbMovement) if numPlayers == 2 { ret_world.AddUnit(NewLocation(0, 3), name, nations[1], dbHealth, dbAttacks, dbArmor, dbMovement) } } return ret_world, nil }