Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 65 additions & 41 deletions src/api/hypixel.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net/http"
"os"
"time"
redis "skycrypt/src/db"
"skycrypt/src/models"
"skycrypt/src/utility"
Expand All @@ -15,93 +16,109 @@ import (

var HYPIXEL_API_KEY = os.Getenv("HYPIXEL_API_KEY")

func GetPlayer(uuid string) (*skycrypttypes.Player, error) {
var rawReponse models.HypixelPlayerResponse
var response skycrypttypes.Player
var json = jsoniter.ConfigCompatibleWithStandardLibrary

var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}


func GetPlayer(uuid string) (*models.Player, error) {
rawReponse := &models.HypixelPlayerResponse{}
response := &models.Player{}

if !utility.IsUUID(uuid) {
respUUID, err := GetUUID(uuid)
if err != nil {
return &response, err
return response, err
}

uuid = respUUID
}

cache, err := redis.Get(fmt.Sprintf(`player:%s`, uuid))
if err == nil && cache != "" {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal([]byte(cache), &rawReponse)
err = json.Unmarshal([]byte(cache), rawReponse)
if err == nil {
return &rawReponse.Player, nil
return rawReponse.Player, nil
}
}

resp, err := http.Get(fmt.Sprintf("https://api.hypixel.net/v2/player?key=%s&uuid=%s", HYPIXEL_API_KEY, uuid))
resp, err := httpClient.Get(fmt.Sprintf("https://api.hypixel.net/v2/player?key=%s&uuid=%s", HYPIXEL_API_KEY, uuid))

if err != nil {
return &response, fmt.Errorf("error making request: %v", err)
return response, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return response, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return &response, fmt.Errorf("error reading response: %v", err)
return response, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &rawReponse)
err = json.Unmarshal(body, rawReponse)
if err != nil {
return &rawReponse.Player, fmt.Errorf("error parsing JSON: %v", err)
return rawReponse.Player, fmt.Errorf("error parsing JSON: %v", err)
}

redis.Set(fmt.Sprintf(`player:%s`, uuid), string(body), 24*60*60)
return &rawReponse.Player, nil
return rawReponse.Player, nil
}

func GetProfiles(uuid string) (*models.HypixelProfilesResponse, error) {
var response models.HypixelProfilesResponse
response := &models.HypixelProfilesResponse{}
if !utility.IsUUID(uuid) {
respUUID, err := GetUUID(uuid)
if err != nil {
return &response, err
return response, err
}

uuid = respUUID
}

cache, err := redis.Get(fmt.Sprintf(`profiles:%s`, uuid))
if err == nil && cache != "" {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal([]byte(cache), &response)
err = json.Unmarshal([]byte(cache), response)
if err == nil {
return &response, nil
return response, nil
}
}

resp, err := http.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/profiles?key=%s&uuid=%s", HYPIXEL_API_KEY, uuid))
resp, err := httpClient.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/profiles?key=%s&uuid=%s", HYPIXEL_API_KEY, uuid))
if err != nil {
return &response, fmt.Errorf("error making request: %v", err)
return response, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return response, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return &response, fmt.Errorf("error reading response: %v", err)
return response, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &response)
err = json.Unmarshal(body, response)
if err != nil {
return &response, fmt.Errorf("error parsing JSON: %v", err)
return response, fmt.Errorf("error parsing JSON: %v", err)
}

if response.Cause != "" && !response.Success {
return &response, fmt.Errorf("error fetching profiles: %s", response.Cause)
return response, fmt.Errorf("error fetching profiles: %s", response.Cause)
}

redis.Set(fmt.Sprintf(`profiles:%s`, uuid), string(body), 5*60) // Cache for 5 minutes
return &response, nil
return response, nil
}

func GetProfile(uuid string, profileId ...string) (*skycrypttypes.Profile, error) {
Expand Down Expand Up @@ -136,31 +153,35 @@ func GetProfile(uuid string, profileId ...string) (*skycrypttypes.Profile, error
return &skycrypttypes.Profile{}, fmt.Errorf("profile with ID %s not found for UUID %s", targetProfileId, uuid)
}

func GetMuseum(profileId string) (map[string]*skycrypttypes.Museum, error) {
var rawReponse models.HypixelMuseumResponse
func GetMuseum(profileId string) (map[string]*models.Museum, error) {
rawReponse := &models.HypixelMuseumResponse{}


cache, err := redis.Get(fmt.Sprintf(`museum:%s`, profileId))
if err == nil && cache != "" {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal([]byte(cache), &rawReponse)
err = json.Unmarshal([]byte(cache), rawReponse)
if err == nil {
return rawReponse.Members, nil
}
}

resp, err := http.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/museum?key=%s&profile=%s", HYPIXEL_API_KEY, profileId))
resp, err := httpClient.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/museum?key=%s&profile=%s", HYPIXEL_API_KEY, profileId))
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &rawReponse)
err = json.Unmarshal(body, rawReponse)
if err != nil {
return nil, fmt.Errorf("error parsing JSON: %v", err)
}
Expand All @@ -169,35 +190,38 @@ func GetMuseum(profileId string) (map[string]*skycrypttypes.Museum, error) {
return rawReponse.Members, nil
}

func GetGarden(profileId string) (*skycrypttypes.Garden, error) {
var rawReponse models.HypixelGardenResponse
func GetGarden(profileId string) (*models.GardenRaw, error) {
rawReponse := &models.HypixelGardenResponse{}

cache, err := redis.Get(fmt.Sprintf(`garden:%s`, profileId))
if err == nil && cache != "" {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal([]byte(cache), &rawReponse)
err = json.Unmarshal([]byte(cache), rawReponse)
if err == nil {
return &rawReponse.Garden, nil
return rawReponse.Garden, nil
}
}

resp, err := http.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/garden?key=%s&profile=%s", HYPIXEL_API_KEY, profileId))
resp, err := httpClient.Get(fmt.Sprintf("https://api.hypixel.net/v2/skyblock/garden?key=%s&profile=%s", HYPIXEL_API_KEY, profileId))
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &rawReponse)
err = json.Unmarshal(body, rawReponse)
if err != nil {
return nil, fmt.Errorf("error parsing JSON: %v", err)
}

redis.Set(fmt.Sprintf(`garden:%s`, profileId), string(body), 60*30) // Cache for 30 minutes
return &rawReponse.Garden, nil
return rawReponse.Garden, nil
}
65 changes: 42 additions & 23 deletions src/api/mowojang.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,51 @@ package api
import (
"fmt"
"io"
"net/http"
"strings"
"time"
redis "skycrypt/src/db"
"skycrypt/src/models"
"skycrypt/src/utility"

"net/http"
"strings"

jsoniter "github.com/json-iterator/go"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

var httpClient = &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}

func GetUUID(username string) (string, error) {
var post models.MowojangReponse
post := &models.MowojangReponse{}

cache, err := redis.Get(fmt.Sprintf("uuid:%s", strings.ToLower(username)))
if err == nil && cache != "" {
return cache, nil
}

resp, err := http.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", username))
resp, err := httpClient.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", username))
if err != nil {
return post.UUID, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return post.UUID, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return post.UUID, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &post)
err = json.Unmarshal(body, post)
if err != nil {
return post.UUID, fmt.Errorf("error parsing JSON: %v", err)
}
Expand All @@ -45,26 +59,29 @@ func GetUUID(username string) (string, error) {
}

func GetUsername(uuid string) (string, error) {
var post models.MowojangReponse
post := &models.MowojangReponse{}

cache, err := redis.Get(fmt.Sprintf("username:%s", uuid))
if err == nil && cache != "" {
return cache, nil
}

resp, err := http.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", uuid))
resp, err := httpClient.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", uuid))
if err != nil {
return post.Name, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return post.Name, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return post.Name, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &post)
err = json.Unmarshal(body, post)
if err != nil {
return post.Name, fmt.Errorf("error parsing JSON: %v", err)
}
Expand All @@ -76,42 +93,44 @@ func GetUsername(uuid string) (string, error) {
}

func ResolvePlayer(uuid string) (*models.MowojangReponse, error) {
var post models.MowojangReponse
post := &models.MowojangReponse{}
if !utility.IsUUID(uuid) {
tempUUID, err := GetUUID(uuid)
if err != nil {
return &post, fmt.Errorf("error resolving UUID for username '%s': %v", uuid, err)
return post, fmt.Errorf("error resolving UUID for username '%s': %v", uuid, err)
}
uuid = tempUUID
}

cache, err := redis.Get(fmt.Sprintf("mowojang:%s", uuid))
if err == nil && cache != "" {
var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal([]byte(cache), &post)
err = json.Unmarshal([]byte(cache), post)
if err == nil {
return &post, nil
return post, nil
}
}

resp, err := http.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", uuid))
resp, err := httpClient.Get(fmt.Sprintf("https://mowojang.matdoes.dev/%s", uuid))
if err != nil {
return &post, fmt.Errorf("error making request: %v", err)
return post, fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
return post, fmt.Errorf("API returned status %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return &post, fmt.Errorf("error reading response: %v", err)
return post, fmt.Errorf("error reading response: %v", err)
}

var json = jsoniter.ConfigCompatibleWithStandardLibrary
err = json.Unmarshal(body, &post)
err = json.Unmarshal(body, post)
if err != nil {
return &post, fmt.Errorf("error parsing JSON: %v", err)
return post, fmt.Errorf("error parsing JSON: %v", err)
}

redis.Set(fmt.Sprintf("mowojang:%s", uuid), string(body), 24*60*60) // Cache for 24 hours

return &post, nil
return post, nil
}