Created
June 26, 2024 19:32
-
-
Save hugmouse/b88fa4ef9398b5eab2ccc81240024f38 to your computer and use it in GitHub Desktop.
tonsky.me pointer simulator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"log" | |
"math/rand" | |
"net/url" | |
"os" | |
"os/signal" | |
"sync" | |
"time" | |
"github.com/gorilla/websocket" | |
) | |
type Pointer struct { | |
ID int `json:"id"` | |
X int `json:"x"` | |
Y int `json:"y"` | |
} | |
const ( | |
XLIMIT = 10000 | |
YLIMIT = 3000 | |
CLIENTID = 1337 | |
PAGE = "/" | |
PLATFORM = "w" | |
) | |
func connectWebSocket(clientID int) (*websocket.Conn, error) { | |
u := url.URL{ | |
Scheme: "wss", | |
Host: "tonsky.me", | |
Path: "/ptrs", | |
RawQuery: fmt.Sprintf("id=%d&page=%s&platform=%s", clientID, PAGE, PLATFORM), | |
} | |
log.Printf("connecting to %s", u.String()) | |
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) | |
if err != nil { | |
return nil, fmt.Errorf("dial: %w", err) | |
} | |
return c, nil | |
} | |
func updatePointer(pointer *Pointer) { | |
pointer.X += rand.Intn(1100) - 500 | |
if pointer.X < 0 { | |
pointer.X = 0 | |
} else if pointer.X > XLIMIT { | |
pointer.X = XLIMIT | |
} | |
pointer.Y += rand.Intn(1100) - 500 | |
if pointer.Y < 0 { | |
pointer.Y = 0 | |
} else if pointer.Y > YLIMIT { | |
pointer.Y = YLIMIT | |
} | |
} | |
func sendPointerData(c *websocket.Conn, pointer Pointer) error { | |
data, err := json.Marshal([]int{pointer.X, pointer.Y}) | |
if err != nil { | |
return fmt.Errorf("marshal: %w", err) | |
} | |
err = c.WriteMessage(websocket.TextMessage, data) | |
if err != nil { | |
return fmt.Errorf("write: %w", err) | |
} | |
log.Printf("sent: %s", data) | |
return nil | |
} | |
func simulatePointer(id int, wg *sync.WaitGroup, done chan struct{}) { | |
defer wg.Done() | |
c, err := connectWebSocket(id) | |
if err != nil { | |
log.Fatal(err) | |
return | |
} | |
defer c.Close() | |
ticker := time.NewTicker(time.Second) | |
defer ticker.Stop() | |
pointer := Pointer{ | |
ID: id, | |
X: rand.Intn(XLIMIT), | |
Y: rand.Intn(YLIMIT), | |
} | |
for { | |
select { | |
case <-done: | |
return | |
case <-ticker.C: | |
updatePointer(&pointer) | |
if err := sendPointerData(c, pointer); err != nil { | |
log.Println(err) | |
return | |
} | |
} | |
} | |
} | |
func main() { | |
interrupt := make(chan os.Signal, 1) | |
signal.Notify(interrupt, os.Interrupt) | |
done := make(chan struct{}) | |
var wg sync.WaitGroup | |
for i := 1; i <= 15; i++ { | |
wg.Add(1) | |
go simulatePointer(CLIENTID+i, &wg, done) | |
} | |
<-interrupt | |
close(done) | |
wg.Wait() | |
log.Println("all connections closed") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment