package main import ( "encoding/json" "fmt" "github.com/google/uuid" netclient "hudly/client" "hudly/hypixel" "hudly/mcfetch" "log" "os" "time" ) var key = "ccebff0f-939a-4afe-b5b3-30a7a665ee38" var UUID = "5328930e-d411-49cb-90ad-4e5c7b27dd86" func demo() { // Ensure a username is provided as a command-line argument if len(os.Args) < 2 { log.Fatal("Please provide a Minecraft username as a command-line argument.") } // Get the username from the command-line arguments username := os.Args[1] thing := hypixel.NewAPIKey(key) api := hypixel.NewAPI(*thing) thing.UsesLeft = 11 // Create a MemoryCache instance memCache := &mcfetch.MemoryCache{} memCache.Init() // Create a channel to receive the result resultChan := make(chan map[string]interface{}) errorChan := make(chan error) // Create an AsyncPlayerFetcher for asynchronous data fetching with MemoryCache asyncFetcher := mcfetch.NewAsyncPlayerFetcher( username, // Minecraft username or UUID memCache, // Pass the memory cache instance 2, // Number of retries 2*time.Second, // Retry delay 5*time.Second, // Request timeout ) // Start asynchronous data fetching asyncFetcher.FetchPlayerData(resultChan, errorChan) // Non-blocking code execution (do something else while waiting) fmt.Println("Fetching data asynchronously...") var userID string // Block until we receive data or an error select { case data := <-resultChan: fmt.Printf("Player data: %+v\n", data) // Check if "uuid" exists and is not nil if uuid, ok := data["id"].(string); ok { userID = uuid } else { fmt.Println(fmt.Sprintf("%+v", data)) log.Fatal("UUID not found or invalid for player") } case err := <-errorChan: log.Fatal(err) } // Use the Hypixel API to get additional player data res, err := api.GetPlayerResponse(userID) if err != nil { panic(err) } fmt.Println(fmt.Sprintf("%+v", res)) } func main() { var cmd string fmt.Print(" | CREATE\n | JOIN\nEnter Choice:\n>") fmt.Scanln(&cmd) if cmd != "CREATE" && cmd != "JOIN" { fmt.Println("Invalid command.") return } client, err := netclient.NewClient("0.0.0.0", uuid.New().String()) if err != nil { log.Fatalf("Failed to create client: %v", err) return } var code string if cmd == "CREATE" { var err error code, err = client.CreateRoom("") if err != nil { log.Fatal(err) return } fmt.Println("Created room:", code) err = client.JoinRoom(code, "password") if err != nil { log.Fatal(err) return } println("Connected to room") } else if cmd == "JOIN" { var password string fmt.Print("Enter Room Code:\n>") fmt.Scanln(&code) fmt.Print("Enter Room Password:\n>") fmt.Scanln(&password) err := client.JoinRoom(code, password) if err != nil { log.Fatal(err) return } fmt.Println("Joined room:", code) } client.ListenForData() // Handle received data in a separate goroutine go func() { for data := range client.DataChannel { fmt.Printf("Received data: %s\n", data) } }() if cmd == "CREATE" { println("Sleeping...") time.Sleep(time.Second * 20) println("Continuing!") thing := hypixel.NewAPIKey(key) api := hypixel.NewAPI(*thing) memCache := &mcfetch.MemoryCache{} memCache.Init() resultChan := make(chan map[string]interface{}) errorChan := make(chan error) players := []string{"illyum", "ergopunch"} stuff := []map[string]interface{}{} // List to hold player JSON objects println("Getting UUIDs") for _, player := range players { asyncFetcher := mcfetch.NewAsyncPlayerFetcher( player, memCache, 2, 2*time.Second, 5*time.Second, ) asyncFetcher.FetchPlayerData(resultChan, errorChan) } var userID string for i := 0; i < len(players); i++ { select { case data := <-resultChan: if uuid, ok := data["id"].(string); ok { userID = uuid } else { fmt.Println(fmt.Sprintf("%+v", data)) log.Fatal("UUID not found or invalid for player") } // Fetch player stats res, err := api.GetPlayerResponse(userID) if err != nil { log.Fatalf("Failed to get player data: %v", err) } // Calculate derived stats res.Player.Stats.Bedwars.WLR = calculateRatio(res.Player.Stats.Bedwars.Wins, res.Player.Stats.Bedwars.Losses) res.Player.Stats.Bedwars.KDR = calculateRatio(res.Player.Stats.Bedwars.Kills, res.Player.Stats.Bedwars.Deaths) res.Player.Stats.Bedwars.FKDR = calculateRatio(res.Player.Stats.Bedwars.FinalKills, res.Player.Stats.Bedwars.FinalDeaths) res.Player.Stats.Bedwars.BBLR = calculateRatio(res.Player.Stats.Bedwars.BedsBroken, res.Player.Stats.Bedwars.BedsLost) // Convert player struct to JSON playerJSON, err := json.Marshal(res) if err != nil { log.Fatalf("Failed to marshal player data: %v", err) } // Append the player JSON to the stuff list var playerMap map[string]interface{} json.Unmarshal(playerJSON, &playerMap) stuff = append(stuff, playerMap) case err := <-errorChan: log.Fatal(err) } } println("UUID Done!") println("Sending data...") // Send the list of JSON objects to the client message, err := json.Marshal(stuff) if err != nil { log.Fatalf("Failed to marshal stuff: %v", err) } err = client.SendData(string(message)) if err != nil { log.Printf("Error sending data: %v", err) } fmt.Println("Sent stuff:", stuff) println("Sending Done!") } select { case <-client.DataChannel: // This blocks the main goroutine until data is received fmt.Println("Data received, exiting...") } fmt.Println("Closing app") } // calculateRatio is a helper function to calculate ratios (e.g., WLR, KDR, etc.) func calculateRatio(numerator, denominator int) float64 { if denominator == 0 { return float64(numerator) } return float64(numerator) / float64(denominator) }