Python version of PlaceNL's headless bot with automatic access token refresh

Overview

Reddit /r/place 2022 headless bot

This headless Python bot will automatically login to reddit, obtain access tokens (and refreshes them when they expire), obtain orders from the C&C server and automatically place pixels at the desired locations.

Requirements

  • Python >= 3.8
  • NumPy
  • Matplotlib
  • Rich
  • aiohttp
  • tomli

Installation & updating to a new version

pip install --force git+https://github.com/PlaceNL/rPlace2022.git

Docker image

For people experienced with Docker, there's also a docker image you can run:

docker run -t --pull=always --restart unless-stopped ghcr.io/placenl/placenl-python -u 'USERNAME' 'PASSWORD'

Usage

Linux / macOS

PlaceNL -u 'USERNAME' 'PASSWORD'

The bot supports multiple users:

PlaceNL -u 'USERNAME1' 'PASSWORD1' -u 'USERNAME2' 'PASSWORD2'

IMPORTANT: On macOS/Linux, use single quotes, otherwise your shell might interpret special characters.

Windows

On Windows, docker is probably the easiest way.

  1. Install Docker Desktop.

  2. Docker requires Windows Subsystem for Linux, so install that too.

  3. Docker requires a kernel update for WSL, install from here: https://docs.microsoft.com/en-us/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package. Only step 4.1 is required.

  4. Open PowerShell and run the above listed Docker command, but use double quotes instead of single quotes (or specify a path to a config file, described below).

    docker run -t --pull=always --restart unless-stopped ghcr.io/placenl/placenl-python -u "USERNAME" "PASSWORD"
  5. It should be up and running! It will also automatically restart in case of a rare crash.

Specifying users in a config file

Besides specifying the username and password combinations on the command line, it's also possible to specify them in a TOML config file. TOML is an INI-like file format, see the config-example.toml for an example.

To specify the path to the config file, add the --from-config flag (shorthand: -c):

PlaceNL --from-config config.toml

If using Docker, you'll need to give the container access to your files, otherwise it won't be able to find your config.toml file. So use cd to navigate to the directory with your config file, and run the following command:

Linux/macOS:

docker run -t --pull=always --restart unless-stopped -v $(pwd):/mnt ghcr.io/placenl/placenl-python -c /mnt/config.toml

Windows (powershell):

docker run -t --pull=always --restart unless-stopped -v ${PWD}:/mnt ghcr.io/placenl/placenl-python -c /mnt/config.toml
Comments
  • Reconnect naar web-socket werkt niet helemaal

    Reconnect naar web-socket werkt niet helemaal

    Een reconnect zorgt ervoor dat het script crash.

    INFO     [PlaceNL.cnc] Notified CNC server of drawn pixel.                                                                                                 PlaceNL.py:198
    [04/03/22 12:52:29] WARNING  [PlaceNL.cnc] Connection to C&C websocket lost, trying again in one minute...                                                                     PlaceNL.py:504
    [04/03/22 12:52:31] ERROR    [asyncio] Task exception was never retrieved                                                                                                 base_events.py:1753
                                 future: <Task finished name='Task-2996' coro=<CNCOrderClient.ping() done, defined at
                                 C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py:155> exception=ConnectionResetError('Cannot write to closing transport')>
                                 Traceback (most recent call last):
                                   File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py", line 158, in ping
                                     await self.ws.send_str(json.dumps({"type": "ping"}))
                                   File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\client_ws.py", line 151, in send_str
                                     await self._writer.send(data, binary=False, compress=compress)
                                   File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\http_websocket.py", line 690, in send
                                     await self._send_frame(message, WSMsgType.TEXT, compress)
                                   File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\http_websocket.py", line 601, in _send_frame
                                     raise ConnectionResetError("Cannot write to closing transport")
                                 ConnectionResetError: Cannot write to closing transport
    Traceback (most recent call last):
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py", line 581, in <module>
        asyncio.run(main())
      File "C:\Users\media\AppData\Local\Programs\Python\Python39\lib\asyncio\runners.py", line 44, in run
        return loop.run_until_complete(main)
      File "C:\Users\media\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
        return future.result()
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py", line 579, in main
        await asyncio.gather(*tasks)
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py", line 502, in cnc_update_task
        await cnc_client.receive_orders()
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\PlaceNL.py", line 165, in receive_orders
        await self.ws.send_str(json.dumps({"type": "getmap"}))
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\client_ws.py", line 151, in send_str
        await self._writer.send(data, binary=False, compress=compress)
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\http_websocket.py", line 690, in send
        await self._send_frame(message, WSMsgType.TEXT, compress)
      File "C:\Users\media\Desktop\PlaceNL\Python\rPlace2022\venv\lib\site-packages\aiohttp\http_websocket.py", line 601, in _send_frame
        raise ConnectionResetError("Cannot write to closing transport")
    ConnectionResetError: Cannot write to closing transport
    
    opened by JasperRab 2
  • Could not send ping, websocket closed?

    Could not send ping, websocket closed?

    Krijg op meerdere systemen eens in de zovel tijd de volgende error

    2 22:24:10] ERROR    [PlaceNL.cnc] Could not send ping, websocket closed?                                                                                                                                                             PlaceNL.py:201
                                 Traceback (most recent call last):                                                                                                                                                                                             
                                   File "/home/[redacted]/build/rplace/placenl/lib/python3.9/site-packages/PlaceNL.py", line 199, in ping                                                                                                                            
                                     await self.ws.send_str(json.dumps({"type": "ping"}))                                                                                                                                                                       
                                   File "/home/[redacted]/build/rplace/placenl/lib/python3.9/site-packages/aiohttp/client_ws.py", line 151, in send_str                                                                                                              
                                     await self._writer.send(data, binary=False, compress=compress)                                                                                                                                                             
                                   File "/home/[redacted]/build/rplace/placenl/lib/python3.9/site-packages/aiohttp/http_websocket.py", line 690, in send                                                                                                             
                                     await self._send_frame(message, WSMsgType.TEXT, compress)                                                                                                                                                                  
                                   File "/home/[redacted]/build/rplace/placenl/lib/python3.9/site-packages/aiohttp/http_websocket.py", line 601, in _send_frame                                                                                                      
                                     raise ConnectionResetError("Cannot write to closing transport")                                                                                                                                                            
                                 ConnectionResetError: Cannot write to closing transport                              
    

    Is deze inmiddels bekend?

    opened by qlum 1
  • crash (raspberry pi)

    crash (raspberry pi)

    Traceback (most recent call last): File "/home/pi/./PlaceNL.py", line 693, in run() File "/home/pi/./PlaceNL.py", line 689, in run asyncio.run(main()) File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run return loop.run_until_complete(main) File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete return future.result() File "/home/pi/./PlaceNL.py", line 685, in main await asyncio.gather(*tasks) File "/home/pi/./PlaceNL.py", line 628, in reddit_client await place_client.load_full_map() File "/home/pi/./PlaceNL.py", line 454, in load_full_map canvas4 = await self.load_canvas(3) File "/home/pi/./PlaceNL.py", line 393, in load_canvas async with self.session.ws_connect(PLACE_WEBSOCKET, protocols=["graphql-ws"], headers=headers) as ws: File "/home/pi/.local/lib/python3.9/site-packages/aiohttp/client.py", line 1138, in aenter self._resp = await self._coro File "/home/pi/.local/lib/python3.9/site-packages/aiohttp/client.py", line 776, in _ws_connect resp = await self.request( File "/home/pi/.local/lib/python3.9/site-packages/aiohttp/client.py", line 559, in _request await resp.start(conn) File "/home/pi/.local/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 898, in start message, payload = await protocol.read() # type: ignore[union-attr] File "/home/pi/.local/lib/python3.9/site-packages/aiohttp/streams.py", line 616, in read await self._waiter aiohttp.client_exceptions.ServerDisconnectedError: Server disconnected

    opened by DaxMoorman 1
  • 2k update nog niet ready?

    2k update nog niet ready?

      File "/usr/local/bin/PlaceNL", line 8, in <module>
        sys.exit(run())
      File "/usr/local/lib/python3.10/site-packages/PlaceNL.py", line 648, in run
        asyncio.run(main())
      File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
        return loop.run_until_complete(main)
      File "/usr/local/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
        return future.result()
      File "/usr/local/lib/python3.10/site-packages/PlaceNL.py", line 644, in main
        await asyncio.gather(*tasks)
      File "/usr/local/lib/python3.10/site-packages/PlaceNL.py", line 593, in reddit_client
        to_update = place_client.get_pixels_to_update(self.order_map)
      File "/usr/local/lib/python3.10/site-packages/PlaceNL.py", line 453, in get_pixels_to_update
        if not numpy.array_equal(order_map[row, col, :3], self.current_canvas[row, col, :3]):
    IndexError: index 1949 is out of bounds for axis 0 with size 1000```
    opened by thomasvt1 1
  • Based on map size dynamically get canvas by id

    Based on map size dynamically get canvas by id

    • bepaald dynamisch welk id de vakjes zouden moeten zetten en combineert de verschillende canvassen
    • maakt gebruik van Pillow i.p.v. matplotlib wat sneller zou moeten zijn.
    • Maakt niet uit of Template dezelfde formaat heeft als r/place

    Als je vragen heb zit op de discord: Dutchboii#1763

    opened by GNutma 0
  • defining backend domain in a single place

    defining backend domain in a single place

    When using this client with another control server, it took me a while to realise theres a hardcoded domain in there.

    I hope you considere including this so that others who want to fork this have it easyser.

    opened by Cube707 0
  • could not obtain access token

    could not obtain access token

    Traceback (most recent call last): File "/home/sam/placeNL/rPlace2022/PlaceNL.py", line 616, in run() File "/home/sam/placeNL/rPlace2022/PlaceNL.py", line 612, in run asyncio.run(main()) File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run return loop.run_until_complete(main) File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete return future.result() File "/home/sam/placeNL/rPlace2022/PlaceNL.py", line 603, in main await asyncio.gather(*tasks) File "/home/sam/placeNL/rPlace2022/PlaceNL.py", line 530, in reddit_client_task async with RedditPlaceClient(session, username, password, user_agent) as place_client: File "/home/sam/placeNL/rPlace2022/PlaceNL.py", line 238, in aenter raise Exception("Could not obtain access token.") Exception: Could not obtain access token.

    opened by Sloth-on-meth 3
Owner
null
Guilherme Matheus 11 Sep 11, 2022
Discord-Token-Formatter - A simple script to convert discord tokens from email token to token only format

Discord-Token-Formatter A simple script to convert discord tokens from email:pas

null 2 Oct 23, 2022
One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind them.

AwesomeVersion One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind

Joakim Sørensen 39 Dec 31, 2022
A wrapper for The Movie Database API v3 and v4 that only uses the read access token (not api key).

fulltmdb A wrapper for The Movie Database API v3 and v4 that only uses the read access token (not api key). Installation Use the package manager pip t

Jacob Hale 2 Sep 26, 2021
Aqui está disponível GRATUITAMENTE, um bot de discord feito em python, saiba que, terá que criar seu bot como aplicação, e utilizar seu próprio token, e lembrando, é um bot básico, não se utiliza Cogs nem slash commands nele!

BotDiscordPython Aqui está disponível GRATUITAMENTE, um bot de discord feito em python, saiba que, terá que criar seu bot como aplicação, e utilizar s

Matheus Muguet 4 Feb 5, 2022
An automated, headless YouTube Uploader

An automated, headless YouTube Uploader Authors: Christian C., Moritz M., Luca S. Related Projects: YouTube Watcher, Twitch Compilation Creator, Neura

null 127 Dec 23, 2022
Buy early bsc gems with custom gas fee, slippage, amount. Auto approve token after buy. Sell buyed token with custom gas fee, slippage, amount. And more.

Pancakeswap Sniper bot Full version of Pancakeswap sniping bot used to snipe during fair coin launches. With advanced options and a graphical user int

Jesus Crypto 204 Apr 27, 2022
Discord Token Finder - Find half of your target's token with just their ID.

Discord Token Finder - Find half of your target's token with just their ID.

Ttawi 2 Apr 7, 2022
DeKrypt 24 Sep 21, 2022
HackZ-Token-Grabber-V2 - HackZ Token Grabber V2

HackZ-Token-Grabber-V2 was made by Love ❌ code ✅ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ??

! ™NightMare 2 Mar 1, 2022
A discord token nuker With loads of options that will screw an account up real bad, also has inbuilt massreport, GroupChat Spammer and Token/Password/Creditcard grabber and so much more!

Installation | Important | Changelogs | Discord NOTE: Hazard is not finished! You can expect bugs, crashes, and non-working functions. Please make an

Rdimo 470 Aug 9, 2022
A results generator and automatic token checker for Yandex Contest

Yandex contest Python checking tools A results generator and automatic token checker for Yandex Contest. Версия на русском языке Installation Clone th

Nikolay Chechulin 9 Dec 14, 2022
File-sharing-Bot: Telegram Bot to store Posts and Documents and it can Access by Special Links.

File-sharing-Bot Telegram Bot to store Posts and Documents and it can Access by Special Links. I Guess This Will Be Usefull For Many People..... ?? .

null 1 Dec 17, 2021
A simple, fast, and awesome discord nuke bot! The only thing you need to add is your bot token.

SimpleNukeBot A simple, fast, and awesome discord nuke bot! The only thing you need to add is your bot token. Instructions: All you need to do is crea

Bisc 1 Apr 18, 2022
An Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot

Adv Auto Filter Bot V2 This Is Just An Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot.. Just Sent Any Text As Query It Wi

null 0 Dec 18, 2021
A Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot

Adv Auto Filter Bot This Is Just An Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot.. Just Sent Any Text As Query It Will

TeamShadow 4 Dec 10, 2021
A bot that is an updated & modified version of calvinnfernando's WebReg-Bot

WaitList-Bot A bot that is an updated & modified version of calvinnfernando's WebReg-Bot to automate getting into waitlisted classes in UCSD WebReg on

Issac In 1 Dec 1, 2022
Telegram Bot to store Posts and Documents and it can Access by Special Links.

File-sharing-Bot Telegram Bot to store Posts and Documents and it can Access by Special Links. I Guess This Will Be Usefull For Many People..... ?? .

Code X Botz 1.2k Jan 8, 2023
This bot automaticaly access to giveaway ! You can won free NFT !

This bot automaticaly access to giveaway ! You can won free NFT !

2s.py 28 Oct 20, 2022