mirror of
				https://github.com/elyby/chrly.git
				synced 2025-05-31 14:11:51 +05:30 
			
		
		
		
	Проект разбит на более мелкие части
This commit is contained in:
		
							
								
								
									
										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)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user