Загрузка данных


"""Kakao session server"""

import asyncio
import base64
import json
import logging
import re
import time
import zlib

try:
    from websockets.asyncio.server import serve
except ImportError:
    try:
        from websockets.server import serve
    except ImportError:
        from websockets import serve

from websockets.exceptions import ConnectionClosed

logging.basicConfig(format='%(message)s', level=logging.DEBUG)


async def handler(websocket):
    # Получаем prereq из URL
    prereq_match = re.search(r'prereq=(.*)', websocket.request.path)

    if not prereq_match:
        print('[SESSION] ERROR: prereq not found', flush=True)
        return

    prereq = prereq_match.group(1)
    prereq = base64.urlsafe_b64decode(prereq)
    prereq = zlib.decompress(prereq)
    prereq = json.loads(prereq)

    request_uri = prereq[0]

    # Ответ на первоначальный запрос авторизации
    header = json.dumps(
        {
            'txNo': prereq[1]['txNo']
        },
        separators=(',', ':')
    )

    body = json.dumps(
        {
            'status': 200,
            'desc': 'success',
            'content': {
                'player': {
                    'playerId': '900000000000',
                },
                'zat': 'zat',
                'zatExpiryTime': int(time.time() * 1000) + 86_400_000,
            }
        },
        separators=(',', ':')
    )

    await websocket.send(
        f'["{request_uri}",{header},{body}]'
    )

    print(
        f'[SESSION] Initial response: {request_uri}',
        flush=True
    )

    try:
        async for message in websocket:
            print(
                f'[SESSION] <- {message}',
                flush=True
            )

            try:
                request = json.loads(message)

                if not isinstance(request, list) or len(request) < 1:
                    print(
                        '[SESSION] Invalid message format',
                        flush=True
                    )
                    continue

                request_uri = request[0]

                # Если в сообщении нет заголовка запроса,
                # оставляем старое поведение
                if len(request) < 3:
                    print(
                        f'[SESSION] Short message: {request_uri}',
                        flush=True
                    )

                    await websocket.send(message)
                    continue

                tx_no = 0

                if isinstance(request[1], dict):
                    tx_no = request[1].get('txNo', 0)

                res_header = json.dumps(
                    {
                        'txNo': tx_no
                    },
                    separators=(',', ':')
                )

                # -------------------------------------------------
                # SDK BASIC LOG
                # -------------------------------------------------

                if request_uri == 'service/v3/log/writeSdkBasicLog':

                    res_body = json.dumps(
                        {
                            'status': 200,
                            'desc': 'success',
                            'content': {}
                        },
                        separators=(',', ':')
                    )

                    response = (
                        f'["{request_uri}",'
                        f'{res_header},'
                        f'{res_body}]'
                    )

                    print(
                        f'[SESSION] -> writeSdkBasicLog: {response}',
                        flush=True
                    )

                    await websocket.send(response)

                # -------------------------------------------------
                # KAKAO USER INFO
                # -------------------------------------------------

                elif request_uri == 'v2/user/me':

                    res_body = json.dumps(
                        {
                            'status': 200,
                            'desc': 'success',
                            'content': {
                                'id': 1000000000,
                                'connected_at': '2000-01-01T00:00:00Z',
                                'has_signed_up': True,
                                'properties': {
                                    'nickname': 'KRdori'
                                },
                                'kakao_account': {
                                    'profile': {
                                        'nickname': 'KRdori'
                                    },
                                    'service_user_id': 100000000000000000,
                                },
                            },
                        },
                        separators=(',', ':'),
                    )

                    response = (
                        f'["{request_uri}",'
                        f'{res_header},'
                        f'{res_body}]'
                    )

                    print(
                        f'[SESSION] -> v2/user/me: {response}',
                        flush=True
                    )

                    await websocket.send(response)

                # -------------------------------------------------
                # ZAT PAUSE
                # -------------------------------------------------

                elif request_uri == 'auth://v3/zat/pause':

                    print(
                        '[SESSION] Handling auth://v3/zat/pause',
                        flush=True
                    )

                    res_body = json.dumps(
                        {
                            'status': 200,
                            'desc': 'success',
                            'content': {}
                        },
                        separators=(',', ':')
                    )

                    response = (
                        f'["{request_uri}",'
                        f'{res_header},'
                        f'{res_body}]'
                    )

                    print(
                        f'[SESSION] -> zat/pause: {response}',
                        flush=True
                    )

                    await websocket.send(response)

                # -------------------------------------------------
                # OTHER REQUESTS
                # -------------------------------------------------

                else:

                    print(
                        f'[SESSION] UNKNOWN URI: {request_uri}',
                        flush=True
                    )

                    print(
                        f'[SESSION] FULL MESSAGE: {message}',
                        flush=True
                    )

                    # Пока не знаем нужный формат ответа —
                    # возвращаем исходное сообщение.
                    await websocket.send(message)

            except Exception as e:

                print(
                    f'[SESSION] Error handling message: {e}',
                    flush=True
                )

                try:
                    await websocket.send(message)
                except Exception:
                    pass

    except ConnectionClosed:

        print(
            '[SESSION] Connection closed',
            flush=True
        )


async def main(port):

    async with serve(
        handler,
        '',
        port,
        ssl=None,
        compression=None,
    ):

        print(
            f'Running session server on port {port}...',
            flush=True
        )

        await asyncio.get_running_loop().create_future()


if __name__ == '__main__':
    asyncio.run(main(8481))