コード例 #1
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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
	}
}
コード例 #2
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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)
	}
}
コード例 #3
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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
		}
	}
}
コード例 #4
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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)
}
コード例 #5
0
ファイル: gamehub.go プロジェクト: Tactique/proxy
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)
	}
}
コード例 #6
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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)
	}
}
コード例 #7
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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)
	}
}
コード例 #8
0
ファイル: gamehub.go プロジェクト: Tactique/proxy
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)
}
コード例 #9
0
ファイル: gamehub.go プロジェクト: Tactique/proxy
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)
}
コード例 #10
0
ファイル: proxy.go プロジェクト: Tactique/proxy
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
}
コード例 #11
0
ファイル: game.go プロジェクト: Tactique/game_engine
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
}
コード例 #12
0
ファイル: world.go プロジェクト: Tactique/game_engine
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
}