mirror of
https://github.com/elyby/chrly.git
synced 2024-11-26 16:51:59 +05:30
#1: Implemented necessary Mojang APIs
This commit is contained in:
parent
4386054ca1
commit
7db4d27fba
87
api/mojang/mojang.go
Normal file
87
api/mojang/mojang.go
Normal file
@ -0,0 +1,87 @@
|
||||
package mojang
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var HttpClient = &http.Client{}
|
||||
|
||||
type SignedTexturesResponse struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Props []Property `json:"properties"`
|
||||
}
|
||||
|
||||
type Property struct {
|
||||
Name string `json:"name"`
|
||||
Signature string `json:"signature,omitempty"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ProfileInfo struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IsLegacy bool `json:"legacy,omitempty"`
|
||||
IsDemo bool `json:"demo,omitempty"`
|
||||
}
|
||||
|
||||
func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
||||
requestBody, _ := json.Marshal(usernames)
|
||||
request, err := http.NewRequest("POST", "https://api.mojang.com/profiles/minecraft", bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
response, err := HttpClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode == 429 {
|
||||
return nil, &TooManyRequestsError{}
|
||||
}
|
||||
|
||||
var result []*ProfileInfo
|
||||
|
||||
body, _ := ioutil.ReadAll(response.Body)
|
||||
_ = json.Unmarshal(body, &result)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func UuidToTextures(uuid string) (*SignedTexturesResponse, error) {
|
||||
request, err := http.NewRequest("GET", "https://sessionserver.mojang.com/session/minecraft/profile/"+uuid, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
response, err := HttpClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode == 429 {
|
||||
return nil, &TooManyRequestsError{}
|
||||
}
|
||||
|
||||
var result *SignedTexturesResponse
|
||||
|
||||
body, _ := ioutil.ReadAll(response.Body)
|
||||
_ = json.Unmarshal(body, &result)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type TooManyRequestsError struct {
|
||||
}
|
||||
|
||||
func (e *TooManyRequestsError) Error() string {
|
||||
return "Too Many Requests"
|
||||
}
|
130
api/mojang/mojang_test.go
Normal file
130
api/mojang/mojang_test.go
Normal file
@ -0,0 +1,130 @@
|
||||
package mojang
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
testify "github.com/stretchr/testify/assert"
|
||||
"gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
func TestUsernamesToUuidsCorrectResponse(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://api.mojang.com").
|
||||
Post("/profiles/minecraft").
|
||||
JSON([]string{"Thinkofdeath", "maksimkurb"}).
|
||||
Reply(200).
|
||||
JSON([]map[string]interface{}{
|
||||
{
|
||||
"id": "4566e69fc90748ee8d71d7ba5aa00d20",
|
||||
"name": "Thinkofdeath",
|
||||
"legacy": false,
|
||||
"demo": true,
|
||||
},
|
||||
{
|
||||
"id": "0d252b7218b648bfb86c2ae476954d32",
|
||||
"name": "maksimkurb",
|
||||
// There is no legacy or demo fields
|
||||
},
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
HttpClient = client
|
||||
|
||||
result, err := UsernamesToUuids([]string{"Thinkofdeath", "maksimkurb"})
|
||||
if assert.NoError(err) {
|
||||
assert.Len(result, 2)
|
||||
assert.Equal("4566e69fc90748ee8d71d7ba5aa00d20", result[0].Id)
|
||||
assert.Equal("Thinkofdeath", result[0].Name)
|
||||
assert.False(result[0].IsLegacy)
|
||||
assert.True(result[0].IsDemo)
|
||||
|
||||
assert.Equal("0d252b7218b648bfb86c2ae476954d32", result[1].Id)
|
||||
assert.Equal("maksimkurb", result[1].Name)
|
||||
assert.False(result[1].IsLegacy)
|
||||
assert.False(result[1].IsDemo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsernamesToUuidsTooManyRequests(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://api.mojang.com").
|
||||
Post("/profiles/minecraft").
|
||||
Reply(429).
|
||||
JSON(map[string]interface{}{
|
||||
"error": "TooManyRequestsException",
|
||||
"errorMessage": "The client has sent too many requests within a certain amount of time",
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
HttpClient = client
|
||||
|
||||
result, err := UsernamesToUuids([]string{"Thinkofdeath", "maksimkurb"})
|
||||
assert.Nil(result)
|
||||
assert.IsType(&TooManyRequestsError{}, err)
|
||||
assert.EqualError(err, "Too Many Requests")
|
||||
}
|
||||
|
||||
func TestUuidToTexturesCorrectResponse(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://sessionserver.mojang.com").
|
||||
Get("/session/minecraft/profile/4566e69fc90748ee8d71d7ba5aa00d20").
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"id": "4566e69fc90748ee8d71d7ba5aa00d20",
|
||||
"name": "Thinkofdeath",
|
||||
"properties": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "textures",
|
||||
"value": "eyJ0aW1lc3RhbXAiOjE1NDMxMDczMDExODUsInByb2ZpbGVJZCI6IjQ1NjZlNjlmYzkwNzQ4ZWU4ZDcxZDdiYTVhYTAwZDIwIiwicHJvZmlsZU5hbWUiOiJUaGlua29mZGVhdGgiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRkMWUwOGIwYmI3ZTlmNTkwYWYyNzc1ODEyNWJiZWQxNzc4YWM2Y2VmNzI5YWVkZmNiOTYxM2U5OTExYWU3NSJ9LCJDQVBFIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjBjYzA4ODQwNzAwNDQ3MzIyZDk1M2EwMmI5NjVmMWQ2NWExM2E2MDNiZjY0YjE3YzgwM2MyMTQ0NmZlMTYzNSJ9fX0=",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
HttpClient = client
|
||||
|
||||
result, err := UuidToTextures("4566e69fc90748ee8d71d7ba5aa00d20")
|
||||
if assert.NoError(err) {
|
||||
assert.Equal("4566e69fc90748ee8d71d7ba5aa00d20", result.Id)
|
||||
assert.Equal("Thinkofdeath", result.Name)
|
||||
assert.Equal(1, len(result.Props))
|
||||
assert.Equal("textures", result.Props[0].Name)
|
||||
assert.Equal(476, len(result.Props[0].Value))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUuidToTexturesTooManyRequests(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://sessionserver.mojang.com").
|
||||
Get("/session/minecraft/profile/4566e69fc90748ee8d71d7ba5aa00d20").
|
||||
Reply(429).
|
||||
JSON(map[string]interface{}{
|
||||
"error": "TooManyRequestsException",
|
||||
"errorMessage": "The client has sent too many requests within a certain amount of time",
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
HttpClient = client
|
||||
|
||||
result, err := UuidToTextures("4566e69fc90748ee8d71d7ba5aa00d20")
|
||||
assert.Nil(result)
|
||||
assert.IsType(&TooManyRequestsError{}, err)
|
||||
assert.EqualError(err, "Too Many Requests")
|
||||
}
|
@ -5,21 +5,10 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/elyby/chrly/api/mojang"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type signedTexturesResponse struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Props []property `json:"properties"`
|
||||
}
|
||||
|
||||
type property struct {
|
||||
Name string `json:"name"`
|
||||
Signature string `json:"signature,omitempty"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (cfg *Config) SignedTextures(response http.ResponseWriter, request *http.Request) {
|
||||
cfg.Logger.IncCounter("signed_textures.request", 1)
|
||||
username := parseUsername(mux.Vars(request)["username"])
|
||||
@ -30,23 +19,23 @@ func (cfg *Config) SignedTextures(response http.ResponseWriter, request *http.Re
|
||||
return
|
||||
}
|
||||
|
||||
responseData:= signedTexturesResponse{
|
||||
Id: strings.Replace(rec.Uuid, "-", "", -1),
|
||||
responseData := mojang.SignedTexturesResponse{
|
||||
Id: strings.Replace(rec.Uuid, "-", "", -1),
|
||||
Name: rec.Username,
|
||||
Props: []property{
|
||||
Props: []mojang.Property{
|
||||
{
|
||||
Name: "textures",
|
||||
Name: "textures",
|
||||
Signature: rec.MojangSignature,
|
||||
Value: rec.MojangTextures,
|
||||
Value: rec.MojangTextures,
|
||||
},
|
||||
{
|
||||
Name: "chrly",
|
||||
Name: "chrly",
|
||||
Value: "how do you tame a horse in Minecraft?",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
responseJson,_ := json.Marshal(responseData)
|
||||
responseJson, _ := json.Marshal(responseData)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Write(responseJson)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user