Merge branch 'sdk' into online

This commit is contained in:
hahwu 2026-04-29 15:23:35 +08:00
commit 7256f6a93d
80 changed files with 1853 additions and 1033 deletions

3
.gitignore vendored
View File

@ -25,4 +25,7 @@ src/server/test/GeoLite2-Country
src/server/msg/Gameapi_grpc.pb.go
src/server/unit_test/*.exe*
src/server/unit_test/log*
src/server/msg/meowmentnet
src/server/.github/agents/merge2-server-lead.agent.md
src/server/runtime/*
src/server/unit_test/runtime/*

View File

@ -3,6 +3,6 @@ package MergeConst
const (
Go_gc_percent = 200
Go_gc_memory_limit = 1024 << 20
Go_game_version = "1.0.4" // 游戏版本号,格式为 "主版本号.次版本号.修订号",每次发布新版本时需要更新
Go_game_version = "1.0.5" // 游戏版本号,格式为 "主版本号.次版本号.修订号",每次发布新版本时需要更新
Go_log_delete_days = 3 // 日志删除天数,超过这个天数的日志文件将被删除
)

View File

@ -2,6 +2,7 @@ package backend
import (
"context"
"fmt"
"net"
"server/conf"
"server/game"
@ -10,54 +11,133 @@ import (
"gitea.bywaystudios.com/pet_home/leaf/log"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type backendServer struct {
msg.UnimplementedBackendServer
}
func (s *backendServer) ReloadActivity(ctx context.Context, req *msg.ReqActivityCfgReload) (*msg.ResActivityCfgReload, error) {
func unaryRequestLogInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (resp interface{}, err error) {
//log.Debug("gRPC request start: method=%s req=%v", info.FullMethod, req)
resp, err = handler(ctx, req)
if err != nil {
log.Error("gRPC request failed: method=%s err=%v", info.FullMethod, err)
return nil, err
}
//log.Debug("gRPC request finished: method=%s", info.FullMethod)
return resp, nil
}
func unaryPanicRecoveryInterceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (_ interface{}, err error) {
defer func() {
if r := recover(); r != nil {
log.Error("ReloadActivity panic: %v", r)
if recovered := recover(); recovered != nil {
log.Error("gRPC request panic: method=%s panic=%v", info.FullMethod, recovered)
err = status.Error(codes.Internal, fmt.Sprintf("rpc panic: %v", recovered))
}
}()
return handler(ctx, req)
}
func (s *backendServer) ReloadActivity(ctx context.Context, req *msg.ReqActivityCfgReload) (*msg.ResActivityCfgReload, error) {
log.Debug("Received ReloadActivity request: %v", req)
game.AcitivityCfgReload()
return nil, nil
}
func (s *backendServer) OrderShipping(ctx context.Context, req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) {
defer func() {
if r := recover(); r != nil {
log.Error("OrderShipping panic: %v", r)
}
}()
log.Debug("Received OrderShipping request: %v", req)
res, err := game.AdminShipping(req)
if err != nil {
log.Error("OrderShipping error: %v", err)
return nil, err
return &msg.ResOrderShipping{
Code: 1,
Msg: err.Error(),
}, err
}
return res, nil
}
func (s *backendServer) UserDetail(ctx context.Context, req *msg.UserDetailParam) (*msg.ResUserDetail, error) {
defer func() {
if r := recover(); r != nil {
log.Error("UserDetail panic: %v", r)
}
}()
log.Debug("Received UserDetail request: %v", req)
res, err := game.AdminPlayerDetailInfo(req)
if err != nil {
log.Error("UserDetail error: %v", err)
return nil, err
return &msg.ResUserDetail{
Code: 1,
Msg: err.Error(),
}, err
}
return res, nil
}
func (s *backendServer) ServerInfo(ctx context.Context, req *msg.ReqServerInfo) (*msg.ResServerInfo, error) {
//log.Debug("Received ServerInfo request: %v", req)
res, err := game.AdminServerInfo()
if err != nil {
log.Error("ServerInfo error: %v", err)
return &msg.ResServerInfo{}, err
}
return res, nil
}
func (s *backendServer) PlayerGm(ctx context.Context, req *msg.ReqAdminGm) (*msg.ResAdminGm, error) {
log.Debug("Received PlayerGm request: %v", req)
res, err := game.AdminPlayerGm(req)
if err != nil {
log.Error("PlayerGm error: %v", err)
return &msg.ResAdminGm{
Code: 1,
Msg: err.Error(),
}, err
}
return res, nil
}
func (s *backendServer) BanPlayer(ctx context.Context, req *msg.ReqAdminBan) (*msg.ResBackend, error) {
log.Debug("Received BanPlayer request: %v", req)
err := game.AdminBanPlayer(req)
if err != nil {
log.Error("BanPlayer error: %v", err)
return &msg.ResBackend{
Code: 1,
Msg: err.Error(),
}, err
}
return &msg.ResBackend{}, nil
}
func (s *backendServer) ReloadMail(ctx context.Context, req *msg.ReqReloadServerMail) (*msg.ResBackend, error) {
log.Debug("Received ReloadMail request: %v", req)
err := game.AdminReloadMail()
if err != nil {
log.Error("ReloadMail error: %v", err)
return &msg.ResBackend{
Code: 1,
Msg: err.Error(),
}, err
}
return &msg.ResBackend{}, nil
}
func Start() {
defer func() {
if r := recover(); r != nil {
log.Debug("Backend server panic: %v", r)
log.Debug("Backend server closing down\n")
}
}()
if conf.Server.RPCAddr == "" {
log.Debug("RPC server address not configured, skipping gRPC server startup")
return
@ -68,7 +148,10 @@ func Start() {
return
}
s := grpc.NewServer()
s := grpc.NewServer(grpc.ChainUnaryInterceptor(
unaryPanicRecoveryInterceptor,
unaryRequestLogInterceptor,
))
msg.RegisterBackendServer(s, &backendServer{})
log.Debug("gRPC server listening on %s", conf.Server.RPCAddr)

View File

@ -1,64 +1,11 @@
package main
import (
"fmt"
"runtime"
"server/game"
"server/game/mod/msg"
"testing"
)
// func TestBenchInit(t *testing.T) {
// f := "wmz00%d"
// for i := 0; i < 10000; i++ {
// UserName := fmt.Sprintf(f, i)
// game.G_GameLogicPtr.Db_AccountInfo.UserName = UserName
// game.G_GameLogicPtr.Db_AccountInfo.UserPassword = "123456"
// if game.G_GameLogicPtr.NewAccountInsertDataToDB() {
// fmt.Printf("UserName:%s\n init success", UserName)
// }
// }
// }
/*
*
cluster 消息处理基准测试
36716 34961 ns/op 1690 B/op 38 allocs/op
*/
func BenchmarkClusterMsg(b *testing.B) {
game.ClusterMgrInit()
runtime.GOMAXPROCS(8)
game.G_getGameLogic()
for i := 0; i < b.N; i++ {
m := &msg.Msg{
HandleType: msg.HANDLE_MOD_PLAYER_LOGIN,
Extra: 0,
}
game.MessageHandle(m)
}
}
func printMemUsage() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
// 输出内存使用情况
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
var playerCount int
game.G_GameLogicPtr.M_Players.Range(func(key, value interface{}) bool {
playerCount++
return true
})
fmt.Printf("\tPlayerNum = %v\n", playerCount)
}
func bToMb(b uint64) uint64 {
return b / 1024 / 1024
}
func BenchmarkChampionshipGroup(b *testing.B) {
for i := 0; i < b.N; i++ {
game.G_GameLogicPtr.CreateChampshipMgr()

View File

@ -91,18 +91,18 @@ func (a *Agent) Run() {
for {
data, err := a.conn.ReadMsg()
if err != nil {
log.Debug("read message error: %v", err)
log.Error("read message error: %v", err)
break
}
m := msg.Msg{}
err = GoUtil.GobUnmarshal(data, &m)
if err != nil {
log.Debug("decode err: %v, data: %s", err, string(data))
log.Error("decode err: %v, data: %s", err, string(data))
return
}
err = processMsg(a, &m)
if err != nil {
log.Debug("ProcessMsg err: %v", err)
log.Error("ProcessMsg err: %v", err)
}
}
}

View File

@ -26,7 +26,7 @@ func HandShake(a *Agent) {
}
data, err := GoUtil.GobMarshal(m)
if err != nil {
log.Debug("HandShake GobMarshal err %v", err)
log.Error("HandShake GobMarshal err %v", err)
return
}
log.Debug("握手 server id :%d", conf.Server.ServerID)
@ -120,7 +120,7 @@ func SendServerMsg(m *msg.Msg, serverId int) error {
if v, ok := serverAgent.Load(serverId); ok {
data, err := GoUtil.GobMarshal(m)
if err != nil {
log.Debug("SendServerMsg GobMarshal err %v", err)
log.Error("SendServerMsg GobMarshal err %v", err)
return err
}
v.(network.Agent).WriteMsg(data)
@ -147,7 +147,7 @@ func CallServerMsg(m *msg.Msg, serverId int) (*msg.Msg, error) {
defer unregisterChanel(m.UniKey)
data, err := GoUtil.GobMarshal(m)
if err != nil {
log.Debug("CallServerMsg GobMarshal err %v", err)
log.Error("CallServerMsg GobMarshal err %v", err)
return nil, err
}
v.(network.Agent).WriteMsg(data)
@ -168,7 +168,7 @@ func CallServerMsg(m *msg.Msg, serverId int) (*msg.Msg, error) {
func SendMsgAll(m *msg.Msg) {
data, err := GoUtil.GobMarshal(m)
if err != nil {
log.Debug("SendMsgAll GobMarshal err %v", err)
log.Error("SendMsgAll GobMarshal err %v", err)
return
}
serverAgent.Range(func(key, value interface{}) bool {

View File

@ -33,7 +33,6 @@ func GetTaskRewardById(Id int) []*item.Item {
func GetTaskById(Id int) string {
data, err := gamedata.GetDataByIntKey(GUIDE_TASK_TASK, Id)
if err != nil {
log.Debug("GetTaskById err:%v, Id=%d", err, Id)
return ""
}
return gamedata.GetStringValue(data, "Task")

View File

@ -3,7 +3,7 @@ package itemCfg
import (
languageCfg "server/conf/language"
"server/gamedata"
"server/msg"
"server/msg/meowmentnet"
"strconv"
"strings"
@ -61,5 +61,5 @@ func GetItemName(Id int) (string, string) {
return "", ""
}
name := gamedata.GetStringValue(data, "Name")
return languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, name), languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, name)
return languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, name), languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, name)
}

View File

@ -2,7 +2,7 @@ package languageCfg
import (
"server/gamedata"
"server/msg"
msg "server/msg/meowmentnet"
)
const (
@ -31,13 +31,13 @@ func _GetClientLanguage(lang msg.LANG_TYPE, key string) string {
return key
}
switch lang {
case msg.LANG_TYPE_LANG_EN:
case msg.LANG_TYPE_LangEn:
return gamedata.GetStringValue(data, "en_US")
case msg.LANG_TYPE_LANG_PTBR:
case msg.LANG_TYPE_LangPtbr:
return gamedata.GetStringValue(data, "pt_BR")
case msg.LANG_TYPE_LANG_CN:
case msg.LANG_TYPE_LangCn:
return gamedata.GetStringValue(data, "zh_CN")
case msg.LANG_TYPE_LANG_ES_LATAM:
case msg.LANG_TYPE_LangEsLatam:
return gamedata.GetStringValue(data, "es_LATAM")
default:
return key
@ -50,13 +50,13 @@ func _GetBackendLanguage(lang msg.LANG_TYPE, key string) string {
return key
}
switch lang {
case msg.LANG_TYPE_LANG_EN:
case msg.LANG_TYPE_LangEn:
return gamedata.GetStringValue(data, "en_US")
case msg.LANG_TYPE_LANG_PTBR:
case msg.LANG_TYPE_LangPtbr:
return gamedata.GetStringValue(data, "pt_BR")
case msg.LANG_TYPE_LANG_CN:
case msg.LANG_TYPE_LangCn:
return gamedata.GetStringValue(data, "zh_CN")
case msg.LANG_TYPE_LANG_ES_LATAM:
case msg.LANG_TYPE_LangEsLatam:
return gamedata.GetStringValue(data, "es_LATAM")
default:
return key

View File

@ -6,7 +6,7 @@ import (
"server/game/mod/item"
GoUtil "server/game_util"
"server/gamedata"
"server/msg"
"server/msg/meowmentnet"
"strings"
)
@ -80,10 +80,10 @@ func GetRecallMail(Title, ItemName, TitleEn, ItemNameEn string) (string, string,
if err != nil {
return "", "", "", ""
}
mt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Content"))
mt := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Content"))
return fmt.Sprintf(mt, Title), fmt.Sprintf(mc, Title, ItemName), fmt.Sprintf(mt_en, TitleEn), fmt.Sprintf(mc_en, Title, ItemNameEn)
}
@ -92,10 +92,10 @@ func GetChargeSendMail(PlayerName string) (string, string, string, string) {
if err != nil {
return "", "", "", ""
}
mt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Content"))
mt := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Content"))
return mt, fmt.Sprintf(mc, PlayerName), mt_en, fmt.Sprintf(mc_en, PlayerName)
}
@ -104,9 +104,9 @@ func GetChargeReceiveMail(PlayerName string, Content string) (string, string, st
if err != nil {
return "", "", "", ""
}
mt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, gamedata.GetStringValue(data, "Content"))
mt := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Title"))
mc := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangCn, gamedata.GetStringValue(data, "Content"))
mt_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Title"))
mc_en := languageCfg.GetLanguage(meowmentnet.LANG_TYPE_LangEn, gamedata.GetStringValue(data, "Content"))
return fmt.Sprintf(mt, PlayerName), fmt.Sprintf(mc, Content), fmt.Sprintf(mt_en, PlayerName), fmt.Sprintf(mc_en, Content)
}

View File

@ -232,7 +232,7 @@ func GetSellNumById(Id int) int {
func GetEmitProduceType(Id int) []string {
data, err := gamedata.GetDataByIntKey(CFG_NAME, Id)
if err != nil {
log.Debug("GetEmitProduceType GetOne Id:%v not found", Id)
//log.Debug("GetEmitProduceType GetOne Id:%v not found", Id)
return []string{}
}

View File

@ -5,7 +5,7 @@
"TCPAddr": ":3601",
"WSAddr": ":3567",
"RPCAddr": ":50051",
"MySqlAddr": "127.0.0.1",
"MySqlAddr": "mysql",
"MySqlPort": "3306",
"MySqlUsr": "root",
"MySqlPwd": "IOagNEq3C84c-20CmHEin5iODVc=",
@ -24,7 +24,7 @@
"ServerName": "Merge_Pet",
"ServerStatus" : 1,
"ServerCenter" : 0,
"GameConfPath": "D:/Github/pet_home_server/src/server/gamedata/config/",
"GameConfPath": "/data/pet_home_server/src/server/gamedata/config/",
"ListenAddr":":9002",
"CenterAddr": "127.0.0.1:7000",
@ -34,8 +34,8 @@
"RedisPort" :"6379",
"RedisPwd" :"",
"RedisWriteAddr":"127.0.0.1:6379",
"RedisReadAddrs":"127.0.0.1:6379",
"RedisWriteAddr":"redis:6379",
"RedisReadAddrs":"redis:6379",
"RedisMasterName":"mymaster",
"RedisConnType":"Direct",

View File

@ -398,20 +398,8 @@ func InsertPlayerModData(data *SqlModStruct) error {
return err
}
func SavePlayerClientData(data *SqlModStruct) error {
sql := "INSERT INTO `t_player_client_data` (`mData` , `updateTime` ,`dwUin`) Values (?,?,?) ON DUPLICATE KEY UPDATE `mData` = ? , `updateTime` = ? "
_, err := SqlDb.Exec(sql, data.ModData, data.UpdataTime, data.DwUin, data.ModData, data.UpdataTime)
return err
}
func GetPlayerClientData(d interface{}, Key string) (err error) {
sql := "select * from t_server_mod where `dwUin` = ?"
err = SqlDb.Get(d, sql, Key)
return
}
func GetServerMailData(data *[]*SqlServerMailStruct) error {
sql := "select `mail_id`, `title`, `content`, `subTitle`, `subTitle_en`, `title_en`, `content_en`, `title_ptbr`, `subTitle_ptbr`, `content_ptbr`, `title_es_latam`, `subTitle_es_latam`, `content_es_latam`, `items`, `start_time`, `register_time`, `end_time`, `mail_type`, `send_type`, `to_uids`, `create_time` from system_mail_info"
sql := "select `mail_id`, `title`, `content`, `subTitle`, `subTitle_en`, `title_en`, `content_en`, `title_ptbr`, `subTitle_ptbr`, `content_ptbr`, `title_es_latam`, `subTitle_es_latam`, `content_es_latam`, `items`, `start_time`, `register_time`, `end_time`, `mail_type`, `send_type`, `to_uids`, `create_time`, `level` from system_mail_info"
err := SqlDb.Select(data, sql)
return err
}

View File

@ -2,6 +2,7 @@ package db
import (
"context"
"fmt"
"server/conf"
"strings"
"time"
@ -331,3 +332,41 @@ func RedisIncrBy(key string, increment int64) (int64, error) {
}
return val, nil
}
func RedisLPush(key string, values ...interface{}) error {
if RdbWrite == nil {
return fmt.Errorf("redis write client is nil")
}
const maxListSize int64 = 10000
pipe := RdbWrite.TxPipeline()
pipe.LPush(ctx, key, values...)
pipe.LTrim(ctx, key, 0, maxListSize-1)
_, err := pipe.Exec(ctx)
if err != nil {
log.Debug("redis lpush failed, err:%v\n", err)
return err
}
return nil
}
func RedisLRange(key string, start, stop int64) ([]string, error) {
if RdbRead == nil {
return nil, nil
}
val, err := RdbRead.LRange(ctx, key, start, stop).Result()
if err != nil {
return nil, err
}
return val, nil
}
func RedisLLen(key string) (int64, error) {
if RdbRead == nil {
return 0, nil
}
val, err := RdbRead.LLen(ctx, key).Result()
if err != nil {
return 0, err
}
return val, nil
}

View File

@ -495,6 +495,7 @@ type SqlServerMailStruct struct {
Send_type int `db:"send_type"`
To_uids string `db:"to_uids"`
CreateTime int64 `db:"create_time"`
Level int `db:"level"`
}
type SqlActivityCfgStruct struct {

View File

@ -19,13 +19,12 @@ import (
"server/game/internal"
MsgMod "server/game/mod/msg"
"server/msg"
msg "server/msg/meowmentnet"
"time"
"github.com/apache/thrift/lib/go/thrift"
"github.com/robfig/cron/v3"
"google.golang.org/protobuf/proto"
"gitea.bywaystudios.com/pet_home/leaf/gate"
"gitea.bywaystudios.com/pet_home/leaf/timer"
@ -38,7 +37,7 @@ var (
var isInitGameLogic = false
var RegisterNetWorkFunc = make(map[string]interface{})
var NewRegisterNetWorkFunc = make(map[string]func(*Player, *proto.Message) error)
var NewRegisterNetWorkFunc = make(map[string]func(*Player, *thrift.TStruct) error)
const (
SERVER_STATUS_OPEN = 1 // 服务器状态 开放
@ -59,8 +58,8 @@ func RegisterNewMsgProcessFunc(key string, value interface{}) {
NewRegisterNetWorkFunc[key] = handler
}
func buildNewMsgHandlerAdapter(value interface{}) (func(*Player, *proto.Message) error, error) {
if fn, ok := value.(func(*Player, *proto.Message) error); ok {
func buildNewMsgHandlerAdapter(value interface{}) (func(*Player, *thrift.TStruct) error, error) {
if fn, ok := value.(func(*Player, *thrift.TStruct) error); ok {
return fn, nil
}
@ -84,10 +83,10 @@ func buildNewMsgHandlerAdapter(value interface{}) (func(*Player, *proto.Message)
return nil, fmt.Errorf("return type must be error")
}
msgIfaceType := reflect.TypeOf((*proto.Message)(nil)).Elem()
msgIfaceType := reflect.TypeOf((*thrift.TStruct)(nil)).Elem()
msgArgType := rt.In(1)
if msgArgType == reflect.TypeOf((*proto.Message)(nil)) {
return func(player *Player, msg *proto.Message) error {
if msgArgType == reflect.TypeOf((*thrift.TStruct)(nil)) {
return func(player *Player, msg *thrift.TStruct) error {
results := rv.Call([]reflect.Value{reflect.ValueOf(player), reflect.ValueOf(msg)})
if results[0].IsNil() {
return nil
@ -96,12 +95,15 @@ func buildNewMsgHandlerAdapter(value interface{}) (func(*Player, *proto.Message)
}, nil
}
if msgArgType.Kind() != reflect.Ptr || !msgArgType.Implements(msgIfaceType) {
return nil, fmt.Errorf("second arg must be *proto.Message or pointer type implementing proto.Message")
return nil, fmt.Errorf("second arg must be *thrift.TStruct or pointer type implementing thrift.TStruct")
}
return func(player *Player, msg *proto.Message) error {
// 注册具体的 thrift 消息类型到全局缓存
registerThriftType(msgArgType)
return func(player *Player, msg *thrift.TStruct) error {
if msg == nil || *msg == nil {
return fmt.Errorf("nil proto message")
return fmt.Errorf("nil thrift message")
}
raw := *msg
@ -118,7 +120,7 @@ func buildNewMsgHandlerAdapter(value interface{}) (func(*Player, *proto.Message)
}, nil
}
func RunNewNetProcessByKey(key string, player *Player, msg *proto.Message) error {
func RunNewNetProcessByKey(key string, player *Player, msg *thrift.TStruct) error {
fun, ok := NewRegisterNetWorkFunc[key]
if ok {
err := fun(player, msg)
@ -164,6 +166,7 @@ type GameLogic struct {
StartTime int64 // 服务器启动时间
MessageMgr *MessageMgr // 消息管理器
ActivityMgr *ActivityMgr // 活动管理器
ConfigMgr *ConfigMgr // 配置管理器
}
type ServerInfo struct {
@ -291,6 +294,8 @@ func (ad *GameLogic) NewAccountInsertDataToDB() bool {
db.FormatAllMemInsertDb(playerMod, tableName)
// 创建玩家日志
player := new(Player)
player.M_DwUin = int64(insertId)
player.GetBaseMod().Account = ad.Db_AccountInfo.UserName
BaseMod := player.PlayMod.getBaseMod()
BaseMod.Account = ad.Db_AccountInfo.UserName
BaseMod.RegisterTime = time.Now().Unix()
@ -300,8 +305,8 @@ func (ad *GameLogic) NewAccountInsertDataToDB() bool {
}
func (ad *GameLogic) PackLoginResInfo(a gate.Agent, ResLogin *msg.ResLogin) {
resBuff, _ := proto.Marshal(ResLogin)
ad.PackResInfo(a, "ResLogin", resBuff)
data := GoUtil.Marshal(ResLogin)
ad.PackResInfo(a, "ResLogin", data)
}
func (ad *GameLogic) PackResInfo(a gate.Agent, Func string, data []byte) {
@ -322,7 +327,7 @@ func (ad *GameLogic) CreateNewPlayer(a gate.Agent, UserName string) *Player {
player.agent = a
err := player.InitPlayer(UserName)
if err != nil {
data, _ := proto.Marshal(&msg.ResLogin{ResultCode: MergeConst.Protocol_Error_Account_Fail})
data := GoUtil.Marshal(&msg.ResLogin{ResultCode: MergeConst.Protocol_Error_Account_Fail})
G_GameLogicPtr.PackResInfo(a, "ResLogin", data)
panic(err)
}
@ -380,6 +385,12 @@ func (ad *GameLogic) CreateActivityMgr() {
ad.ActivityMgr.Init()
}
// 配置管理器
func (ad *GameLogic) CreateConfigMgr() {
ad.ConfigMgr = &ConfigMgr{}
ad.ConfigMgr.Init()
}
func (ad *GameLogic) CreateMessageMgr() {
ad.MessageMgr = &MessageMgr{
ServerMod: new(ServerMod),
@ -562,6 +573,7 @@ func G_getGameLogic() *GameLogic {
G_GameLogicPtr.RegisterNetWorkFunc() // 注册客户端接口
G_GameLogicPtr.InitActivity() // 初始化活动
G_GameLogicPtr.CreateActivityMgr() //创建活动管理器
G_GameLogicPtr.CreateConfigMgr() // 创建配置管理器
if conf.Server.ServerType == "center" {
// G_GameLogicPtr.CreateFriendMgr() //创建好友管理器
G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器
@ -593,7 +605,7 @@ func (ad *GameLogic) InitServerInfo() {
func (ad *GameLogic) SendServerVersion(a gate.Agent) {
res := &msg.ResServerVersion{}
res.Version = G_GameLogicPtr.Version
data, _ := proto.Marshal(res)
data := GoUtil.Marshal(res)
G_getGameLogic().PackResInfo(a, "ResServerVersion", data)
}
@ -640,7 +652,7 @@ func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) er
}
agent := player.GetAgentByPlayer()
notify := &msg.ForceKickOut{}
data, _ := proto.Marshal(notify)
data := GoUtil.Marshal(notify)
if agent != nil && a != agent {
G_getGameLogic().PackResInfo(agent, "ForceKickOut", data)
internal.AsignPlayerToAgents(agent, ad.NotInitPlayer)

View File

@ -15,7 +15,7 @@ import (
"server/game/mod/item"
"server/game/mod/mail"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"
@ -65,14 +65,14 @@ func (p *Player) ActivityLogin() {
// 清空猫草大作战数据无需发邮件
MailMod := p.PlayMod.getMailMod()
MailMod.SendMail(&mail.MailStruct{
Title: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, "backend_gardenend_mail_title"),
TitleEn: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, "backend_gardenend_mail_title"),
Content: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, "backend_gardenend_mail_content"),
ContentEn: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, "backend_gardenend_mail_content"),
TitlePtBr: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, "backend_gardenend_mail_title"),
ContentPtBr: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, "backend_gardenend_mail_content"),
TitleEsLatam: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, "backend_gardenend_mail_title"),
ContentEsLatam: languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, "backend_gardenend_mail_content"),
Title: languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, "backend_gardenend_mail_title"),
TitleEn: languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, "backend_gardenend_mail_title"),
Content: languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, "backend_gardenend_mail_content"),
ContentEn: languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, "backend_gardenend_mail_content"),
TitlePtBr: languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, "backend_gardenend_mail_title"),
ContentPtBr: languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, "backend_gardenend_mail_content"),
TitleEsLatam: languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, "backend_gardenend_mail_title"),
ContentEsLatam: languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, "backend_gardenend_mail_content"),
Items: catnipUnReward,
Type: mail.MAIL_TYPE_NORMAL,
})
@ -110,18 +110,18 @@ func (p *Player) ActivityLogin() {
func (p *Player) SendActivityMail(ItemId, ItemNum, ActivityId int, RewardItems []*item.Item) {
MailMod := p.PlayMod.getMailMod()
activity_title_key, mail_title_key, mail_content_key := activityCfg.GetActivityRecycleMail(ActivityId)
activity_title_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, activity_title_key)
activity_title_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, activity_title_key)
activity_title_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, activity_title_key)
activity_title_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, activity_title_key)
mt_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_title_key)
mc_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_content_key)
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_title_key)
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_content_key)
mt_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_title_key)
mc_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_content_key)
mt_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_title_key)
mc_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_content_key)
activity_title_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, activity_title_key)
activity_title_en := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, activity_title_key)
activity_title_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, activity_title_key)
activity_title_es := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, activity_title_key)
mt_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, mail_title_key)
mc_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, mail_content_key)
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, mail_title_key)
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, mail_content_key)
mt_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, mail_title_key)
mc_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, mail_content_key)
mt_es := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, mail_title_key)
mc_es := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, mail_content_key)
Items := []*item.Item{item.NewItem(ItemId, ItemNum)}
Items = append(Items, RewardItems...)
MailMod.SendMail(&mail.MailStruct{
@ -141,14 +141,14 @@ func (p *Player) SendActivityMail(ItemId, ItemNum, ActivityId int, RewardItems [
// 发送活动邮件
func (p *Player) SendActivityMail2(items []*item.Item, mail_title, mail_content string) {
MailMod := p.PlayMod.getMailMod()
mt_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_title)
mc_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, mail_content)
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_title)
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, mail_content)
mt_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_title)
mc_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, mail_content)
mt_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_title)
mc_es := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, mail_content)
mt_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, mail_title)
mc_zh := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, mail_content)
mt_en := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, mail_title)
mc_en := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, mail_content)
mt_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, mail_title)
mc_pt := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, mail_content)
mt_es := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, mail_title)
mc_es := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, mail_content)
MailMod.SendMail(&mail.MailStruct{
Title: mt_zh,
Content: mc_zh,

View File

@ -1,18 +1,17 @@
package game
import (
"encoding/json"
"fmt"
"server/db"
"server/game/mod/activity"
"server/game/mod/msg"
Msg "server/game/mod/msg"
GoUtil "server/game_util"
protoMsg "server/msg"
protoMsg "server/msg/meowmentnet"
"sync"
"gitea.bywaystudios.com/pet_home/leaf/log"
"google.golang.org/protobuf/encoding/protojson"
)
type ActivityMgr struct {
@ -206,21 +205,21 @@ func unmarshalActivityCfg(atype int, buf []byte) (interface{}, error) {
switch atype {
case 1:
cfg := &protoMsg.MiningCfg{}
err := protojson.Unmarshal(buf, cfg)
err := json.Unmarshal(buf, cfg)
if err != nil {
return nil, err
}
return cfg, nil
case 9:
cfg := &protoMsg.ChampionshipCfg{}
err := protojson.Unmarshal(buf, cfg)
err := json.Unmarshal(buf, cfg)
if err != nil {
return nil, err
}
return cfg, nil
case 10:
cfg := &protoMsg.CatReturnGiftCfg{}
err := protojson.Unmarshal(buf, cfg)
err := json.Unmarshal(buf, cfg)
if err != nil {
return nil, err
}

View File

@ -5,12 +5,12 @@ import (
"fmt"
"runtime"
"server/MergeConst"
"server/conf"
"server/db"
Msg "server/game/mod/msg"
GoUtil "server/game_util"
"server/gamedata"
"server/msg"
"server/msg/meowmentnet"
"time"
"gitea.bywaystudios.com/pet_home/leaf/gate"
@ -49,18 +49,18 @@ func AdminProcess(funcName string, args []interface{}) {
log.Debug("AdminProcess error: %v", "Func not found")
}
func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg.ResLogin, accountInfoOut *db.Db_Account) {
if detail.Type == msg.LOGIN_TYPE_CODE_LOGIN {
func VerifyUser(accountInfo *db.Db_Account, detail *meowmentnet.ReqLogin) (ResLogin *meowmentnet.ResLogin, accountInfoOut *db.Db_Account) {
if detail.Type == meowmentnet.LOGIN_TYPE(meowmentnet.LOGIN_TYPE_CodeLogin) {
err := VerifyCode(detail.UserName, detail.Code)
if err != nil {
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_Code_Error,
DwUin: 0,
}
return
}
}
if detail.Type == msg.LOGIN_TYPE_SDK_LOGIN {
if detail.Type == meowmentnet.LOGIN_TYPE(meowmentnet.LOGIN_TYPE_SdkLogin) {
if accountInfo == nil {
accountInfo = db.GetAccountInfoFromDb(detail.Device)
}
@ -71,22 +71,22 @@ func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg
}
}
if accountInfo == nil {
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_NoExsit,
DwUin: 0,
}
return
}
if detail.Type == msg.LOGIN_TYPE_ACCOUNT_LOGIN && accountInfo.UserPassword != detail.UserPwd {
ResLogin = &msg.ResLogin{
if detail.Type == meowmentnet.LOGIN_TYPE(meowmentnet.LOGIN_TYPE_AccountLogin) && accountInfo.UserPassword != detail.UserPwd {
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_OR_PWD_ERROR,
DwUin: 0,
}
return
}
if detail.Type == msg.LOGIN_TYPE_DEVICE_LOGIN {
if detail.Type == meowmentnet.LOGIN_TYPE(meowmentnet.LOGIN_TYPE_DeviceLogin) {
if detail.Device != accountInfo.DeviceId {
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_Device_Error,
DwUin: 0,
}
@ -96,7 +96,7 @@ func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg
playerbaseinfo := db.GetPlayerBaseInfoFromDbByName(detail.UserName)
if playerbaseinfo == nil {
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_NoExsit,
DwUin: 0,
}
@ -104,14 +104,14 @@ func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg
}
if playerbaseinfo.Ban > GoUtil.Now() || playerbaseinfo.Ban == -1 {
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: MergeConst.Protocol_Error_Account_Ban,
DwUin: 0,
}
return
}
accountInfoOut = accountInfo
ResLogin = &msg.ResLogin{
ResLogin = &meowmentnet.ResLogin{
ResultCode: 0,
DwUin: playerbaseinfo.DwUin,
FaceBookId: playerbaseinfo.FaceBookId,
@ -137,7 +137,7 @@ func ReqAdminShipping(args []interface{}) error {
}
player := G_GameLogicPtr.GetPlayer(int64(orderInfo.Uid))
if player != nil {
go player.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{
go player.TriggerShippingOrderOrigin(&meowmentnet.ReqShippingOrder{
OrderSn: req.OrderSn,
})
res["Msg"] = "player online,triggered sync"
@ -265,11 +265,37 @@ func ReqServerInfo(args []interface{}) error {
res["UsageMem"] = 0
res["FreeMem"] = 0
}
res["Version"] = conf.Server.Version
res["Version"] = MergeConst.Go_game_version
AdminPlayerBack(a, res)
return nil
}
func AdminServerInfo() (*msg.ResServerInfo, error) {
res := &msg.ResServerInfo{}
res.PlayerNum = int32(G_GameLogicPtr.GetPlayerNum())
res.StartTime = int32(G_GameLogicPtr.GetStartTime())
var m runtime.MemStats
runtime.ReadMemStats(&m)
res.TotalAlloc = fmt.Sprintf("%dM", m.TotalAlloc/(1024*1024))
// 2. 获取系统内存使用信息
vmStat, _ := mem.VirtualMemory()
// 3. 获取 CPU 使用率(一秒内采样)
cpuPercent, err := cpu.Percent(time.Second, false)
if err == nil && len(cpuPercent) > 0 {
res.CPU = cpuPercent[0]
}
res.Alloc = fmt.Sprintf("%dM", m.Alloc/(1024*1024))
res.Sys = m.Sys / (1024 * 1024)
res.NumGC = m.NumGC
res.NumGoroutine = int32(runtime.NumGoroutine())
if vmStat != nil {
res.FreeMem = vmStat.Available / (1024 * 1024)
res.UsageMem = vmStat.Used / (1024 * 1024)
}
res.Version = MergeConst.Go_game_version
return res, nil
}
func ReqReloadServerMail(args []interface{}) error {
G_GameLogicPtr.MailMgrCall(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL_RELOAD})
G_GameLogicPtr.NotifyAll(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL})
@ -313,6 +339,25 @@ func ReqAdminGm(args []interface{}) error {
return nil
}
func AdminPlayerGm(req *msg.ReqAdminGm) (*msg.ResAdminGm, error) {
res := &msg.ResAdminGm{Code: 0, Msg: "ok"}
player := G_GameLogicPtr.GetPlayer(req.Uid)
if player == nil {
res.Code = 1
res.Msg = "player not found"
return res, nil
}
player.lock.Lock()
defer player.lock.Unlock()
if err := ReqGmCommand_(player, req.Command); err != nil {
res.Code = 1
res.Msg = err.Error()
return res, err
}
return res, nil
}
func ReqAdminBan(args []interface{}) error {
a, buf := ParseAdminArgs(args)
req := &msg.ReqAdminBan{}
@ -325,6 +370,17 @@ func ReqAdminBan(args []interface{}) error {
return nil
}
func AdminBanPlayer(req *msg.ReqAdminBan) error {
return db.UpdatePlayerBan(req.Uid, int64(req.Time))
}
func AdminReloadMail() error {
G_GameLogicPtr.MailMgrCall(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL_RELOAD})
G_GameLogicPtr.NotifyAll(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL})
log.Debug("AdminReloadMail success")
return nil
}
func AcitivityCfgReload() {
if G_GameLogicPtr.ActivityMgr != nil {
G_GameLogicPtr.ActivityMgr.Reload()
@ -348,7 +404,7 @@ func AdminShipping(req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) {
// 玩家在线,通知发货
player := G_GameLogicPtr.GetPlayer(int64(orderInfo.Uid))
if player != nil {
go player.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{
go player.TriggerShippingOrderOrigin(&meowmentnet.ReqShippingOrder{
OrderSn: req.OrderSn,
})
res.Msg = "player online,triggered sync"

View File

@ -1,6 +1,7 @@
package game
import (
"encoding/gob"
"fmt"
"maps"
"math"
@ -14,7 +15,7 @@ import (
"server/game/mod/friend"
"server/game/mod/msg"
GoUtil "server/game_util"
proto "server/msg"
proto "server/msg/meowmentnet"
"sort"
"sync"
"time"
@ -90,6 +91,12 @@ type CRank struct {
H int
}
func init() {
gob.Register(&proto.ResChampshipPreRank{})
gob.Register(&proto.ResChampshipRank{})
gob.Register([]interface{}{})
}
func (c *ChampshipMgr) Init() {
dispterTimer = make(map[string]*timer.Timer, 0)
c.key = CHAMPSHIP_MGR_KEY
@ -383,7 +390,7 @@ func (c *ChampshipMgr) GetPreRankMsg(uid int) *proto.ResChampshipPreRank {
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Score: float64(v.Score),
Name: robot.Name,
Avatar: int32(robot.Avatar),
Face: int32(robot.Face),
@ -411,7 +418,7 @@ func (c *ChampshipMgr) GetPreRankMsg(uid int) *proto.ResChampshipPreRank {
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Score: float64(v.Score),
Name: simplePlayer.Name,
Avatar: int32(simplePlayer.Avatar),
Face: int32(simplePlayer.Face),
@ -429,7 +436,7 @@ func (c *ChampshipMgr) GetPreRankMsg(uid int) *proto.ResChampshipPreRank {
return &proto.ResChampshipPreRank{
MyRank: int32(myRank),
MyScore: float32(myScore),
MyScore: float64(myScore),
RankList: RL,
}
}
@ -470,7 +477,7 @@ func (c *ChampshipMgr) GetRankMsg(uid int) *proto.ResChampshipRank {
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Score: float64(v.Score),
Name: robot.Name,
Avatar: int32(robot.Avatar),
Face: int32(robot.Face),
@ -498,7 +505,7 @@ func (c *ChampshipMgr) GetRankMsg(uid int) *proto.ResChampshipRank {
}
RL[int32(k+1)] = &proto.ResPlayerRank{
Uid: int64(v.Uid),
Score: float32(v.Score),
Score: float64(v.Score),
Name: simplePlayer.Name,
Avatar: int32(simplePlayer.Avatar),
Face: int32(simplePlayer.Face),
@ -516,7 +523,7 @@ func (c *ChampshipMgr) GetRankMsg(uid int) *proto.ResChampshipRank {
return &proto.ResChampshipRank{
MyRank: int32(myRank),
MyScore: float32(myScore),
MyScore: float64(myScore),
RankList: RL,
}
}

View File

@ -16,7 +16,7 @@ import (
piggyBank "server/game/mod/piggy_bank"
"server/game/mod/quest"
GoUtil "server/game_util"
proto "server/msg"
proto "server/msg/meowmentnet"
"strings"
"time"

View File

@ -0,0 +1,75 @@
package game
import (
"encoding/json"
GoUtil "server/game_util"
"sync"
"gitea.bywaystudios.com/pet_home/leaf/log"
"gitea.bywaystudios.com/pet_home/nacos"
)
type ConfigMgr struct {
ConfigData sync.Map
}
func (m *ConfigMgr) Init() {
m.LoadConfig()
}
func (c *ConfigMgr) LoadConfig() {
// 加载配置数据
nacosClient, err := nacos.GetNacosClient()
if err != nil {
log.Error("Failed to create Nacos client: %v", err)
return
}
game_config_data := make(map[string]interface{})
err = nacosClient.GetJSON("game_config", "game", &game_config_data)
if err != nil {
log.Error("Failed to load config: %v", err)
return
}
c.ConfigData.Store("game_config", game_config_data)
log.Debug("Config loaded: %v", game_config_data)
nacosClient.Listen("game_config", "game", func(event nacos.ChangeEvent) {
log.Debug("Config updated: %v", event)
updatedConfig := make(map[string]interface{})
err := json.Unmarshal([]byte(event.Content), &updatedConfig)
if err != nil {
log.Error("Failed to parse updated config: %v", err)
return
}
c.ConfigData.Store("game_config", updatedConfig)
log.Debug("Config updated in memory: %v", updatedConfig)
})
}
func (m *ConfigMgr) GetGameConfig() map[string]interface{} {
if config, ok := m.ConfigData.Load("game_config"); ok {
return config.(map[string]interface{})
}
return nil
}
func (m *ConfigMgr) GetConfigValue(key string) interface{} {
config := m.GetGameConfig()
if config != nil {
return config[key]
}
return nil
}
func (m *ConfigMgr) GetTestUids() []int {
config := m.GetGameConfig()
if config != nil {
if uids, ok := config["test_uids"].([]interface{}); ok {
intUids := make([]int, len(uids))
for i, uid := range uids {
intUids[i] = GoUtil.Int(uid) // 使用 GoUtil.Int 将 interface{} 转换为 int
}
return intUids
}
}
return nil
}

View File

@ -1,6 +1,7 @@
package game
import (
"encoding/json"
"fmt"
"reflect"
"server/MergeConst"
@ -10,15 +11,12 @@ import (
"strings"
"time"
"server/msg"
msg "server/msg/meowmentnet"
"gitea.bywaystudios.com/pet_home/leaf/gate"
"gitea.bywaystudios.com/pet_home/leaf/log"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"server/db"
)
@ -73,46 +71,46 @@ func HandleClientReq(args []interface{}) {
case "ClientTick":
case "ReqChangePassword":
detail := &msg.ReqChangePassword{}
proto.Unmarshal(buf, detail)
GoUtil.Unmarshal(buf, detail)
accountInfo := db.GetAccountInfoFromDb(detail.UserName)
if accountInfo == nil {
ResChangePassword := &msg.ResChangePassword{}
ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_NoExsit
data, _ := proto.Marshal(ResChangePassword)
data := GoUtil.Marshal(ResChangePassword)
G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data)
return
}
if accountInfo.UserPassword != detail.OldPwd && detail.OldPwd != "-1" {
ResChangePassword := &msg.ResChangePassword{}
ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_ERROR
data, _ := proto.Marshal(ResChangePassword)
data := GoUtil.Marshal(ResChangePassword)
G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data)
return
}
if strings.Count(detail.NewPwd, "")-1 < 6 {
if strings.Count(detail.NewPwd_, "")-1 < 6 {
ResChangePassword := &msg.ResChangePassword{}
ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_Short
data, _ := proto.Marshal(ResChangePassword)
data := GoUtil.Marshal(ResChangePassword)
G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data)
return
}
accountInfo.UserPassword = detail.NewPwd
accountInfo.UserPassword = detail.NewPwd_
err := db.UpdateAccountInfoToDb(accountInfo)
if err != nil {
ResChangePassword := &msg.ResChangePassword{}
ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_Fail
data, _ := proto.Marshal(ResChangePassword)
data := GoUtil.Marshal(ResChangePassword)
G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data)
return
}
ResChangePassword := &msg.ResChangePassword{}
ResChangePassword.ResultCode = 0
data, _ := proto.Marshal(ResChangePassword)
data := GoUtil.Marshal(ResChangePassword)
G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data)
case "ReqAdminInfo": // 后台接口
AdminProcess(m.GetFunc(), []interface{}{a, buf})
case "ReqLoginCode":
detailMsg, err := UnmarshalProtoMessageByName(m.GetFunc(), buf)
detailMsg, err := UnmarshalThriftMessageByName(m.GetFunc(), buf)
if err != nil {
log.Error("unmarshal %s failed: %v", m.GetFunc(), err)
return
@ -125,13 +123,13 @@ func HandleClientReq(args []interface{}) {
ResLoginCode.Msg = err.Error()
}
ResLoginCode.Code = Code
data, _ := proto.Marshal(ResLoginCode)
data := GoUtil.Marshal(ResLoginCode)
G_GameLogicPtr.PackResInfo(a, "ResLoginCode", data)
case "ReqServerVersion":
G_GameLogicPtr.SendServerVersion(a)
case "ReqRegisterAccount":
detail := &msg.ReqRegisterAccount{}
proto.Unmarshal(buf, detail)
GoUtil.Unmarshal(buf, detail)
log.Debug("player %s start register", detail.UserName)
gl := G_getGameLogic()
defer func() {
@ -143,7 +141,7 @@ func HandleClientReq(args []interface{}) {
if gl.IsExsitAccount(detail.UserName) {
ResRegisterAccount := &msg.ResRegisterAccount{}
ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Exist
data, _ := proto.Marshal(ResRegisterAccount)
data := GoUtil.Marshal(ResRegisterAccount)
gl.PackResInfo(a, "ResRegisterAccount", data)
break
}
@ -152,17 +150,17 @@ func HandleClientReq(args []interface{}) {
if !gl.NewAccountInsertDataToDB() {
ResRegisterAccount := &msg.ResRegisterAccount{}
ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Fail
data, _ := proto.Marshal(ResRegisterAccount)
data := GoUtil.Marshal(ResRegisterAccount)
gl.PackResInfo(a, "ResRegisterAccount", data)
break
}
ResRegisterAccount := &msg.ResRegisterAccount{}
ResRegisterAccount.ResultCode = 0
data, _ := proto.Marshal(ResRegisterAccount)
data := GoUtil.Marshal(ResRegisterAccount)
gl.PackResInfo(a, "ResRegisterAccount", data)
case "ReqLogin": // 登录请求
detail := &msg.ReqLogin{}
proto.Unmarshal(buf, detail)
GoUtil.Unmarshal(buf, detail)
accountInfo := db.GetAccountInfoFromDb(detail.UserName)
log.Debug("player %s start login", detail.UserName)
defer func() {
@ -200,16 +198,21 @@ func HandleClientReq(args []interface{}) {
p.(*Player).PlayMod.getBaseMod().DiviceId = detail.Device //加锁
p.(*Player).PushClientRes(ResLogin)
p.(*Player).LoginBackData()
p.(*Player).TeLog("Login_log", nil)
p.(*Player).TeLog("reqlogin_log", nil)
if newPlayer {
p.(*Player).TeLog("login", map[string]interface{}{
"is_first": !p.(*Player).PlayMod.getBaseMod().GetIsRegisterLogined(), // 是否注册登录过
})
}
p.(*Player).ProcessTrigger()
}
log.Debug("uid : %d, init user process : %s, execTime : %v , isNew: %v", p.(*Player).M_DwUin, m.GetFunc(), time.Since(start), newPlayer)
case "ReqServerTime": // 获取服务器时间
detail := &msg.ReqServerTime{}
proto.Unmarshal(buf, detail)
GoUtil.Unmarshal(buf, detail)
res := &msg.ResServerTime{}
res.ServerTime = (int32)(time.Now().Unix())
data, _ := proto.Marshal(res)
data := GoUtil.Marshal(res)
G_getGameLogic().PackResInfo(a, "ResServerTime", data)
case "ReqOfflineReconnect": // 断线重连
ReqOfflineReconnectFunc(a, buf)
@ -232,7 +235,7 @@ func HandleClientReq(args []interface{}) {
p.(*Player).args = make(map[string]interface{})
p.(*Player).args["func"] = m
p.(*Player).args["agent"] = a
detailMsg, err := UnmarshalProtoMessageByName(m.GetFunc(), buf)
detailMsg, err := UnmarshalThriftMessageByName(m.GetFunc(), buf)
if err != nil {
log.Error("uid : %d, func : %s, unmarshal error : %s", p.(*Player).M_DwUin, m.GetFunc(), err)
p.(*Player).TeLog("func_unmarshal_error", map[string]interface{}{
@ -244,8 +247,12 @@ func HandleClientReq(args []interface{}) {
err = RunNewNetProcessByKey(m.GetFunc(), p.(*Player), &detailMsg)
str := ""
if conf.Server.GameName == "pet_home" || conf.Server.GameName == "merge_pet_sdk" {
strbuf, _ := protojson.Marshal(detailMsg)
str = string(strbuf)
jsonBuf, err := json.Marshal(detailMsg)
if err != nil {
log.Error("marshal %s to json failed: %v", m.GetFunc(), err)
return
}
str = string(jsonBuf)
}
if err != nil {
log.Error("uid : %d, func : %s, err : %s", p.(*Player).M_DwUin, m.GetFunc(), err)

View File

@ -2,6 +2,7 @@ package game
import (
"encoding/gob"
"fmt"
mergeCluster "server/cluster"
"server/game/mod/activity"
"server/game/mod/card"
@ -70,6 +71,10 @@ type VarExpireData struct {
mu sync.Mutex
}
func (v *VarExpireData) String() string {
return fmt.Sprintf("VarExpireData{D: %v, T: %d, U: %d}", v.D, v.T, v.U)
}
type CatnipPartner struct {
Uid int
Partner int

View File

@ -30,7 +30,7 @@ import (
"server/game/mod/order"
"server/game/mod/playroom"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"strconv"
"strings"
"time"
@ -58,11 +58,11 @@ func ReqGmCommand_(player *Player, Command string) error {
case "additem":
id, _ := strconv.Atoi(arg[1])
num, _ := strconv.Atoi(arg[2])
player.HandleItem([]*item.Item{item.NewItem(id, num)}, msg.ITEM_POP_LABEL_GM.String())
player.HandleItem([]*item.Item{item.NewItem(id, num)}, msg.ITEM_POP_LABEL_Gm.String())
case "subitem":
id, _ := strconv.Atoi(arg[1])
num, _ := strconv.Atoi(arg[2])
player.HandleItem([]*item.Item{item.NewItem(id, -num)}, msg.ITEM_POP_LABEL_GM.String())
player.HandleItem([]*item.Item{item.NewItem(id, -num)}, msg.ITEM_POP_LABEL_Gm.String())
case "reset_order":
player.PlayMod.mod_list.Order.Step = 0
player.PlayMod.mod_list.Order.InitData()
@ -271,7 +271,7 @@ func ReqGmCommand_(player *Player, Command string) error {
N: ChampshipMod.GetN(),
},
End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK,
}
SendMsgToCenterAsync(m)
case "resetUserInfo":
@ -566,7 +566,7 @@ func ReqGmCommand_(player *Player, Command string) error {
})
}
}
player.HandleItem(items, msg.ITEM_POP_LABEL_GM.String())
player.HandleItem(items, msg.ITEM_POP_LABEL_Gm.String())
case "resetCompensation":
compensationMod := player.PlayMod.getCompensationMod()
compensationMod.C20250910 = false

View File

@ -11,7 +11,7 @@ import (
MsgMod "server/game/mod/msg"
"server/game/mod/playroom"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"time"
)

View File

@ -42,6 +42,7 @@ type ServerMail struct {
Send_type int
Mail_type int
To_uids []int
Level int
}
func (m *MailMgr) Init() {
@ -101,12 +102,13 @@ func (r *MailMgr) LoadMail(msg *msg.Msg) (interface{}, error) {
Mail_type: v.Mail_type,
Send_type: v.Send_type,
To_uids: uids,
Level: v.Level,
}
}
return nil, nil
}
func (r *MailMgr) Sync(Uid int, Register int64) []ServerMail {
func (r *MailMgr) Sync(uid, level int, register int64) []ServerMail {
// 同步邮件
now := GoUtil.Now()
list := make([]ServerMail, 0)
@ -117,13 +119,16 @@ func (r *MailMgr) Sync(Uid int, Register int64) []ServerMail {
if v.End_time > 0 && v.End_time < now {
continue
}
if v.Register_time > 0 && v.Register_time < Register {
if v.Register_time > 0 && v.Register_time < register {
continue
}
if v.Level > 0 && v.Level > level {
continue
}
if v.Send_type == MAIL_SEND_TYPE_SERVER { //全服邮件
list = append(list, *v)
} else {
if GoUtil.InArray(Uid, v.To_uids) {
if GoUtil.InArray(uid, v.To_uids) {
list = append(list, *v)
}
}

View File

@ -24,7 +24,7 @@ import (
"server/game/mod/order"
"server/game/mod/playroom"
GoUtil "server/game_util"
proto "server/msg"
proto "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"
@ -618,7 +618,7 @@ func (p *Player) handle(m *msg.Msg) error {
}
func SyncMailMsg(p *Player) {
serverMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetRegisterTime())
serverMailList := G_GameLogicPtr.MailMgr.Sync(int(p.M_DwUin), p.GetPlayerBaseMod().GetLevel(), p.GetPlayerBaseMod().GetRegisterTime())
MailMod := p.PlayMod.getMailMod()
for _, v := range serverMailList {
if GoUtil.InArray(v.Id, MailMod.ServerMail) {
@ -915,12 +915,12 @@ func (player *Player) AddOrder() {
preheatStep := OrderMod.PreheatStep[chessColor]
OrderMod.PreheatStep[chessColor]++
if preheatStep < 4 {
newChessId := mergeDataCfg.GetChessIdByLvAndColor(BaseMod.GetEnergyMul()+preheatStep+1, chessColor)
NewChessId_ := mergeDataCfg.GetChessIdByLvAndColor(BaseMod.GetEnergyMul()+preheatStep+1, chessColor)
items, ok := order.PreheatItems[OrderMod.PreheatStep[chessColor]]
if !ok {
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, order.GetOrderStar([]int{newChessId}, ChessMod.GetStarEmitList()))}
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, order.GetOrderStar([]int{NewChessId_}, ChessMod.GetStarEmitList()))}
}
OrderMod.AddPreheatOrder([]int{newChessId}, order.DIFF_LOW, order.Preheat_type, items)
OrderMod.AddPreheatOrder([]int{NewChessId_}, order.DIFF_LOW, order.Preheat_type, items)
}
}
for _, v := range OrderMod.OrderList {
@ -956,13 +956,13 @@ func (player *Player) FixOrderBug() {
if exit {
continue
}
newChessId := mergeDataCfg.GetChessIdByLvAndColor(BaseMod.GetEnergyMul()+v+1, k)
NewChessId_ := mergeDataCfg.GetChessIdByLvAndColor(BaseMod.GetEnergyMul()+v+1, k)
OrderMod.PreheatStep[k]++
items, ok := order.PreheatItems[OrderMod.PreheatStep[k]]
if !ok {
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, order.GetOrderStar([]int{newChessId}, ChessMod.GetStarEmitList()))}
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, order.GetOrderStar([]int{NewChessId_}, ChessMod.GetStarEmitList()))}
}
OrderMod.AddPreheatOrder([]int{newChessId}, order.DIFF_LOW, order.Preheat_type, items)
OrderMod.AddPreheatOrder([]int{NewChessId_}, order.DIFF_LOW, order.Preheat_type, items)
}
}

View File

@ -6,6 +6,7 @@ import (
"runtime/debug"
mergeCluster "server/cluster"
"server/conf"
"server/db"
"server/game/mod/msg"
GoUtil "server/game_util"
"sync"
@ -21,7 +22,7 @@ type MessageMiddleware func(MessageHandlerFunc) MessageHandlerFunc
var save_msg_type = []int{
msg.HANDLE_MOD_PLAYER_MSG,
msg.HANDLE_MDO_CHAMPSHIP_INRANK,
msg.HANDLE_MOD_CHAMPSHIP_INRANK,
msg.HANDLE_MOD_USER_VAR_SET,
}
@ -44,6 +45,7 @@ type MessageMgr struct {
type MessageData struct {
MessageList map[int64]*MessageList
PlayerList map[int64]int
Version int
mu sync.Mutex
}
@ -94,6 +96,9 @@ func (m *MessageMgr) MessageMgrInit() {
m.data.(*MessageData).PlayerList = make(map[int64]int)
m.handler = make(map[int]MessageHandlerFunc)
m.middlewares = []MessageMiddleware{}
if conf.Server.ServerType == "center" {
m.version()
}
// 初始化 Worker Pool (10个worker, 1000个队列大小)
m.workerPool = NewWorkerPool(50, 10000)
// 注册默认中间件
@ -102,44 +107,47 @@ func (m *MessageMgr) MessageMgrInit() {
m.Use(TimeoutMiddleware(5 * time.Second))
m.NodeRegister()
m.CenterRegister()
FixBug()
log.Debug("MessageMgr initialized successfully")
}
func FixBug() {
messageMgrData := getMessageData()
// 先更新 PlayerList需要加锁
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
func (m *MessageMgr) version() {
data := getMessageData()
data.mu.Lock()
defer data.mu.Unlock()
now := GoUtil.Now()
for k, v := range messageMgrData.MessageList {
if k < 100000 {
delete(messageMgrData.MessageList, k)
continue
}
newMsgList := make([]*msg.Msg, 0, len(v.Messages))
// 反向遍历以安全删除元素
for _, message := range v.Messages {
if message == nil {
if data.Version == 0 {
data.Version = 1
for k, v := range data.MessageList {
if k < 100000 {
continue
}
if message.HandleType != msg.HANDLE_MOD_PLAYER_MSG {
continue
key := GoUtil.GetMessageKey(int(k))
for _, message := range v.Messages {
if message == nil {
continue
}
if message.HandleType != msg.HANDLE_MOD_PLAYER_MSG {
continue
}
if message.Type == msg.HADNLE_TYPE_AGREE || message.Type == msg.HANDLE_TYPE_DEL {
continue
}
if message.End < now {
log.Debug("delete message %v", message)
continue
}
value, err := GoUtil.JsonMarshal(message)
if err != nil {
log.Debug("json marshal message failed, err:%v\n", err)
continue
}
err = db.RedisLPush(key, value)
if err != nil {
log.Debug("redis lpush message failed, err:%v\n", err)
continue
}
log.Debug("user outline message transfer to redis uid %d, value %+v", k, message)
}
if message.Type == msg.HADNLE_TYPE_AGREE || message.Type == msg.HANDLE_TYPE_DEL {
newMsgList = append(newMsgList, message)
continue
}
if message.End < now {
log.Debug("delete message %v", message)
continue
}
newMsgList = append(newMsgList, message)
}
v.Messages = newMsgList
if len(v.Messages) == 0 {
log.Debug("delete messagelist uid:%d", k)
delete(messageMgrData.MessageList, k)
}
}
}
@ -168,7 +176,7 @@ func (m *MessageMgr) CenterRegister() {
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_SET, MessageHandlerFunc(SetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_USER_VAR_GET, MessageHandlerFunc(GetUserVarDataHandler))
m.RegisterHandler(msg.HANDLE_MOD_CATNIP_PARTNER, MessageHandlerFunc(CatnipPartnerHandler))
m.RegisterHandler(msg.HANDLE_MDO_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_INRANK, MessageHandlerFunc(ChampshipInRankHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_INFO, MessageHandlerFunc(ChampshipRankInfoHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_RANK_LIST, MessageHandlerFunc(ChampshipRankListHandler))
m.RegisterHandler(msg.HANDLE_MOD_CHAMPSHIP_PRE_RANK, MessageHandlerFunc(ChampshipRankPreHandler))
@ -262,19 +270,6 @@ func ClusterSyncHandler(data *msg.Msg) (interface{}, error) {
})
return true
})
// 发送暂存区消息(先复制再释放锁,避免长时间持有锁)
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
TempMessageList := messageMgrData.MessageList
messageMgrData.MessageList = make(map[int64]*MessageList)
messageMgrData.mu.Unlock() // 立即释放锁,在锁外发送消息
log.Debug("[Middleware] Cluster sync send temp message len: %d", len(TempMessageList))
for _, Message := range TempMessageList {
for _, msgItem := range Message.Messages {
SendMsgToCenterAsync(msgItem)
}
}
return nil, nil
}
@ -288,14 +283,13 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
messageMgrData.mu.Unlock()
log.Debug("[Middleware] Player login success player id: %v, node: %v", data.From, data.Extra.(int))
// 对玩家消息列表加锁
messages := getMessge(int64(data.From))
messages.mu.Lock()
// 复制消息列表,避免在锁内发送消息
messageList := getOutlineMessage(int64(data.From))
// 清空数据
resetApplyCount(int64(data.From))
// 过滤过期消息
now := GoUtil.Now()
validMessages := make([]*msg.Msg, 0, len(messages.Messages))
for _, message := range messages.Messages {
validMessages := make([]*msg.Msg, 0, len(messageList))
for _, message := range messageList {
if message.HandleType != msg.HANDLE_MOD_PLAYER_MSG {
continue
}
@ -303,22 +297,18 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
validMessages = append(validMessages, message)
}
}
messages.Messages = validMessages
messagesToSend := make([]*msg.Msg, len(messages.Messages))
copy(messagesToSend, messages.Messages)
messages.mu.Unlock()
ReplyPlayerMsgASync(data, nil)
// 在锁外发送离线消息
var applyUids []int64
var otherUids []int64
for _, message := range messagesToSend {
for _, message := range validMessages {
if message.Type == msg.HANDLE_TYPE_APPLY {
applyUids = append(applyUids, int64(message.From))
} else {
otherUids = append(otherUids, int64(message.From))
}
}
for _, message := range messagesToSend {
for _, message := range validMessages {
if message.Type == msg.HANDLE_TYPE_APPLY && len(applyUids) >= 3 {
message.H = msg.MSG_TYPE_OFFLINE // 标记为离线消息
}
@ -347,7 +337,7 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) {
"other_count": len(otherUids),
},
}, node) // 发送离线消息处理完成通知
log.Debug("[Middleware] Player sync logout message player id: %v, len: %d", data.From, len(messagesToSend))
log.Debug("[Middleware] Player sync logout message player id: %v, len: %d", data.From, len(validMessages))
return nil, nil
}
@ -361,20 +351,7 @@ func PlayerLogoutHandler(data *msg.Msg) (interface{}, error) {
}
func ComsumerMsgHandler(data *msg.Msg) (interface{}, error) {
messages := getMessge(int64(data.From))
messages.mu.Lock()
defer messages.mu.Unlock()
for i, msgItem := range messages.Messages {
if msgItem == nil {
continue
}
if msgItem.UniKey == data.UniKey {
// 删除消息
messages.Messages = append(messages.Messages[:i], messages.Messages[i+1:]...)
log.Debug("[Middleware] Comsume message success type: %d, player id: %v", msgItem.Type, msgItem.From)
break
}
}
log.Debug("[Middleware] Comsume message success type: %d, player id: %v", data.Type, data.From)
return nil, nil
}
@ -405,23 +382,14 @@ func CenterPlayerMsgHandler(data *msg.Msg) (interface{}, error) {
SendMsgToNodeAsync(data, node)
} else {
// 不在线则存储消息
applycount := 0
if !GoUtil.InArray(data.Type, notify_msg_type) {
messages := getMessge(PlayerId)
messages.mu.Lock()
messages.Messages = append(messages.Messages, data)
for _, msgItem := range messages.Messages {
if msgItem == nil {
continue
}
if msgItem.Type == msg.HANDLE_TYPE_APPLY {
applycount++
saveOutlineMessage(data)
if data.Type == msg.HANDLE_TYPE_APPLY {
count, err := incrApplyCount(int64(data.To))
if count > 1 && err == nil {
go NotifyFriendApply(data.To, data.From)
}
}
if applycount > 1 && data.Type == msg.HANDLE_TYPE_APPLY {
go NotifyFriendApply(data.To, data.From)
}
messages.mu.Unlock()
}
}
return nil, nil
@ -448,7 +416,6 @@ func PlayerReplyMsgHandler(data *msg.Msg) (interface{}, error) {
mergeCluster.GetCallbackChanMu().RLock()
chanel, ok := mergeCluster.CallbackChan[data.UniKey]
mergeCluster.GetCallbackChanMu().RUnlock()
if ok {
// log.Debug("reply message ")
chanel <- data
@ -525,7 +492,6 @@ func (m *MessageMgr) MessageHandleAsync(message *msg.Msg) error {
// 兼容旧版本的函数
func MessageHandle(m *msg.Msg) error {
// log.Debug("RecvMessage m %v", m)
// 这里可以调用 MessageMgr 的处理方法
G_GameLogicPtr.MessageMgr.MessageHandleAsync(m)
return nil
@ -871,9 +837,6 @@ func SendPlayerMsgSync(m *msg.Msg) (interface{}, error) {
}
func FriendMgrSend(m1 *msg.Msg) error {
if m1.SendT == 0 {
m1.SendT = GoUtil.Now()
}
SendPlayerMsgAsync(m1)
return nil
}
@ -895,7 +858,6 @@ func sendMessageAsync(m *msg.Msg, node int) error {
saveMessage(m)
return err
}
deleteMessage(m)
return nil
}
@ -913,47 +875,19 @@ func sendMessageSync(m *msg.Msg, node int) (*msg.Msg, error) {
saveMessage(m)
return nil, err
}
deleteMessage(m)
return msg, nil
}
// 保存消息到本地
func saveMessage(m *msg.Msg) error {
data := getMessageData()
data.mu.Lock()
defer data.mu.Unlock()
// 使用不加锁的内部方法,避免死锁
messages := getMessgeUnsafe(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
now := GoUtil.Now()
applycount := 0
for _, msgItem := range messages.Messages {
if msgItem == nil {
continue
}
if msgItem.UniKey == m.UniKey {
// 已存在相同消息,直接返回
return nil
}
if msgItem.End != 0 && msgItem.End < now {
// 删除过期消息
messages.Messages = append(messages.Messages[:0], messages.Messages[1:]...)
}
if msgItem.Type == msg.HANDLE_TYPE_APPLY {
applycount++
}
saveOutlineMessage(m)
applycount, err := incrApplyCount(int64(m.To))
if err != nil {
log.Error("Failed to increment apply count for player %d: %v", m.To, err)
}
if applycount > 1 && m.Type == msg.HANDLE_TYPE_APPLY {
go NotifyFriendApply(m.To, m.From)
}
// 添加消息
messages.Messages = append(messages.Messages, m)
// 设置上限为2000条超过则丢弃最早的消息
if len(messages.Messages) > 2000 {
excess := len(messages.Messages) - 2000
messages.Messages = messages.Messages[excess:]
}
return nil
}
@ -984,39 +918,51 @@ func getMessge(PlayerId int64) *MessageList {
return getMessgeUnsafe(PlayerId)
}
func deleteMessage(m *msg.Msg) error {
func getOutlineMessage(PlayerId int64) []*msg.Msg {
values, err := db.RedisLRange(GoUtil.GetMessageKey(int(PlayerId)), 0, -1)
if err != nil {
log.Error("Failed to get outline messages from Redis for player %d: %v", PlayerId, err)
return nil
}
var messages []*msg.Msg
for _, v := range values {
var message *msg.Msg
err := GoUtil.JsonUnmarshal([]byte(v), &message)
if err != nil {
log.Error("Failed to unmarshal message from Redis for player %d: %v", PlayerId, err)
continue
}
messages = append(messages, message)
}
db.RedisDel(GoUtil.GetMessageKey(int(PlayerId))) // 获取后删除消息
return messages
}
func saveOutlineMessage(m *msg.Msg) error {
if m == nil {
return nil
}
messages := getMessge(int64(m.To))
messages.mu.Lock()
defer messages.mu.Unlock()
key := GoUtil.GetMessageKey(int(m.To))
value, err := GoUtil.JsonMarshal(m)
if err != nil {
log.Error("Failed to marshal message for Redis for player %d: %v", m.To, err)
return err
}
return db.RedisLPush(key, value)
}
// 使用更安全的方式删除元素找到索引后再删除避免在range中修改切片
foundIndex := -1
for i, msgItem := range messages.Messages {
if msgItem == nil {
continue
}
if msgItem.UniKey == m.UniKey {
foundIndex = i
log.Debug("[Middleware] send message success; message: %v, player id: %v", msgItem, msgItem.From)
break
}
func incrApplyCount(PlayerId int64) (int, error) {
key := fmt.Sprintf("apply_count_%d", PlayerId)
count, err := db.RedisIncrBy(key, 1)
if err != nil {
log.Error("Failed to increment apply count in Redis for player %d: %v", PlayerId, err)
return 0, err
}
return int(count), nil
}
if foundIndex >= 0 {
// 删除消息:将后面的元素前移,避免内存泄漏
copy(messages.Messages[foundIndex:], messages.Messages[foundIndex+1:])
messages.Messages[len(messages.Messages)-1] = nil // 清除最后一个元素的引用
messages.Messages = messages.Messages[:len(messages.Messages)-1]
}
if len(messages.Messages) == 0 {
// 如果消息列表为空,则删除该玩家的消息列表
messageMgrData := getMessageData()
messageMgrData.mu.Lock()
defer messageMgrData.mu.Unlock()
delete(messageMgrData.MessageList, int64(m.To))
}
func resetApplyCount(PlayerId int64) error {
key := fmt.Sprintf("apply_count_%d", PlayerId)
db.RedisDel(key)
return nil
}

View File

@ -4,7 +4,7 @@ import (
"fmt"
avatarCfg "server/conf/avatar"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type AvatarMod struct {

View File

@ -6,7 +6,7 @@ import (
baseCfg "server/conf/base"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
const (
@ -14,38 +14,39 @@ const (
)
type Base struct {
Account string
Uid int64
Level int
Exp int
PExp int
Energy int
Star int
Diamond int
LoginTime int64
LoginDay int // 登录天数
LogoutTime int64
RecoverTime int64
FackBookId string
EnergyMul int
IsFirstBuy bool
EnergyBuy int
NickName string
PetName string
FacebookUrl string
Cumulative int // 累计在线时间
TodayCumulative int // 今日累计在线时间
LoginBack bool // 回归补偿
EnergyAD int // 每日看广告获得的能量次数
Seed bool
Source int // 体力资源
Lang msg.LANG_TYPE // 语言
IdCardName string
IdCardNum string
AddCode string // 用于添加好友的code
DiviceId string // 设备id
RegisterTime int64 // 注册时间
CountryCode string // 国家码
Account string
Uid int64
Level int
Exp int
PExp int
Energy int
Star int
Diamond int
LoginTime int64
LoginDay int // 登录天数
LogoutTime int64
RecoverTime int64
FackBookId string
EnergyMul int
IsFirstBuy bool
EnergyBuy int
NickName string
PetName string
FacebookUrl string
Cumulative int // 累计在线时间
TodayCumulative int // 今日累计在线时间
LoginBack bool // 回归补偿
EnergyAD int // 每日看广告获得的能量次数
Seed bool
Source int // 体力资源
Lang msg.LANG_TYPE // 语言
IdCardName string
IdCardNum string
AddCode string // 用于添加好友的code
DiviceId string // 设备id
RegisterTime int64 // 注册时间
CountryCode string // 国家码
IsRegisterLogined bool // 是否注册登录过
}
func (b *Base) InitData(Uid int, Ip string) {
@ -70,6 +71,14 @@ func (b *Base) InitData(Uid int, Ip string) {
}
}
func (b *Base) GetIsRegisterLogined() bool {
is := b.IsRegisterLogined
if !is {
b.IsRegisterLogined = true
}
return is
}
func (b *Base) Login() int64 {
now := GoUtil.Now()
if !GoUtil.IsSameDay(b.LoginTime, now) {

View File

@ -5,7 +5,7 @@ import (
cardCfg "server/conf/card"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"gitea.bywaystudios.com/pet_home/leaf/log"
)

View File

@ -6,7 +6,7 @@ import (
mergeDataCfg "server/conf/merge_data"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type ChampshipMod struct {

View File

@ -9,7 +9,7 @@ import (
"server/game/mod/item"
"server/game/mod/order"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"gitea.bywaystudios.com/pet_home/leaf/log"
)

View File

@ -8,7 +8,7 @@ import (
userCfg "server/conf/user"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"strings"
)
@ -401,7 +401,7 @@ func (cb *ChessBorad) FinishOrderChessByBag(chess int) error {
}
// 棋子转换
func (cb *ChessBorad) ExChess(oldChessId, newChessId int) error {
func (cb *ChessBorad) ExChess(oldChessId, NewChessId_ int) error {
if oldChessId > 0 {
newList, b := GoUtil.PopElemSlice(cb.ChessList, oldChessId)
if !b {
@ -409,7 +409,7 @@ func (cb *ChessBorad) ExChess(oldChessId, newChessId int) error {
}
cb.ChessList = newList
}
return cb.AddChess(newChessId)
return cb.AddChess(NewChessId_)
}
// 增加棋盘缓冲器

View File

@ -5,7 +5,7 @@ import (
collectCfg "server/conf/collect"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type Collect struct {

View File

@ -6,7 +6,7 @@ import (
"server/game/mod/item"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"

View File

@ -8,7 +8,7 @@ import (
orderCfg "server/conf/order"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
)

View File

@ -4,7 +4,7 @@ import (
"fmt"
emojiCfg "server/conf/emoji"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type EmojiMod struct {

View File

@ -5,7 +5,7 @@ import (
"math"
endlessCfg "server/conf/endless"
"server/game/mod/item"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
)

View File

@ -4,7 +4,7 @@ import (
"fmt"
faceCfg "server/conf/face"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type FaceMod struct {

View File

@ -7,7 +7,7 @@ import (
"server/game/mod/card"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
)

View File

@ -5,7 +5,7 @@ import (
friendTreasureCfg "server/conf/friend_treasure"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type FriendTreasureMod struct {

View File

@ -4,7 +4,7 @@ import (
"fmt"
fur_cfg "server/conf/fur"
"server/game/mod/item"
"server/msg"
msg "server/msg/meowmentnet"
)
type FurMod struct {

View File

@ -5,7 +5,7 @@ import (
guidecfg "server/conf/guide"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type Guide struct {

View File

@ -6,7 +6,7 @@ import (
"server/game/mod/item"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type GuideTaskMod struct {

View File

@ -6,7 +6,7 @@ import (
handbookCfg "server/conf/handbook"
startMergeCfg "server/conf/start_merge"
"server/game/mod/item"
"server/msg"
msg "server/msg/meowmentnet"
)
type Handbook struct {

View File

@ -5,7 +5,7 @@ import (
inviteCfg "server/conf/invite"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type InviteMod struct {

View File

@ -3,7 +3,7 @@ package item
import (
"fmt"
"math"
"server/msg"
msg "server/msg/meowmentnet"
)
type Item struct {

View File

@ -2,7 +2,7 @@ package kv
import (
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type KvMod struct {

View File

@ -7,7 +7,7 @@ import (
mergeDataCfg "server/conf/merge_data"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
const (
@ -537,29 +537,29 @@ func getLimitEventMsg(eType int, event *LTEInfo) *msg.LimitEvent {
if !ok {
return nil
}
param[msg.LimitEventParam_LUCKY_CAT_EARNINGS.String()] = int32(d.MaxEarings)
param[msg.LimitEventParam_LuckyCatEarnings.String()] = int32(d.MaxEarings)
case EVENT_TYPE_CAT_TRICK:
d, ok := event.D.(*CatTrick)
if !ok {
return nil
}
energy := d.Energy
param[msg.LimitEventParam_CAT_TRICK_ENERGY.String()] = int32(energy)
param[msg.LimitEventParam_CatTrickEnergy.String()] = int32(energy)
case EVENT_TYPE_PAYBACK_DAY:
d, ok := event.D.(*PaybackDay)
if !ok {
return nil
}
param[msg.LimitEventParam_PAYBACK_DAY_COUNT.String()] = int32(d.Count)
param[msg.LimitEventParam_PaybackDayCount.String()] = int32(d.Count)
case EVENT_TYPE_SENCE_DASH:
times := GoUtil.Int(event.Info["Times"])
param[msg.LimitEventParam_SENCE_DASH_TIMES.String()] = int32(times)
param[msg.LimitEventParam_SenceDashTimes.String()] = int32(times)
}
return &msg.LimitEvent{
EndTime: endTime,
ShowTime: showTime,
Cd: int32(cd),
Mul: float32(mul),
Mul: float64(mul),
StartTime: int32(event.StartT),
Param: param,
}

View File

@ -4,7 +4,7 @@ import (
"fmt"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type MailMod struct {

View File

@ -51,7 +51,7 @@ const (
HANDLE_MOD_USER_VAR_GET = 20010 // 获取玩家变量
HANDLE_MOD_USER_VAR_SET = 20011 // 设置玩家变量
HANDLE_MOD_REPLY_PLAYER_MSG = 20012 // 回复玩家消息
HANDLE_MDO_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜
HANDLE_MOD_CHAMPSHIP_INRANK = 20013 // 锦标赛入榜
HANDLE_MOD_CHAMPSHIP_RANK_INFO = 20014 // 锦标赛排名信息
HANDLE_MOD_CHAMPSHIP_RANK_LIST = 20015 // 锦标赛排行榜
HANDLE_MOD_CHAMPSHIP_PRE_RANK = 20016 // 锦标赛上期排名
@ -239,8 +239,8 @@ func formatHandleType(handleType int) string {
return "HANDLE_MOD_USER_VAR_SET"
case HANDLE_MOD_REPLY_PLAYER_MSG:
return "HANDLE_MOD_REPLY_PLAYER_MSG"
case HANDLE_MDO_CHAMPSHIP_INRANK:
return "HANDLE_MDO_CHAMPSHIP_INRANK"
case HANDLE_MOD_CHAMPSHIP_INRANK:
return "HANDLE_MOD_CHAMPSHIP_INRANK"
case HANDLE_MOD_CHAMPSHIP_RANK_INFO:
return "HANDLE_MOD_CHAMPSHIP_RANK_INFO"
case HANDLE_MOD_CHAMPSHIP_RANK_LIST:

View File

@ -6,7 +6,7 @@ import (
orderCfg "server/conf/order"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"strings"
"time"
)
@ -344,19 +344,19 @@ func (o *OrderMod) CreatePriorityOrder(lv int, emit []int) bool {
if B == 1 {
newColor := GoUtil.RandStringSlice(produce[1:])
diffLv := GoUtil.RandMap(map[int]int{DIFF_LOW: 70, DIFF_MID: 30})
newChessId := 0
NewChessId_ := 0
switch diffLv {
case DIFF_LOW:
newLv := GoUtil.RandNum(4, 3+durLv)
newChessId = mergeDataCfg.GetChessIdByLvAndColor(newLv, newColor)
NewChessId_ = mergeDataCfg.GetChessIdByLvAndColor(newLv, newColor)
case DIFF_MID:
newLv := GoUtil.RandNum(4+durLv, 3+durLv*2)
newChessId = mergeDataCfg.GetChessIdByLvAndColor(newLv, newColor)
NewChessId_ = mergeDataCfg.GetChessIdByLvAndColor(newLv, newColor)
}
if newChessId == 0 {
if NewChessId_ == 0 {
continue
}
o.addOrder([]int{newChessId}, diffLv, Common_type)
o.addOrder([]int{NewChessId_}, diffLv, Common_type)
return true
}
}
@ -701,16 +701,16 @@ func (o *OrderMod) ChangeEnergyMul(lv int, emit []int, energyMul int, chessList
chessId := v.MergeId[0]
chessColor := mergeDataCfg.GetColorById(chessId)
preheatStep := o.PreheatStep[chessColor]
newChessId := mergeDataCfg.GetChessIdByLvAndColor(energyMul+preheatStep, chessColor)
if newChessId == 0 {
NewChessId_ := mergeDataCfg.GetChessIdByLvAndColor(energyMul+preheatStep, chessColor)
if NewChessId_ == 0 {
continue
}
delete(o.OrderList, k)
items, ok := PreheatItems[preheatStep]
if !ok {
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, GetOrderStar([]int{newChessId}, emit))}
items = []*item.Item{item.NewItem(item.ITEM_STAR_ID, GetOrderStar([]int{NewChessId_}, emit))}
}
o.addPreheatOrder([]int{newChessId}, DIFF_LOW, Preheat_type, items)
o.addPreheatOrder([]int{NewChessId_}, DIFF_LOW, Preheat_type, items)
}
}

View File

@ -4,7 +4,7 @@ import (
chargeCfg "server/conf/charge"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type PiggyBankMod struct {

View File

@ -8,7 +8,7 @@ import (
"server/game/mod/item"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"

View File

@ -3,7 +3,7 @@ package quest
import (
"fmt"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"strconv"
"strings"
)

View File

@ -5,7 +5,7 @@ import (
sevenLoginCfg "server/conf/seven_login"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
)
type SevenLoginMod struct {

View File

@ -5,7 +5,7 @@ import (
languageCfg "server/conf/language"
notification_cfg "server/conf/notification"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"gitea.bywaystudios.com/pet_home/leaf/log"
)

View File

@ -7,7 +7,7 @@ import (
"server/game/mod/item"
limitedTimeEvent "server/game/mod/limited_time_event"
GoUtil "server/game_util"
proto "server/msg"
proto "server/msg/meowmentnet"
)
func (p *Player) NotifyPlayroomTask() {
@ -287,7 +287,7 @@ func (p *Player) ChargeBackData() {
specialChargeWeek = int32(GoUtil.FullWeeksSince(c.LastSpecialCharge))
}
p.PushClientRes(&proto.ResCharge{
Charge: float32(c.Charge),
Charge: float64(c.Charge),
Total: int32(c.Total),
First: GoUtil.MapIntToSlice(c.EnergyShop),
SpecialShop: specialShop,
@ -295,10 +295,10 @@ func (p *Player) ChargeBackData() {
ChessShop: chessShop,
Gift: GoUtil.MapIntToInt32(c.Gift),
Ad: c.Ad,
SpecialCharge: float32(c.SpecialCharge),
SpecialCharge: float64(c.SpecialCharge),
SpecialChargeWeek: specialChargeWeek,
TodayCharge: float32(c.TodayCharge),
MonthCharge: float32(c.MonthCharge),
TodayCharge: float64(c.TodayCharge),
MonthCharge: float64(c.MonthCharge),
Wish: resWish,
AdEndTime: c.AdEndTime,
WeeklyDiscount: weeklyDiscount,

View File

@ -14,12 +14,10 @@ import (
Msg "server/game/mod/msg"
"server/game/mod/order"
"server/game/mod/quest"
"server/msg"
msg "server/msg/meowmentnet"
"time"
"gitea.bywaystudios.com/pet_home/leaf/log"
"google.golang.org/protobuf/proto"
)
type PlayerBaseData struct {
@ -203,10 +201,7 @@ func (p *PlayerBaseData) ReqRemoveAd(player *Player, req *msg.ReqRemoveAd) {
res := &msg.ResRemoveAd{}
p.Data.NoAd = 1
res.ResultCode = 0
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(res)
G_getGameLogic().PackResInfo(agent, "ResRemoveAd", data)
player.PushClientRes(res)
}
func (p *PlayerBaseData) ResPlayerBaseInfo(player *Player) {
@ -255,10 +250,8 @@ func (p *PlayerBaseData) ReqBindFacebookAccount(player *Player, req *msg.ReqBind
}
BaseMod := player.PlayMod.getBaseMod()
BaseMod.FackBookId = req.BindAccountId
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(res)
p.SaveDataFromDB("")
G_getGameLogic().PackResInfo(agent, "ResBindFacebookAccount", data)
player.PushAndSendClienRes(res)
}
func (p *PlayerBaseData) ReqUnBindFacebook(player *Player, req *msg.ReqUnBindFacebook) {
@ -268,10 +261,8 @@ func (p *PlayerBaseData) ReqUnBindFacebook(player *Player, req *msg.ReqUnBindFac
p.Data.FaceBookId = ""
BaseMod := player.PlayMod.getBaseMod()
BaseMod.FackBookId = ""
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(res)
G_getGameLogic().PackResInfo(agent, "ResUnBindFacebook", data)
p.SaveDataFromDB("")
player.PushAndSendClienRes(res)
player.TeLog("platform_disconnect", map[string]interface{}{
"platform_type": "Facebook",
"platform_id": req.BindAccountId,
@ -332,9 +323,7 @@ func (p *PlayerBaseData) ReqOnlyBindFacebook(player *Player, req *msg.ReqOnlyBin
BaseMod := player.PlayMod.getBaseMod()
BaseMod.FackBookId = req.BindAccountId
p.SaveDataFromDB("")
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(res)
G_getGameLogic().PackResInfo(agent, "ResOnlyBindFacebook", data)
player.PushAndSendClienRes(res)
}
func (p *PlayerBaseData) ReqSynGameData(player *Player, req *msg.ReqSynGameData) {
@ -342,7 +331,7 @@ func (p *PlayerBaseData) ReqSynGameData(player *Player, req *msg.ReqSynGameData)
sqlStr := "SELECT * FROM t_player_baseinfo WHERE FaceBookId = ?"
sqlStruck := db.ResPlayerBaseInfo{}
isHaveOther := false
if err := db.SqlDb.Get(&sqlStruck, sqlStr, req.NewFBId); err != nil {
if err := db.SqlDb.Get(&sqlStruck, sqlStr, req.NewFBId_); err != nil {
isHaveOther = false
} else {
isHaveOther = true
@ -352,13 +341,9 @@ func (p *PlayerBaseData) ReqSynGameData(player *Player, req *msg.ReqSynGameData)
}
oldPlayer := G_GameLogicPtr.GetPlayer(sqlStruck.DwUin)
if oldPlayer != nil {
agent := oldPlayer.GetAgentByPlayer()
// notify := &msg.ForceKickOut{}
notify := &msg.ResSynGameData{}
data, _ := proto.Marshal(notify)
if agent != nil {
G_getGameLogic().PackResInfo(agent, "ResSynGameData", data)
}
oldPlayer.PushAndSendClienRes(notify)
oldPlayer.ClearData()
G_GameLogicPtr.M_Players.Delete(sqlStruck.DwUin)
}
@ -392,9 +377,9 @@ func (p *PlayerBaseData) ReqSynGameData(player *Player, req *msg.ReqSynGameData)
return
}
sqlStruck.FaceBookId = req.NewFBId
sqlStruck.FaceBookId = req.NewFBId_
sqlStruck.UserName = userName
_, err = db.SqlDb.Exec("update t_player_baseinfo set user_name = ?, FaceBookId = ? where dwUin = ?", userName, req.NewFBId, sqlStruck.DwUin)
_, err = db.SqlDb.Exec("update t_player_baseinfo set user_name = ?, FaceBookId = ? where dwUin = ?", userName, req.NewFBId_, sqlStruck.DwUin)
if err != nil {
tx.Rollback()
return
@ -421,9 +406,7 @@ func (p *PlayerBaseData) ReqSynGameData(player *Player, req *msg.ReqSynGameData)
"platform_type": "facebook",
})
p.SaveDataFromDB("")
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(res)
G_getGameLogic().PackResInfo(agent, "ResSynGameData", data)
player.PushAndSendClienRes(res)
}
func (p *PlayerBaseData) ClearData() bool {

View File

@ -11,12 +11,10 @@ import (
"server/game/mod/order"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"
"google.golang.org/protobuf/proto"
)
type PlayerChessData struct {
@ -35,19 +33,15 @@ func (p *PlayerChessData) SaveDataFromDB(key interface{}) bool {
}
func (p *PlayerChessData) ResPlayerChessData(player *Player) {
agent := player.GetAgentByPlayer()
res := &p.Data
ChessMod := player.PlayMod.getChessMod()
res.ChessList = ChessMod.BackData().ChessList
res.MChessData = ChessMod.ChessMap
data, _ := proto.Marshal(res)
G_getGameLogic().PackResInfo(agent, "ResPlayerChessData", data)
player.PushClientRes(res)
}
func (p *PlayerChessData) ResChessColorData(player *Player) {
agent := player.GetAgentByPlayer()
data, _ := proto.Marshal(&p.ColorData)
G_getGameLogic().PackResInfo(agent, "ResChessColorData", data)
player.PushClientRes(&p.ColorData)
}
// 同步棋盘数据
@ -57,7 +51,7 @@ func (p *PlayerChessData) UpdatePlayerChessData(player *Player, req *msg.UpdateP
addChessList, addNewEmit, err := p.HandleChess(player, update.MChessHandle)
if err != nil {
res := &msg.ResUpdatePlayerChessData{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
}
handleStr := ""
@ -72,12 +66,12 @@ func (p *PlayerChessData) UpdatePlayerChessData(player *Player, req *msg.UpdateP
return err
}
player.PushClientRes(&msg.ResUpdatePlayerChessData{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
})
p.Data.MChessData = update.MChessData
if !p.checkChessEqual(player) {
res := &msg.ResUpdatePlayerChessData{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "棋子数据不一致",
}
handleStr := ""
@ -110,7 +104,7 @@ func (p *PlayerChessData) UpdateChessData(player *Player, mChessData map[string]
p.Data.MChessData = mChessData
if !p.checkChessEqual(player) {
res := &msg.ResUpdatePlayerChessData{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "棋子数据不一致",
}
log.Debug("棋子数据不一致地图, %v---%v---%v", player.PlayMod.getChessMod().ChessMap, p.Data.MChessData, player.PlayMod.getChessMod().GetChessList())
@ -202,7 +196,7 @@ func (p *PlayerChessData) HandleChess(player *Player, handle_list []*msg.ChessHa
chessId := int(v.ChessId)
emitId := int(v.Emit)
switch v.Type {
case msg.HANDLE_TYPE_ADD: //增加棋子
case msg.HANDLE_TYPE_Add: //增加棋子
err := ChessMod.AddChess(chessId)
if err != nil {
return nil, nil, err
@ -222,25 +216,25 @@ func (p *PlayerChessData) HandleChess(player *Player, handle_list []*msg.ChessHa
addNewEmit = append(addNewEmit, chessId)
}
player.PushClientRes(HandbookMod.BackData())
case msg.HANDLE_TYPE_COMPOSE: //合成棋子
newChessId, err := ChessMod.ComposeChess(chessId)
case msg.HANDLE_TYPE_Compose: //合成棋子
NewChessId_, err := ChessMod.ComposeChess(chessId)
if err != nil {
return nil, nil, err
}
b := HandbookMod.SetHandbook(newChessId) // 添加图鉴
b := HandbookMod.SetHandbook(NewChessId_) // 添加图鉴
if b {
addNewEmit = append(addNewEmit, newChessId)
addNewEmit = append(addNewEmit, NewChessId_)
}
addChessList = append(addChessList, newChessId)
newChessIdLv := mergeDataCfg.GetLvById(newChessId)
TriggerList = append(TriggerList, &quest.Trigger{Label: quest.TRIGGER_LABEL_MERGELVTIME, A: []interface{}{newChessIdLv}})
addChessList = append(addChessList, NewChessId_)
NewChessId_Lv := mergeDataCfg.GetLvById(NewChessId_)
TriggerList = append(TriggerList, &quest.Trigger{Label: quest.TRIGGER_LABEL_MERGELVTIME, A: []interface{}{NewChessId_Lv}})
TriggerList = append(TriggerList, &quest.Trigger{Label: quest.TRIGGER_LABEL_MERGETIME})
player.PushClientRes(HandbookMod.BackData())
triggerComposeChess(player, newChessId, player.PlayMod.getBaseMod().EnergyMul, player.PlayMod.getChessMod().GetEmitList())
triggerComposeChess(player, NewChessId_, player.PlayMod.getBaseMod().EnergyMul, player.PlayMod.getChessMod().GetEmitList())
// 获取活动道具
ActItem := player.GetActivityItem(GoUtil.Int32ToInt(v.ActType))
itemList = item.Merge(itemList, ActItem)
case msg.HANDLE_TYPE_BUY: //购买棋子
case msg.HANDLE_TYPE_Buy: //购买棋子
loseGold, err := ChessMod.BuyChess(chessId)
if err != nil {
return nil, nil, err
@ -248,7 +242,7 @@ func (p *PlayerChessData) HandleChess(player *Player, handle_list []*msg.ChessHa
addChessList = append(addChessList, chessId)
buyChess += loseGold
itemList = append(itemList, &item.Item{Id: item.ITEM_STAR_ID, Num: int(-loseGold)})
case msg.HANDLE_TYPE_SELL: //出售棋子
case msg.HANDLE_TYPE_Sell: //出售棋子
items, err := ChessMod.SellChess(chessId)
if checkChess(chessId, BaseMod.GetEnergyMul(), ChessMod.GetEmitList()) { // 在订单中无法生成的棋子 出售获得原价宠物币
items = []*item.Item{{Id: item.ITEM_STAR_ID, Num: mergeDataCfg.GetStarById(chessId)}}
@ -278,7 +272,11 @@ func (p *PlayerChessData) HandleChess(player *Player, handle_list []*msg.ChessHa
// 获取活动道具
ActItem := player.GetActivityItem(GoUtil.Int32ToInt(v.ActType))
itemList = item.Merge(itemList, ActItem)
case msg.HANDLE_TYPE_REMOVE: //移除棋子
case msg.HANDLE_TYPE_Remove: //移除棋子
player.TeLog("remove_chess", map[string]interface{}{
"chess_id": chessId,
"chess_name": mergeDataCfg.GetNameById(chessId),
})
ChessMod.RemoveChess(chessId)
}

View File

@ -28,7 +28,7 @@ import (
"server/game/mod/playroom"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"strconv"
"sync"
"time"
@ -38,9 +38,8 @@ import (
"gitea.bywaystudios.com/pet_home/leaf/log"
"github.com/apache/thrift/lib/go/thrift"
"github.com/robfig/cron/v3"
"google.golang.org/protobuf/proto"
)
// import "reflect"
@ -147,25 +146,25 @@ func (p *Player) SendClientRes() {
p.Msg = make([]PlayerMsg, 0)
}
func (p *Player) PushClientRes(m proto.Message) {
func (p *Player) PushClientRes(m thrift.TStruct) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
data := GoUtil.Marshal(m)
p.Msg = append(p.Msg, PlayerMsg{
F: key,
B: buff,
B: data,
})
}
func (p *Player) PushAndSendClienRes(m proto.Message) {
func (p *Player) PushAndSendClienRes(m thrift.TStruct) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, buff)
data := GoUtil.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, data)
}
func (p *Player) SendErrClienRes(m proto.Message) {
func (p *Player) SendErrClienRes(m thrift.TStruct) {
key := GetStructName(m)
buff, _ := proto.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, buff)
data := GoUtil.Marshal(m)
G_GameLogicPtr.PackResInfo(p.GetAgent(), key, data)
}
func (p *Player) QuestTrigger(tr *quest.Trigger) {
@ -1191,13 +1190,14 @@ func (p *Player) HandleInChampshipRank() {
N: ChampshipMod.GetN(),
},
End: GoUtil.ZeroTimestamp() + 86400, // 第二天零点删除
HandleType: MsgMod.HANDLE_MDO_CHAMPSHIP_INRANK,
HandleType: MsgMod.HANDLE_MOD_CHAMPSHIP_INRANK,
}
SendMsgToCenterAsync(m)
}
func (p *Player) AddLog(uid int, ltype int, param string, send int64) {
FriendMod := p.PlayMod.getFriendMod()
log.Debug("add log uid: %d, type: %d, param: %s, send: %d", uid, ltype, param, send)
Id := FriendMod.AddLog(uid, ltype, param, send)
p.PlayMod.save()
p.PushClientRes(&msg.NotifyFriendLog{

View File

@ -2,16 +2,22 @@ package game
import (
"fmt"
"reflect"
GoUtil "server/game_util"
"server/msg"
"sync"
thrift "github.com/apache/thrift/lib/go/thrift"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
)
var (
protoMessageTypeCacheOnce sync.Once
protoMessageTypeByName sync.Map
protoMessageTypeCacheOnce sync.Once
protoMessageTypeByName sync.Map
thriftMessageTypeCacheOnce sync.Once
thriftMessageTypeByName sync.Map
)
func buildProtoMessageTypeCache() {
@ -26,6 +32,27 @@ func buildProtoMessageTypeCache() {
})
}
func registerThriftType(msgType reflect.Type) {
if msgType == nil || msgType.Kind() != reflect.Ptr {
return
}
elemType := msgType.Elem()
if elemType.Name() != "" {
thriftMessageTypeByName.Store(elemType.Name(), msgType)
}
thriftMessageTypeByName.Store(msgType.String(), msgType)
thriftMessageTypeByName.Store(elemType.String(), msgType)
if elemType.PkgPath() != "" && elemType.Name() != "" {
thriftMessageTypeByName.Store(elemType.PkgPath()+"."+elemType.Name(), msgType)
}
}
func buildThriftMessageTypeCache() {
msg.Processor.Range(func(_ uint16, msgType reflect.Type) {
registerThriftType(msgType)
})
}
func FindProtoMessageTypeByName(name string) (protoreflect.MessageType, error) {
messageType, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(name))
if err == nil {
@ -40,6 +67,15 @@ func FindProtoMessageTypeByName(name string) (protoreflect.MessageType, error) {
return nil, fmt.Errorf("protobuf message type not found: %s", name)
}
func FindThriftMessageTypeByName(name string) (reflect.Type, error) {
thriftMessageTypeCacheOnce.Do(buildThriftMessageTypeCache)
if cachedType, ok := thriftMessageTypeByName.Load(name); ok {
return cachedType.(reflect.Type), nil
}
return nil, fmt.Errorf("thrift message type not found: %s", name)
}
func NewProtoMessageByName(name string) (proto.Message, error) {
messageType, err := FindProtoMessageTypeByName(name)
if err != nil {
@ -49,6 +85,21 @@ func NewProtoMessageByName(name string) (proto.Message, error) {
return messageType.New().Interface(), nil
}
func NewThriftMessageByName(name string) (thrift.TStruct, error) {
messageType, err := FindThriftMessageTypeByName(name)
if err != nil {
return nil, err
}
message := reflect.New(messageType.Elem()).Interface()
thriftMessage, ok := message.(thrift.TStruct)
if !ok {
return nil, fmt.Errorf("thrift message type %s does not implement thrift.TStruct", messageType)
}
return thriftMessage, nil
}
func UnmarshalProtoMessageByName(name string, data []byte) (proto.Message, error) {
message, err := NewProtoMessageByName(name)
if err != nil {
@ -61,3 +112,14 @@ func UnmarshalProtoMessageByName(name string, data []byte) (proto.Message, error
return message, nil
}
func UnmarshalThriftMessageByName(name string, data []byte) (thrift.TStruct, error) {
message, err := NewThriftMessageByName(name)
if err != nil {
return nil, err
}
if err := GoUtil.Unmarshal(data, message); err != nil {
return nil, err
}
return message, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ import (
"server/game/mod/item"
MsqMod "server/game/mod/msg"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"strconv"
)
@ -100,14 +100,14 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
FriendMod := player.PlayMod.getFriendMod()
if Uid == int(player.M_DwUin) {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "cannot apply yourself",
})
return fmt.Errorf("cannot apply yourself")
}
if FriendMod.CheckFriend(Uid) {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "already friend",
})
return fmt.Errorf("already friend")
@ -115,7 +115,7 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
// 好友人数到达上限2000人玩家将无法再发送好友申请
if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "friend list full",
})
return fmt.Errorf("friend list full")
@ -124,7 +124,7 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
sendApplyTime := FriendMod.GetSendApplyTime(Uid)
if sendApplyTime != 0 && GoUtil.Now()-sendApplyTime < oneday {
player.PushClientRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Uid: req.Uid,
Msg: "already applied",
})
@ -136,7 +136,7 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
Items, err := FriendMod.GetSponsorReward()
if err != nil {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -146,7 +146,7 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
err = player.HandleItem(Items, msg.ITEM_POP_LABEL_ApplyFriendSponsor.String())
if err != nil {
player.SendErrClienRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -176,7 +176,7 @@ func ReqApplyFriend(player *Player, req *msg.ReqApplyFriend) error {
}
FriendMgrSend(m)
player.PushClientRes(&msg.ResApplyFriend{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Uid: req.Uid,
})
return nil
@ -188,7 +188,7 @@ func ReqAgreeFriend(player *Player, req *msg.ReqAgreeFriend) error {
FriendMod := player.PlayMod.getFriendMod()
if !FriendMod.CheckApply(Uid) {
player.SendErrClienRes(&msg.ResAgreeFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "apply uid not exist",
})
return fmt.Errorf("apply uid not exist")
@ -196,7 +196,7 @@ func ReqAgreeFriend(player *Player, req *msg.ReqAgreeFriend) error {
// 好友人数到达上限2000人玩家将无法再同意好友申请
if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() {
player.SendErrClienRes(&msg.ResAgreeFriend{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "friend list full",
})
return fmt.Errorf("friend list full")
@ -207,7 +207,7 @@ func ReqAgreeFriend(player *Player, req *msg.ReqAgreeFriend) error {
}
FriendMod.AddFriend(Uid)
player.PushClientRes(&msg.ResAgreeFriend{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Uid: req.Uid,
Player: G_GameLogicPtr.GetResSimplePlayerByUid(int(req.Uid)),
})
@ -243,7 +243,7 @@ func ReqDelFriend(player *Player, req *msg.ReqDelFriend) error {
FriendMod.DelFriend(Uid)
player.PlayMod.save()
player.PushClientRes(&msg.ResDelFriend{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Uid: req.Uid,
})
player.AddLog(Uid, friend.LOG_TYPE_FRIEND_DELETE, "", GoUtil.Now())
@ -261,7 +261,7 @@ func ReqRefuseFriend(player *Player, req *msg.ReqRefuseFriend) error {
FriendMod.RefuseApply(Uid)
player.PlayMod.save()
player.PushClientRes(&msg.ResRefuseFriend{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Uid: req.Uid,
})
now := GoUtil.Now()
@ -302,7 +302,7 @@ func ReqFriendTLUpvote(player *Player, req *msg.ReqFriendTLUpvote) error {
Items, FUid, err := FriendMod.Upvote(int(req.Id))
if err != nil {
player.SendErrClienRes(&msg.ResFriendTLUpvote{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -310,7 +310,7 @@ func ReqFriendTLUpvote(player *Player, req *msg.ReqFriendTLUpvote) error {
err = player.HandleItem(Items, msg.ITEM_POP_LABEL_TLUpvote.String())
if err != nil {
player.SendErrClienRes(&msg.ResFriendTLUpvote{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -329,7 +329,7 @@ func ReqFriendTLUpvote(player *Player, req *msg.ReqFriendTLUpvote) error {
FriendMgrSend(m)
player.PlayMod.save()
player.PushClientRes(&msg.ResFriendTLUpvote{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Id: req.Id,
})
player.TeLog("friend_upvote", map[string]interface{}{
@ -343,7 +343,7 @@ func ReqFriendTReward(player *Player, req *msg.ReqFriendTReward) error {
Items, err := FriendMod.GetReward(int(req.Id))
if err != nil {
player.SendErrClienRes(&msg.ResFriendTReward{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -351,14 +351,14 @@ func ReqFriendTReward(player *Player, req *msg.ReqFriendTReward) error {
err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendTReward.String())
if err != nil {
player.SendErrClienRes(&msg.ResFriendTReward{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
}
player.PlayMod.save()
player.PushClientRes(&msg.ResFriendTReward{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Id: req.Id,
})
return nil
@ -369,12 +369,12 @@ func ReqFriendReplyHandle(player *Player, req *msg.ReqFriendReplyHandle) error {
ReplyInfo := FriendMod.ReplyFriend(int(req.LogId))
if ReplyInfo == nil {
player.SendErrClienRes(&msg.ResFriendReplyHandle{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "reply info not exist",
})
return fmt.Errorf("reply info not exist")
}
ErrType := msg.FRIEND_REPLY_HANDLE_ERR_TYPE_NONE
ErrType := msg.FRIEND_REPLY_HANDLE_ERR_TYPE_None
now := GoUtil.Now()
items := make([]*item.Item, 0)
if ReplyInfo.Type == friend.REPLY_TYPE_GREETING_Get {
@ -439,7 +439,7 @@ func ReqFriendReplyHandle(player *Player, req *msg.ReqFriendReplyHandle) error {
}
player.CatnipBackData()
} else {
ErrType = msg.FRIEND_REPLY_HANDLE_ERR_TYPE_CATNIP
ErrType = msg.FRIEND_REPLY_HANDLE_ERR_TYPE_Catnip
}
}
}
@ -447,7 +447,7 @@ func ReqFriendReplyHandle(player *Player, req *msg.ReqFriendReplyHandle) error {
err := player.HandleItem(items, msg.ITEM_POP_LABEL_FriendReplyHandle.String())
if err != nil {
player.SendErrClienRes(&msg.ResFriendReplyHandle{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -455,7 +455,7 @@ func ReqFriendReplyHandle(player *Player, req *msg.ReqFriendReplyHandle) error {
}
player.FriendLogBackData()
player.PushClientRes(&msg.ResFriendReplyHandle{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
LogId: req.LogId,
Type: req.Type,
ErrType: ErrType,
@ -466,7 +466,7 @@ func ReqFriendReplyHandle(player *Player, req *msg.ReqFriendReplyHandle) error {
func ReqFriendByCode(player *Player, req *msg.ReqFriendByCode) error {
if req.Code == "" {
player.SendErrClienRes(&msg.ResFriendByCode{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "code is empty",
})
return fmt.Errorf("code is empty")
@ -474,7 +474,7 @@ func ReqFriendByCode(player *Player, req *msg.ReqFriendByCode) error {
CodeNum := GoUtil.ParseUniqueStringToInt(req.Code)
if CodeNum <= 0 {
player.SendErrClienRes(&msg.ResFriendByCode{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "code is invalid",
})
return fmt.Errorf("code is invalid")
@ -482,7 +482,7 @@ func ReqFriendByCode(player *Player, req *msg.ReqFriendByCode) error {
Uid := int64(CodeNum) + int64(100000) + int64(conf.Server.AppID*100000000)
if Uid == player.M_DwUin {
player.SendErrClienRes(&msg.ResFriendByCode{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "can not add yourself",
})
return fmt.Errorf("can not add yourself")
@ -491,13 +491,13 @@ func ReqFriendByCode(player *Player, req *msg.ReqFriendByCode) error {
PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(int(Uid))
if PlayerSimpleData == nil {
player.SendErrClienRes(&msg.ResFriendByCode{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: "player not exist",
})
return fmt.Errorf("player not exist")
}
player.PushClientRes(&msg.ResFriendByCode{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Player: PlayerSimpleData,
})
return nil
@ -508,7 +508,7 @@ func ReqAddNpc(player *Player, req *msg.ReqAddNpc) error {
err := FriendMod.SetNpc(int(req.NpcId))
if err != nil {
player.SendErrClienRes(&msg.ResAddNpc{
Code: msg.RES_CODE_FAIL,
Code: msg.RES_CODE_Fail,
Msg: err.Error(),
})
return err
@ -526,7 +526,7 @@ func ReqAddNpc(player *Player, req *msg.ReqAddNpc) error {
FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING_Get, "", GoUtil.Now()+oneday, nil)
player.AddLog(int(req.NpcId), friend.LOG_TYPE_FRIEND_BECOME_NPC, GoUtil.String(req.NpcId), GoUtil.Now())
player.PushClientRes(&msg.ResAddNpc{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
NpcId: req.NpcId,
})
return nil

View File

@ -1,7 +1,7 @@
package game
import (
"server/msg"
msg "server/msg/meowmentnet"
)
func ReqPetFur(player *Player, req *msg.ReqPetFur) error {

View File

@ -25,6 +25,7 @@ const (
PER_SAVE_TIME = 60
MESSAGE_MGR_KEY = "MESSAGE_MGR"
ACTIVITY_MGR_KEY = "ACTIVITY_MGR"
CONFIG_MGR_KEY = "CONFIG_MGR"
)
type ServerMod struct {

View File

@ -17,7 +17,7 @@ import (
"server/game/mod/order"
"server/game/mod/quest"
GoUtil "server/game_util"
"server/msg"
msg "server/msg/meowmentnet"
"sort"
"gitea.bywaystudios.com/pet_home/leaf/log"
@ -47,14 +47,14 @@ func (player *Player) MailTrigger(Tr *quest.Trigger) bool {
tr := false
for _, v := range t {
if player.checkTriggerCondition(v.Trigger) {
Title := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, v.Title)
Content := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_CN, v.Content)
TitleEn := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, v.Title)
ContentEn := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_EN, v.Content)
TitlePtBr := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, v.Title)
ContentPtBr := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_PTBR, v.Content)
TitleEsLatam := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, v.Title)
ContentEsLatam := languageCfg.GetLanguage(msg.LANG_TYPE_LANG_ES_LATAM, v.Content)
Title := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, v.Title)
Content := languageCfg.GetLanguage(msg.LANG_TYPE_LangCn, v.Content)
TitleEn := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, v.Title)
ContentEn := languageCfg.GetLanguage(msg.LANG_TYPE_LangEn, v.Content)
TitlePtBr := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, v.Title)
ContentPtBr := languageCfg.GetLanguage(msg.LANG_TYPE_LangPtbr, v.Content)
TitleEsLatam := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, v.Title)
ContentEsLatam := languageCfg.GetLanguage(msg.LANG_TYPE_LangEsLatam, v.Content)
MailMod.SendMail(&mail.MailStruct{
Title: Title,
SubTitle: "",
@ -102,7 +102,7 @@ func (player *Player) TriggerShippingOrderOrigin(req *msg.ReqShippingOrder) {
if Status == MergeConst.ORDER_STATUS_CANCEL { // 取消支付
player.CancelOrder(OrderSn)
player.PushClientRes(&msg.ResShippingOrder{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
Msg: "cancel success",
})
return
@ -161,7 +161,7 @@ func (player *Player) TriggerShippingOrderOrigin(req *msg.ReqShippingOrder) {
}
player.TeLog("pay", orderDataMap)
player.PushClientRes(&msg.ResShippingOrder{
Code: msg.RES_CODE_SUCCESS,
Code: msg.RES_CODE_Success,
})
player.SendClientRes()
}

View File

@ -11,7 +11,7 @@ import (
"server/game/mod/item"
"server/game/mod/order"
"server/game/mod/quest"
"server/msg"
msg "server/msg/meowmentnet"
"time"
"gitea.bywaystudios.com/pet_home/leaf/log"
@ -375,10 +375,3 @@ func UnitCatnip(p *Player) error {
fmt.Printf("buf len:%dk\n", buf.Len()/1024)
return nil
}
func Benchmark(player *Player) {
ChampshipMod := player.PlayMod.getChampshipMod()
ChampshipMod.AddScore([]int{949, 941, 10})
player.HandleInChampshipRank()
player.HandleInUserRank()
}

View File

@ -42,7 +42,7 @@ func GetDailyVarData(key string) interface{} {
func GetUserVarData(key string, PlayerId int) interface{} {
cache := map[string]*VarExpireData{}
err := LoadCacheVarData(GoUtil.GetVarKey(int(PlayerId)), &cache)
err := LoadUserVarData(GoUtil.GetVarKey(int(PlayerId)), &cache)
if err != nil {
// log.Error("GetUserVarData err : %s, key: %s", err, key)
return nil
@ -194,23 +194,43 @@ func (p *Player) GetCatnipPartner(Uid int) []int {
}
func SaveCacheVarData(key string, value interface{}) {
data, err := GoUtil.GobMarshal(value)
buf, err := json.Marshal(value)
if err != nil {
log.Error("SaveCacheVarData GobMarshal err : %s", err)
log.Error("failed to marshal user var data for key %s: %v", key, err)
return
}
db.RedisSetKeyBytes(key, data, 0)
db.RedisSetKey(key, string(buf), 0)
}
func LoadCacheVarData(key string, value interface{}) error {
data, err := db.RedisGetKeyBytes(key)
data, err := db.RedisGetKey(key)
if err != nil {
return err
}
if data == nil {
if data == "" {
return fmt.Errorf("no data")
}
return GoUtil.GobUnmarshal(data, value)
return json.Unmarshal([]byte(data), value)
}
func SaveUserVarData(key string, value interface{}) {
buf, err := json.Marshal(value)
if err != nil {
log.Error("failed to marshal user var data for key %s: %v", key, err)
return
}
db.RedisSetKey(key, string(buf), 0)
}
func LoadUserVarData(key string, value interface{}) error {
data, err := db.RedisGetKey(key)
if err != nil {
return err
}
if data == "" {
return fmt.Errorf("no data")
}
return json.Unmarshal([]byte(data), value)
}
const (

View File

@ -110,9 +110,42 @@ func (f *VarMgr) version() {
// future version update
f.fixbug() // 修复用户变量冗余数据
f.getData().Version = 2
case 2:
f.translateToRedis() // 将用户变量迁移到Redis
f.getData().Version = 3
}
}
func (f *VarMgr) translateToRedis() {
data := f.getData()
data.mu.Lock()
defer data.mu.Unlock()
for k, v := range data.NewUseVar {
if v == nil {
continue
}
key := GoUtil.GetVarKey(k)
SaveUserVarData(key, v)
log.Debug("translateToRedis: uid %d, varData %+v", k, v)
}
for k, v := range data.NewVar {
if v == nil {
continue
}
SaveCacheVarData(k, v)
log.Debug("translateToRedis: varKey %s, varData %+v", k, v)
}
for k, v := range data.DailyVar {
if v == nil {
continue
}
SaveCacheVarData(k, v)
log.Debug("translateToRedis: dailyVarKey %s, varData %+v", k, v)
}
data.NewVar = make(map[string]*VarExpireData)
data.NewUseVar = make(map[int]map[string]*VarExpireData)
}
func (f *VarMgr) ZeroUpdate() {
data := f.getData()
data.mu.Lock()
@ -124,13 +157,6 @@ func (f *VarMgr) ZeroUpdate() {
Four: Card1,
Five: Card2,
})
for k, v := range data.NewVar {
if v.T < GoUtil.ZeroTimestamp() {
delete(data.NewVar, k)
}
}
// 清空每日变量
data.DailyVar = make(map[string]*VarExpireData)
f.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() {
f.ZeroUpdate()
})
@ -160,25 +186,20 @@ func (f *VarMgr) HandleCatnipPartner(Uid, Partner, GameId int, EndTime int64) (i
}
func (f *VarMgr) SetUserVar(uid int, key string, value interface{}) {
varData := f.getData().NewUseVar[uid]
if varData == nil {
varData = make(map[string]*VarExpireData)
f.getData().NewUseVar[uid] = varData
}
varData := make(map[string]*VarExpireData)
LoadUserVarData(GoUtil.GetVarKey(uid), &varData)
ved, ok := varData[key]
if !ok {
ved = &VarExpireData{}
}
ved.D = value
varData[key] = ved
SaveCacheVarData(GoUtil.GetVarKey(uid), varData)
SaveUserVarData(GoUtil.GetVarKey(uid), varData)
}
func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData {
varData := f.getData().NewUseVar[uid]
if varData == nil {
varData = make(map[string]*VarExpireData)
}
varData := make(map[string]*VarExpireData)
LoadUserVarData(GoUtil.GetVarKey(uid), &varData)
ved, ok := varData[key]
if !ok {
ved = &VarExpireData{}
@ -188,10 +209,10 @@ func (f *VarMgr) GetUserVar(uid int, key string) *VarExpireData {
}
func (f *VarMgr) SetVar(key string, value interface{}) {
f.getData().NewVar[key] = &VarExpireData{
D: value,
}
SaveCacheVarData(key, f.getData().NewVar[key])
data := &VarExpireData{}
LoadCacheVarData(key, data)
data.D = value
SaveCacheVarData(key, data)
}
func (f *VarMgr) getData() *VarData {
@ -227,18 +248,23 @@ func GetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
data := getVarData()
data.mu.Lock()
defer data.mu.Unlock()
userVar := &VarExpireData{}
if v, ok := m.Extra.(msg.VarData); ok {
if varData, ok := data.NewUseVar[m.From]; ok {
userVar, _ = varData[v.Key]
}
if userVar == nil {
userVar = &VarExpireData{}
}
ReplyPlayerMsgASync(m, userVar.D)
return userVar, nil
v, ok := m.Extra.(msg.VarData)
if !ok {
log.Error("GetUserVarDataHandler err : invalid parameters, key: %s", v.Key)
return nil, fmt.Errorf("invalid parameters for getting var data")
}
return nil, fmt.Errorf("invalid parameters for getting var data")
varData := make(map[string]*VarExpireData)
err := LoadUserVarData(GoUtil.GetVarKey(m.From), &varData)
if err != nil {
log.Error("GetUserVarDataHandler err : %s, key: %s", err, v.Key)
return nil, fmt.Errorf("failed to load user var data: %v", err)
}
userVar, _ := varData[v.Key]
if userVar == nil {
userVar = &VarExpireData{}
}
ReplyPlayerMsgASync(m, userVar.D)
return userVar, nil
}
func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
@ -249,10 +275,10 @@ func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
if !ok {
return nil, fmt.Errorf("invalid parameters for setting var data")
}
varData := data.NewUseVar[m.To]
if varData == nil {
varData = make(map[string]*VarExpireData)
data.NewUseVar[m.To] = varData
varData := make(map[string]*VarExpireData)
err := LoadUserVarData(GoUtil.GetVarKey(m.To), &varData)
if err != nil {
log.Debug("SetUserVarDataHandler err : %s, key: %s", err, v.Key)
}
ved := varData[v.Key]
if ved == nil {
@ -264,7 +290,7 @@ func SetUserVarDataHandler(m *msg.Msg) (interface{}, error) {
}
varData[v.Key] = ved
log.Debug("SetUserVarDataHandler: uid %d, key %s, value %v, setType %d, end %d", m.To, v.Key, v.Value, v.SetType, m.End)
SaveCacheVarData(GoUtil.GetVarKey(m.To), varData)
SaveUserVarData(GoUtil.GetVarKey(m.To), varData)
return nil, nil
}

View File

@ -2,6 +2,7 @@ package GoUtil
import (
"bytes"
"context"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
@ -10,6 +11,7 @@ import (
"encoding/base64"
"encoding/gob"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"math"
@ -26,6 +28,7 @@ import (
"gitea.bywaystudios.com/pet_home/leaf/log"
"github.com/apache/thrift/lib/go/thrift"
"github.com/oschwald/geoip2-golang"
)
@ -567,7 +570,7 @@ func GobUnmarshal(data []byte, obj interface{}) error {
decode := gob.NewDecoder(bytes.NewReader(data))
err := decode.Decode(obj)
if err != nil {
log.Debug("GobUnmarshal error: %s", err.Error())
log.Error("GobUnmarshal error: %s", err.Error())
return err
}
return nil
@ -839,7 +842,11 @@ func GetISOCodeByIP(ip string) (string, error) {
}
func GetVarKey(Uid int) string {
return fmt.Sprintf("var_%d", Uid)
return fmt.Sprintf("new_var_%d", Uid)
}
func GetMessageKey(Uid int) string {
return fmt.Sprintf("message_%d", Uid)
}
const (
@ -874,7 +881,7 @@ func NotifyPlayer(uid, pushid int, title, content string) {
req, err := http.NewRequest(method, url, payload)
if err != nil {
log.Debug("notify error:", err)
log.Error("notify error:", err)
return
}
d, _ := time.ParseDuration("30m")
@ -898,14 +905,14 @@ func NotifyPlayer(uid, pushid int, title, content string) {
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
log.Debug("notify error:", err)
log.Error("notify error:", err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
log.Debug("notify error:", err)
log.Error("notify error:", err)
return
}
log.Debug("notification send uid %d, type %d , res %s", uid, pushid, string(body))
@ -966,3 +973,52 @@ func FormatStarItemNum(num, factor int) int {
Num := math.Round(float64(num) * float64(factor) / 100)
return int(Num) / 5 * 5
}
func newCompactSerializer() *thrift.TSerializer {
transport := thrift.NewTMemoryBufferLen(1024)
protocol := thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(transport)
return &thrift.TSerializer{Transport: transport, Protocol: protocol}
}
func newCompactDeserializer() *thrift.TDeserializer {
transport := thrift.NewTMemoryBufferLen(1024)
protocol := thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(transport)
return &thrift.TDeserializer{Transport: transport, Protocol: protocol}
}
func Marshal(m thrift.TStruct) []byte {
serializer := newCompactSerializer()
data, err := serializer.Write(context.Background(), m)
if err != nil {
log.Error("thrift Marshal error:", err)
return nil
}
return data
}
func Unmarshal(data []byte, m thrift.TStruct) error {
deserializer := newCompactDeserializer()
err := deserializer.Read(context.Background(), m, data)
if err != nil {
log.Error("thrift Unmarshal error:", err)
return err
}
return nil
}
func JsonMarshal(v interface{}) ([]byte, error) {
data, err := json.Marshal(v)
if err != nil {
return nil, err
}
return data, nil
}
func JsonUnmarshal(data []byte, v interface{}) error {
err := json.Unmarshal(data, v)
if err != nil {
log.Error("json Unmarshal error:", err)
return err
}
return nil
}

View File

@ -66,7 +66,7 @@ func InitCfg(cfgname string) {
file, err := os.Open(absPath)
if err != nil {
log.Debug("打开文件失败:%v", err)
log.Error("打开文件失败:%v", err)
return
}
defer file.Close()
@ -74,7 +74,7 @@ func InitCfg(cfgname string) {
// 读取文件内容到字节数组
byteValue, err := io.ReadAll(file)
if err != nil {
log.Debug("读取文件失败:%v", err)
log.Error("读取文件失败:%v", err)
return
}
// 移除 BOM
@ -85,7 +85,7 @@ func InitCfg(cfgname string) {
// 反序列化JSON数据
err = json.Unmarshal(byteValue, &data)
if err != nil {
log.Debug("config name:%s,反序列化失败:%v", cfgname, err)
log.Error("config name:%s,反序列化失败:%v", cfgname, err)
return
}
// 直接使用data无需多余拷贝

View File

@ -2,13 +2,14 @@ package gate
import (
"server/game"
"server/msg"
msg "server/msg"
"server/msg/meowmentnet"
)
func init() {
// 这里指定消息 Hello 路由到 game 模块
// 模块间使用 ChanRPC 通讯,消息路由也不例外
msg.Processor.SetRouter(&msg.ClientReq{}, game.ChanRPC)
msg.Processor.SetRouter(&msg.ClientRes{}, game.ChanRPC)
msg.Processor.SetRouter(&msg.AdminReq{}, game.ChanRPC)
msg.Processor.SetRouter(&meowmentnet.ClientReq{}, game.ChanRPC)
msg.Processor.SetRouter(&meowmentnet.ClientRes{}, game.ChanRPC)
msg.Processor.SetRouter(&meowmentnet.AdminReq{}, game.ChanRPC)
}

View File

@ -4,7 +4,7 @@ go 1.25.5
require (
gitea.bywaystudios.com/pet_home/galog v0.0.0-20260313081346-5689712d8f74
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260313092348-57448df16cd8
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260409104501-67c163ff07c2
gitea.bywaystudios.com/pet_home/thinkdata v0.0.0-20260401014936-68c5994be89c
github.com/alibabacloud-go/cloudauth-20190307/v4 v4.9.2
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11
@ -44,7 +44,7 @@ require (
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
golang.org/x/time v0.1.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
@ -57,8 +57,42 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
gitea.bywaystudios.com/pet_home/nacos v0.0.0-20260422063809-d6268b6aa6e3 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 // indirect
github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect
github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 // indirect
github.com/alibabacloud-go/darabonba-string v1.0.2 // indirect
github.com/alibabacloud-go/kms-20160120/v3 v3.2.3 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 // indirect
github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 // indirect
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 // indirect
github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 // indirect
github.com/apache/thrift v0.22.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/deckarep/golang-set v1.7.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/nacos-group/nacos-sdk-go/v2 v2.3.5 // indirect
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.12.2 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

View File

@ -1,13 +1,57 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
gitea.bywaystudios.com/pet_home/galog v0.0.0-20260313081346-5689712d8f74 h1:Z2tn7BpurJXYdKBGThg3SndbLX9ARTy6msRy5ihdrm0=
gitea.bywaystudios.com/pet_home/galog v0.0.0-20260313081346-5689712d8f74/go.mod h1:Sj45tVreK2AFDH+k03Q0uy8paaF6TINOT6vqWIFG4sg=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260313092348-57448df16cd8 h1:qs0cKcOE/uI8ABumwubKR9TKMFa3u9jUR9hQ4SThq4Q=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260313092348-57448df16cd8/go.mod h1:9rWUv5SNj6indAuM2dAT76uO34a/C2FGptEDKkyg21U=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260409020159-53d700ade952 h1:z3vtUEQTdzm5LqH9jwLaLUwU5WYwobwvSpboUu8kpSY=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260409020159-53d700ade952/go.mod h1:v2aZGGOhLPUWCtgtwMztLucxBmk85qsnOuR8X+wDmdQ=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260409104501-67c163ff07c2 h1:EnuWeend4oN/VAjzHcZYibQg5Ksuw9UTG0XJGEJzL6M=
gitea.bywaystudios.com/pet_home/leaf v0.0.0-20260409104501-67c163ff07c2/go.mod h1:v2aZGGOhLPUWCtgtwMztLucxBmk85qsnOuR8X+wDmdQ=
gitea.bywaystudios.com/pet_home/nacos v0.0.0-20260422063809-d6268b6aa6e3 h1:uqq/4VOcpAxjpYH2DwdTc4+VZPGi1Nlavdkcu0mr0V4=
gitea.bywaystudios.com/pet_home/nacos v0.0.0-20260422063809-d6268b6aa6e3/go.mod h1:0VmTyAIjgzP6OWN4IlomxfcGIBsslBdGb1wW+DgojcY=
gitea.bywaystudios.com/pet_home/thinkdata v0.0.0-20260401014936-68c5994be89c h1:FjL8acgHxp1CMi+JSMwD1GXWIe7WIo1h8LoFVaLI87A=
gitea.bywaystudios.com/pet_home/thinkdata v0.0.0-20260401014936-68c5994be89c/go.mod h1:VNNASaG7YCk+7We0m+SQ6/fMacEjx+TTFvcS/1Rp+6Q=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA=
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo=
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
@ -22,6 +66,7 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.9/go.mod h1:bb+Io8Sn2RuM3/Rpme6ll86jMyFSrD1bxeV/+v61KeU=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11 h1:GkVQ9AphMCmgAYakcTpH/OuFz0mQUypO/JiOvo0wgVA=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
@ -36,6 +81,8 @@ github.com/alibabacloud-go/dysmsapi-20170525/v5 v5.1.1 h1:Kle0H03Z85fDLHnO3dadhS
github.com/alibabacloud-go/dysmsapi-20170525/v5 v5.1.1/go.mod h1:mYOaEwXaib4RLB2NY8cXFjKbxPQHUqt6lhPEOvqR8aw=
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
github.com/alibabacloud-go/kms-20160120/v3 v3.2.3 h1:vamGcYQFwXVqR6RWcrVTTqlIXZVsYjaA7pZbx+Xw6zw=
github.com/alibabacloud-go/kms-20160120/v3 v3.2.3/go.mod h1:3rIyughsFDLie1ut9gQJXkWkMg/NfXBCk+OtXnPu3lw=
github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28=
@ -51,6 +98,7 @@ github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/Ke
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA=
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
github.com/alibabacloud-go/tea v1.3.8 h1:Sk2+BDJC//xJ1/Eljf+Dlg2u2tgWpA9P7mlb87AEcEs=
github.com/alibabacloud-go/tea v1.3.8/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
@ -66,6 +114,7 @@ github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQ
github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
github.com/alibabacloud-go/tea-utils/v2 v2.0.3/go.mod h1:sj1PbjPodAVTqGTA3olprfeeqqmwD0A5OQz94o9EuXQ=
github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
@ -73,19 +122,41 @@ github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/
github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0=
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 h1:ie/8RxBOfKZWcrbYSJi2Z8uX8TcOlSMwPlEJh83OeOw=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 h1:nJYyoFP+aqGKgPs9JeZgS1rWQ4NndNR0Zfhh161ZltU=
github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1/go.mod h1:WzGOmFFTlUzXM03CJnHWMQ85UN6QGpOXZocCjwkiyOg=
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8 h1:QeUdR7JF7iNCvO/81EhxEr3wDwxk4YBoYZOq6E0AjHI=
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.8/go.mod h1:xP0KIZry6i7oGPF24vhAPr1Q8vLZRcMcxtft5xDKwCU=
github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 h1:8S0mtD101RDYa0LXwdoqgN0RxdMmmJYjq8g2mk7/lQ4=
github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5/go.mod h1:M19fxYz3gpm0ETnoKweYyYtqrtnVtrpKFpwsghbw+cQ=
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/aliyun/credentials-go v1.4.6 h1:CG8rc/nxCNKfXbZWpWDzI9GjF4Tuu3Es14qT8Y0ClOk=
github.com/aliyun/credentials-go v1.4.6/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc=
github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
@ -94,11 +165,23 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
@ -107,45 +190,105 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -153,27 +296,67 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nacos-group/nacos-sdk-go/v2 v2.3.5 h1:Hux7C4N4rWhwBF5Zm4yyYskrs9VTgrRTA8DZjoEhQTs=
github.com/nacos-group/nacos-sdk-go/v2 v2.3.5/go.mod h1:ygUBdt7eGeYBt6Lz2HO3wx7crKXk25Mp80568emGMWU=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc h1:Ak86L+yDSOzKFa7WM5bf5itSOo1e3Xh8bm5YCMUXIjQ=
github.com/orcaman/concurrent-map v0.0.0-20210501183033-44dafcb38ecc/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNsSFzQATJI=
github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
@ -183,11 +366,19 @@ github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZ
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
@ -200,13 +391,24 @@ go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2W
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
@ -214,11 +416,39 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
@ -226,18 +456,41 @@ golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
@ -248,29 +501,75 @@ golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
@ -285,6 +584,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
@ -292,28 +592,73 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
@ -321,17 +666,73 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
@ -340,17 +741,47 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -1,14 +1,16 @@
package msg
import (
"gitea.bywaystudios.com/pet_home/leaf/network/protobuf"
"server/msg/meowmentnet"
"gitea.bywaystudios.com/pet_home/leaf/network/thrift"
)
var Processor = protobuf.NewProcessor()
var Processor = thrift.NewProcessor()
func init() {
Processor.Register(&ClientReq{})
Processor.Register(&ClientRes{})
Processor.Register(&AdminReq{})
Processor.Register(&AdminRes{})
Processor.Register(&meowmentnet.ClientReq{})
Processor.Register(&meowmentnet.ClientRes{})
Processor.Register(&meowmentnet.AdminReq{})
Processor.Register(&meowmentnet.AdminRes{})
}

View File

@ -1,6 +1,15 @@
package unit
import "testing"
import (
"fmt"
languageCfg "server/conf/language"
notification_cfg "server/conf/notification"
"server/game"
GoUtil "server/game_util"
"server/msg"
"server/msg/meowmentnet"
"testing"
)
func TestCatReturnGift(t *testing.T) {
player := getTestPlayer()
@ -9,3 +18,10 @@ func TestCatReturnGift(t *testing.T) {
player.GetCatReturnGiftMod().Id = 26
player.CatReturnGiftZeroUpdate()
}
func TestNotification(t *testing.T) {
titlekey, infokey := notification_cfg.GetFriendApplyNotificationMsg()
title := languageCfg.GetLanguage(meowmentnet.LANG_TYPE(msg.LANG_TYPE_LANG_CN), titlekey)
info := languageCfg.GetLanguage(meowmentnet.LANG_TYPE(msg.LANG_TYPE_LANG_CN), infokey)
GoUtil.NotifyPlayer(GoUtil.Int(3790944), game.NOTIFY_TYPE_PETROOM_GAME, fmt.Sprintf(title, "猫猫"), fmt.Sprintf(info, "猫猫"))
}

View File

@ -18,3 +18,21 @@ func TestInteract(t *testing.T) {
PlayroomMod := player.GetPlayroomMod()
PlayroomMod.AddInteractNum(BaseMod.GetLevel())
}
func TestConfigMgr(t *testing.T) {
configMgr := &game.ConfigMgr{}
configMgr.Init()
gameConfig := configMgr.GetGameConfig()
if gameConfig == nil {
t.Error("Failed to load game config")
} else {
t.Logf("Game config loaded successfully: %v", gameConfig)
}
testUids := configMgr.GetTestUids()
if testUids == nil {
t.Error("Failed to get test UIDs")
} else {
t.Logf("Test UIDs: %v", testUids)
}
}