Home

88x31 button you can draw on

i hope this isn't a mistake :3

I made this 88x31 button which you can draw on with GET requests. It's added to my home page. Feel free to automate anything you want to draw on it. The interface is very simple on purpose and I don't plan to add any more functionality to it. This is scary, please be nice <3

For example, go to
https://cqql.site/chaosbtn/draw?x=3&y=1&r=255&g=255&b=255
to make a pixel turn white. (first from the top and third from the left, counting from 0). The r/g/b values go from 0 to 255 and x/y go from 0 to 87 and 30 respectively.

Here's what the button looks like now, so you can see your changes!

btn

I might set up my own automations for it (with some generative art) in the future.

Have fun!

creatures

lexi

I woke up to there being a boykisser on the button, so i looked at the history of changes and found who was messing with it from their pfp :3

profile picture of lexi (a pink pixelated cat face) and a boykisser to the right of it, on a blue geometric background

lexi (@orthoplex) wrote code to draw boykissers at random positions on the button

full of boykissers

here's the script:

import time, random, urllib.request, matplotlib.image
im = (255 * matplotlib.image.imread("boykisser.png")).astype(int)
while True:
    X = random.randint(1,88)
    Y = random.randint(1,31)
    print(f"drawing boykisser @ {X},{Y}")
    for y,row in enumerate(im):
        for x,(r,g,b,a) in enumerate(row):
            if a == 0: continue
            url = f"https://cqql.site/chaosbtn/draw?x={(x+X)%88}&y={(y+Y)%31}&r={r}&g={g}&b={b}"
            while b"OK" not in urllib.request.urlopen(url).read():
                time.sleep(1)

snow

then snow joined with this defacing campain /j

made with windows

with code in go

func draw() error {
    f, err := os.Open("img.jpg")
    if err != nil {
        return err
    }

    img, err := jpeg.Decode(f)
    if err != nil {
        return err
    }

    for {
        for x := 0; x < 88; x++ {
            for y := 0; y < 31; y++ {
                r, g, b, _ := img.At(x, y).RGBA()

                uri := fmt.Sprintf("https://cqql.site/chaosbtn/draw?x=%d&y=%d&r=%d&g=%d&b=%d", x, y, r/257, g/257, b/257)
                req, err := http.NewRequest("GET", uri, nil)
                if err != nil {
                    return err
                }

                _, err = http.DefaultClient.Do(req)
                if err != nil {
                    return err
                }
            }
        }
    }
}

boykisser vs. windows

... then snow broght out the big guns with this code which she says
> skips all pixels that are already windows
> so i can defend my defacement art more efficiently :3

and the fight started

screenshot of the button being fought over by windows and boykissers

but then she updated the code...
> made it stop caring about the request's response so it can hammer harder
> just send it off and move on we dont neeed to waste 200ms waiting for an "ok"

what 88 threads do to a mf

made with windows

at that point, the server software hosting this button kept dying from those two DDoSing it but then docker-compose restart: always kept bringing it back to life, over and over forever. in a loop of death and revival.

so i decided to optimize the server software a bit, because it was choking on saving each /draw request as a file - too much io. i made it save to disk only once per second but the in-memory button (which is what's served) gets updated on every request.

this is insane, so i decided to step in (we can't let windows win). i told snow that i'll run lexi's code on the vps itself (lower latency but not modifying the server software, so it's not cheating!).

for a brief moment the boykisser won

made with windows but the windows logo is covered by the boykisser

but snow said she may buy a vps in the same datacenter as this to get shorter request times. hyperfocused adhd creatures are scary...

well, turns out she didn't have to.
> i already had a vps in the same datacenter as you
> so yeah just quickly rsync'd over my script and launched it there
> saves me like 15ms per request :hehe:

now, running lexi's code on localhost, we started seeing only a sprinkle of boykisser on the windows logo.

made with windows but the windows logo is covered by a few pixels of the boykisser

but there's no winning with snow, at least using python as the weapon. through trial and error, she got a vps on the same physical machine as my vps. and showed off her sub millisecond ping

sub millisecond ping from snow's vps to mine

finally, we conceded. i'll have to buy snow coffee for this.

nix

nix joined!

and drew on the button with a makefile :o
(after a while of waiting for me to finish debugging)

ace enby flag (split at an angle through the middle) with a colon three and an ascii heart in black text

it would be too long to paste it here but this is how fae generated it

from PIL import Image


def start():

    im = Image.open("aceEnby.png", "r")
    pixelData = list(im.getdata())

    with open("Makefile", "w") as f:

        f.write(".PHONY: draw\ndraw:")
        for x in range(0, 88):
            for y in range(0, 31):
                f.write(" draw" + str(x*31+y))

        f.write("\n\n")
        for x in range(0, 88):
            for y in range(0, 31):
                f.write("draw"+str(x*31+y)+":\n")
                f.write("\tcurl 'https://cqql.site/chaosbtn/draw?x=")
                f.write(str(x))
                f.write("&y=")
                f.write(str(y))
                f.write("&r=")
                f.write(str(pixelData[x+y*88][0]))
                f.write("&g=")
                f.write(str(pixelData[x+y*88][1]))
                f.write("&b=")
                f.write(str(pixelData[x+y*88][2]))
                f.write("'\n")

start()

fae released the code under cc0 / public domain.

also fae discovered:
> fun fact I basically just learned today:
> if you start make like this
> make -j
> without specifying a number, it takes it as meaning infinite threads

this silly idea turned out to be overpowered because make -j lead to all draws happening in individual threads

baba

later, nix's flag was joined by baba. i don't know who drew it.

button with an acenby flag and a small baba creature from baba is you

Alyssa

I saw Alyssa experimenting at different moments, drawing DANK in different ways on the button.

handdrawn dank in red on the background of the windows button from snow

dank drawn with random pixels on a gradient background

dank drawn with random colored pixels on the background of the windows button from snow

another nice use of transparency and only redrawing pixels that need changing. her code is available here: why2.py

ariel

the gradient in the button above came from a linguist catboy who used python pandas dataframes to store the image data.

dank drawn with random pixels on a gradient background

same with this one, which came before nix's acenby flag.

purple to blue horizontal gradient

his script can draw any gradient on the button from user input, up to 5 colors. it's really cool (and universal). you should give it a try, the code is available here: gradient.py

return of snow

it's necessary to mark snow's achievement, while still letting others have their fun. from this point on, there always has been a big unconquerable snowflake in the middle of the button that everyone just decided to draw around.

the button with a big snowflake in the middle

lexi is back

very important addition from lexi.

tragbar katze

silt

silt joined the party in style as usual, with a script in uiua.

⍜°⍉↙₃⁅×255◌°img&frab"button.png"
°¤↙₁⤸₂⍜°⍉↙₂°⊡
⍜♭₂⤸₁⍉⊂∩°⍉
?
wait≡spawn(⍢∘(⍣(
  $"GET /chaosbtn/draw?y=_&x=_&r=_&g=_&b=_ HTTP/1.1\r\nHost: cqql.site\r\nConnection: close\r\n\r\n"
  &s $"REQUEST _".
  ⍜(&tlsc "cqql.site:443"|&rs∞⊸&w:)
  &s ⤚$"REPLY _ _" ⧻⊚⌕"\"OK\"".
  &p ""
  ≠1
|1)))◌⍥(:°⊂)⊸⧻⇌

screenshot of the above code with syntax highlighting

it runs every pixel in a separate thread.

this is the button silt wanted to draw:

silt was here

but snow's snowflake prevails

silt's button with snow's snowflake in the middle

do you want to have your own?

I also hosted everything to allow more creatures to host their own buttons like this, including a safeguard to easily revert the button to its original state. It's a perk for any supporters on my Ko-Fi page (reach out to me if you'd like one).

Home