Skip to content

Instantly share code, notes, and snippets.

@hugmouse
Created June 26, 2024 19:32
Show Gist options
  • Save hugmouse/b88fa4ef9398b5eab2ccc81240024f38 to your computer and use it in GitHub Desktop.
Save hugmouse/b88fa4ef9398b5eab2ccc81240024f38 to your computer and use it in GitHub Desktop.
tonsky.me pointer simulator
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