package main import ( "encoding/json" "fmt" "log" "net/url" "time" "github.com/gorilla/websocket" ) type MessageEnvelope struct { Type string `json:"type"` Data json.RawMessage `json:"data"` } type ModHandshake struct { ServerID string `json:"server_id"` } type BotHandshake struct { BotID string `json:"bot_id"` } type User struct { ID string `json:"id"` Name string `json:"name"` } type ModMessage struct { MsgID string `json:"msg_id"` Server string `json:"server"` User User `json:"user"` Content string `json:"content"` Meta map[string]interface{} `json:"meta,omitempty"` Ts string `json:"ts,omitempty"` } type BotMessage struct { MsgID string `json:"msg_id"` ChannelID string `json:"channel_id"` Author string `json:"author"` Content string `json:"content"` Meta map[string]interface{} `json:"meta,omitempty"` Ts string `json:"ts,omitempty"` } func simulateMod() { u := url.URL{Scheme: "ws", Host: "localhost:3333", Path: "/ws"} u.RawQuery = "api_key=gateway" conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { log.Fatalf("mod dial error: %v", err) } defer conn.Close() fmt.Println("[MOD] Connected") // Send handshake handshake := ModHandshake{ServerID: "survival_server"} hsData, _ := json.Marshal(handshake) envelope := MessageEnvelope{ Type: "mod", Data: hsData, } envData, _ := json.Marshal(envelope) if err := conn.WriteMessage(websocket.TextMessage, envData); err != nil { log.Fatalf("mod handshake write error: %v", err) } fmt.Println("[MOD] Sent handshake") // Read handshake response _, resp, err := conn.ReadMessage() if err != nil { log.Fatalf("mod handshake response error: %v", err) } fmt.Printf("[MOD] Handshake response: %s\n", string(resp)) // Send a few messages for i := 1; i <= 3; i++ { msg := ModMessage{ MsgID: fmt.Sprintf("mod_msg_%d", i), Server: "survival_server", User: User{ID: "player_123", Name: "Steve"}, Content: fmt.Sprintf("Message %d from Minecraft!", i), Meta: map[string]interface{}{ "coordinates": map[string]int{"x": 100 + i*10, "y": 64, "z": 200}, }, Ts: time.Now().UTC().Format(time.RFC3339), } msgData, _ := json.Marshal(msg) if err := conn.WriteMessage(websocket.TextMessage, msgData); err != nil { log.Fatalf("mod message write error: %v", err) } fmt.Printf("[MOD] Sent message: %s\n", msg.Content) // Read response _, resp, err := conn.ReadMessage() if err != nil { log.Fatalf("mod response error: %v", err) } fmt.Printf("[MOD] Response: %s\n", string(resp)) time.Sleep(1 * time.Second) } fmt.Println("[MOD] Closing connection") } func simulateBot() { time.Sleep(2 * time.Second) // Let mod connect first u := url.URL{Scheme: "ws", Host: "localhost:3333", Path: "/ws"} u.RawQuery = "api_key=gateway" conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { log.Fatalf("bot dial error: %v", err) } defer conn.Close() fmt.Println("[BOT] Connected") // Send handshake handshake := BotHandshake{BotID: "discord_bot_1"} hsData, _ := json.Marshal(handshake) envelope := MessageEnvelope{ Type: "bot", Data: hsData, } envData, _ := json.Marshal(envelope) if err := conn.WriteMessage(websocket.TextMessage, envData); err != nil { log.Fatalf("bot handshake write error: %v", err) } fmt.Println("[BOT] Sent handshake") // Read handshake response _, resp, err := conn.ReadMessage() if err != nil { log.Fatalf("bot handshake response error: %v", err) } fmt.Printf("[BOT] Handshake response: %s\n", string(resp)) // Send a few messages for i := 1; i <= 3; i++ { msg := BotMessage{ MsgID: fmt.Sprintf("bot_msg_%d", i), ChannelID: "987654321", Author: "DiscordUser#1234", Content: fmt.Sprintf("Message %d from Discord!", i), Meta: map[string]interface{}{ "reactions": []string{"👍", "❤️"}, }, Ts: time.Now().UTC().Format(time.RFC3339), } msgData, _ := json.Marshal(msg) if err := conn.WriteMessage(websocket.TextMessage, msgData); err != nil { log.Fatalf("bot message write error: %v", err) } fmt.Printf("[BOT] Sent message: %s\n", msg.Content) // Read response _, resp, err := conn.ReadMessage() if err != nil { log.Fatalf("bot response error: %v", err) } fmt.Printf("[BOT] Response: %s\n", string(resp)) time.Sleep(1 * time.Second) } fmt.Println("[BOT] Closing connection") } func main() { fmt.Println("Starting WebSocket client simulator...") fmt.Println("Connecting to ws://localhost:3333/ws with api_key=test_key") go simulateMod() go simulateBot() // Let them run time.Sleep(15 * time.Second) fmt.Println("Simulator finished") }