def delete_session(cls): remote_addr = get_remote_addr(request) params = request.params try: session_id = params['session'] hmac = params['hmac'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} calculated_hmac = _calculate_session_hmac(cls.secret, remote_addr, session_id) if hmac != calculated_hmac: response.status_int = 400 return {'ok': False, 'msg': 'Invalid server information.'} try: with cls.lock: del cls.sessions[session_id] LOG.info('Deleted empty session: %s', session_id) except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown session.'} return {'ok': True}
def unregister(cls): remote_addr = get_remote_addr(request) params = request.params host = params.get('host', remote_addr) try: hmac = params['hmac'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} calculated_hmac = _calculate_registration_hmac(cls.secret, remote_addr) if hmac != calculated_hmac: response.status_int = 400 return {'ok': False, 'msg': 'Invalid server information.'} try: server = cls.servers[host] del cls.servers[host] except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown server IP.'} LOG.info('Multiplayer server unregistered from %s:%d', host, server.port) return {'ok': True}
def heartbeat(cls): remote_addr = get_remote_addr(request) try: params = request.params host = params.get('host', remote_addr) num_players = params.get('numplayers') hmac = params['hmac'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing server information.'} calculated_hmac = _calculate_heartbeat_hmac(cls.secret, remote_addr, num_players, None) if hmac != calculated_hmac: response.status_int = 400 return {'ok': False, 'msg': 'Invalid server information.'} try: server = cls.servers[host] except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown server IP.'} try: server.update(request.params) except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing server information.'} except ValueError: response.status_int = 400 return {'ok': False, 'msg': 'Incorrect server information.'} #LOG.info('%s: %s', host, str(server)) return {'ok': True}
def register(cls): remote_addr = get_remote_addr(request) try: params = request.params host = params.get('host', remote_addr) hmac = params['hmac'] server = MultiplayerServer(params) except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing server information.'} except ValueError: response.status_int = 400 return {'ok': False, 'msg': 'Incorrect server information.'} calculated_hmac = _calculate_registration_hmac(cls.secret, remote_addr) if hmac != calculated_hmac: response.status_int = 400 return {'ok': False, 'msg': 'Invalid server information.'} LOG.info('Multiplayer server registered from %s as %s:%d', remote_addr, host, server.port) cls.servers[host] = server return {'ok': True}
def leave(cls): params = request.params try: session_id = params['session'] player_id = params['player'] _ = params['gameSessionId'] # Check for compatibility with gamesite API which does use this except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} sessions = cls.sessions try: session = sessions[session_id] except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown session.'} with cls.lock: if session.has_player(player_id): request_ip = get_remote_addr(request) stored_ip = session.get_player_ip(player_id) if stored_ip is not None and request_ip != stored_ip: response.status_int = 401 return {'ok': False} LOG.info('Player %s leaving session %s', player_id, session_id) session.remove_player(player_id) cls._clean_empty_sessions() return {'ok': True}
def client_leave(cls): remote_addr = get_remote_addr(request) params = request.params try: session_id = params['session'] player_id = params['client'] hmac = params['hmac'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} calculated_hmac = _calculate_client_hmac(cls.secret, remote_addr, session_id, player_id) if hmac != calculated_hmac: response.status_int = 400 return {'ok': False, 'msg': 'Invalid server information.'} sessions = cls.sessions try: session = sessions[session_id] except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown session.'} with cls.lock: if session.has_player(player_id): request_ip = get_remote_addr(request) stored_ip = session.get_player_ip(player_id) if stored_ip is not None and request_ip != stored_ip: response.status_int = 401 return {'ok': False} LOG.info('Player %s left session %s', player_id, session_id) session.remove_player(player_id) cls._clean_empty_sessions() return {'ok': True}
def create(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Unknown game.'} try: num_slots = int(request.params['slots']) _ = request.params['gameSessionId'] # Check for compatibility with gamesite API which does use this except (KeyError, ValueError): response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} with cls.lock: cls.last_player_id += 1 player_id = str(cls.last_player_id) sessions = cls.sessions cls.last_session_id += 1 session_id = str(cls.last_session_id) server_address = None secret = None if cls.secret is not None: stale_time = time() - 80 for ip, server in cls.servers.iteritems(): if stale_time < server.updated: server_address = '%s:%d' % (ip, server.port) secret = cls.secret break session = MultiplayerSession(session_id, slug, num_slots, server_address, secret) LOG.info('Created session %s (%d slots)', session_id, num_slots) sessions[session_id] = session request_ip = get_remote_addr(request) session.add_player(player_id, request_ip) LOG.info('Player %s joins session %s', player_id, session_id) info = {'server': session.get_player_address(request.host, request_ip, player_id), 'sessionid': session_id, 'playerid': player_id, 'numplayers': session.get_num_players()} return {'ok': True, 'data': info}
def join(cls): params = request.params try: session_id = params['session'] _ = request.params['gameSessionId'] # Check for compatibility with gamesite API which does use this except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} try: session = cls.sessions[session_id] except KeyError: response.status_int = 404 return {'ok': False, 'msg': 'Unknown session.'} with cls.lock: session.update_status() request_ip = get_remote_addr(request) player_id = params.get('player', None) if player_id is None: cls.last_player_id += 1 player_id = str(cls.last_player_id) else: stored_ip = session.get_player_ip(player_id) if stored_ip is not None and request_ip != stored_ip: response.status_int = 401 return {'ok': False} if session.can_join(player_id): session.add_player(player_id, request_ip) LOG.info('Player %s joins session %s', player_id, session_id) info = {'server': session.get_player_address(request.host, request_ip, player_id), 'sessionid': session_id, 'playerid': player_id, 'numplayers': session.get_num_players()} return {'ok': True, 'data': info} response.status_int = 409 return {'ok': False, 'msg': 'No slot available.'}
def join_any(cls, slug): params = request.params try: _ = params['gameSessionId'] # Check for compatibility with gamesite API which does use this except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing game information.'} game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Unknown game.'} with cls.lock: cls.last_player_id += 1 player_id = str(cls.last_player_id) sessions = cls.sessions session = session_id = None for existing_session in sessions.itervalues(): if existing_session.game == slug: existing_session.update_status() if existing_session.can_join(player_id): session = existing_session session_id = existing_session.session_id break if session is not None: request_ip = get_remote_addr(request) session.add_player(player_id, request_ip) LOG.info('Player %s joins session %s', player_id, session_id) info = {'server': session.get_player_address(request.host, request_ip, player_id), 'sessionid': session_id, 'playerid': player_id, 'numplayers': session.get_num_players()} else: # No session to join info = {} return {'ok': True, 'data': info}