Probably last commit

Added more stats, created streamer from logs file to retroactively make
timelapses, removed most of images off of the board.
This commit is contained in:
Casey 2024-07-07 10:17:53 +03:00
parent 26e8b804ee
commit c286990f75
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
3 changed files with 67 additions and 51 deletions

View File

@ -5,7 +5,7 @@ from aiohttp import ClientSession
from aiohttp_socks import ProxyConnector
from PIL import Image, ImageFont, ImageDraw, ImageFilter, ImageSequence, ImageChops
from base64 import b64decode
from random import choice
from random import choice, randint
from json import load
from time import time as time_now
@ -33,6 +33,8 @@ class AsyncBotManager:
self._read_boxes = 0
self._last_printout = time_now()
self._active: set[int] = set()
@staticmethod
def get_text_image(text: str, font: ImageFont.ImageFont | ImageFont.FreeTypeFont) -> Image.Image:
left, top, right, bottom = font.getbbox(text)
@ -155,12 +157,26 @@ class AsyncBotManager:
else:
print("unknown event", event, data)
now = time_now()
if (now - self._last_printout) > 1:
if (now - self._last_printout) > 10:
outgoing = self._written_boxes / (now - self._last_printout)
incoming = self._read_boxes / (now - self._last_printout)
print()
print(f"Incoming: {incoming:7.2f}/s Outgoing: {outgoing:7.2f}/s")
print(f"Alive workers: {len(self._active)}")
n_correct, n_wrong = 0, 0
for index, expected in self.difference.items():
y, x = divmod(index, 1000)
actual = self.canvas.getpixel((x, y)) > 0 # type: ignore
if expected != actual:
n_wrong += 1
else:
n_correct += 1
print(f"Invalid: {n_wrong:4d} Valid: {n_correct:4d}")
self._written_boxes = 0
self._read_boxes = 0
self._active.clear()
self._last_printout = now
for pixmaps, spf in self.animations:
frame_index = int(now / spf)
@ -182,10 +198,12 @@ class AsyncBotManager:
async with ClientSession(connector=proxy) as http:
async with AsyncSimpleClient(http_session=http) as sio:
await sio.connect(f"{self.base}/socket.io")
offset = randint(0, 1000000)
while not self._shutdown:
diff = list(self.difference.items())
for _ in range(100):
index, expected = choice(diff)
index, expected = diff[offset % len(diff)]
offset += randint(0, 100)
y, x = divmod(index, 1000)
current = self.canvas.getpixel((x, y)) > 0 # type: ignore
if current != expected:
@ -194,7 +212,8 @@ class AsyncBotManager:
await sio.emit("toggle_bit", {"index": index})
await asyncio.sleep(delay)
break
await asyncio.sleep(0.1)
self._active.add(bot_index)
await asyncio.sleep(0.01)
async def __aenter__(self):
self._listener_task = asyncio.create_task(self.listener())
@ -215,10 +234,12 @@ async def amain() -> None:
mgr.add_avoid_rect(
avoid["x"], avoid["y"], avoid["w"], avoid["h"]
)
print("AVOID rectangle {w}x{h}+{x}+{y}".format(**avoid))
elif avoid["type"] == "range":
mgr.add_avoid_range(
avoid["start"], avoid["stop"], avoid.get("step", 1)
)
print("AVOID range {start}-{stop}".format(**avoid))
elif avoid["type"] == "image":
with Image.open(avoid["path"]).convert("LA") as im:
assert im.width == 1000 and im.height == 1000
@ -227,9 +248,12 @@ async def amain() -> None:
l, a = im.getpixel((x, y)) # type: ignore
if a > 128:
mgr.add_avoid_index(x + y * 1000)
print("AVOID image", avoid["path"])
for elem in settings["elements"]:
if elem["type"] == "text":
mgr.put_text(elem["x"], elem["y"], elem["text"], elem.get("font", "default"), elem.get("size", 8))
print("ADD text", elem["x"], elem["y"], elem["text"])
elif elem["type"] == "text_anim":
frames: list[Image.Image] = []
for text in elem["lines"]:

View File

@ -13,14 +13,6 @@
"h": 10,
"description": "Not ruining fun for normal users"
},
{
"type": "rect",
"x": 732,
"y": 184,
"w": 231,
"h": 326,
"description": "The Bald Critic"
},
{
"type": "rect",
"x": 0,
@ -47,56 +39,20 @@
"type": "image",
"path": "./avoid_masks/noita.png",
"description": "Noita logo by Cr4xy"
},
{
"type": "image",
"path": "./avoid_masks/fnf.png",
"description": "FNF by vshab"
}
],
"elements": [
{
"type": "rgb111",
"path": "./pictures/trans.png",
"x": 200,
"y": 200
},
{
"type": "image",
"path": "./pictures/kangel.png",
"x": 256,
"y": 360
},
{
"type": "image",
"path": "./pictures/boykisser.png",
"x": 69,
"y": 420
},
{
"type": "image",
"path": "./pictures/colon3.png",
"x": 333,
"y": 333
},
{
"type": "animation",
"path": "./pictures/neko.gif",
"x": 263,
"y": 225,
"spf": 5
},
{
"type": "image",
"path": "./pictures/casey.png",
"x": 256,
"y": 256
"x": 32,
"y": 420
},
{
"type": "rgb565",
"path": "./pictures/niko.png",
"x": 48,
"y": 12
"y": 48
}
]
}

36
stream-from-stdin.py Normal file
View File

@ -0,0 +1,36 @@
# x-run: cat _junk/logs.txt | python3 %
from base64 import b64decode
from sys import stdout, stdin, stderr
from json import loads
canvas = bytearray(125000)
last_update: int = 0
last_frame: int = 0
n_frames = 0
for line in stdin:
_, data = line.strip().split(" ", 1)
event, data = loads(data)
if event == "full_state":
buffer = b64decode(data["full_state"].encode() + b"=")
last_update = data["timestamp"]
canvas[:] = buffer
elif event == "batched_bit_toggles":
bits_on, bits_off, timestamp = data
if timestamp >= last_update:
for ndx in bits_on:
byte, bit = divmod(ndx, 8)
canvas[byte] |= (1 << bit)
for ndx in bits_off:
byte, bit = divmod(ndx, 8)
canvas[byte] &= 0xFF ^ (1 << bit)
last_update = timestamp
if (last_update - last_frame) > 6_000:
stdout.buffer.write(canvas)
stdout.buffer.flush()
last_frame = last_update