mirror of
https://github.com/elyby/chrly.git
synced 2024-11-27 01:01:59 +05:30
Проект разбит на более мелкие части
This commit is contained in:
parent
baa1cd3010
commit
6a7cc9ae77
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,5 @@
|
|||||||
# IDEA
|
# IDEA
|
||||||
/.idea
|
/.idea
|
||||||
|
|
||||||
|
# Docker Compose override file
|
||||||
|
docker-compose.override.yml
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
FROM golang:1.7
|
FROM golang:1.7
|
||||||
|
|
||||||
RUN mkdir -p /go/src/app
|
RUN mkdir -p /go/src/elyby/minecraft-skinsystem \
|
||||||
|
&& ln -s /go/src/elyby/minecraft-skinsystem /go/src/app
|
||||||
|
|
||||||
WORKDIR /go/src/app
|
WORKDIR /go/src/app
|
||||||
|
|
||||||
COPY ./src /go/src/app
|
COPY ./minecraft-skinsystem.go /go/src/app/
|
||||||
|
COPY ./lib /go/src/app/lib
|
||||||
|
|
||||||
RUN go-wrapper download
|
RUN go-wrapper download
|
||||||
RUN go-wrapper install
|
RUN go-wrapper install
|
||||||
|
21
lib/routes/Skins.go
Normal file
21
lib/routes/Skins.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"log"
|
||||||
|
"elyby/minecraft-skinsystem/lib/tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSkin(w http.ResponseWriter, r *http.Request) {
|
||||||
|
username := tools.ParseUsername(mux.Vars(r)["username"])
|
||||||
|
log.Println("request skin for username " + username);
|
||||||
|
rec, err := tools.FindRecord(username)
|
||||||
|
if (err != nil) {
|
||||||
|
http.Redirect(w, r, "http://skins.minecraft.net/MinecraftSkins/" + username + ".png", 301)
|
||||||
|
log.Println("Cannot get skin for username " + username)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, rec.Url, 301);
|
||||||
|
}
|
38
lib/routes/Textures.go
Normal file
38
lib/routes/Textures.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"log"
|
||||||
|
"elyby/minecraft-skinsystem/lib/structures"
|
||||||
|
"encoding/json"
|
||||||
|
"elyby/minecraft-skinsystem/lib/tools"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetTextures(w http.ResponseWriter, r *http.Request) {
|
||||||
|
username := tools.ParseUsername(mux.Vars(r)["username"])
|
||||||
|
log.Println("request textures for username " + username)
|
||||||
|
|
||||||
|
rec, err := tools.FindRecord(username)
|
||||||
|
if (err != nil || rec.SkinId == 0) {
|
||||||
|
rec.Url = "http://skins.minecraft.net/MinecraftSkins/" + username + ".png"
|
||||||
|
rec.Hash = string(tools.BuildNonElyTexturesHash(username))
|
||||||
|
}
|
||||||
|
|
||||||
|
textures := structures.TexturesResponse{
|
||||||
|
Skin: &structures.Skin{
|
||||||
|
Url: rec.Url,
|
||||||
|
Hash: rec.Hash,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec.IsSlim) {
|
||||||
|
textures.Skin.Metadata = &structures.SkinMetadata{
|
||||||
|
Model: "slim",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response,_ := json.Marshal(textures)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Write(response)
|
||||||
|
}
|
7
lib/services/services.go
Normal file
7
lib/services/services.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mediocregopher/radix.v2/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Redis *redis.Client
|
7
lib/structures/Skin.go
Normal file
7
lib/structures/Skin.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package structures
|
||||||
|
|
||||||
|
type Skin struct {
|
||||||
|
Url string `json:"url"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
Metadata *SkinMetadata `json:"metadata,omitempty"`
|
||||||
|
}
|
11
lib/structures/SkinItem.go
Normal file
11
lib/structures/SkinItem.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package structures
|
||||||
|
|
||||||
|
type SkinItem struct {
|
||||||
|
UserId int `json:"userId"`
|
||||||
|
Nickname string `json:"nickname"`
|
||||||
|
SkinId int `json:"skinId"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Is1_8 bool `json:"is1_8"`
|
||||||
|
IsSlim bool `json:"isSlim"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
}
|
5
lib/structures/SkinMetadata.go
Normal file
5
lib/structures/SkinMetadata.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package structures
|
||||||
|
|
||||||
|
type SkinMetadata struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
}
|
5
lib/structures/TexturesResponse.go
Normal file
5
lib/structures/TexturesResponse.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package structures
|
||||||
|
|
||||||
|
type TexturesResponse struct {
|
||||||
|
Skin *Skin `json:"SKIN"`
|
||||||
|
}
|
48
lib/tools/tools.go
Normal file
48
lib/tools/tools.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"crypto/md5"
|
||||||
|
"strconv"
|
||||||
|
"encoding/hex"
|
||||||
|
"elyby/minecraft-skinsystem/lib/structures"
|
||||||
|
"elyby/minecraft-skinsystem/lib/services"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseUsername(username string) string {
|
||||||
|
const suffix = ".png"
|
||||||
|
if strings.HasSuffix(username, suffix) {
|
||||||
|
username = strings.TrimSuffix(username, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
return username
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildNonElyTexturesHash(username string) string {
|
||||||
|
n := time.Now()
|
||||||
|
hour := time.Date(n.Year(), n.Month(), n.Day(), n.Hour(), 0, 0, 0, time.UTC).Unix()
|
||||||
|
hasher := md5.New()
|
||||||
|
hasher.Write([]byte("non-ely-" + strconv.FormatInt(hour, 10) + "-" + username))
|
||||||
|
|
||||||
|
return hex.EncodeToString(hasher.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindRecord(username string) (structures.SkinItem, error) {
|
||||||
|
var record structures.SkinItem;
|
||||||
|
result, err := services.Redis.Cmd("GET", BuildKey(username)).Str();
|
||||||
|
if (err == nil) {
|
||||||
|
decodeErr := json.Unmarshal([]byte(result), &record)
|
||||||
|
if (decodeErr != nil) {
|
||||||
|
log.Println("Cannot decode record data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return record, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildKey(username string) string {
|
||||||
|
return "username:" + strings.ToLower(username)
|
||||||
|
}
|
31
minecraft-skinsystem.go
Normal file
31
minecraft-skinsystem.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/mediocregopher/radix.v2/redis"
|
||||||
|
|
||||||
|
"elyby/minecraft-skinsystem/lib/routes"
|
||||||
|
"elyby/minecraft-skinsystem/lib/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
var client, redisErr = redis.Dial("tcp", "redis:6379")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if redisErr != nil {
|
||||||
|
log.Fatal("Redis unavailable")
|
||||||
|
}
|
||||||
|
|
||||||
|
services.Redis = client
|
||||||
|
|
||||||
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
router.HandleFunc("/skins/{username}", routes.GetSkin)
|
||||||
|
router.HandleFunc("/textures/{username}", routes.GetTextures)
|
||||||
|
router.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Hello"))
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Fatal(http.ListenAndServe(":80", router))
|
||||||
|
}
|
133
src/main.go
133
src/main.go
@ -1,133 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/mediocregopher/radix.v2/redis"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
"strconv"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
)
|
|
||||||
|
|
||||||
var client, redisErr = redis.Dial("tcp", "redis:6379")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
if redisErr != nil {
|
|
||||||
log.Fatal("Redis unavailable")
|
|
||||||
}
|
|
||||||
|
|
||||||
router := mux.NewRouter().StrictSlash(true)
|
|
||||||
router.HandleFunc("/skins/{username}", GetSkin)
|
|
||||||
router.HandleFunc("/textures/{username}", GetTextures)
|
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":80", router))
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetSkin(w http.ResponseWriter, r *http.Request) {
|
|
||||||
username := ParseUsername(mux.Vars(r)["username"])
|
|
||||||
log.Println("request skin for username " + username);
|
|
||||||
rec, err := FindRecord(username)
|
|
||||||
if (err != nil) {
|
|
||||||
http.Redirect(w, r, "http://skins.minecraft.net/MinecraftSkins/" + username + ".png", 301)
|
|
||||||
log.Println("Cannot get skin for username " + username)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
http.Redirect(w, r, rec.Url, 301);
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTextures(w http.ResponseWriter, r *http.Request) {
|
|
||||||
username := ParseUsername(mux.Vars(r)["username"])
|
|
||||||
log.Println("request textures for username " + username)
|
|
||||||
|
|
||||||
rec, err := FindRecord(username)
|
|
||||||
if (err != nil || rec.SkinId == 0) {
|
|
||||||
rec.Url = "http://skins.minecraft.net/MinecraftSkins/" + username + ".png"
|
|
||||||
rec.Hash = string(BuildNonElyTexturesHash(username))
|
|
||||||
}
|
|
||||||
|
|
||||||
textures := TexturesResponse{
|
|
||||||
Skin: &Skin{
|
|
||||||
Url: rec.Url,
|
|
||||||
Hash: rec.Hash,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec.IsSlim) {
|
|
||||||
textures.Skin.Metadata = &SkinMetadata{
|
|
||||||
Model: "slim",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response,_ := json.Marshal(textures)
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
// STRUCTURES
|
|
||||||
|
|
||||||
type SkinItem struct {
|
|
||||||
UserId int `json:"userId"`
|
|
||||||
Nickname string `json:"nickname"`
|
|
||||||
SkinId int `json:"skinId"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
Is1_8 bool `json:"is1_8"`
|
|
||||||
IsSlim bool `json:"isSlim"`
|
|
||||||
Hash string `json:"hash"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TexturesResponse struct {
|
|
||||||
Skin *Skin `json:"SKIN"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Skin struct {
|
|
||||||
Url string `json:"url"`
|
|
||||||
Hash string `json:"hash"`
|
|
||||||
Metadata *SkinMetadata `json:"metadata,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SkinMetadata struct {
|
|
||||||
Model string `json:"model"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TOOLS
|
|
||||||
|
|
||||||
func ParseUsername(username string) string {
|
|
||||||
const suffix = ".png"
|
|
||||||
if strings.HasSuffix(username, suffix) {
|
|
||||||
username = strings.TrimSuffix(username, suffix)
|
|
||||||
}
|
|
||||||
|
|
||||||
return username
|
|
||||||
}
|
|
||||||
|
|
||||||
func BuildNonElyTexturesHash(username string) string {
|
|
||||||
n := time.Now()
|
|
||||||
hour := time.Date(n.Year(), n.Month(), n.Day(), n.Hour(), 0, 0, 0, time.UTC).Unix()
|
|
||||||
hasher := md5.New()
|
|
||||||
hasher.Write([]byte("non-ely-" + strconv.FormatInt(hour, 10) + "-" + username))
|
|
||||||
|
|
||||||
return hex.EncodeToString(hasher.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindRecord(username string) (SkinItem, error) {
|
|
||||||
var record SkinItem;
|
|
||||||
result, err := client.Cmd("GET", BuildKey(username)).Str();
|
|
||||||
if (err == nil) {
|
|
||||||
decodeErr := json.Unmarshal([]byte(result), &record)
|
|
||||||
if (decodeErr != nil) {
|
|
||||||
log.Println("Cannot decode record data")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return record, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func BuildKey(username string) string {
|
|
||||||
return "username:" + strings.ToLower(username)
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user