michaelshumshum / r-placer

bot for 2022 r/place
MIT License
93 stars 20 forks source link

next steps #24

Open michaelshumshum opened 1 year ago

michaelshumshum commented 1 year ago
  1. find a method to obtain the canvas image. replace the get_board method in management.py with the new method.

that's pretty much it. the request payload is the same as before. the JWT bearer token continues to use the API token. use the developer tools in your browser to observe the network behaviour.

the person who gets the script working again, i will provide you with my 50 accounts from last year.

OGMatrix commented 1 year ago

already did it but i have to implementing it in your code.

so basically you need the websocket

def get_board(self, access_token_in):
        logger.debug("Connecting and obtaining board images")
        while True:
            try:
                ws = create_connection(
                    "wss://gql-realtime-2.reddit.com/query",
                    origin="https://garlic-bread.reddit.com",
                )
                break
            except Exception:
                logger.error(
                    "Failed to connect to websocket, trying again in 30 seconds..."
                )
                time.sleep(30)

        ws.send(
            json.dumps(
                {
                    "type": "connection_init",
                    "payload": {"Authorization": "Bearer " + access_token_in},
                }
            )
        )
        while True:
            try:
                msg = ws.recv()
            except WebSocketConnectionClosedException as e:
                logger.error(e)
                continue
            if msg is None:
                logger.error("Reddit failed to acknowledge connection_init")
                exit()
            if msg.startswith('{"type":"connection_ack"}'):
                logger.debug("Connected to WebSocket server")
                break
        logger.debug("Obtaining Canvas information")
        ws.send(
            json.dumps(
                {
                    "id": "1",
                    "type": "start",
                    "payload": {
                        "variables": {
                            "input": {
                                "channel": {
                                    "teamOwner": "GARLICBREAD",
                                    "category": "CONFIG",
                                }
                            }
                        },
                        "extensions": {},
                        "operationName": "configuration",
                        "query": "subscription configuration($input: SubscribeInput!) {\n  subscribe(input: $input) {\n    id\n    ... on BasicMessage {\n      data {\n        __typename\n        ... on ConfigurationMessageData {\n          colorPalette {\n            colors {\n              hex\n              index\n              __typename\n            }\n            __typename\n          }\n          canvasConfigurations {\n            index\n            dx\n            dy\n            __typename\n          }\n          canvasWidth\n          canvasHeight\n          __typename\n        }\n      }\n      __typename\n    }\n    __typename\n  }\n}\n",
                    },
                }
            )
        )

        while True:
            canvas_payload = json.loads(ws.recv())
            if canvas_payload["type"] == "data":
                canvas_details = canvas_payload["payload"]["data"]["subscribe"]["data"]
                logger.debug("Canvas config: {}", canvas_payload)
                break

        canvas_sockets = []

        canvas_count = len(canvas_details["canvasConfigurations"])

        for i in range(0, canvas_count):
            canvas_sockets.append(2 + i)
            logger.debug("Creating canvas socket {}", canvas_sockets[i])

            ws.send(
                json.dumps(
                    {
                        "id": str(2 + i),
                        "type": "start",
                        "payload": {
                            "variables": {
                                "input": {
                                    "channel": {
                                        "teamOwner": "GARLICBREAD",
                                        "category": "CANVAS",
                                        "tag": str(i),
                                    }
                                }
                            },
                            "extensions": {},
                            "operationName": "replace",
                            "query": """subscription replace($input: SubscribeInput!) {
    subscribe(input: $input) {
      id
      ... on BasicMessage {
        data {
          __typename
          ... on FullFrameMessageData {
            __typename
            name
            timestamp
          }
          ... on DiffFrameMessageData {
            __typename
            name
            currentTimestamp
            previousTimestamp
          }
        }
      }
    }
  }""",
                        },
                    }
                )
            )

        imgs = []
        logger.debug("A total of {} canvas sockets opened", len(canvas_sockets))

        while len(canvas_sockets) > 0:
            temp = json.loads(ws.recv())
            logger.debug("Waiting for WebSocket message")

            print(temp)

            if temp["type"] == "data":
                logger.debug("Received WebSocket data type message")
                msg = temp["payload"]["data"]["subscribe"]

                print(msg)

                if msg["data"]["__typename"] == "FullFrameMessageData":
                    logger.debug("Received full frame message")
                    img_id = int(temp["id"])
                    logger.debug("Image ID: {}", img_id)

                    if img_id in canvas_sockets:
                        logger.debug("Getting image: {}", msg["data"]["name"])
                        try:
                            imgs.append(
                                [
                                    img_id,
                                    Image.open(
                                        BytesIO(
                                            requests.get(
                                                msg["data"]["name"],
                                                stream=True,
                                                proxies=proxy.get_random_proxy(
                                                    self, name=None
                                                ),
                                            ).content
                                        )
                                    ),
                                ]
                            )
                        except Exception:
                            print("Error with image")
                        canvas_sockets.remove(img_id)
                        logger.debug(
                            "Canvas sockets remaining: {}", len(canvas_sockets)
                        )

        for i in range(0, canvas_count - 1):
            ws.send(json.dumps({"id": str(2 + i), "type": "stop"}))

        ws.close()

        new_img_width = (
            max(map(lambda x: x["dx"], canvas_details["canvasConfigurations"])) +
            canvas_details["canvasWidth"]
        )
        logger.debug("New image width: {}", new_img_width)

        new_img_height = (
            max(map(lambda x: x["dy"], canvas_details["canvasConfigurations"])) +
            canvas_details["canvasHeight"]
        )
        logger.debug("New image height: {}", new_img_height)

        new_img = Image.new("RGB", (new_img_width, new_img_height))

        for idx, img in enumerate(sorted(imgs, key=lambda x: x[0])):
            logger.debug("Adding image (ID {}): {}", img[0], img[1])
            dx_offset = int(canvas_details["canvasConfigurations"][idx]["dx"])
            dy_offset = int(canvas_details["canvasConfigurations"][idx]["dy"])
            new_img.paste(img[1], (dx_offset, dy_offset))

        return new_img

this is a working code do something with it and implementing it @michaelshumshum

tryptech commented 1 year ago

Not sure it does, I'm running the same code but error out by failing to connect other the websocket almost immediately

OGMatrix commented 1 year ago

websocket is working fine for me

michaelshumshum commented 1 year ago

Not sure it does, I'm running the same code but error out by failing to connect other the websocket almost immediately

please indicate any exceptions. it is not helpful to just say "it doesn't work".

@OGMatrix it's clear this code was copied from somewhere else as it is uses the actual logger module, as opposed to my makeshift one. i have nothing against copying code, but it is awful that you copy and pasted it here, then asked ME to implement it.

OGMatrix commented 1 year ago

i forked https://github.com/rdeepak2002/reddit-place-script-2022 and changed everything to work with the new api. so this get board is from there with new values but working. and Im sorry that I was so disrespectful. currently working on mixing up the projects on myself maybe then its working fine

michaelshumshum commented 1 year ago

the websocket works fine, but for the canvasConfiguration it tells us that the canvas is 3000x2000. this is useful information since we know that the canvas will be come this size probably. but at the moment, the image it provides us with is not useful. we can crop the image, but in the future, we will need to manually adjust to the canvas.

board

Alvaro2x2 commented 1 year ago

Can you push the version with the websockets integrated?

hedihadi commented 1 year ago

Can you push the version with the websockets integrated?

obviously it's not ready, either donate to the maintainer, help him with code, or just keep watching.

OGMatrix commented 1 year ago

glad I was able to help a little bit

michaelshumshum commented 1 year ago

websockets change pushed

fixed other things temporarily. will need a permanent fix soon

Hedwig7s commented 1 year ago

websockets change pushed

fixed other things temporarily. will need a permanent fix soon

If the bot's supposed to function it ain't working (yes using my own api keys)

Hedwig7s commented 1 year ago

Doesn't work with updated config.json either

michaelshumshum commented 1 year ago

Doesn't work with updated config.json either

what do you mean by "not working"? like the script doesn't start or workers are starting without anything else? you need to show me what's occuring on your end.

yes, i know it's not working quite well. all my accoutns have been rate limited, so my testing is limited.

Someduckwithahat commented 1 year ago

Same as before on my end, the workers are starting without anything else happening. I updated the api key / secrets in config.json file, updated dev_accounts.json and created with a accounts.csv.

Hedwig7s commented 1 year ago

Workers starting, no pixels placed

Hedwig7s commented 1 year ago

Also

Exception in thread event-queuer:
Traceback (most recent call last):
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 449, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 444, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 1374, in getresponse
    response.begin()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 318, in begin
    version, status, reason = self._read_status()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 287, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\util\retry.py", line 550, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\packages\six.py", line 769, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 449, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\urllib3\connectionpool.py", line 444, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 1374, in getresponse
    response.begin()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 318, in begin
    version, status, reason = self._read_status()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\http\client.py", line 287, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\CENSORED\Downloads\r-placer-master\management.py", line 286, in event_queuer
    events = sorted(list(self.stage_events().items()), key=sorted_key)
  File "C:\Users\CENSORED\Downloads\r-placer-master\management.py", line 251, in stage_events
    for (x, y), color in self.get_board().items():
  File "C:\Users\CENSORED\Downloads\r-placer-master\management.py", line 99, in get_board
    self.accounts[0]['class'].get_auth_token()
  File "C:\Users\CENSORED\Downloads\r-placer-master\bot.py", line 101, in get_auth_token
    _add_developer_account(self.username)
  File "C:\Users\CENSORED\Downloads\r-placer-master\bot.py", line 59, in _add_developer_account
    r = s.post('https://www.reddit.com/api/adddeveloper',
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\CENSORED\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
NFKRZZ commented 1 year ago

i forked https://github.com/rdeepak2002/reddit-place-script-2022 and changed everything to work with the new api. so this get board is from there with new values but working. and Im sorry that I was so disrespectful. currently working on mixing up the projects on myself maybe then its working fine

could you link the repository? I tried to fix it to no avail yesterday.

cereal-kitty commented 1 year ago

does anybody find out how to make it work?