|
|
|
@ -1,49 +1,39 @@
@@ -1,49 +1,39 @@
|
|
|
|
|
package configure |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"encoding/json" |
|
|
|
|
"fmt" |
|
|
|
|
"io/ioutil" |
|
|
|
|
"log" |
|
|
|
|
"math/rand" |
|
|
|
|
"sync" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/go-redis/redis/v7" |
|
|
|
|
"github.com/patrickmn/go-cache" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var RoomKeys = LoadRoomKey(*GetKeyFile()) |
|
|
|
|
var RoomKeys *RoomKeysType |
|
|
|
|
|
|
|
|
|
var roomUpdated = false |
|
|
|
|
|
|
|
|
|
var saveInFile = true |
|
|
|
|
var redisCli *redis.Client |
|
|
|
|
var saveInLocal = true |
|
|
|
|
|
|
|
|
|
type RoomKeysType struct { |
|
|
|
|
redisCli *redis.Client |
|
|
|
|
localCache *cache.Cache |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func Init() { |
|
|
|
|
saveInFile = GetRedisAddr() == nil |
|
|
|
|
|
|
|
|
|
rand.Seed(time.Now().UnixNano()) |
|
|
|
|
if saveInFile { |
|
|
|
|
go func() { |
|
|
|
|
for { |
|
|
|
|
time.Sleep(15 * time.Second) |
|
|
|
|
if roomUpdated { |
|
|
|
|
RoomKeys.Save(*roomKeySaveFile) |
|
|
|
|
roomUpdated = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
saveInLocal = GetRedisAddr() == nil |
|
|
|
|
|
|
|
|
|
return |
|
|
|
|
RoomKeys = &RoomKeysType{ |
|
|
|
|
localCache: cache.New(cache.NoExpiration, 0), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
redisCli = redis.NewClient(&redis.Options{ |
|
|
|
|
RoomKeys.redisCli = redis.NewClient(&redis.Options{ |
|
|
|
|
Addr: *GetRedisAddr(), |
|
|
|
|
Password: *GetRedisPwd(), |
|
|
|
|
DB: 0, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
_, err := redisCli.Ping().Result() |
|
|
|
|
_, err := RoomKeys.redisCli.Ping().Result() |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
@ -51,62 +41,18 @@ func Init() {
@@ -51,62 +41,18 @@ func Init() {
|
|
|
|
|
log.Printf("Redis connected") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type RoomKeysType struct { |
|
|
|
|
mapChanKey sync.Map |
|
|
|
|
mapKeyChan sync.Map |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func LoadRoomKey(f string) *RoomKeysType { |
|
|
|
|
result := &RoomKeysType{ |
|
|
|
|
mapChanKey: sync.Map{}, |
|
|
|
|
mapKeyChan: sync.Map{}, |
|
|
|
|
} |
|
|
|
|
raw := map[string]string{} |
|
|
|
|
content, err := ioutil.ReadFile(f) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Printf("Failed to read file %s for room keys", f) |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
if json.Unmarshal(content, &raw) != nil { |
|
|
|
|
log.Printf("Failed to unmarshal file %s for room keys", f) |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
for room, key := range raw { |
|
|
|
|
result.mapChanKey.Store(room, key) |
|
|
|
|
result.mapKeyChan.Store(key, room) |
|
|
|
|
} |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RoomKeysType) Save(f string) { |
|
|
|
|
raw := map[string]string{} |
|
|
|
|
r.mapChanKey.Range(func(channel, key interface{}) bool { |
|
|
|
|
raw[channel.(string)] = key.(string) |
|
|
|
|
return true |
|
|
|
|
}) |
|
|
|
|
content, err := json.Marshal(raw) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Println("Failed to marshal room keys") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if ioutil.WriteFile(f, content, 0644) != nil { |
|
|
|
|
log.Println("Failed to save room keys") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// set/reset a random key for channel
|
|
|
|
|
func (r *RoomKeysType) SetKey(channel string) (key string, err error) { |
|
|
|
|
if !saveInFile { |
|
|
|
|
if !saveInLocal { |
|
|
|
|
for { |
|
|
|
|
key = randStringRunes(48) |
|
|
|
|
if _, err = redisCli.Get(key).Result(); err == redis.Nil { |
|
|
|
|
err = redisCli.Set(channel, key, 0).Err() |
|
|
|
|
if _, err = r.redisCli.Get(key).Result(); err == redis.Nil { |
|
|
|
|
err = r.redisCli.Set(channel, key, 0).Err() |
|
|
|
|
if err != nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err = redisCli.Set(key, channel, 0).Err() |
|
|
|
|
err = r.redisCli.Set(key, channel, 0).Err() |
|
|
|
|
return |
|
|
|
|
} else if err != nil { |
|
|
|
|
return |
|
|
|
@ -116,9 +62,9 @@ func (r *RoomKeysType) SetKey(channel string) (key string, err error) {
@@ -116,9 +62,9 @@ func (r *RoomKeysType) SetKey(channel string) (key string, err error) {
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
key = randStringRunes(48) |
|
|
|
|
if _, found := r.mapKeyChan.Load(key); !found { |
|
|
|
|
r.mapChanKey.Store(channel, key) |
|
|
|
|
r.mapKeyChan.Store(key, channel) |
|
|
|
|
if _, found := r.localCache.Get(key); !found { |
|
|
|
|
r.localCache.SetDefault(channel, key) |
|
|
|
|
r.localCache.SetDefault(key, channel) |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -127,8 +73,8 @@ func (r *RoomKeysType) SetKey(channel string) (key string, err error) {
@@ -127,8 +73,8 @@ func (r *RoomKeysType) SetKey(channel string) (key string, err error) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) { |
|
|
|
|
if !saveInFile { |
|
|
|
|
if newKey, err = redisCli.Get(channel).Result(); err == redis.Nil { |
|
|
|
|
if !saveInLocal { |
|
|
|
|
if newKey, err = r.redisCli.Get(channel).Result(); err == redis.Nil { |
|
|
|
|
newKey, err = r.SetKey(channel) |
|
|
|
|
log.Printf("[KEY] new channel [%s]: %s", channel, newKey) |
|
|
|
|
return |
|
|
|
@ -139,7 +85,7 @@ func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) {
@@ -139,7 +85,7 @@ func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) {
|
|
|
|
|
|
|
|
|
|
var key interface{} |
|
|
|
|
var found bool |
|
|
|
|
if key, found = r.mapChanKey.Load(channel); found { |
|
|
|
|
if key, found = r.localCache.Get(channel); found { |
|
|
|
|
return key.(string), nil |
|
|
|
|
} |
|
|
|
|
newKey, err = r.SetKey(channel) |
|
|
|
@ -148,11 +94,11 @@ func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) {
@@ -148,11 +94,11 @@ func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RoomKeysType) GetChannel(key string) (channel string, err error) { |
|
|
|
|
if !saveInFile { |
|
|
|
|
return redisCli.Get(key).Result() |
|
|
|
|
if !saveInLocal { |
|
|
|
|
return r.redisCli.Get(key).Result() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
chann, found := r.mapKeyChan.Load(key) |
|
|
|
|
chann, found := r.localCache.Get(key) |
|
|
|
|
if found { |
|
|
|
|
return chann.(string), nil |
|
|
|
|
} else { |
|
|
|
@ -161,28 +107,28 @@ func (r *RoomKeysType) GetChannel(key string) (channel string, err error) {
@@ -161,28 +107,28 @@ func (r *RoomKeysType) GetChannel(key string) (channel string, err error) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RoomKeysType) DeleteChannel(channel string) bool { |
|
|
|
|
if !saveInFile { |
|
|
|
|
return redisCli.Del(channel).Err() != nil |
|
|
|
|
if !saveInLocal { |
|
|
|
|
return r.redisCli.Del(channel).Err() != nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key, ok := r.mapChanKey.Load(channel) |
|
|
|
|
key, ok := r.localCache.Get(channel) |
|
|
|
|
if ok { |
|
|
|
|
r.mapChanKey.Delete(channel) |
|
|
|
|
r.mapKeyChan.Delete(key) |
|
|
|
|
r.localCache.Delete(channel) |
|
|
|
|
r.localCache.Delete(key.(string)) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (r *RoomKeysType) DeleteKey(key string) bool { |
|
|
|
|
if !saveInFile { |
|
|
|
|
return redisCli.Del(key).Err() != nil |
|
|
|
|
if !saveInLocal { |
|
|
|
|
return r.redisCli.Del(key).Err() != nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
channel, ok := r.mapKeyChan.Load(key) |
|
|
|
|
channel, ok := r.localCache.Get(key) |
|
|
|
|
if ok { |
|
|
|
|
r.mapChanKey.Delete(channel) |
|
|
|
|
r.mapKeyChan.Delete(key) |
|
|
|
|
r.localCache.Delete(channel.(string)) |
|
|
|
|
r.localCache.Delete(key) |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
return false |
|
|
|
|