@classmethod
    @postonly
    @multiplayer_service
    @jsonify
    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 __HOLE__:
            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.'}
dataset/ETHPy150Open turbulenz/turbulenz_local/turbulenz_local/controllers/apiv1/multiplayer.py/MultiplayerController.join