def auto_add_player(player_connection): """Add the player to the lobby with the fewest players.""" least = float('inf') handle = None for each in lobbies: if len(each) < least and len(each) < MAX_LOBBY_SIZE + 1: # + 1 since the engine resides in the list as well least = len(each) handle = each if handle is not None: handle.append(player_connection) handle[0].sendMessage(format_msg( 'a user has joined your lobby.', MSG.info)) else: info('ERROR! Player tried to connect, but no lobbies were available!', INFO_ID) # ask an existing gameloop server to spinoff another gameloop server lobbies[0].get_game_client().sendMessage(format_msg( 'master ws server requesting new game instance', MSG.instance_request )) # while that's spinning up, tell the player to try connecting again player_connection.sendMessage(format_msg( 'all lobbies were full, creating new lobby, try reconnecting again soon', MSG.reconnect_request )) player_connection.sendClose()
def start_server(address, port): # see http://autobahn.ws/python/websocket/programming.html # accept both string and int, since client has to accept int if isinstance(port, int): port = str(port) global lobby_count lobby_count = 0 composite_address = 'ws://' + address + ':' + port info("starting websocket server at {}".format(composite_address), INFO_ID) factory = WebSocketServerFactory(composite_address) factory.protocol = GameServerProtocol loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop = asyncio.get_event_loop() coro = loop.create_server(factory, address, port) server = loop.run_until_complete(coro) try: loop.run_forever() except KeyboardInterrupt: info('cleaning up.', INFO_ID) finally: server.close() loop.close()
def onMessage(self, payload, isBinary): assert isBinary is False as_string = payload.decode('utf8') # info('received raw message: {}'.format(as_string), INFO_ID) message = obj_from_json(as_string) assert 'type' in message m_type = message['type'] # info('received message (type {}): {}'.format(m_type, as_string), INFO_ID) if m_type == MSG.chat.name: self.handleChat(as_string) elif m_type == MSG.tower_request.name: self.handleTowerRequest(as_string) elif m_type == MSG.tower_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.game_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.identifier.name: self.handleIdentifier(as_string) elif m_type == MSG.instance_request.name or m_type == MSG.new_lobby_request.name: self.handleInstanceRequest(as_string) elif m_type == MSG.lobby_request.name: self.handleLobbyJoinRequest(as_string) elif m_type == MSG.leave_lobby.name: self.handleLeaveLobby(as_string) elif m_type == MSG.game_start_request.name: self.handleStartGame(as_string) elif m_type == MSG.creep_request.name: self.handleCreepRequest(as_string) else: info( 'warning! server does not handle message with type {}'.format( m_type), INFO_ID)
def auto_add_player(player_connection): """Add the player to the lobby with the fewest players.""" least = float('inf') handle = None for each in lobbies: if len(each) < least and len(each) < MAX_LOBBY_SIZE + 1: # + 1 since the engine resides in the list as well least = len(each) handle = each if handle is not None: handle.append(player_connection) handle[0].sendMessage( format_msg('a user has joined your lobby.', MSG.info)) else: info('ERROR! Player tried to connect, but no lobbies were available!', INFO_ID) # ask an existing gameloop server to spinoff another gameloop server lobbies[0].get_game_client().sendMessage( format_msg('master ws server requesting new game instance', MSG.instance_request)) # while that's spinning up, tell the player to try connecting again player_connection.sendMessage( format_msg( 'all lobbies were full, creating new lobby, try reconnecting again soon', MSG.reconnect_request)) player_connection.sendClose()
def onMessage(self, payload, isBinary): assert isBinary is False as_string = payload.decode('utf8') # info('received raw message: {}'.format(as_string), INFO_ID) message = obj_from_json(as_string) assert 'type' in message m_type = message['type'] # info('received message (type {}): {}'.format(m_type, as_string), INFO_ID) if m_type == MSG.chat.name: self.handleChat(as_string) elif m_type == MSG.tower_request.name: self.handleTowerRequest(as_string) elif m_type == MSG.tower_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.game_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.identifier.name: self.handleIdentifier(as_string) elif m_type == MSG.instance_request.name or m_type == MSG.new_lobby_request.name: self.handleInstanceRequest(as_string) elif m_type == MSG.lobby_request.name: self.handleLobbyJoinRequest(as_string) elif m_type == MSG.leave_lobby.name: self.handleLeaveLobby(as_string) elif m_type == MSG.game_start_request.name: self.handleStartGame(as_string) elif m_type == MSG.creep_request.name: self.handleCreepRequest(as_string) else: info('warning! server does not handle message with type {}'.format( m_type), INFO_ID)
def start_client(address, port): # see http://autobahn.ws/python/websocket/programming.html # because starting a client requires an integer port, # while starting a server requires a string port, accept both. if isinstance(port, str): port = int(port) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop = asyncio.get_event_loop() global client_loop client_loop = loop composite_address = 'ws://' + address + ':' + str(port) info('client connecting to {}'.format(composite_address), INFO_ID) factory = WebSocketClientFactory(composite_address) factory.protocol = GameClientProtocol info( "client creating connection to address {} and port {}".format( address, str(port)), INFO_ID) coro = loop.create_connection(factory, address, port) global client_protocol transport, client_protocol = loop.run_until_complete(coro) loop.run_forever()
def start_client(address, port): # see http://autobahn.ws/python/websocket/programming.html # because starting a client requires an integer port, # while starting a server requires a string port, accept both. if isinstance(port, str): port = int(port) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop = asyncio.get_event_loop() global client_loop client_loop = loop composite_address = 'ws://' + address + ':' + str(port) info('client connecting to {}'.format(composite_address), INFO_ID) factory = WebSocketClientFactory(composite_address) factory.protocol = GameClientProtocol info("client creating connection to address {} and port {}".format( address, str(port)), INFO_ID) coro = loop.create_connection(factory, address, port) global client_protocol transport, client_protocol = loop.run_until_complete(coro) loop.run_forever()
def onClose(self, wasClean, code, reason): info("WebSocket connection closed: {0}".format(reason), INFO_ID) if self in all_connections: all_connections.remove(self) lobby = get_players_lobby(self) if lobby: lobby.remove_player(self) broadcast_lobby_list()
def onOpen(self): connected.append(self) if gameloop_client: gameloop_client.sendMessage(format_msg( 'a user has connected', MSG.info), False) info("connections: " + str(len(connected)), INFO_ID) self.sendMessage(format_msg( 'you have joined the server.', MSG.info), False)
def handleIdentifier(self, json_msg): """Handle identification messages, such as the server identification message.""" unpacked = obj_from_json(json_msg) assert 'secret' in unpacked if unpacked['secret'] == GAMELOOP_CLIENT_IDENTIFIER: global gameloop_client gameloop_client = self info("game engine client registered", INFO_ID) else: info('game client authentication failed with bad secret: {}'.format(unpacked['secret']))
def handleIdentifier(self, json_msg): """Handle identification messages, such as the server identification message.""" unpacked = obj_from_json(json_msg) assert 'secret' in unpacked if unpacked['secret'] == GAMELOOP_CLIENT_IDENTIFIER: create_lobby(self) info("game engine client registered", INFO_ID) elif unpacked['secret'] == PLAYER_IDENTIFIER: assign_user_id(self) all_connections.append(self) send_lobby_list(self) else: info( 'new connection failed to identify itself as user or gameloop client.', INFO_ID)
def onMessage(self, payload, isBinary): assert isBinary is False as_string = payload.decode('utf8') # info('received raw message: {}'.format(as_string), INFO_ID) message = obj_from_json(as_string) assert 'type' in message m_type = message['type'] info('received message (type {}): {}'.format(m_type, as_string), INFO_ID) if m_type == MSG.chat.name: self.handleChat(as_string) elif m_type == MSG.tower_request.name: self.handleTowerRequest(as_string) elif m_type == MSG.tower_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.game_update.name: self.handleTowerUpdate(as_string) elif m_type == MSG.identifier.name: self.handleIdentifier(as_string) else: info('warning! server does not handle message with type {}'.format( m_type), INFO_ID)
def onMessage(self, payload, isBinary): assert isBinary is False info('received: {}'.format(payload.decode('utf8')), INFO_ID) self.message_que.append(payload.decode('utf8'))
def onConnect(self, request): # onConnect happens before onOpen(). It isn't as useful # because onConnect() happens before the connection has succeeded. # if you want to do something when a client connects, you probably # want to do it in onOpen(). This is more like "onAttempt()". info("Client connecting: {0}".format(request.peer), INFO_ID)
def onOpen(self): info("opened connection {}".format(self), INFO_ID)
def onClose(self, wasClean, code, reason): info("WebSocket connection closed: {0}".format(reason), INFO_ID) connected.remove(self)