package mcfetch import ( "encoding/json" "errors" "net/http" "time" ) // PlayerFetcher is responsible for fetching Minecraft player data synchronously type PlayerFetcher struct { playerName string retries int retryDelay time.Duration timeout time.Duration cache ICache } type FetchedPlayerResult struct { UUID string `json:"id"` Name string `json:"name"` } // NewPlayerFetcher creates a new PlayerFetcher with an abstract cache (ICache) func NewPlayerFetcher(playerName string, cache ICache, retries int, retryDelay time.Duration, timeout time.Duration) *PlayerFetcher { cache.Init() return &PlayerFetcher{ playerName: playerName, retries: retries, retryDelay: retryDelay, timeout: timeout, cache: cache, } } // FetchPlayerData fetches the player data synchronously func (pf *PlayerFetcher) FetchPlayerData() (*FetchedPlayerResult, error) { //cachedData, found := pf.cache.Get(pf.playerName) //if found { // return &FetchedPlayerResult{}, nil //} var player FetchedPlayerResult for i := 0; i < pf.retries; i++ { resp, err := pf.makeRequest(pf.playerName) if err == nil { defer resp.Body.Close() if err := json.NewDecoder(resp.Body).Decode(&player); err == nil { // pf.cache.Set(pf.playerName, player) // pf.cache.Sync() return &player, nil } } time.Sleep(pf.retryDelay) } return nil, errors.New("Failed to fetch player data after retries") } // makeRequest performs the HTTP request to Mojang API func (pf *PlayerFetcher) makeRequest(playerName string) (*http.Response, error) { client := http.Client{Timeout: pf.timeout} url := "https://api.mojang.com/users/profiles/minecraft/" + playerName resp, err := client.Get(url) if err != nil || resp.StatusCode != http.StatusOK { return nil, errors.New("Request failed") } return resp, nil }