2024-01-10 06:12:10 +05:30
|
|
|
package mojang
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/brunomvsouza/singleflight"
|
|
|
|
)
|
|
|
|
|
|
|
|
var InvalidUsername = errors.New("the username passed doesn't meet Mojang's requirements")
|
|
|
|
|
|
|
|
// https://help.minecraft.net/hc/en-us/articles/4408950195341#h_01GE5JX1Z0CZ833A7S54Y195KV
|
|
|
|
var allowedUsernamesRegex = regexp.MustCompile(`(?i)^[0-9a-z_]{3,16}$`)
|
|
|
|
|
|
|
|
type UuidsProvider interface {
|
|
|
|
GetUuid(username string) (*ProfileInfo, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
type TexturesProvider interface {
|
2024-01-30 13:35:04 +05:30
|
|
|
GetTextures(uuid string) (*ProfileResponse, error)
|
2024-01-10 06:12:10 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
type MojangTexturesProvider struct {
|
|
|
|
UuidsProvider
|
|
|
|
TexturesProvider
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
group singleflight.Group[string, *ProfileResponse]
|
2024-01-10 06:12:10 +05:30
|
|
|
}
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
func (p *MojangTexturesProvider) GetForUsername(username string) (*ProfileResponse, error) {
|
2024-01-10 06:12:10 +05:30
|
|
|
if !allowedUsernamesRegex.MatchString(username) {
|
|
|
|
return nil, InvalidUsername
|
|
|
|
}
|
|
|
|
|
|
|
|
username = strings.ToLower(username)
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
result, err, _ := p.group.Do(username, func() (*ProfileResponse, error) {
|
2024-01-10 06:12:10 +05:30
|
|
|
profile, err := p.UuidsProvider.GetUuid(username)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if profile == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return p.TexturesProvider.GetTextures(profile.Id)
|
|
|
|
})
|
|
|
|
|
|
|
|
return result, err
|
|
|
|
}
|
|
|
|
|
|
|
|
type NilProvider struct {
|
|
|
|
}
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
func (*NilProvider) GetForUsername(username string) (*ProfileResponse, error) {
|
2024-01-10 06:12:10 +05:30
|
|
|
return nil, nil
|
|
|
|
}
|