156 lines
3.0 KiB
Go
156 lines
3.0 KiB
Go
package util
|
|
|
|
import (
|
|
"backend/msg"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
crand "crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
"strconv"
|
|
"time"
|
|
|
|
"golang.org/x/net/websocket"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
// 获取结构体名称
|
|
func GetStructName(v interface{}) string {
|
|
t := reflect.TypeOf(v)
|
|
if t.Kind() == reflect.Ptr {
|
|
t = t.Elem()
|
|
}
|
|
if t.Kind() == reflect.Struct {
|
|
return t.Name()
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func PackMsg(m proto.Message) []byte {
|
|
buf, _ := proto.Marshal(m)
|
|
Func := GetStructName(m)
|
|
req := &msg.AdminReq{
|
|
Func: Func,
|
|
Info: buf,
|
|
}
|
|
buf, _ = proto.Marshal(req)
|
|
return append([]byte{0, 2}, buf...)
|
|
}
|
|
|
|
func UnpackMsg(buf []byte, n int) ([]byte, error) {
|
|
res := &msg.AdminRes{}
|
|
err := proto.Unmarshal(buf[2:n], res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return res.Info, nil
|
|
}
|
|
|
|
func ParseUid(uid int) (int, int) {
|
|
AppId := uid / 100000000
|
|
ServerId := uid % 100000000 / 100000
|
|
return AppId, ServerId
|
|
}
|
|
|
|
func Int(a interface{}) int {
|
|
if a == nil {
|
|
return 0
|
|
}
|
|
switch v := a.(type) {
|
|
case int:
|
|
return v
|
|
case int32:
|
|
return int(v)
|
|
case int64:
|
|
return int(v)
|
|
case float64:
|
|
return int(v)
|
|
case string:
|
|
r, err := strconv.Atoi(v)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return r
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func Now() int64 {
|
|
return time.Now().Unix()
|
|
}
|
|
|
|
func SendAdminMsg(ws *websocket.Conn, req proto.Message) (map[string]interface{}, error) {
|
|
reqBuf := PackMsg(req)
|
|
_, err := ws.Write(reqBuf)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to write to websocket: %v", err)
|
|
}
|
|
|
|
readbuf := make([]byte, 4096)
|
|
n, err := ws.Read(readbuf)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read from websocket: %v", err)
|
|
}
|
|
resBuf, _ := UnpackMsg(readbuf, n)
|
|
r := make(map[string]interface{})
|
|
json.Unmarshal(resBuf, &r)
|
|
return r, nil
|
|
}
|
|
|
|
func FloatDecimals(f float64, n int) float64 {
|
|
format := fmt.Sprintf("%%.%df", n)
|
|
r, _ := strconv.ParseFloat(fmt.Sprintf(format, f), 64)
|
|
return r
|
|
}
|
|
|
|
const (
|
|
SECRET_KEY = ")VQbB(vpy=U(wcp)"
|
|
)
|
|
|
|
// 加密字符串
|
|
func Encrypt(plainText string) (string, error) {
|
|
block, err := aes.NewCipher([]byte(SECRET_KEY))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
cipherText := make([]byte, aes.BlockSize+len(plainText))
|
|
iv := cipherText[:aes.BlockSize]
|
|
if _, err := io.ReadFull(crand.Reader, iv); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
stream := cipher.NewCFBEncrypter(block, iv)
|
|
stream.XORKeyStream(cipherText[aes.BlockSize:], []byte(plainText))
|
|
|
|
return base64.URLEncoding.EncodeToString(cipherText), nil
|
|
}
|
|
|
|
// 解密字符串
|
|
func Decrypt(cipherText string) (string, error) {
|
|
cipherTextBytes, err := base64.URLEncoding.DecodeString(cipherText)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
block, err := aes.NewCipher([]byte(SECRET_KEY))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if len(cipherTextBytes) < aes.BlockSize {
|
|
return "", fmt.Errorf("cipherText too short")
|
|
}
|
|
|
|
iv := cipherTextBytes[:aes.BlockSize]
|
|
cipherTextBytes = cipherTextBytes[aes.BlockSize:]
|
|
|
|
stream := cipher.NewCFBDecrypter(block, iv)
|
|
stream.XORKeyStream(cipherTextBytes, cipherTextBytes)
|
|
|
|
return string(cipherTextBytes), nil
|
|
}
|