#!/usr/bin/env python3 """ Entry point to play the game. """ import argparse import asyncio import contextlib import json import logging import websockets import swiftstory.game_manager from swiftstory.exception import WrongAction, JoinError from swiftstory.client import Client from swiftstory.status import error game_manager = swiftstory.game_manager.GameManager() def message_received_handler(client, message): def join_game(): try: game_name = json_msg['game_name'] except KeyError: return error('field `game_name\' is required') else: lang = json_msg.get('lang') return client.join_game(game_name, lang) def designate_card(): card_id = None try: card_id = int(json_msg['card_id']) except (KeyError, TypeError): pass finally: return client.designate_card(card_id) def play_white_card(): try: card_id = int(json_msg['card_id']) except KeyError: return error('field `card_id\' is required') else: return client.play_white_card(card_id) opcodes_map = { "join_game": join_game, "view_player_cards": lambda: client.view_player_cards(), "view_black_card": lambda: client.view_black_card(), "view_played_cards": lambda: client.view_played_cards(), "pick_black_card": lambda: client.pick_black_card(), "collect_cards": lambda: client.collect_cards(), "designate_card": designate_card, "play_white_card": play_white_card, } try: json_msg = json.loads(message) except json.JSONDecodeError: return error('badly formatted json') try: return opcodes_map[json_msg["op"]]() except (KeyError, TypeError): return error('invalid command') except WrongAction as e: return error(str(e)) except JoinError as e: logging.warning("player could not join game: %s", e.__repr__()) return error(str(e)) async def connection_handler(websocket, path): client = Client(websocket, game_manager) with contextlib.suppress(websockets.exceptions.ConnectionClosed): async for message in client.socket: await client.socket.send(message_received_handler(client, message)) client.disconnect() def main(): parser = argparse.ArgumentParser() parser.add_argument('--listen', type=str, default='0.0.0.0') parser.add_argument('--port', type=int, default=1236) args = vars(parser.parse_args()) logging.basicConfig(level=logging.INFO) start_server = websockets.serve(connection_handler, args['listen'], args['port']) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever() if __name__ == '__main__': main()