Last active 1742992793 Unlisted

cqql_extreme-edition.go Raw
1package main
2
3import (
4 "errors"
5 "fmt"
6 "image"
7 "image/png"
8 "net"
9 "net/http"
10 "os"
11 "sync"
12 "time"
13)
14
15var (
16 fetchClient = &http.Client{
17 Timeout: 500 * time.Millisecond,
18 }
19
20 submitClient = &http.Client{
21 Timeout: 50 * time.Millisecond,
22 }
23)
24
25func main() {
26 f, err := os.Open("img.png")
27 if err != nil {
28 panic(err)
29 }
30
31 img, err := png.Decode(f)
32 if err != nil {
33 panic(err)
34 }
35
36 for {
37 if err := draw(img); err != nil {
38 fmt.Println(err)
39 }
40
41 <-time.After(100 * time.Millisecond)
42 }
43}
44
45func draw(img image.Image) error {
46 fmt.Println("redraw")
47
48 req, err := http.NewRequest("GET", "https://cqql.site/chaosbtn", nil)
49 if err != nil {
50 return err
51 }
52
53 res, err := fetchClient.Do(req)
54 if err != nil {
55 return err
56 }
57 defer res.Body.Close()
58
59 if res.StatusCode != 200 {
60 return errors.New("could not fetch current button state")
61 }
62
63 currentState, err := png.Decode(res.Body)
64 if err != nil {
65 return err
66 }
67
68 wg := &sync.WaitGroup{}
69
70 for x := 0; x < 88; x++ {
71 wg.Add(1)
72 go drawCol(wg, x, img, currentState)
73 }
74 wg.Wait()
75
76 return nil
77}
78
79func drawCol(wg *sync.WaitGroup, x int, img image.Image, currentState image.Image) error {
80 defer wg.Done()
81
82 for y := 0; y < 31; y++ {
83 r, g, b, _ := img.At(x, y).RGBA()
84 curR, curG, curB, _ := currentState.At(x, y).RGBA()
85
86 if r == curR && g == curG && b == curB {
87 continue
88 }
89
90 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)
91 fmt.Printf("send [%02d,%02d] [%03d %03d %03d]\n", x, y, r/257, g/257, b/257)
92
93 req, err := http.NewRequest("GET", uri, nil)
94 if err != nil {
95 return err
96 }
97
98 _, err = submitClient.Do(req)
99 if err != nil {
100 var netErr net.Error
101 if errors.As(err, &netErr) && netErr.Timeout() {
102 continue
103 }
104
105 return err
106 }
107 }
108
109 return nil
110}
111