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!
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

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

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

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

            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

            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

            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.

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
             
        
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)
        

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.

Alyssa
I saw Alyssa experimenting at different moments, drawing DANK in different ways on the button.
 
            
        
     
            
        
     
        
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.
             
        
same with this one, which came before nix's acenby flag.
             
        
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.

lexi is back
very important addition from lexi.

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)))◌⍥(:°⊂)⊸⧻⇌

it runs every pixel in a separate thread.
this is the button silt wanted to draw:

but snow's snowflake prevails

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).