mirror of
https://github.com/elyby/chrly.git
synced 2025-05-31 14:11:51 +05:30
Переработка структуры проекта
This commit is contained in:
39
ui/cape.go
Normal file
39
ui/cape.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"elyby/minecraft-skinsystem/utils"
|
||||
)
|
||||
|
||||
func (s *uiService) Cape(response http.ResponseWriter, request *http.Request) {
|
||||
if mux.Vars(request)["converted"] == "" {
|
||||
s.logger.IncCounter("capes.request", 1)
|
||||
}
|
||||
|
||||
username := utils.ParseUsername(mux.Vars(request)["username"])
|
||||
rec, err := s.capesRepo.FindByUsername(username)
|
||||
if err != nil {
|
||||
http.Redirect(response, request, "http://skins.minecraft.net/MinecraftCloaks/" + username + ".png", 301)
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", "image/png")
|
||||
io.Copy(response, rec.File)
|
||||
}
|
||||
|
||||
func (s *uiService) CapeGET(response http.ResponseWriter, request *http.Request) {
|
||||
s.logger.IncCounter("capes.get_request", 1)
|
||||
username := request.URL.Query().Get("name")
|
||||
if username == "" {
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mux.Vars(request)["username"] = username
|
||||
mux.Vars(request)["converted"] = "1"
|
||||
|
||||
s.Cape(response, request)
|
||||
}
|
28
ui/face.go
Normal file
28
ui/face.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"elyby/minecraft-skinsystem/utils"
|
||||
)
|
||||
|
||||
const defaultHash = "default"
|
||||
|
||||
func (s *uiService) Face(response http.ResponseWriter, request *http.Request) {
|
||||
username := utils.ParseUsername(mux.Vars(request)["username"])
|
||||
rec, err := s.skinsRepo.FindByUsername(username)
|
||||
var hash string
|
||||
if err != nil || rec.SkinId == 0 {
|
||||
hash = defaultHash
|
||||
} else {
|
||||
hash = rec.Hash
|
||||
}
|
||||
|
||||
http.Redirect(response, request, utils.BuildElyUrl(buildFaceUrl(hash)), 301)
|
||||
}
|
||||
|
||||
func buildFaceUrl(hash string) string {
|
||||
return "/minecraft/skin_buffer/faces/" + hash + ".png"
|
||||
}
|
33
ui/minecraft_php.go
Normal file
33
ui/minecraft_php.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Метод-наследие от первой версии системы скинов.
|
||||
// Всё ещё иногда используется
|
||||
// Просто конвертируем данные и отправляем их в основной обработчик
|
||||
func (s *uiService) MinecraftPHP(response http.ResponseWriter, request *http.Request) {
|
||||
username := request.URL.Query().Get("name")
|
||||
required := request.URL.Query().Get("type")
|
||||
if username == "" || required == "" {
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mux.Vars(request)["username"] = username
|
||||
mux.Vars(request)["converted"] = "1"
|
||||
|
||||
switch required {
|
||||
case "skin":
|
||||
s.logger.IncCounter("skins.minecraft-php-request", 1)
|
||||
s.Skin(response, request)
|
||||
case "cloack":
|
||||
s.logger.IncCounter("capes.minecraft-php-request", 1)
|
||||
s.Cape(response, request)
|
||||
default:
|
||||
response.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}
|
18
ui/not_found.go
Normal file
18
ui/not_found.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func NotFound(response http.ResponseWriter, request *http.Request) {
|
||||
json, _ := json.Marshal(map[string]string{
|
||||
"status": "404",
|
||||
"message": "Not Found",
|
||||
"link": "http://docs.ely.by/skin-system.html",
|
||||
})
|
||||
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.WriteHeader(http.StatusNotFound)
|
||||
response.Write(json)
|
||||
}
|
25
ui/service.go
Normal file
25
ui/service.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"elyby/minecraft-skinsystem/model"
|
||||
|
||||
"github.com/mono83/slf/wd"
|
||||
)
|
||||
|
||||
type uiService struct {
|
||||
logger wd.Watchdog
|
||||
skinsRepo model.SkinsRepository
|
||||
capesRepo model.CapesRepository
|
||||
}
|
||||
|
||||
func NewUiService(
|
||||
logger wd.Watchdog,
|
||||
skinsRepo model.SkinsRepository,
|
||||
capesRepo model.CapesRepository,
|
||||
) (*uiService, error) {
|
||||
return &uiService{
|
||||
logger: logger,
|
||||
skinsRepo: skinsRepo,
|
||||
capesRepo: capesRepo,
|
||||
}, nil
|
||||
}
|
55
ui/signed_textures.go
Normal file
55
ui/signed_textures.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"elyby/minecraft-skinsystem/utils"
|
||||
)
|
||||
|
||||
type signedTexturesResponse struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IsEly bool `json:"ely,omitempty"`
|
||||
Props []property `json:"properties"`
|
||||
}
|
||||
|
||||
type property struct {
|
||||
Name string `json:"name"`
|
||||
Signature string `json:"signature,omitempty"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (s *uiService) SignedTextures(response http.ResponseWriter, request *http.Request) {
|
||||
s.logger.IncCounter("signed_textures.request", 1)
|
||||
username := utils.ParseUsername(mux.Vars(request)["username"])
|
||||
|
||||
rec, err := s.skinsRepo.FindByUsername(username)
|
||||
if err != nil || rec.SkinId == 0 || rec.MojangTextures == "" {
|
||||
response.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
responseData:= signedTexturesResponse{
|
||||
Id: strings.Replace(rec.Uuid, "-", "", -1),
|
||||
Name: rec.Username,
|
||||
Props: []property{
|
||||
{
|
||||
Name: "textures",
|
||||
Signature: rec.MojangSignature,
|
||||
Value: rec.MojangTextures,
|
||||
},
|
||||
{
|
||||
Name: "ely",
|
||||
Value: "but why are you asking?",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
responseJson,_ := json.Marshal(responseData)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Write(responseJson)
|
||||
}
|
38
ui/skin.go
Normal file
38
ui/skin.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"elyby/minecraft-skinsystem/utils"
|
||||
)
|
||||
|
||||
func (s *uiService) Skin(response http.ResponseWriter, request *http.Request) {
|
||||
if mux.Vars(request)["converted"] == "" {
|
||||
s.logger.IncCounter("skins.request", 1)
|
||||
}
|
||||
|
||||
username := utils.ParseUsername(mux.Vars(request)["username"])
|
||||
rec, err := s.skinsRepo.FindByUsername(username)
|
||||
if err != nil {
|
||||
http.Redirect(response, request, "http://skins.minecraft.net/MinecraftSkins/" + username + ".png", 301)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(response, request, utils.BuildElyUrl(rec.Url), 301)
|
||||
}
|
||||
|
||||
func (s *uiService) SkinGET(response http.ResponseWriter, request *http.Request) {
|
||||
s.logger.IncCounter("skins.get_request", 1)
|
||||
username := request.URL.Query().Get("name")
|
||||
if username == "" {
|
||||
response.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mux.Vars(request)["username"] = username
|
||||
mux.Vars(request)["converted"] = "1"
|
||||
|
||||
s.Skin(response, request)
|
||||
}
|
92
ui/textures.go
Normal file
92
ui/textures.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"elyby/minecraft-skinsystem/model"
|
||||
"elyby/minecraft-skinsystem/utils"
|
||||
)
|
||||
|
||||
type texturesResponse struct {
|
||||
Skin *Skin `json:"SKIN"`
|
||||
Cape *Cape `json:"CAPE,omitempty"`
|
||||
}
|
||||
|
||||
type Skin struct {
|
||||
Url string `json:"url"`
|
||||
Hash string `json:"hash"`
|
||||
Metadata *skinMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type skinMetadata struct {
|
||||
Model string `json:"model"`
|
||||
}
|
||||
|
||||
type Cape struct {
|
||||
Url string `json:"url"`
|
||||
Hash string `json:"hash"`
|
||||
}
|
||||
|
||||
func (s *uiService) Textures(response http.ResponseWriter, request *http.Request) {
|
||||
s.logger.IncCounter("textures.request", 1)
|
||||
username := utils.ParseUsername(mux.Vars(request)["username"])
|
||||
|
||||
skin, err := s.skinsRepo.FindByUsername(username)
|
||||
if err != nil || skin.SkinId == 0 {
|
||||
skin.Url = "http://skins.minecraft.net/MinecraftSkins/" + username + ".png"
|
||||
skin.Hash = string(utils.BuildNonElyTexturesHash(username))
|
||||
} else {
|
||||
skin.Url = utils.BuildElyUrl(skin.Url)
|
||||
}
|
||||
|
||||
textures := texturesResponse{
|
||||
Skin: &Skin{
|
||||
Url: skin.Url,
|
||||
Hash: skin.Hash,
|
||||
},
|
||||
}
|
||||
|
||||
if skin.IsSlim {
|
||||
textures.Skin.Metadata = &skinMetadata{
|
||||
Model: "slim",
|
||||
}
|
||||
}
|
||||
|
||||
cape, err := s.capesRepo.FindByUsername(username)
|
||||
if err == nil {
|
||||
// capeUrl, err := services.Router.Get("cloaks").URL("username", username)
|
||||
capeUrl := "/capes/" + username
|
||||
if err != nil {
|
||||
s.logger.Error(err.Error())
|
||||
}
|
||||
|
||||
var scheme string = "http://"
|
||||
if request.TLS != nil {
|
||||
scheme = "https://"
|
||||
}
|
||||
|
||||
textures.Cape = &Cape{
|
||||
// Url: scheme + request.Host + capeUrl.String(),
|
||||
Url: scheme + request.Host + capeUrl,
|
||||
Hash: calculateCapeHash(cape),
|
||||
}
|
||||
}
|
||||
|
||||
responseData,_ := json.Marshal(textures)
|
||||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Write(responseData)
|
||||
}
|
||||
|
||||
func calculateCapeHash(cape model.Cape) string {
|
||||
hasher := md5.New()
|
||||
io.Copy(hasher, cape.File)
|
||||
|
||||
return hex.EncodeToString(hasher.Sum(nil))
|
||||
}
|
39
ui/ui.go
Normal file
39
ui/ui.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
|
||||
}
|
||||
|
||||
func Start(cfg Config, s *uiService, lst net.Listener) {
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
router.HandleFunc("/skins/{username}", s.Skin).Methods("GET")
|
||||
router.HandleFunc("/cloaks/{username}", s.Cape).Methods("GET")
|
||||
router.HandleFunc("/textures/{username}", s.Textures).Methods("GET")
|
||||
router.HandleFunc("/textures/signed/{username}", s.SignedTextures).Methods("GET")
|
||||
router.HandleFunc("/skins/{username}/face", s.Face).Methods("GET")
|
||||
router.HandleFunc("/skins/{username}/face.png", s.Face).Methods("GET")
|
||||
// Legacy
|
||||
router.HandleFunc("/minecraft.php", s.MinecraftPHP).Methods("GET")
|
||||
router.HandleFunc("/skins/", s.SkinGET).Methods("GET")
|
||||
router.HandleFunc("/cloaks/", s.CapeGET).Methods("GET")
|
||||
// 404
|
||||
router.NotFoundHandler = http.HandlerFunc(NotFound)
|
||||
|
||||
server := &http.Server{
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1 << 16,
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
go server.Serve(lst)
|
||||
}
|
Reference in New Issue
Block a user