diff --git a/lib/data/SkinItem.go b/lib/data/SkinItem.go index ee666e1..0aca44f 100644 --- a/lib/data/SkinItem.go +++ b/lib/data/SkinItem.go @@ -11,21 +11,55 @@ import ( ) type SkinItem struct { - UserId int `json:"userId"` - Username string `json:"username"` - SkinId int `json:"skinId"` - Url string `json:"url"` - Is1_8 bool `json:"is1_8"` - IsSlim bool `json:"isSlim"` - Hash string `json:"hash"` + UserId int `json:"userId"` + Username string `json:"username"` + SkinId int `json:"skinId"` + Url string `json:"url"` + Is1_8 bool `json:"is1_8"` + IsSlim bool `json:"isSlim"` + Hash string `json:"hash"` + oldUsername string } +const accountIdToUsernameKey string = "hash:username-to-account-id" + func (s *SkinItem) Save() { str, _ := json.Marshal(s) - services.RedisPool.Cmd("SET", tools.BuildKey(s.Username), str) + pool, _ := services.RedisPool.Get() + pool.Cmd("MULTI") + + // Если пользователь сменил ник, то мы должны удать его ключ + if (s.oldUsername != "" && s.oldUsername != s.Username) { + pool.Cmd("DEL", tools.BuildKey(s.oldUsername)) + } + + // Если это новая запись или если пользователь сменил ник, то обновляем значение в хэш-таблице + if (s.oldUsername != "" || s.oldUsername != s.Username) { + pool.Cmd("HSET", accountIdToUsernameKey, s.UserId, s.Username) + } + + pool.Cmd("SET", tools.BuildKey(s.Username), str) + + pool.Cmd("EXEC") + + s.oldUsername = s.Username } -func FindRecord(username string) (SkinItem, error) { +func (s *SkinItem) Delete() { + if (s.oldUsername == "") { + return; + } + + pool, _ := services.RedisPool.Get() + pool.Cmd("MULTI") + + pool.Cmd("DEL", tools.BuildKey(s.oldUsername)) + pool.Cmd("HDEL", accountIdToUsernameKey, s.UserId) + + pool.Cmd("EXEC") +} + +func FindByUsername(username string) (SkinItem, error) { var record SkinItem; response := services.RedisPool.Cmd("GET", tools.BuildKey(username)); if (response.IsType(redis.Nil)) { @@ -38,7 +72,20 @@ func FindRecord(username string) (SkinItem, error) { if (decodeErr != nil) { log.Println("Cannot decode record data") } + + record.oldUsername = record.Username } return record, err } + +func FindById(id int) (SkinItem, error) { + response := services.RedisPool.Cmd("HGET", accountIdToUsernameKey, id); + if (response.IsType(redis.Nil)) { + return SkinItem{}, DataNotFound{"unknown"} + } + + username, _ := response.Str() + + return FindByUsername(username) +} diff --git a/lib/routes/Skin.go b/lib/routes/Skin.go index 650fd37..baeaeb2 100644 --- a/lib/routes/Skin.go +++ b/lib/routes/Skin.go @@ -13,7 +13,7 @@ import ( func Skin(w http.ResponseWriter, r *http.Request) { username := tools.ParseUsername(mux.Vars(r)["username"]) log.Println("request skin for username " + username); - rec, err := data.FindRecord(username) + rec, err := data.FindByUsername(username) if (err != nil) { http.Redirect(w, r, "http://skins.minecraft.net/MinecraftSkins/" + username + ".png", 301) return diff --git a/lib/routes/Textures.go b/lib/routes/Textures.go index e298922..fa9f573 100644 --- a/lib/routes/Textures.go +++ b/lib/routes/Textures.go @@ -15,7 +15,7 @@ func Textures(w http.ResponseWriter, r *http.Request) { username := tools.ParseUsername(mux.Vars(r)["username"]) log.Println("request textures for username " + username) - rec, err := data.FindRecord(username) + rec, err := data.FindByUsername(username) if (err != nil || rec.SkinId == 0) { rec.Url = "http://skins.minecraft.net/MinecraftSkins/" + username + ".png" rec.Hash = string(tools.BuildNonElyTexturesHash(username))