admin_backend/util/util.go
2025-02-20 18:13:36 +08:00

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
}