#!/usr/bin/env python3 """ Entry point to play the game. """ import argparse import asyncio import contextlib import json import logging import websockets import swiftstory.GameManager from swiftstory.exception import WrongAction, JoinError from swiftstory.Client import Client from swiftstory.Status import error game_manager = swiftstory.GameManager.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()