From 74e1d4d3c0ac419d02d97362c0ea6442898d7f39 Mon Sep 17 00:00:00 2001 From: 王家文 Date: Mon, 27 May 2024 12:18:10 +0800 Subject: [PATCH] feat✨:配置管理 --- conf/bytes/abtestcfg.bytes | 5 +++++ configs-db/confapi/config.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confapi/get.go | 19 +++++++++++++++++++ configs-db/confbase/external.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confbase/interface.go | 31 +++++++++++++++++++++++++++++++ configs-db/confcardholder/config.go | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confcardholder/decode.go | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confcardholder/get.go | 24 ++++++++++++++++++++++++ configs-db/confglobal/config.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confglobal/get.go | 19 +++++++++++++++++++ configs-db/confroomrank/config.go | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confroomrank/decode.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ configs-db/confroomrank/get.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ configs-db/init.go | 29 +++++++++++++++++++++++++++++ configs/confapi/config.go | 48 ------------------------------------------------ configs/confapi/get.go | 19 ------------------- configs/confbase/external.go | 113 ----------------------------------------------------------------------------------------------------------------- configs/confbase/interface.go | 31 ------------------------------- configs/confcardholder/config.go | 152 -------------------------------------------------------------------------------------------------------------------------------------------------------- configs/confcardholder/decode.go | 170 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- configs/confcardholder/get.go | 24 ------------------------ configs/confglobal/config.go | 67 ------------------------------------------------------------------- configs/confglobal/get.go | 19 ------------------- configs/config.go | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs/confroomrank/config.go | 129 --------------------------------------------------------------------------------------------------------------------------------- configs/confroomrank/decode.go | 50 -------------------------------------------------- configs/confroomrank/get.go | 44 -------------------------------------------- configs/external.go | 42 ++++++++++++++++++++++++++++++++++++++++++ configs/init.go | 29 ----------------------------- configs/reader.go | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configs/utils.go | 14 ++++++++++++++ controllers/admin.go | 2 +- controllers/demo.go | 13 +++++++++++-- go.mod | 6 +++--- main.go | 5 +++++ middleware/sign/index.go | 2 +- service-common/svcommon/simulate.go | 6 +++--- service-common/svredis/index.go | 6 +++--- service/cardholder/handle.go | 16 ++++++++-------- service/cardholder/logic.go | 12 ++++++------ service/cardholder/player.go | 2 +- service/roomrank/handle.go | 2 +- service/roomrank/logic.go | 6 +++--- service/roomrank/player.go | 6 +++--- service/roomrank/room.go | 2 +- util/utmap/map.go | 66 ------------------------------------------------------------------ util/utmisc/goroutine.go | 15 --------------- util/utmisc/random.go | 21 --------------------- util/utslice/slice.go | 161 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- util/utstring/list.go | 51 --------------------------------------------------- util/utstring/string.go | 30 ------------------------------ util/uttype/equals.go | 8 -------- util/uttype/type.go | 21 --------------------- util/utuuid/uuid.go | 7 ------- util/zconvert/list.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/zconvert/map.go | 25 +++++++++++++++++++++++++ util/zconvert/number.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ util/zmap/map.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/zmisc/goroutine.go | 15 +++++++++++++++ util/zmisc/random.go | 21 +++++++++++++++++++++ util/zslice/slice.go | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/ztype/compare.go | 17 +++++++++++++++++ util/ztype/equals.go | 8 ++++++++ util/ztype/type.go | 25 +++++++++++++++++++++++++ util/zuuid/uuid.go | 7 +++++++ 65 files changed, 2067 insertions(+), 1311 deletions(-) create mode 100644 conf/bytes/abtestcfg.bytes create mode 100644 configs-db/confapi/config.go create mode 100644 configs-db/confapi/get.go create mode 100644 configs-db/confbase/external.go create mode 100644 configs-db/confbase/interface.go create mode 100644 configs-db/confcardholder/config.go create mode 100644 configs-db/confcardholder/decode.go create mode 100644 configs-db/confcardholder/get.go create mode 100644 configs-db/confglobal/config.go create mode 100644 configs-db/confglobal/get.go create mode 100644 configs-db/confroomrank/config.go create mode 100644 configs-db/confroomrank/decode.go create mode 100644 configs-db/confroomrank/get.go create mode 100644 configs-db/init.go delete mode 100644 configs/confapi/config.go delete mode 100644 configs/confapi/get.go delete mode 100644 configs/confbase/external.go delete mode 100644 configs/confbase/interface.go delete mode 100644 configs/confcardholder/config.go delete mode 100644 configs/confcardholder/decode.go delete mode 100644 configs/confcardholder/get.go delete mode 100644 configs/confglobal/config.go delete mode 100644 configs/confglobal/get.go create mode 100644 configs/config.go delete mode 100644 configs/confroomrank/config.go delete mode 100644 configs/confroomrank/decode.go delete mode 100644 configs/confroomrank/get.go create mode 100644 configs/external.go delete mode 100644 configs/init.go create mode 100644 configs/reader.go create mode 100644 configs/utils.go delete mode 100644 util/utmap/map.go delete mode 100644 util/utmisc/goroutine.go delete mode 100644 util/utmisc/random.go delete mode 100644 util/utslice/slice.go delete mode 100644 util/utstring/list.go delete mode 100644 util/utstring/string.go delete mode 100644 util/uttype/equals.go delete mode 100644 util/uttype/type.go delete mode 100644 util/utuuid/uuid.go create mode 100644 util/zconvert/list.go create mode 100644 util/zconvert/map.go create mode 100644 util/zconvert/number.go create mode 100644 util/zmap/map.go create mode 100644 util/zmisc/goroutine.go create mode 100644 util/zmisc/random.go create mode 100644 util/zslice/slice.go create mode 100644 util/ztype/compare.go create mode 100644 util/ztype/equals.go create mode 100644 util/ztype/type.go create mode 100644 util/zuuid/uuid.go diff --git a/conf/bytes/abtestcfg.bytes b/conf/bytes/abtestcfg.bytes new file mode 100644 index 0000000..12f7577 --- /dev/null +++ b/conf/bytes/abtestcfg.bytes @@ -0,0 +1,5 @@ + +]default (*regtime,1900-01-01 00:00:002/Signin,1|randomOrderAndBoard,1|limitTimeGoods,1 +\signin) <*regtime,1900-01-01 00:00:002/Signin,2|randomOrderAndBoard,1|limitTimeGoods,1 +irandomOrderAndBoard= P*regtime,1900-01-01 00:00:002/Signin,1|randomOrderAndBoard,2|limitTimeGoods,1 +dlimitTimeGoodsP d*regtime,1900-01-01 00:00:002/Signin,1|randomOrderAndBoard,1|limitTimeGoods,2 \ No newline at end of file diff --git a/configs-db/confapi/config.go b/configs-db/confapi/config.go new file mode 100644 index 0000000..5073b22 --- /dev/null +++ b/configs-db/confapi/config.go @@ -0,0 +1,48 @@ +package confapi + +import ( + "apigame/configs-db/confbase" + "apigame/service-common/svconst" + "fmt" +) + +// ApiGameConfig api游戏配置 +type ApiGameConfig struct { + Raw *Raw +} + +func (c *ApiGameConfig) GetUid() string { + return c.Raw.GameId +} + +func (c *ApiGameConfig) CheckCurrent() bool { + return true +} + +func (c *ApiGameConfig) ConfInfo(suffix string) *confbase.ConfInfo { + tableName := "s_game_config" + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) + return &confbase.ConfInfo{ + DbMysql: svconst.DbApi, + TableName: tableName, + KeyName: "gameid", + CacheKey: cacheKey, + CacheCurrent: cacheKey + ":current", + CacheTime: 300, + } +} + +// Raw 配置原始数据 +type Raw struct { + AppId string `gorm:"column:appid"` + GameId string `gorm:"column:gameid"` + Secret string `gorm:"column:secret"` + AppKey string `gorm:"column:appkey"` + Name string `gorm:"column:name"` +} + +// Decode 解析配置原始数据 +func (c *ApiGameConfig) Decode(gameId string, rawData any) { + raw := rawData.(*Raw) + c.Raw = raw +} diff --git a/configs-db/confapi/get.go b/configs-db/confapi/get.go new file mode 100644 index 0000000..1f13c10 --- /dev/null +++ b/configs-db/confapi/get.go @@ -0,0 +1,19 @@ +package confapi + +import ( + "apigame/configs-db/confbase" + "errors" +) + +// GetConfig 获取 api游戏配置 +func GetConfig(gameId string) (conf *ApiGameConfig, err error) { + + conf = new(ApiGameConfig) + has := confbase.GetConfig[*ApiGameConfig, Raw](gameId, gameId, conf) + if !has { + err = errors.New("confapi.GetConfig error") + return + } + + return +} diff --git a/configs-db/confbase/external.go b/configs-db/confbase/external.go new file mode 100644 index 0000000..a3568db --- /dev/null +++ b/configs-db/confbase/external.go @@ -0,0 +1,113 @@ +package confbase + +import ( + "apigame/util/util-lx/lxalilog" + "apigame/util/zjson" + "apigame/util/zredis" + "fmt" + "runtime/debug" +) + +var CacheState = 1 // 0=关闭 1=打开 + +func SaveCache[T IConfData](gameId string, obj T) { + info := obj.ConfInfo(gameId) + _ = zredis.SetEx(info.CacheKey, zjson.Str(obj), info.CacheTime) +} + +func LoadCache[T IConfData](gameId string, obj T) (has bool) { + if CacheState == 0 { + return false + } + has = true + info := obj.ConfInfo(gameId) + text, err := zredis.Get(info.CacheKey) + if err != nil { + has = false + return + } + err = zjson.Obj(text, &obj) + if err != nil { + fmt.Println(err) + has = false + return + } + return +} + +func LoadData[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) { + confRaw := new(T2) + info := obj.ConfInfo(gameId) + db := info.DbMysql + result := db.Table(info.TableName).Where(fmt.Sprintf("%s = ?", info.KeyName), confId).First(confRaw) + + has = result.RowsAffected != 0 + err := result.Error + if err != nil { + lxalilog.Errors(err, "confbase.LoadData error", gameId, confId) + fmt.Printf("%s", debug.Stack()) + return + } + if !has { + return + } + + obj.Decode(gameId, confRaw) + return +} + +func FindDuringTime[T1 IConfData, T2 IConfRawData](obj T1, raw *T2, gameId string) (has bool) { + info := obj.ConfInfo(gameId) + db := info.DbMysql + result := db.Table(info.TableName).Where(info.CurrentQuery, info.CurrentArgs...).First(raw) + has = result.RowsAffected != 0 + return +} + +func GetConfig[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) { + has = LoadCache(gameId, obj) + if has { + return + } + has = LoadData[T1, T2](gameId, confId, obj) + if !has { + return + } + SaveCache(gameId, obj) + return +} + +// GetCurrent 获取 当前配置 +func GetCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool { + has := false + info := obj.ConfInfo(gameId) + currentKey := info.CacheCurrent + currentId := zredis.GetString(currentKey) + if currentId != "" { + has = GetConfig[T1, T2](gameId, currentId, obj) + if has { + if !obj.CheckCurrent() { + has = false + } + } + } + return has +} + +// FindCurrent 查找 当前配置 +func FindCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool { + has := false + info := obj.ConfInfo(gameId) + currentKey := info.CacheCurrent + currentId := zredis.GetString(currentKey) + confRaw := new(T2) + has = FindDuringTime[T1, T2](obj, confRaw, gameId) + if has { + obj.Decode(gameId, confRaw) + SaveCache(gameId, obj) + has = true + currentId = obj.GetUid() + _ = zredis.Set(currentKey, currentId) + } + return has +} diff --git a/configs-db/confbase/interface.go b/configs-db/confbase/interface.go new file mode 100644 index 0000000..7974c97 --- /dev/null +++ b/configs-db/confbase/interface.go @@ -0,0 +1,31 @@ +package confbase + +import "gorm.io/gorm" + +// ConfInfo 配置对象信息 +type ConfInfo struct { + DbMysql *gorm.DB + TableName string + KeyName string + CurrentQuery any + CurrentArgs []any + CacheKey string + CacheCurrent string + CacheTime int +} + +// IConfData 配置对象 +type IConfData interface { + // ConfInfo redis存储信息 + ConfInfo(suffix string) *ConfInfo + // Decode 解码 + Decode(gameId string, rawData any) + // GetUid 获取keyID + GetUid() string + // CheckCurrent 判断当前开放 + CheckCurrent() bool +} + +// IConfRawData mysql存储对象 +type IConfRawData interface { +} diff --git a/configs-db/confcardholder/config.go b/configs-db/confcardholder/config.go new file mode 100644 index 0000000..edf63c4 --- /dev/null +++ b/configs-db/confcardholder/config.go @@ -0,0 +1,152 @@ +package confcardholder + +import ( + "apigame/configs-db/confbase" + "apigame/service-common/svconst" + "apigame/util/util-lx/lxtime" + "apigame/util/zconvert" + "fmt" +) + +// ActivityConfig 卡牌活动配置 分析后数据 +type ActivityConfig struct { + Raw *ActivityConfigRaw `json:"-"` + + Id int64 // ID + OpenLevel int // 开启等级 + PreviewTime int64 // 预告时间 + StartTime int64 // 开始时间 + EndTime int64 // 结束时间 + Round int // 轮数 + IconPath string // icon资源路径 + + Awards map[string]string // 奖励配置 + AlbumConfig map[int]AlbumConfig // 卡组配置 + CardConfig map[int]CardConfig // 卡牌配置 + CardholderConfig map[int]OpenCardholderConfig // 卡包开卡规则 + NormalCardStarConfig map[string]NormalCardStarConfig // k=ID_用户序列_用户分组 卡片星级配置 + CardSequenceConfig map[string]CardSequenceConfig // k=ID_用户序列_用户分组 卡片星级对应卡牌配置 + StarShopConfig map[int]StarShopConfig // 星星商店配置 + + Client *ActivityConfigClient + GameId string // 所属游戏ID +} + +func (c *ActivityConfig) GetUid() string { + return zconvert.Int64ToStr(c.Id) +} + +func (c *ActivityConfig) CheckCurrent() bool { + timeNow := lxtime.NowUninx() + return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1 +} + +func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo { + tableName := svconst.MYSQL_TABLE_S_CARDHOLDER_CONFIG + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) + timeNow := lxtime.NowUninx() + return &confbase.ConfInfo{ + DbMysql: svconst.DbConfig, + TableName: fmt.Sprintf("%s_%s", tableName, suffix), + KeyName: "id", + CurrentQuery: "status = ? AND start_time <= ? AND end_time >= ?", + CurrentArgs: []any{1, timeNow, timeNow}, + CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id), + CacheCurrent: cacheKey + ":current", + CacheTime: 300, + } +} + +// ActivityConfigRaw 卡牌活动配置 原始数据 +type ActivityConfigRaw struct { + Id int64 `gorm:"column:id;primaryKey"` // ID + OpenLevel int // 开启等级 + PreviewTime int64 // 预告时间 + StartTime int64 // 开始时间 + EndTime int64 // 结束时间 + Round int // 轮数 + IconPath string // icon资源路径 + + Awards string // 奖励配置 + AlbumConfig string // 卡组配置 + CardConfig string // 卡牌配置 + CardHolderConfig string // 卡包开卡规则 + NormalCardStarSequence string // 卡片星级配置 + CardSequenceConfig string // 卡片星级对应卡牌配置 + StarShopConfig string // 星星商店配置 + + Ver string // 版本号 + Status int // 状态 0=关闭 1=开启 + UpdateTime int64 // 修改时间戳 +} + +// ActivityConfigClient 卡牌活动配置 给客户端数据 +type ActivityConfigClient struct { + Id int64 `form:"id" json:"id"` // ID + Round int `form:"round" json:"round"` // 轮数 + IconPath string `form:"icon_path" json:"icon_path"` // icon资源路径 + RoundAwards map[string]string `form:"round_awards" json:"round_awards"` // 轮次奖励配置 + Albums []AlbumConfig `form:"albums" json:"albums"` // 卡组配置 + Cards []CardConfig `form:"cards" json:"cards"` // 卡牌配置 + Holders []OpenCardholderConfig `form:"holders" json:"holders"` // 卡包开卡规则 + StarShop []StarShopConfig `form:"star_shop" json:"star_shop"` // 星星商店配置 +} + +// AlbumConfig 卡组表 +type AlbumConfig struct { + SetId int `json:"set_id"` // 卡组名 + Name int `json:"name"` // 卡组图片 + Icon string `json:"icon"` // 卡组id + Rewards map[string]string `json:"rewards"` // 集齐奖励 k=轮次 + StartTime int64 `json:"start_time"` // 开始时间 + EndTime int64 `json:"end_time"` // 结束时间 +} + +// CardConfig 卡牌表 +type CardConfig struct { + Id int `json:"id"` // ID + Name int `json:"name"` // 卡牌名字 + Icon string `json:"icon"` // 卡牌图标 + Desc int `json:"desc"` // 卡牌描述 + SetId int `json:"album_setid"` // 卡组id + Star int `json:"star"` // 星级 + IsGold int `json:"is_gold"` // 是否是金卡 + IsSend int `json:"is_send"` // 卡片是否可赠送 +} + +// OpenCardholderConfig 卡包开卡规则表 +type OpenCardholderConfig struct { + Id int `json:"id"` // ID + CardPackIcon string `json:"img"` // 卡包资源名 + IsGoldCardholder int `json:"is_gold_card_holder"` // 是否是金卡包 + IsNew int `json:"is_new"` // 是否是新卡包 + GuaranteedStarCardId int `json:"guaranteed_star_card_id"` // 保底卡星级序列ID + NormalCardNumber int `json:"normal_card_number"` // 非保底卡数量 + MinimumGuaranteeCardId int `json:"minimum_guarantee_card_id"` // 非保底卡牌序列ID + ActivityId int `json:"activity_id"` // 对应活动ID + Star int `json:"star"` // star + Name int `json:"name"` // name +} + +// NormalCardStarConfig 非保底卡星级ID +type NormalCardStarConfig struct { + Id int `json:"id"` // ID + SequenceId int `json:"user_sequence_id"` // 用户序列组ID + Cohort int `json:"cohort"` // 用户分组 + NormalCardSequenceId []int `json:"normal_card_sequence_id"` // 非保底星级序列 +} + +// CardSequenceConfig 星级ID对应的卡片 +type CardSequenceConfig struct { + Id int `json:"id"` // ID + SequenceId int `json:"user_sequence_id"` // 用户序列组ID + Cohort int `json:"cohort"` // 用户分组 + CardIdList []int `json:"card_id_list"` // 卡牌抽取序列 +} + +// StarShopConfig 星星商店配置 +type StarShopConfig struct { + Id int `json:"id"` // ID + NeedStarNumber int `json:"need_star_number"` // 需求星星数 + CardBagIds string `json:"card_bag_ids"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量} +} diff --git a/configs-db/confcardholder/decode.go b/configs-db/confcardholder/decode.go new file mode 100644 index 0000000..629d92d --- /dev/null +++ b/configs-db/confcardholder/decode.go @@ -0,0 +1,170 @@ +package confcardholder + +import ( + "apigame/util/util-lx/lxalilog" + "encoding/json" + "errors" + "fmt" +) + +// Decode 解析配置原始数据 +func (c *ActivityConfig) Decode(gameId string, rawData any) { + raw := rawData.(*ActivityConfigRaw) + c.GameId = gameId + c.Raw = raw + + c.Id = raw.Id + c.OpenLevel = raw.OpenLevel + c.PreviewTime = raw.PreviewTime + c.StartTime = raw.StartTime + c.EndTime = raw.EndTime + c.Round = raw.Round + c.IconPath = raw.IconPath + + c.Awards = make(map[string]string) + c.AlbumConfig = make(map[int]AlbumConfig) + c.CardConfig = make(map[int]CardConfig) + c.CardholderConfig = make(map[int]OpenCardholderConfig) + c.NormalCardStarConfig = make(map[string]NormalCardStarConfig) + c.CardSequenceConfig = make(map[string]CardSequenceConfig) + c.StarShopConfig = make(map[int]StarShopConfig) + // 解析奖励 + { + err := json.Unmarshal([]byte(raw.Awards), &c.Awards) + if err != nil { + lxalilog.Errors(err, raw.Awards, gameId, raw.Id) + return + } + } + // 卡组配置 + { + configs := make([]AlbumConfig, 0) + err := json.Unmarshal([]byte(raw.AlbumConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.AlbumConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.AlbumConfig[i2.SetId] = i2 + } + } + // 卡牌配置 + { + configs := make([]CardConfig, 0) + err := json.Unmarshal([]byte(raw.CardConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.CardConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.CardConfig[i2.Id] = i2 + } + } + // 卡包开卡规则 + { + configs := make([]OpenCardholderConfig, 0) + err := json.Unmarshal([]byte(raw.CardHolderConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.CardHolderConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.CardholderConfig[i2.Id] = i2 + } + } + // 卡片星级配置 + { + configs := make([]NormalCardStarConfig, 0) + err := json.Unmarshal([]byte(raw.NormalCardStarSequence), &configs) + if err != nil { + lxalilog.Errors(err, raw.NormalCardStarSequence, gameId, raw.Id) + return + } + for _, i2 := range configs { + combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort) + c.NormalCardStarConfig[combineId] = i2 + } + } + // 卡片星级对应卡牌配置 + { + configs := make([]CardSequenceConfig, 0) + err := json.Unmarshal([]byte(raw.CardSequenceConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.CardSequenceConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort) + c.CardSequenceConfig[combineId] = i2 + } + } + // 星星商店配置 + { + configs := make([]StarShopConfig, 0) + err := json.Unmarshal([]byte(raw.StarShopConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.StarShopConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.StarShopConfig[i2.Id] = i2 + } + } + + c.GenerateConfigClient() +} + +// GenerateConfigClient 生成给客户端的配置 +func (c *ActivityConfig) GenerateConfigClient() { + configClient := &ActivityConfigClient{ + Id: c.Id, + Round: c.Round, + IconPath: c.IconPath, + RoundAwards: c.Awards, + Albums: make([]AlbumConfig, 0), + Cards: make([]CardConfig, 0), + Holders: make([]OpenCardholderConfig, 0), + StarShop: make([]StarShopConfig, 0), + } + for _, i2 := range c.AlbumConfig { + configClient.Albums = append(configClient.Albums, i2) + } + for _, i2 := range c.CardConfig { + configClient.Cards = append(configClient.Cards, i2) + } + for _, i2 := range c.CardholderConfig { + configClient.Holders = append(configClient.Holders, i2) + } + for _, i2 := range c.StarShopConfig { + configClient.StarShop = append(configClient.StarShop, i2) + } + c.Client = configClient +} + +// CombineIdSequenceIdCohort 组合ID k=ID_用户序列_用户分组 +func CombineIdSequenceIdCohort(id, sequenceId, cohort int) string { + return fmt.Sprintf("%d_%d_%d", id, sequenceId, cohort) +} + +// FindNormalCardStarConfig 查找配置 非保底卡星级ID +func (c *ActivityConfig) FindNormalCardStarConfig(id, sequenceId, cohort int) (conf NormalCardStarConfig, has bool) { + combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort) + conf, has = c.NormalCardStarConfig[combineId] + if !has { + lxalilog.Errors(errors.New("ht_cardholder NormalCardStarConfig error"), id, sequenceId, cohort) + } + return +} + +// FindCardSequenceConfig 查找配置 星级ID对应的卡片 +func (c *ActivityConfig) FindCardSequenceConfig(id, sequenceId, cohort int) (conf CardSequenceConfig, has bool) { + combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort) + conf, has = c.CardSequenceConfig[combineId] + if !has { + lxalilog.Errors(errors.New("ht_cardholder CardSequenceConfig error"), id, sequenceId, cohort) + fmt.Println(id) + fmt.Println(sequenceId) + fmt.Println(cohort) + } + return +} diff --git a/configs-db/confcardholder/get.go b/configs-db/confcardholder/get.go new file mode 100644 index 0000000..6b1f161 --- /dev/null +++ b/configs-db/confcardholder/get.go @@ -0,0 +1,24 @@ +package confcardholder + +import ( + "apigame/configs-db/confbase" +) + +// GetCurrent 获取 当前配置 +func GetCurrent(gameId string) (conf *ActivityConfig, has bool) { + conf = new(ActivityConfig) + has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) + if !has { + conf = new(ActivityConfig) + has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) + } + return +} + +// GetConfig 获取 配置根据Id +func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) { + conf = new(ActivityConfig) + has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf) + + return +} diff --git a/configs-db/confglobal/config.go b/configs-db/confglobal/config.go new file mode 100644 index 0000000..6d60780 --- /dev/null +++ b/configs-db/confglobal/config.go @@ -0,0 +1,67 @@ +package confglobal + +import ( + "apigame/configs-db/confbase" + "apigame/service-common/svconst" + "apigame/util/util-lx/lxalilog" + "encoding/json" + "fmt" +) + +// GlobalConfig 全局配置 +type GlobalConfig struct { + Raw *Raw `json:"-"` + Names []string + Avatars []string + AvatarPath string +} + +func (c *GlobalConfig) GetUid() string { + return c.Raw.GameId +} + +func (c *GlobalConfig) CheckCurrent() bool { + return true +} + +func (c *GlobalConfig) ConfInfo(suffix string) *confbase.ConfInfo { + tableName := "s_game_global_config" + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) + return &confbase.ConfInfo{ + DbMysql: svconst.DbConfig, + TableName: tableName, + KeyName: "gameid", + CacheKey: cacheKey, + CacheCurrent: cacheKey + ":current", + CacheTime: 300, + } +} + +// Raw 配置原始数据 +type Raw struct { + GameId string `gorm:"column:gameid"` + NameConfig string + AvatarConfig string + AvatarPath string +} + +// Decode 解析配置原始数据 +func (c *GlobalConfig) Decode(gameId string, rawData any) { + raw := rawData.(*Raw) + c.Raw = raw + { + err := json.Unmarshal([]byte(raw.NameConfig), &c.Names) + if err != nil { + lxalilog.Errors(err, raw.NameConfig, gameId, raw.GameId) + return + } + } + { + err := json.Unmarshal([]byte(raw.AvatarConfig), &c.Avatars) + if err != nil { + lxalilog.Errors(err, raw.AvatarConfig, gameId, raw.GameId) + return + } + } + c.AvatarPath = raw.AvatarPath +} diff --git a/configs-db/confglobal/get.go b/configs-db/confglobal/get.go new file mode 100644 index 0000000..0ad90fe --- /dev/null +++ b/configs-db/confglobal/get.go @@ -0,0 +1,19 @@ +package confglobal + +import ( + "apigame/configs-db/confbase" + "errors" +) + +// GetConfig 获取 api游戏配置 +func GetConfig(gameId string) (conf *GlobalConfig, err error) { + + conf = new(GlobalConfig) + has := confbase.GetConfig[*GlobalConfig, Raw](gameId, gameId, conf) + if !has { + err = errors.New("confglobal.GetConfig error") + return + } + + return +} diff --git a/configs-db/confroomrank/config.go b/configs-db/confroomrank/config.go new file mode 100644 index 0000000..bf24f63 --- /dev/null +++ b/configs-db/confroomrank/config.go @@ -0,0 +1,129 @@ +package confroomrank + +import ( + "apigame/configs-db/confbase" + "apigame/service-common/svconst" + "apigame/util/util-lx/lxtime" + "apigame/util/zconvert" + "fmt" +) + +// ActivityConfig 房间排行活动配置 分析后数据 +type ActivityConfig struct { + Raw *ActivityConfigRaw `json:"-"` + + Id int64 // ID + Typ int // 排行榜类型 + OpenLevel int // 开启等级 + OpenScore int64 // 开启积分 + PreviewTime int64 // 预告时间 + StartTime int64 // 开始时间 + EndTime int64 // 结束时间 + ReleaseTime string // 结算发奖时间 + + Robot map[int]RobotConfig // 机器人配置 + Room map[int]RoomConfig // 房间配置 + + GameId string // 所属游戏ID +} + +func (c *ActivityConfig) GetUid() string { + return zconvert.Int64ToStr(c.Id) +} + +func (c *ActivityConfig) CheckCurrent() bool { + timeNow := lxtime.NowUninx() + return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1 +} + +func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo { + tableName := svconst.MYSQL_TABLE_S_ROOMRANK_CONFIG + cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) + timeNow := lxtime.NowUninx() + return &confbase.ConfInfo{ + DbMysql: svconst.DbConfig, + TableName: fmt.Sprintf("%s_%s", tableName, suffix), + KeyName: "id", + CurrentQuery: "typ = ? AND status = ? AND start_time <= ? AND end_time >= ?", + CurrentArgs: []any{c.Typ, 1, timeNow, timeNow}, + CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id), + CacheCurrent: fmt.Sprintf("%s:%d:current", cacheKey, c.Typ), + CacheTime: 300, + } +} + +// ActivityConfigRaw 房间排行活动配置 原始数据 +type ActivityConfigRaw struct { + Id int64 `gorm:"column:id;primaryKey"` // ID + Serial int64 // 轮次ID + Typ int // 排行榜类型 + OpenLevel int // 开启等级 + OpenScore int64 // 开启积分 + PreviewTime int64 // 预告时间 + StartTime int64 // 开始时间 + EndTime int64 // 结束时间 + ReleaseTime string // 结算发奖时间 + + BootConfig string // 机器人配置 + RoomConfig string // 房间配置 + + Ver string // 版本号 + Status int // 状态 0=关闭 1=开启 + UpdateTime int64 // 修改时间戳 +} + +// GenerateConfigClient 生成给客户端的配置 +func (c *ActivityConfigRaw) GenerateConfigClient() *ActivityConfigClient { + configClient := &ActivityConfigClient{ + Id: c.Id, + Typ: c.Typ, + Serial: c.Serial, + OpenLevel: c.OpenLevel, + OpenScore: c.OpenScore, + PreviewTime: c.PreviewTime, + StartTime: c.StartTime, + EndTime: c.EndTime, + ReleaseTime: c.ReleaseTime, + Ver: c.Ver, + Status: c.Status, + } + return configClient +} + +// ActivityConfigClient 房间排行活动配置 给客户端数据 +type ActivityConfigClient struct { + Id int64 `form:"id" json:"id"` // ID + Typ int `form:"typ" json:"typ"` // 排行榜类型 + Serial int64 `form:"serial" json:"serial"` // 轮次ID + OpenLevel int `form:"open_level" json:"open_level"` // 开启等级 + OpenScore int64 `form:"open_score" json:"open_score"` // 开启积分 + PreviewTime int64 `form:"preview_time" json:"preview_time"` // 预告时间 + StartTime int64 `form:"start_time" json:"start_time"` // 开始时间 + EndTime int64 `form:"end_time" json:"end_time"` // 结束时间 + ReleaseTime string `form:"release_time" json:"release_time"` // 结算发奖时间 + Ver string `form:"ver" json:"ver"` // 版本号 + Status int `form:"status" json:"status"` // 状态 0=关闭 1=开启 +} + +// RobotConfig 机器人配置 +type RobotConfig struct { + Id int `json:"id"` // id + MinScore int `json:"min_score"` // 最低分数 + TotalScore int `json:"total_score"` // 总分数 + Range int `json:"range"` // 总分浮动范围(%) +} + +// RoomConfig 房间配置 +type RoomConfig struct { + Id int `json:"id"` // id + Levels []int `json:"level_range"` // 等级范围 + UserClass int `json:"rating"` // 评级 + UserScore []int `json:"score_range"` // 分数范围 + TotalPlayer int `json:"room_user_number"` // 房间总人数 + PlayerTypeCount [][]int `json:"user_type_number"` // 玩家类型数量 + AutoRobot []int `json:"auto_room"` // 自动填充机器人 + InitRobot [][]int `json:"disposition_robots"` // 配置机器人 + Awards map[string]string `json:"rewards"` // 奖励 + SettleScores []int `json:"score_adjest"` // 结算分数调整 + SettleUserType []int `json:"user_type"` // 结算用户类型 +} diff --git a/configs-db/confroomrank/decode.go b/configs-db/confroomrank/decode.go new file mode 100644 index 0000000..e7e4aa4 --- /dev/null +++ b/configs-db/confroomrank/decode.go @@ -0,0 +1,50 @@ +package confroomrank + +import ( + "apigame/util/util-lx/lxalilog" + "encoding/json" +) + +// Decode 解析配置原始数据 +func (c *ActivityConfig) Decode(gameId string, rawData any) { + raw := rawData.(*ActivityConfigRaw) + c.GameId = gameId + c.Raw = raw + + c.Id = raw.Id + c.Typ = raw.Typ + c.OpenLevel = raw.OpenLevel + c.OpenScore = raw.OpenScore + c.PreviewTime = raw.PreviewTime + c.StartTime = raw.StartTime + c.EndTime = raw.EndTime + c.ReleaseTime = raw.ReleaseTime + + c.Robot = make(map[int]RobotConfig) + c.Room = make(map[int]RoomConfig) + + // 解析 机器人 + { + configs := make([]RobotConfig, 0) + err := json.Unmarshal([]byte(raw.BootConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.BootConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.Robot[i2.Id] = i2 + } + } + // 解析 房间 + { + configs := make([]RoomConfig, 0) + err := json.Unmarshal([]byte(raw.RoomConfig), &configs) + if err != nil { + lxalilog.Errors(err, raw.RoomConfig, gameId, raw.Id) + return + } + for _, i2 := range configs { + c.Room[i2.Id] = i2 + } + } +} diff --git a/configs-db/confroomrank/get.go b/configs-db/confroomrank/get.go new file mode 100644 index 0000000..29c2388 --- /dev/null +++ b/configs-db/confroomrank/get.go @@ -0,0 +1,44 @@ +package confroomrank + +import ( + "apigame/configs-db/confbase" + "apigame/util/util-lx/lxalilog" + "apigame/util/util-lx/lxtime" +) + +// GetCurrent 获取 当前配置 +func GetCurrent(gameId string, topType int) (conf *ActivityConfig, has bool) { + conf = new(ActivityConfig) + conf.Typ = topType + has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) + if !has { + conf = new(ActivityConfig) + conf.Typ = topType + has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) + } + return +} + +// GetConfig 获取 配置根据Id +func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) { + conf = new(ActivityConfig) + has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf) + + return +} + +// GetCurrentConfigs 获取当前配置列表 +func GetCurrentConfigs(gameId string) []*ActivityConfigRaw { + obj := new(ActivityConfig) + info := obj.ConfInfo(gameId) + db := info.DbMysql + timeNow := lxtime.NowUninx() + objs := make([]*ActivityConfigRaw, 0) + result := db.Table(info.TableName).Where( + "status = ? AND start_time <= ? AND end_time >= ?", + 1, timeNow, timeNow).Find(&objs) + if result.Error != nil { + lxalilog.Errors(result.Error, "confroomrank.GetCurrentConfigs error", gameId) + } + return objs +} diff --git a/configs-db/init.go b/configs-db/init.go new file mode 100644 index 0000000..57072c5 --- /dev/null +++ b/configs-db/init.go @@ -0,0 +1,29 @@ +package configs_db + +import ( + "apigame/configs-db/confapi" + "apigame/configs-db/confcardholder" + "apigame/configs-db/confglobal" + "apigame/service-common/svconst" +) + +func Init() bool { + + for _, gameId := range svconst.GameList { + _, _ = confapi.GetConfig(gameId) + } + + for _, gameId := range svconst.GameList { + _, _ = confglobal.GetConfig(gameId) + } + + for _, gameId := range svconst.GameListCardHolder { + _, _ = confcardholder.GetCurrent(gameId) + } + + //for _, gameId := range svconst.GameListRoomRank { + // _, _ = confroomrank.GetCurrent(gameId) + //} + + return true +} diff --git a/configs/confapi/config.go b/configs/confapi/config.go deleted file mode 100644 index 2cbe322..0000000 --- a/configs/confapi/config.go +++ /dev/null @@ -1,48 +0,0 @@ -package confapi - -import ( - "apigame/configs/confbase" - "apigame/service-common/svconst" - "fmt" -) - -// ApiGameConfig api游戏配置 -type ApiGameConfig struct { - Raw *Raw -} - -func (c *ApiGameConfig) GetUid() string { - return c.Raw.GameId -} - -func (c *ApiGameConfig) CheckCurrent() bool { - return true -} - -func (c *ApiGameConfig) ConfInfo(suffix string) *confbase.ConfInfo { - tableName := "s_game_config" - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) - return &confbase.ConfInfo{ - DbMysql: svconst.DbApi, - TableName: tableName, - KeyName: "gameid", - CacheKey: cacheKey, - CacheCurrent: cacheKey + ":current", - CacheTime: 300, - } -} - -// Raw 配置原始数据 -type Raw struct { - AppId string `gorm:"column:appid"` - GameId string `gorm:"column:gameid"` - Secret string `gorm:"column:secret"` - AppKey string `gorm:"column:appkey"` - Name string `gorm:"column:name"` -} - -// Decode 解析配置原始数据 -func (c *ApiGameConfig) Decode(gameId string, rawData any) { - raw := rawData.(*Raw) - c.Raw = raw -} diff --git a/configs/confapi/get.go b/configs/confapi/get.go deleted file mode 100644 index f14dce2..0000000 --- a/configs/confapi/get.go +++ /dev/null @@ -1,19 +0,0 @@ -package confapi - -import ( - "apigame/configs/confbase" - "errors" -) - -// GetConfig 获取 api游戏配置 -func GetConfig(gameId string) (conf *ApiGameConfig, err error) { - - conf = new(ApiGameConfig) - has := confbase.GetConfig[*ApiGameConfig, Raw](gameId, gameId, conf) - if !has { - err = errors.New("confapi.GetConfig error") - return - } - - return -} diff --git a/configs/confbase/external.go b/configs/confbase/external.go deleted file mode 100644 index a3568db..0000000 --- a/configs/confbase/external.go +++ /dev/null @@ -1,113 +0,0 @@ -package confbase - -import ( - "apigame/util/util-lx/lxalilog" - "apigame/util/zjson" - "apigame/util/zredis" - "fmt" - "runtime/debug" -) - -var CacheState = 1 // 0=关闭 1=打开 - -func SaveCache[T IConfData](gameId string, obj T) { - info := obj.ConfInfo(gameId) - _ = zredis.SetEx(info.CacheKey, zjson.Str(obj), info.CacheTime) -} - -func LoadCache[T IConfData](gameId string, obj T) (has bool) { - if CacheState == 0 { - return false - } - has = true - info := obj.ConfInfo(gameId) - text, err := zredis.Get(info.CacheKey) - if err != nil { - has = false - return - } - err = zjson.Obj(text, &obj) - if err != nil { - fmt.Println(err) - has = false - return - } - return -} - -func LoadData[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) { - confRaw := new(T2) - info := obj.ConfInfo(gameId) - db := info.DbMysql - result := db.Table(info.TableName).Where(fmt.Sprintf("%s = ?", info.KeyName), confId).First(confRaw) - - has = result.RowsAffected != 0 - err := result.Error - if err != nil { - lxalilog.Errors(err, "confbase.LoadData error", gameId, confId) - fmt.Printf("%s", debug.Stack()) - return - } - if !has { - return - } - - obj.Decode(gameId, confRaw) - return -} - -func FindDuringTime[T1 IConfData, T2 IConfRawData](obj T1, raw *T2, gameId string) (has bool) { - info := obj.ConfInfo(gameId) - db := info.DbMysql - result := db.Table(info.TableName).Where(info.CurrentQuery, info.CurrentArgs...).First(raw) - has = result.RowsAffected != 0 - return -} - -func GetConfig[T1 IConfData, T2 IConfRawData](gameId string, confId any, obj T1) (has bool) { - has = LoadCache(gameId, obj) - if has { - return - } - has = LoadData[T1, T2](gameId, confId, obj) - if !has { - return - } - SaveCache(gameId, obj) - return -} - -// GetCurrent 获取 当前配置 -func GetCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool { - has := false - info := obj.ConfInfo(gameId) - currentKey := info.CacheCurrent - currentId := zredis.GetString(currentKey) - if currentId != "" { - has = GetConfig[T1, T2](gameId, currentId, obj) - if has { - if !obj.CheckCurrent() { - has = false - } - } - } - return has -} - -// FindCurrent 查找 当前配置 -func FindCurrent[T1 IConfData, T2 IConfRawData](gameId string, obj T1) bool { - has := false - info := obj.ConfInfo(gameId) - currentKey := info.CacheCurrent - currentId := zredis.GetString(currentKey) - confRaw := new(T2) - has = FindDuringTime[T1, T2](obj, confRaw, gameId) - if has { - obj.Decode(gameId, confRaw) - SaveCache(gameId, obj) - has = true - currentId = obj.GetUid() - _ = zredis.Set(currentKey, currentId) - } - return has -} diff --git a/configs/confbase/interface.go b/configs/confbase/interface.go deleted file mode 100644 index 7974c97..0000000 --- a/configs/confbase/interface.go +++ /dev/null @@ -1,31 +0,0 @@ -package confbase - -import "gorm.io/gorm" - -// ConfInfo 配置对象信息 -type ConfInfo struct { - DbMysql *gorm.DB - TableName string - KeyName string - CurrentQuery any - CurrentArgs []any - CacheKey string - CacheCurrent string - CacheTime int -} - -// IConfData 配置对象 -type IConfData interface { - // ConfInfo redis存储信息 - ConfInfo(suffix string) *ConfInfo - // Decode 解码 - Decode(gameId string, rawData any) - // GetUid 获取keyID - GetUid() string - // CheckCurrent 判断当前开放 - CheckCurrent() bool -} - -// IConfRawData mysql存储对象 -type IConfRawData interface { -} diff --git a/configs/confcardholder/config.go b/configs/confcardholder/config.go deleted file mode 100644 index f93ff1a..0000000 --- a/configs/confcardholder/config.go +++ /dev/null @@ -1,152 +0,0 @@ -package confcardholder - -import ( - "apigame/configs/confbase" - "apigame/service-common/svconst" - "apigame/util/util-lx/lxtime" - "apigame/util/utstring" - "fmt" -) - -// ActivityConfig 卡牌活动配置 分析后数据 -type ActivityConfig struct { - Raw *ActivityConfigRaw `json:"-"` - - Id int64 // ID - OpenLevel int // 开启等级 - PreviewTime int64 // 预告时间 - StartTime int64 // 开始时间 - EndTime int64 // 结束时间 - Round int // 轮数 - IconPath string // icon资源路径 - - Awards map[string]string // 奖励配置 - AlbumConfig map[int]AlbumConfig // 卡组配置 - CardConfig map[int]CardConfig // 卡牌配置 - CardholderConfig map[int]OpenCardholderConfig // 卡包开卡规则 - NormalCardStarConfig map[string]NormalCardStarConfig // k=ID_用户序列_用户分组 卡片星级配置 - CardSequenceConfig map[string]CardSequenceConfig // k=ID_用户序列_用户分组 卡片星级对应卡牌配置 - StarShopConfig map[int]StarShopConfig // 星星商店配置 - - Client *ActivityConfigClient - GameId string // 所属游戏ID -} - -func (c *ActivityConfig) GetUid() string { - return utstring.Int64ToString(c.Id) -} - -func (c *ActivityConfig) CheckCurrent() bool { - timeNow := lxtime.NowUninx() - return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1 -} - -func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo { - tableName := svconst.MYSQL_TABLE_S_CARDHOLDER_CONFIG - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) - timeNow := lxtime.NowUninx() - return &confbase.ConfInfo{ - DbMysql: svconst.DbConfig, - TableName: fmt.Sprintf("%s_%s", tableName, suffix), - KeyName: "id", - CurrentQuery: "status = ? AND start_time <= ? AND end_time >= ?", - CurrentArgs: []any{1, timeNow, timeNow}, - CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id), - CacheCurrent: cacheKey + ":current", - CacheTime: 300, - } -} - -// ActivityConfigRaw 卡牌活动配置 原始数据 -type ActivityConfigRaw struct { - Id int64 `gorm:"column:id;primaryKey"` // ID - OpenLevel int // 开启等级 - PreviewTime int64 // 预告时间 - StartTime int64 // 开始时间 - EndTime int64 // 结束时间 - Round int // 轮数 - IconPath string // icon资源路径 - - Awards string // 奖励配置 - AlbumConfig string // 卡组配置 - CardConfig string // 卡牌配置 - CardHolderConfig string // 卡包开卡规则 - NormalCardStarSequence string // 卡片星级配置 - CardSequenceConfig string // 卡片星级对应卡牌配置 - StarShopConfig string // 星星商店配置 - - Ver string // 版本号 - Status int // 状态 0=关闭 1=开启 - UpdateTime int64 // 修改时间戳 -} - -// ActivityConfigClient 卡牌活动配置 给客户端数据 -type ActivityConfigClient struct { - Id int64 `form:"id" json:"id"` // ID - Round int `form:"round" json:"round"` // 轮数 - IconPath string `form:"icon_path" json:"icon_path"` // icon资源路径 - RoundAwards map[string]string `form:"round_awards" json:"round_awards"` // 轮次奖励配置 - Albums []AlbumConfig `form:"albums" json:"albums"` // 卡组配置 - Cards []CardConfig `form:"cards" json:"cards"` // 卡牌配置 - Holders []OpenCardholderConfig `form:"holders" json:"holders"` // 卡包开卡规则 - StarShop []StarShopConfig `form:"star_shop" json:"star_shop"` // 星星商店配置 -} - -// AlbumConfig 卡组表 -type AlbumConfig struct { - SetId int `json:"set_id"` // 卡组名 - Name int `json:"name"` // 卡组图片 - Icon string `json:"icon"` // 卡组id - Rewards map[string]string `json:"rewards"` // 集齐奖励 k=轮次 - StartTime int64 `json:"start_time"` // 开始时间 - EndTime int64 `json:"end_time"` // 结束时间 -} - -// CardConfig 卡牌表 -type CardConfig struct { - Id int `json:"id"` // ID - Name int `json:"name"` // 卡牌名字 - Icon string `json:"icon"` // 卡牌图标 - Desc int `json:"desc"` // 卡牌描述 - SetId int `json:"album_setid"` // 卡组id - Star int `json:"star"` // 星级 - IsGold int `json:"is_gold"` // 是否是金卡 - IsSend int `json:"is_send"` // 卡片是否可赠送 -} - -// OpenCardholderConfig 卡包开卡规则表 -type OpenCardholderConfig struct { - Id int `json:"id"` // ID - CardPackIcon string `json:"img"` // 卡包资源名 - IsGoldCardholder int `json:"is_gold_card_holder"` // 是否是金卡包 - IsNew int `json:"is_new"` // 是否是新卡包 - GuaranteedStarCardId int `json:"guaranteed_star_card_id"` // 保底卡星级序列ID - NormalCardNumber int `json:"normal_card_number"` // 非保底卡数量 - MinimumGuaranteeCardId int `json:"minimum_guarantee_card_id"` // 非保底卡牌序列ID - ActivityId int `json:"activity_id"` // 对应活动ID - Star int `json:"star"` // star - Name int `json:"name"` // name -} - -// NormalCardStarConfig 非保底卡星级ID -type NormalCardStarConfig struct { - Id int `json:"id"` // ID - SequenceId int `json:"user_sequence_id"` // 用户序列组ID - Cohort int `json:"cohort"` // 用户分组 - NormalCardSequenceId []int `json:"normal_card_sequence_id"` // 非保底星级序列 -} - -// CardSequenceConfig 星级ID对应的卡片 -type CardSequenceConfig struct { - Id int `json:"id"` // ID - SequenceId int `json:"user_sequence_id"` // 用户序列组ID - Cohort int `json:"cohort"` // 用户分组 - CardIdList []int `json:"card_id_list"` // 卡牌抽取序列 -} - -// StarShopConfig 星星商店配置 -type StarShopConfig struct { - Id int `json:"id"` // ID - NeedStarNumber int `json:"need_star_number"` // 需求星星数 - CardBagIds string `json:"card_bag_ids"` // 可换取的卡包ID {卡包类型,卡包ID,卡包数量} -} diff --git a/configs/confcardholder/decode.go b/configs/confcardholder/decode.go deleted file mode 100644 index 629d92d..0000000 --- a/configs/confcardholder/decode.go +++ /dev/null @@ -1,170 +0,0 @@ -package confcardholder - -import ( - "apigame/util/util-lx/lxalilog" - "encoding/json" - "errors" - "fmt" -) - -// Decode 解析配置原始数据 -func (c *ActivityConfig) Decode(gameId string, rawData any) { - raw := rawData.(*ActivityConfigRaw) - c.GameId = gameId - c.Raw = raw - - c.Id = raw.Id - c.OpenLevel = raw.OpenLevel - c.PreviewTime = raw.PreviewTime - c.StartTime = raw.StartTime - c.EndTime = raw.EndTime - c.Round = raw.Round - c.IconPath = raw.IconPath - - c.Awards = make(map[string]string) - c.AlbumConfig = make(map[int]AlbumConfig) - c.CardConfig = make(map[int]CardConfig) - c.CardholderConfig = make(map[int]OpenCardholderConfig) - c.NormalCardStarConfig = make(map[string]NormalCardStarConfig) - c.CardSequenceConfig = make(map[string]CardSequenceConfig) - c.StarShopConfig = make(map[int]StarShopConfig) - // 解析奖励 - { - err := json.Unmarshal([]byte(raw.Awards), &c.Awards) - if err != nil { - lxalilog.Errors(err, raw.Awards, gameId, raw.Id) - return - } - } - // 卡组配置 - { - configs := make([]AlbumConfig, 0) - err := json.Unmarshal([]byte(raw.AlbumConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.AlbumConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.AlbumConfig[i2.SetId] = i2 - } - } - // 卡牌配置 - { - configs := make([]CardConfig, 0) - err := json.Unmarshal([]byte(raw.CardConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.CardConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.CardConfig[i2.Id] = i2 - } - } - // 卡包开卡规则 - { - configs := make([]OpenCardholderConfig, 0) - err := json.Unmarshal([]byte(raw.CardHolderConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.CardHolderConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.CardholderConfig[i2.Id] = i2 - } - } - // 卡片星级配置 - { - configs := make([]NormalCardStarConfig, 0) - err := json.Unmarshal([]byte(raw.NormalCardStarSequence), &configs) - if err != nil { - lxalilog.Errors(err, raw.NormalCardStarSequence, gameId, raw.Id) - return - } - for _, i2 := range configs { - combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort) - c.NormalCardStarConfig[combineId] = i2 - } - } - // 卡片星级对应卡牌配置 - { - configs := make([]CardSequenceConfig, 0) - err := json.Unmarshal([]byte(raw.CardSequenceConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.CardSequenceConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - combineId := CombineIdSequenceIdCohort(i2.Id, i2.SequenceId, i2.Cohort) - c.CardSequenceConfig[combineId] = i2 - } - } - // 星星商店配置 - { - configs := make([]StarShopConfig, 0) - err := json.Unmarshal([]byte(raw.StarShopConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.StarShopConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.StarShopConfig[i2.Id] = i2 - } - } - - c.GenerateConfigClient() -} - -// GenerateConfigClient 生成给客户端的配置 -func (c *ActivityConfig) GenerateConfigClient() { - configClient := &ActivityConfigClient{ - Id: c.Id, - Round: c.Round, - IconPath: c.IconPath, - RoundAwards: c.Awards, - Albums: make([]AlbumConfig, 0), - Cards: make([]CardConfig, 0), - Holders: make([]OpenCardholderConfig, 0), - StarShop: make([]StarShopConfig, 0), - } - for _, i2 := range c.AlbumConfig { - configClient.Albums = append(configClient.Albums, i2) - } - for _, i2 := range c.CardConfig { - configClient.Cards = append(configClient.Cards, i2) - } - for _, i2 := range c.CardholderConfig { - configClient.Holders = append(configClient.Holders, i2) - } - for _, i2 := range c.StarShopConfig { - configClient.StarShop = append(configClient.StarShop, i2) - } - c.Client = configClient -} - -// CombineIdSequenceIdCohort 组合ID k=ID_用户序列_用户分组 -func CombineIdSequenceIdCohort(id, sequenceId, cohort int) string { - return fmt.Sprintf("%d_%d_%d", id, sequenceId, cohort) -} - -// FindNormalCardStarConfig 查找配置 非保底卡星级ID -func (c *ActivityConfig) FindNormalCardStarConfig(id, sequenceId, cohort int) (conf NormalCardStarConfig, has bool) { - combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort) - conf, has = c.NormalCardStarConfig[combineId] - if !has { - lxalilog.Errors(errors.New("ht_cardholder NormalCardStarConfig error"), id, sequenceId, cohort) - } - return -} - -// FindCardSequenceConfig 查找配置 星级ID对应的卡片 -func (c *ActivityConfig) FindCardSequenceConfig(id, sequenceId, cohort int) (conf CardSequenceConfig, has bool) { - combineId := CombineIdSequenceIdCohort(id, sequenceId, cohort) - conf, has = c.CardSequenceConfig[combineId] - if !has { - lxalilog.Errors(errors.New("ht_cardholder CardSequenceConfig error"), id, sequenceId, cohort) - fmt.Println(id) - fmt.Println(sequenceId) - fmt.Println(cohort) - } - return -} diff --git a/configs/confcardholder/get.go b/configs/confcardholder/get.go deleted file mode 100644 index cc7efdb..0000000 --- a/configs/confcardholder/get.go +++ /dev/null @@ -1,24 +0,0 @@ -package confcardholder - -import ( - "apigame/configs/confbase" -) - -// GetCurrent 获取 当前配置 -func GetCurrent(gameId string) (conf *ActivityConfig, has bool) { - conf = new(ActivityConfig) - has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) - if !has { - conf = new(ActivityConfig) - has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) - } - return -} - -// GetConfig 获取 配置根据Id -func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) { - conf = new(ActivityConfig) - has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf) - - return -} diff --git a/configs/confglobal/config.go b/configs/confglobal/config.go deleted file mode 100644 index 1ff7805..0000000 --- a/configs/confglobal/config.go +++ /dev/null @@ -1,67 +0,0 @@ -package confglobal - -import ( - "apigame/configs/confbase" - "apigame/service-common/svconst" - "apigame/util/util-lx/lxalilog" - "encoding/json" - "fmt" -) - -// GlobalConfig 全局配置 -type GlobalConfig struct { - Raw *Raw `json:"-"` - Names []string - Avatars []string - AvatarPath string -} - -func (c *GlobalConfig) GetUid() string { - return c.Raw.GameId -} - -func (c *GlobalConfig) CheckCurrent() bool { - return true -} - -func (c *GlobalConfig) ConfInfo(suffix string) *confbase.ConfInfo { - tableName := "s_game_global_config" - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) - return &confbase.ConfInfo{ - DbMysql: svconst.DbConfig, - TableName: tableName, - KeyName: "gameid", - CacheKey: cacheKey, - CacheCurrent: cacheKey + ":current", - CacheTime: 300, - } -} - -// Raw 配置原始数据 -type Raw struct { - GameId string `gorm:"column:gameid"` - NameConfig string - AvatarConfig string - AvatarPath string -} - -// Decode 解析配置原始数据 -func (c *GlobalConfig) Decode(gameId string, rawData any) { - raw := rawData.(*Raw) - c.Raw = raw - { - err := json.Unmarshal([]byte(raw.NameConfig), &c.Names) - if err != nil { - lxalilog.Errors(err, raw.NameConfig, gameId, raw.GameId) - return - } - } - { - err := json.Unmarshal([]byte(raw.AvatarConfig), &c.Avatars) - if err != nil { - lxalilog.Errors(err, raw.AvatarConfig, gameId, raw.GameId) - return - } - } - c.AvatarPath = raw.AvatarPath -} diff --git a/configs/confglobal/get.go b/configs/confglobal/get.go deleted file mode 100644 index ca4cfe1..0000000 --- a/configs/confglobal/get.go +++ /dev/null @@ -1,19 +0,0 @@ -package confglobal - -import ( - "apigame/configs/confbase" - "errors" -) - -// GetConfig 获取 api游戏配置 -func GetConfig(gameId string) (conf *GlobalConfig, err error) { - - conf = new(GlobalConfig) - has := confbase.GetConfig[*GlobalConfig, Raw](gameId, gameId, conf) - if !has { - err = errors.New("confglobal.GetConfig error") - return - } - - return -} diff --git a/configs/config.go b/configs/config.go new file mode 100644 index 0000000..8fa1308 --- /dev/null +++ b/configs/config.go @@ -0,0 +1,282 @@ +// DO NOT EDIT! +// This code is auto generated by go-xlsx-exporter +// VERSION 1.3 +// go-protobuf v1.27.1 + +package configs + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +/* type ConvertHandler func (field string, value interface{}) interface{} + +type MessageBase struct { + +} + +func (item *MessageBase) GetConvertData(field string, value interface{}) { + +} */ +// Defined in table: data/abtest.xlsx:abtest; +type AbTestCfg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ID uint32 `protobuf:"varint,1,opt,name=ID,proto3uint32" json:"ID,omitempty"` /** 编号 */ + + Name string `protobuf:"bytes,2,opt,name=Name,proto3string" json:"Name,omitempty"` /** 分组名 */ + + Min uint32 `protobuf:"varint,3,opt,name=Min,proto3uint32" json:"Min,omitempty"` /** ID下限 */ + + Max uint32 `protobuf:"varint,4,opt,name=Max,proto3uint32" json:"Max,omitempty"` /** ID上限 */ + + Condition string `protobuf:"bytes,5,opt,name=Condition,proto3string" json:"Condition,omitempty"` /** 条件 */ + + Config string `protobuf:"bytes,6,opt,name=Config,proto3string" json:"Config,omitempty"` /** 配置 */ + +} + +func (x *AbTestCfg) Reset() { + *x = AbTestCfg{} + if protoimpl.UnsafeEnabled { + mi := &file_config_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AbTestCfg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AbTestCfg) ProtoMessage() {} + +func (x *AbTestCfg) ProtoReflect() protoreflect.Message { + mi := &file_config_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AbTestCfg.ProtoReflect.Descriptor instead. +func (*AbTestCfg) Descriptor() ([]byte, []int) { + return file_config_proto_rawDescGZIP(), []int{0} +} + +func (x *AbTestCfg) GetID() uint32 { + if x != nil { + return x.ID + } + return 0 +} + +func (x *AbTestCfg) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AbTestCfg) GetMin() uint32 { + if x != nil { + return x.Min + } + return 0 +} + +func (x *AbTestCfg) GetMax() uint32 { + if x != nil { + return x.Max + } + return 0 +} + +func (x *AbTestCfg) GetCondition() string { + if x != nil { + return x.Condition + } + return "" +} + +func (x *AbTestCfg) GetConfig() string { + if x != nil { + return x.Config + } + return "" +} + + +// Defined in table: data/abtest.xlsx:abtest; +type AbTestCfg_ARRAY struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + + Items []*AbTestCfg `protobuf:"bytes,1,rep,name=Items,proto3*AbTestCfg" json:"Items,omitempty"` + +} + +func (x *AbTestCfg_ARRAY) Reset() { + *x = AbTestCfg_ARRAY{} + if protoimpl.UnsafeEnabled { + mi := &file_config_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AbTestCfg_ARRAY) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AbTestCfg_ARRAY) ProtoMessage() {} + +func (x *AbTestCfg_ARRAY) ProtoReflect() protoreflect.Message { + mi := &file_config_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AbTestCfg_ARRAY.ProtoReflect.Descriptor instead. +func (*AbTestCfg_ARRAY) Descriptor() ([]byte, []int) { + return file_config_proto_rawDescGZIP(), []int{1} +} + +func (x *AbTestCfg_ARRAY) GetItems() []*AbTestCfg { + if x != nil { + return x.Items + } + return nil +} + + +var File_config_proto protoreflect.FileDescriptor + +var file_config_proto_rawDesc = []byte{ +0x0a,0x0c,0x63,0x6f,0x6e,0x66,0x69,0x67,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x12,0x07, +0x63,0x6f,0x6e,0x66,0x69,0x67,0x73,0x22,0x89,0x01,0x0a,0x09,0x41,0x62,0x54,0x65, +0x73,0x74,0x43,0x66,0x67,0x12,0x0e,0x0a,0x02,0x49,0x44,0x18,0x01,0x20,0x01,0x28, +0x0d,0x52,0x02,0x49,0x44,0x12,0x12,0x0a,0x04,0x4e,0x61,0x6d,0x65,0x18,0x02,0x20, +0x01,0x28,0x09,0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x10,0x0a,0x03,0x4d,0x69,0x6e, +0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x03,0x4d,0x69,0x6e,0x12,0x10,0x0a,0x03,0x4d, +0x61,0x78,0x18,0x04,0x20,0x01,0x28,0x0d,0x52,0x03,0x4d,0x61,0x78,0x12,0x1c,0x0a, +0x09,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x18,0x05,0x20,0x01,0x28,0x09, +0x52,0x09,0x43,0x6f,0x6e,0x64,0x69,0x74,0x69,0x6f,0x6e,0x12,0x16,0x0a,0x06,0x43, +0x6f,0x6e,0x66,0x69,0x67,0x18,0x06,0x20,0x01,0x28,0x09,0x52,0x06,0x43,0x6f,0x6e, +0x66,0x69,0x67,0x22,0x3b,0x0a,0x0f,0x41,0x62,0x54,0x65,0x73,0x74,0x43,0x66,0x67, +0x5f,0x41,0x52,0x52,0x41,0x59,0x12,0x28,0x0a,0x05,0x49,0x74,0x65,0x6d,0x73,0x18, +0x01,0x20,0x03,0x28,0x0b,0x32,0x12,0x2e,0x63,0x6f,0x6e,0x66,0x69,0x67,0x73,0x2e, +0x41,0x62,0x54,0x65,0x73,0x74,0x43,0x66,0x67,0x52,0x05,0x49,0x74,0x65,0x6d,0x73, +0x62,0x06,0x70,0x72,0x6f,0x74,0x6f,0x33, +} + +var ( + file_config_proto_rawDescOnce sync.Once + file_config_proto_rawDescData = file_config_proto_rawDesc +) + +func file_config_proto_rawDescGZIP() []byte { + file_config_proto_rawDescOnce.Do(func() { + file_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_proto_rawDescData) + }) + return file_config_proto_rawDescData +} + +var file_config_proto_enumTypes = make([]protoimpl.EnumInfo, 0) +var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_config_proto_goTypes = []interface{}{ + (*AbTestCfg)(nil), // 0: configs.AbTestCfg + (*AbTestCfg_ARRAY)(nil), // 1: configs.AbTestCfg_ARRAY + +} + +var file_config_proto_depIdxs = []int32{ + 0, // 0: configs.AbTestCfg_ARRAY:type_name -> configs.AbTestCfg +1, // [1:1] is the sub-list for method output_type +1, // [1:1] is the sub-list for method input_type +1, // [1:1] is the sub-list for extension type_name +1, // [1:1] is the sub-list for extension extendee +0, // [0:1] is the sub-list for field type_name +} + +func file_config_proto_init() { + if File_config_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AbTestCfg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + + file_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AbTestCfg_ARRAY); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_config_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_config_proto_goTypes, + DependencyIndexes: file_config_proto_depIdxs, + EnumInfos: file_config_proto_enumTypes, + MessageInfos: file_config_proto_msgTypes, + }.Build() + File_config_proto = out.File + file_config_proto_rawDesc = nil + file_config_proto_goTypes = nil + file_config_proto_depIdxs = nil +} + +func init() { + file_config_proto_init() +} \ No newline at end of file diff --git a/configs/confroomrank/config.go b/configs/confroomrank/config.go deleted file mode 100644 index 4fc0988..0000000 --- a/configs/confroomrank/config.go +++ /dev/null @@ -1,129 +0,0 @@ -package confroomrank - -import ( - "apigame/configs/confbase" - "apigame/service-common/svconst" - "apigame/util/util-lx/lxtime" - "apigame/util/utstring" - "fmt" -) - -// ActivityConfig 房间排行活动配置 分析后数据 -type ActivityConfig struct { - Raw *ActivityConfigRaw `json:"-"` - - Id int64 // ID - Typ int // 排行榜类型 - OpenLevel int // 开启等级 - OpenScore int64 // 开启积分 - PreviewTime int64 // 预告时间 - StartTime int64 // 开始时间 - EndTime int64 // 结束时间 - ReleaseTime string // 结算发奖时间 - - Robot map[int]RobotConfig // 机器人配置 - Room map[int]RoomConfig // 房间配置 - - GameId string // 所属游戏ID -} - -func (c *ActivityConfig) GetUid() string { - return utstring.Int64ToString(c.Id) -} - -func (c *ActivityConfig) CheckCurrent() bool { - timeNow := lxtime.NowUninx() - return timeNow >= c.StartTime && timeNow <= c.EndTime && c.Raw.Status == 1 -} - -func (c *ActivityConfig) ConfInfo(suffix string) *confbase.ConfInfo { - tableName := svconst.MYSQL_TABLE_S_ROOMRANK_CONFIG - cacheKey := fmt.Sprintf("%s:%s:%s", svconst.REDIS_CACHEP_REFIX, tableName, suffix) - timeNow := lxtime.NowUninx() - return &confbase.ConfInfo{ - DbMysql: svconst.DbConfig, - TableName: fmt.Sprintf("%s_%s", tableName, suffix), - KeyName: "id", - CurrentQuery: "typ = ? AND status = ? AND start_time <= ? AND end_time >= ?", - CurrentArgs: []any{c.Typ, 1, timeNow, timeNow}, - CacheKey: fmt.Sprintf("%s:%d", cacheKey, c.Id), - CacheCurrent: fmt.Sprintf("%s:%d:current", cacheKey, c.Typ), - CacheTime: 300, - } -} - -// ActivityConfigRaw 房间排行活动配置 原始数据 -type ActivityConfigRaw struct { - Id int64 `gorm:"column:id;primaryKey"` // ID - Serial int64 // 轮次ID - Typ int // 排行榜类型 - OpenLevel int // 开启等级 - OpenScore int64 // 开启积分 - PreviewTime int64 // 预告时间 - StartTime int64 // 开始时间 - EndTime int64 // 结束时间 - ReleaseTime string // 结算发奖时间 - - BootConfig string // 机器人配置 - RoomConfig string // 房间配置 - - Ver string // 版本号 - Status int // 状态 0=关闭 1=开启 - UpdateTime int64 // 修改时间戳 -} - -// GenerateConfigClient 生成给客户端的配置 -func (c *ActivityConfigRaw) GenerateConfigClient() *ActivityConfigClient { - configClient := &ActivityConfigClient{ - Id: c.Id, - Typ: c.Typ, - Serial: c.Serial, - OpenLevel: c.OpenLevel, - OpenScore: c.OpenScore, - PreviewTime: c.PreviewTime, - StartTime: c.StartTime, - EndTime: c.EndTime, - ReleaseTime: c.ReleaseTime, - Ver: c.Ver, - Status: c.Status, - } - return configClient -} - -// ActivityConfigClient 房间排行活动配置 给客户端数据 -type ActivityConfigClient struct { - Id int64 `form:"id" json:"id"` // ID - Typ int `form:"typ" json:"typ"` // 排行榜类型 - Serial int64 `form:"serial" json:"serial"` // 轮次ID - OpenLevel int `form:"open_level" json:"open_level"` // 开启等级 - OpenScore int64 `form:"open_score" json:"open_score"` // 开启积分 - PreviewTime int64 `form:"preview_time" json:"preview_time"` // 预告时间 - StartTime int64 `form:"start_time" json:"start_time"` // 开始时间 - EndTime int64 `form:"end_time" json:"end_time"` // 结束时间 - ReleaseTime string `form:"release_time" json:"release_time"` // 结算发奖时间 - Ver string `form:"ver" json:"ver"` // 版本号 - Status int `form:"status" json:"status"` // 状态 0=关闭 1=开启 -} - -// RobotConfig 机器人配置 -type RobotConfig struct { - Id int `json:"id"` // id - MinScore int `json:"min_score"` // 最低分数 - TotalScore int `json:"total_score"` // 总分数 - Range int `json:"range"` // 总分浮动范围(%) -} - -// RoomConfig 房间配置 -type RoomConfig struct { - Id int `json:"id"` // id - Levels []int `json:"level_range"` // 等级范围 - UserClass int `json:"rating"` // 评级 - UserScore []int `json:"score_range"` // 分数范围 - TotalPlayer int `json:"room_user_number"` // 房间总人数 - PlayerTypeCount [][]int `json:"user_type_number"` // 玩家类型数量 - AutoRobot []int `json:"auto_room"` // 自动填充机器人 - InitRobot [][]int `json:"disposition_robots"` // 配置机器人 - Awards map[string]string `json:"rewards"` // 奖励 - SettleScores []int `json:"score_adjest"` // 结算分数调整 - SettleUserType []int `json:"user_type"` // 结算用户类型 -} diff --git a/configs/confroomrank/decode.go b/configs/confroomrank/decode.go deleted file mode 100644 index e7e4aa4..0000000 --- a/configs/confroomrank/decode.go +++ /dev/null @@ -1,50 +0,0 @@ -package confroomrank - -import ( - "apigame/util/util-lx/lxalilog" - "encoding/json" -) - -// Decode 解析配置原始数据 -func (c *ActivityConfig) Decode(gameId string, rawData any) { - raw := rawData.(*ActivityConfigRaw) - c.GameId = gameId - c.Raw = raw - - c.Id = raw.Id - c.Typ = raw.Typ - c.OpenLevel = raw.OpenLevel - c.OpenScore = raw.OpenScore - c.PreviewTime = raw.PreviewTime - c.StartTime = raw.StartTime - c.EndTime = raw.EndTime - c.ReleaseTime = raw.ReleaseTime - - c.Robot = make(map[int]RobotConfig) - c.Room = make(map[int]RoomConfig) - - // 解析 机器人 - { - configs := make([]RobotConfig, 0) - err := json.Unmarshal([]byte(raw.BootConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.BootConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.Robot[i2.Id] = i2 - } - } - // 解析 房间 - { - configs := make([]RoomConfig, 0) - err := json.Unmarshal([]byte(raw.RoomConfig), &configs) - if err != nil { - lxalilog.Errors(err, raw.RoomConfig, gameId, raw.Id) - return - } - for _, i2 := range configs { - c.Room[i2.Id] = i2 - } - } -} diff --git a/configs/confroomrank/get.go b/configs/confroomrank/get.go deleted file mode 100644 index 2171a0c..0000000 --- a/configs/confroomrank/get.go +++ /dev/null @@ -1,44 +0,0 @@ -package confroomrank - -import ( - "apigame/configs/confbase" - "apigame/util/util-lx/lxalilog" - "apigame/util/util-lx/lxtime" -) - -// GetCurrent 获取 当前配置 -func GetCurrent(gameId string, topType int) (conf *ActivityConfig, has bool) { - conf = new(ActivityConfig) - conf.Typ = topType - has = confbase.GetCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) - if !has { - conf = new(ActivityConfig) - conf.Typ = topType - has = confbase.FindCurrent[*ActivityConfig, ActivityConfigRaw](gameId, conf) - } - return -} - -// GetConfig 获取 配置根据Id -func GetConfig(gameId string, confId int64) (conf *ActivityConfig, has bool) { - conf = new(ActivityConfig) - has = confbase.GetConfig[*ActivityConfig, ActivityConfigRaw](gameId, confId, conf) - - return -} - -// GetCurrentConfigs 获取当前配置列表 -func GetCurrentConfigs(gameId string) []*ActivityConfigRaw { - obj := new(ActivityConfig) - info := obj.ConfInfo(gameId) - db := info.DbMysql - timeNow := lxtime.NowUninx() - objs := make([]*ActivityConfigRaw, 0) - result := db.Table(info.TableName).Where( - "status = ? AND start_time <= ? AND end_time >= ?", - 1, timeNow, timeNow).Find(&objs) - if result.Error != nil { - lxalilog.Errors(result.Error, "confroomrank.GetCurrentConfigs error", gameId) - } - return objs -} diff --git a/configs/external.go b/configs/external.go new file mode 100644 index 0000000..fc85cc8 --- /dev/null +++ b/configs/external.go @@ -0,0 +1,42 @@ +package configs + +import ( + "fmt" + "reflect" +) + +func Init() bool { + fmt.Println("configs Init") + Initial("./conf/bytes", "ID") + + //InitExt() + return true +} + +func GetConfig[T any](id string, t T) (obj *T) { + var table = GetTable(t) + dt := table.GetItem(id) + if dt == nil { + return nil + } + obj = dt.(*T) + return +} + +func HasConfig[T any](id string, t T) (has bool) { + var table = GetTable(t) + return table.GetItem(id) != nil +} + +func GetOne[T any](t T) (obj *T) { + var table = GetTable(t) + if len(table.Items()) > 0 { + return table.Items()[0].(*T) + } + return nil +} + +func GetTable[T any](t T) (table *DataTable) { + table = GetDataTable(reflect.TypeOf(t)) + return +} diff --git a/configs/init.go b/configs/init.go deleted file mode 100644 index 5d6a4f9..0000000 --- a/configs/init.go +++ /dev/null @@ -1,29 +0,0 @@ -package configs - -import ( - "apigame/configs/confapi" - "apigame/configs/confcardholder" - "apigame/configs/confglobal" - "apigame/service-common/svconst" -) - -func Init() bool { - - for _, gameId := range svconst.GameList { - _, _ = confapi.GetConfig(gameId) - } - - for _, gameId := range svconst.GameList { - _, _ = confglobal.GetConfig(gameId) - } - - for _, gameId := range svconst.GameListCardHolder { - _, _ = confcardholder.GetCurrent(gameId) - } - - //for _, gameId := range svconst.GameListRoomRank { - // _, _ = confroomrank.GetCurrent(gameId) - //} - - return true -} diff --git a/configs/reader.go b/configs/reader.go new file mode 100644 index 0000000..aaa7dbc --- /dev/null +++ b/configs/reader.go @@ -0,0 +1,280 @@ +package configs + +import ( + "fmt" + "os" + "reflect" + "strings" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +type DataTableMap map[string]IData +type DataItemMap map[string]IData + +type DataArray []interface{} +type DataMap map[string]interface{} + +var ( + DefaultIndexKey = "ID" + BytesFileExt = ".bytes" + + dataDir = "" + dataItemMap = make(DataItemMap, 0) + dataTableMap = make(DataTableMap, 0) +) + +type IFilenameGenerator interface { + GetFilename(typeName string) string +} + +type IData interface { + DataType() reflect.Type +} + +func DataDir() string { + return dataDir +} + +func Initial(dir, defaultKeyName string) { + dataDir = strings.ReplaceAll(dir, "\\", "/") + if strings.LastIndex(dataDir, "/") != len(dataDir)-1 { + dataDir = dataDir + "/" + } + + if defaultKeyName != "" { + DefaultIndexKey = defaultKeyName + } +} + +func RegistDataTable(indexKey string, dataType reflect.Type) { + if _, ok := dataTableMap[dataType.Name()]; !ok { + var t = NewDataTable(indexKey, dataType) + dataTableMap[dataType.Name()] = t + } +} + +func RegistDataTableExt(table IData) { + var dataType = table.DataType() + if _, ok := dataTableMap[dataType.Name()]; !ok { + dataTableMap[dataType.Name()] = table + } +} + +func GetDataItem(dataType reflect.Type) *DataItem { + var dt *DataItem + if item, ok := dataItemMap[dataType.Name()]; !ok { + var t = NewDataItem(dataType) + dataItemMap[dataType.Name()] = t + dt = t + } else { + dt = item.(*DataItem) + } + return dt +} + +func GetDataTable(dataType reflect.Type) *DataTable { + var dt *DataTable + if item, ok := dataTableMap[dataType.Name()]; !ok { + var t = NewDataTable("", dataType) + dataTableMap[dataType.Name()] = t + dt = t + } else { + dt = item.(*DataTable) + } + return dt +} + +func getFullname(dataType reflect.Type) string { + var pkgs = strings.Split(dataType.PkgPath(), "/") + var pkg = pkgs[len(pkgs)-1] + var name = dataType.Name() + return fmt.Sprintf("%s.%s", pkg, name) +} + +type DataItem struct { + dataType reflect.Type + data interface{} + fileGen IFilenameGenerator +} + +func NewDataItem(dataType reflect.Type) *DataItem { + t := new(DataItem) + t.dataType = dataType + t.fileGen = t + return t +} + +func (t *DataItem) DataType() reflect.Type { + return t.dataType +} + +func (t *DataItem) Item() interface{} { + t.load() + return t.data +} + +func (t *DataItem) Clear() { + t.data = nil +} + +func (t *DataItem) GetFilename(typeName string) string { + return fmt.Sprintf("%s%s%s", dataDir, strings.ToLower(typeName), BytesFileExt) +} + +func (t *DataItem) load() { + if t.data != nil { + return + } + + var filename = t.fileGen.GetFilename(t.dataType.Name()) + if ok, _ := PathExists(filename); !ok { + fmt.Printf("can not find data file %s", filename) + return + } + + fullName := getFullname(t.dataType) + msgName := protoreflect.FullName(fullName) + msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName) + if err != nil { + fmt.Printf("can not find proto message named %v, %v", fullName, err) + return + } + message := msgType.New().Interface() + + bytes, err := os.ReadFile(filename) + if err != nil { + fmt.Printf("read bytes file failed, %v", err) + return + } + + err = proto.Unmarshal(bytes, message) + if err != nil { + fmt.Printf("proto unmarshal failed, %v", err) + return + } + + t.data = message +} + +type DataTable struct { + indexKey string + dataType reflect.Type + data DataArray + dataMap DataMap + fileGen IFilenameGenerator +} + +func NewDataTable(indexKey string, dataType reflect.Type) *DataTable { + if indexKey == "" { + indexKey = DefaultIndexKey + } + + t := new(DataTable) + t.indexKey = indexKey + t.dataType = dataType + t.fileGen = t + return t +} + +func (t *DataTable) DataType() reflect.Type { + return t.dataType +} + +func (t *DataTable) Items() DataArray { + if t.data == nil { + t.load() + } + return t.data +} + +func (t *DataTable) ItemsMap() DataMap { + if t.data == nil { + t.load() + } + t.itemsAsMap() + return t.dataMap +} + +func (t *DataTable) GetItem(id string) interface{} { + var dataMap = t.ItemsMap() + if dt, ok := dataMap[id]; ok { + return dt + } + return nil +} + +func (t *DataTable) Clear() { + t.data = nil + t.dataMap = nil +} + +func (t *DataTable) GetFilename(typeName string) string { + return fmt.Sprintf("%s%s%s", dataDir, strings.ToLower(typeName), BytesFileExt) +} + +func (t *DataTable) load() { + if t.data != nil { + return + } + + var filename = t.fileGen.GetFilename(t.dataType.Name()) + if ok, _ := PathExists(filename); !ok { + fmt.Printf("can not find data file %s", filename) + return + } + + fullName := getFullname(t.dataType) + "_ARRAY" + msgName := protoreflect.FullName(fullName) + msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName) + if err != nil { + fmt.Printf("can not find proto message named %v, %v", fullName, err) + return + } + message := msgType.New().Interface() + + bytes, err := os.ReadFile(filename) + if err != nil { + fmt.Printf("read bytes file failed, %v", err) + return + } + + err = proto.Unmarshal(bytes, message) + if err != nil { + fmt.Printf("proto unmarshal failed, %v", err) + return + } + + var value = reflect.ValueOf(message) + var elm = value.Elem() + if elm.Kind() != reflect.Struct { + fmt.Printf("type %s kind error", fullName) + return + } + + t.data = make(DataArray, 0) + var items = elm.FieldByName("Items").Interface() + if reflect.TypeOf(items).Kind() == reflect.Slice { + s := reflect.ValueOf(items) + for i := 0; i < s.Len(); i++ { + ele := s.Index(i) + t.data = append(t.data, ele.Interface()) + } + } +} + +func (t *DataTable) itemsAsMap() { + if t.dataMap != nil { + return + } + t.dataMap = make(DataMap) + + for _, item := range t.data { + var value = reflect.ValueOf(item) + var elm = value.Elem() + var idx = elm.FieldByName(t.indexKey).Interface() + t.dataMap[fmt.Sprintf("%v", idx)] = item + } +} diff --git a/configs/utils.go b/configs/utils.go new file mode 100644 index 0000000..f2276b1 --- /dev/null +++ b/configs/utils.go @@ -0,0 +1,14 @@ +package configs + +import "os" + +func PathExists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} diff --git a/controllers/admin.go b/controllers/admin.go index 4503648..b211881 100644 --- a/controllers/admin.go +++ b/controllers/admin.go @@ -1,7 +1,7 @@ package controllers import ( - "apigame/configs/confbase" + "apigame/configs-db/confbase" "apigame/models" "apigame/service/code-msg" ) diff --git a/controllers/demo.go b/controllers/demo.go index cebbbdc..f9c068f 100644 --- a/controllers/demo.go +++ b/controllers/demo.go @@ -1,9 +1,10 @@ package controllers import ( + "apigame/configs" "apigame/models" "apigame/service/code-msg" - "apigame/util/util-lx/lxalilog" + "apigame/util/zjson" "encoding/json" "fmt" ) @@ -23,7 +24,7 @@ func (c *DemoController) Demo() { fmt.Println("DemoController.demo") - lxalilog.Errors("DemoController.demo") + //lxalilog.Errors("DemoController.demo") //{ // gameId := "10149" @@ -42,6 +43,14 @@ func (c *DemoController) Demo() { // fmt.Println(conf) // } //} + { + cs := configs.GetTable(configs.AbTestCfg{}).Items() + //for _, dt := range cs { + // conf := dt.(*configs.AbTestCfg) + // fmt.Println(conf) + //} + fmt.Println("cs", zjson.Str(cs)) + } c.RetRspCodeData(code_msg.RECODE_OK, rsp) } diff --git a/go.mod b/go.mod index c24ea7b..864169d 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,12 @@ require ( github.com/garyburd/redigo v1.6.4 github.com/go-sql-driver/mysql v1.7.0 github.com/gomodule/redigo v2.0.0+incompatible + github.com/google/uuid v1.6.0 github.com/lixu-any/go-tools v0.0.0-20221128094643-07d54c69e9bf github.com/mitchellh/mapstructure v1.1.2 + github.com/redis/go-redis/v9 v9.0.3 github.com/samber/lo v1.39.0 + google.golang.org/protobuf v1.25.0 gorm.io/driver/mysql v1.5.6 gorm.io/gorm v1.25.9 ) @@ -26,7 +29,6 @@ require ( github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.4.2 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -37,7 +39,6 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.10.0 // indirect github.com/prometheus/procfs v0.1.3 // indirect - github.com/redis/go-redis/v9 v9.0.3 // indirect github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect go.uber.org/atomic v1.5.0 // indirect golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect @@ -47,7 +48,6 @@ require ( golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 // indirect - google.golang.org/protobuf v1.25.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/main.go b/main.go index 36b27a0..1315038 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "apigame/configs" + "apigame/configs-db" _ "apigame/routers" "apigame/service" "apigame/service-common/svconst" @@ -65,6 +66,10 @@ func Init() bool { // //_ = config.InitLxLimit() + if !configs_db.Init() { + return false + } + if !configs.Init() { return false } diff --git a/middleware/sign/index.go b/middleware/sign/index.go index f0ab408..a9c9b3f 100644 --- a/middleware/sign/index.go +++ b/middleware/sign/index.go @@ -1,7 +1,7 @@ package sign import ( - "apigame/configs/confapi" + "apigame/configs-db/confapi" "apigame/middleware/sdk" "apigame/service/code-msg" "apigame/util/util-lx/lxalilog" diff --git a/service-common/svcommon/simulate.go b/service-common/svcommon/simulate.go index e7f60bd..5a9b900 100644 --- a/service-common/svcommon/simulate.go +++ b/service-common/svcommon/simulate.go @@ -1,8 +1,8 @@ package svcommon import ( - "apigame/configs/confglobal" - "apigame/util/utmisc" + "apigame/configs-db/confglobal" + "apigame/util/zmisc" "math/rand" ) @@ -24,7 +24,7 @@ func GetIndexNames(gameId string, amount int) []int { if err == nil { count := len(config.Names) if count > 0 { - return utmisc.RandomMultiple(amount, 0, count) + return zmisc.RandomMultiple(amount, 0, count) } } return list diff --git a/service-common/svredis/index.go b/service-common/svredis/index.go index a0e5dc3..d291435 100644 --- a/service-common/svredis/index.go +++ b/service-common/svredis/index.go @@ -3,7 +3,7 @@ package svredis import ( "apigame/service-common/svconst" "apigame/util/util-lx/lxredis" - "apigame/util/utstring" + "apigame/util/zconvert" "apigame/util/zjson" "apigame/util/zredis" "apigame/util/zredislock" @@ -33,7 +33,7 @@ func Init() bool { // 初始化Redis { - zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db)) + zredis.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, zconvert.ToInt(confRedis.Db)) if !zredis.Check() { return false } @@ -43,7 +43,7 @@ func Init() bool { // 初始化redis锁 { - zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, utstring.StringToInt(confRedis.Db)) + zredislock.Init(confRedis.Host+":"+confRedis.Port, confRedis.Pwd, zconvert.ToInt(confRedis.Db)) fmt.Println(svconst.AppName + " zredislock init success") } diff --git a/service/cardholder/handle.go b/service/cardholder/handle.go index e352c7c..2e319f9 100644 --- a/service/cardholder/handle.go +++ b/service/cardholder/handle.go @@ -1,14 +1,14 @@ package cardholder import ( - "apigame/configs/confcardholder" + "apigame/configs-db/confcardholder" "apigame/models" "apigame/service-common/svmysql" "apigame/service/code-msg" "apigame/util/util-lx/lxalilog" "apigame/util/util-lx/lxtime" - "apigame/util/utslice" - "apigame/util/utstring" + "apigame/util/zconvert" + "apigame/util/zslice" ) // HandleGetConfig 活动配置 @@ -112,7 +112,7 @@ func HandleOpen(req *models.ReqCardHolderOpen) (code string, rsp models.RspCardH sequenceId, cohort, openMode) // 打乱顺序 - utslice.Shuffle(newCards) + zslice.Shuffle(newCards) for _, i3 := range newCards { allNewCards = append(allNewCards, i3) } @@ -268,7 +268,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model // 从配置里拿到卡包ID和数量列表 cardholderIdCount := make(map[int]int) - cardholderIdCountList := utstring.StringToListListInt(confStarShop.CardBagIds, "|", ",") + cardholderIdCountList := zconvert.ToListListInt(confStarShop.CardBagIds, "|", ",") for _, i2 := range cardholderIdCountList { if len(i2) >= 3 { cardholderIdCount[i2[1]] = i2[2] @@ -292,7 +292,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model sequenceId, cohort, openMode) // 打乱顺序 - utslice.Shuffle(newCards) + zslice.Shuffle(newCards) for _, i3 := range newCards { allNewCards = append(allNewCards, i3) } @@ -314,7 +314,7 @@ func HandleShopExchange(req *models.ReqStarShopExchange) (code string, rsp model // 存档 SavePlayer(gameId, player) - utslice.Shuffle(rsp.NewCards) + zslice.Shuffle(rsp.NewCards) // 返回信息 rsp.CardHolderInfo = GetInfo(player, config) @@ -374,7 +374,7 @@ func HandleAutoExchangeInfo(req *models.ReqAutoExchangeInfo) (code string, rsp m // 存档 SavePlayer(gameId, player) - utslice.Shuffle(rsp.NewCards) + zslice.Shuffle(rsp.NewCards) // 返回信息 rsp.CardHolderInfo = GetInfo(player, config) diff --git a/service/cardholder/logic.go b/service/cardholder/logic.go index 4b8a784..5fc4193 100644 --- a/service/cardholder/logic.go +++ b/service/cardholder/logic.go @@ -1,15 +1,15 @@ package cardholder import ( - "apigame/configs/confcardholder" + "apigame/configs-db/confcardholder" "apigame/models" "apigame/service-common/svmysql" "apigame/service/code-msg" "apigame/util/util-lx/lxalilog" "apigame/util/util-lx/lxtime" - "apigame/util/utslice" - "apigame/util/utstring" + "apigame/util/zconvert" "apigame/util/zjson" + "apigame/util/zslice" "github.com/samber/lo" "math" "sort" @@ -241,7 +241,7 @@ func DoOpenCheckAward(gameId string, } // 集齐处理发奖 player.Details.Album[albumId] += 1 - award := confAlbum.Rewards[utstring.IntToString(player.Details.Round)] + award := confAlbum.Rewards[zconvert.IntToStr(player.Details.Round)] awardAlbum[albumId] = award { // 记录日志 @@ -254,7 +254,7 @@ func DoOpenCheckAward(gameId string, // 判断 处理 发放轮次奖励 轮次完成 if CheckRoundFinish(player, config) { // 返回奖励 - awardRound = config.Awards[utstring.IntToString(player.Details.Round)] + awardRound = config.Awards[zconvert.IntToStr(player.Details.Round)] // 记录日志 recordBase := NewRecordBase(player.Uid, sequenceId, cohort, config.Id, player.Details.Round) @@ -395,7 +395,7 @@ func NextActivityAutoExchange(gameId string, player *Player, config *confcardhol sequenceId, cohort, openMode) // 打乱顺序 - utslice.Shuffle(newCards) + zslice.Shuffle(newCards) for _, i3 := range newCards { allNewCards = append(allNewCards, i3) } diff --git a/service/cardholder/player.go b/service/cardholder/player.go index aa26933..8ffcda1 100644 --- a/service/cardholder/player.go +++ b/service/cardholder/player.go @@ -1,7 +1,7 @@ package cardholder import ( - "apigame/configs/confcardholder" + "apigame/configs-db/confcardholder" "apigame/service-common/svmysql" "apigame/util/util-lx/lxalilog" "apigame/util/util-lx/lxtime" diff --git a/service/roomrank/handle.go b/service/roomrank/handle.go index 9bb82f9..0a64cc1 100644 --- a/service/roomrank/handle.go +++ b/service/roomrank/handle.go @@ -1,7 +1,7 @@ package roomrank import ( - "apigame/configs/confroomrank" + "apigame/configs-db/confroomrank" "apigame/models" "apigame/service/code-msg" "apigame/util/util-lx/lxtime" diff --git a/service/roomrank/logic.go b/service/roomrank/logic.go index 9c863ca..2a38e27 100644 --- a/service/roomrank/logic.go +++ b/service/roomrank/logic.go @@ -1,10 +1,10 @@ package roomrank import ( - "apigame/configs/confroomrank" + "apigame/configs-db/confroomrank" "apigame/service-common/svconst" "apigame/util/util-lx/lxtime" - "apigame/util/utstring" + "apigame/util/zconvert" "apigame/util/ztime" "fmt" "time" @@ -91,7 +91,7 @@ func TrySettle(gameId string, topType int, player *Player) (hasChange bool) { if !hasConfRoom { return } - if confAward, hasConfAward := confRoom.Awards[utstring.IntToString(player.SettleRank)]; hasConfAward { + if confAward, hasConfAward := confRoom.Awards[zconvert.IntToStr(player.SettleRank)]; hasConfAward { player.SettleAward = confAward } if len(confRoom.SettleScores) > rankIndex { diff --git a/service/roomrank/player.go b/service/roomrank/player.go index a41d7b6..36fe75c 100644 --- a/service/roomrank/player.go +++ b/service/roomrank/player.go @@ -1,13 +1,13 @@ package roomrank import ( - "apigame/configs/confroomrank" + "apigame/configs-db/confroomrank" "apigame/models" "apigame/service-common/svcommon" "apigame/service-common/svmysql" "apigame/util/util-lx/lxalilog" "apigame/util/util-lx/lxtime" - "apigame/util/utstring" + "apigame/util/zconvert" ) func tryInitPlayer(gameId string, player *Player) { @@ -118,7 +118,7 @@ func GetInfoFromRoom(gameId string, player *Player, room *Room, config *confroom IsRobot: p.IsRobot(), } if confRoom, hasConfRoom := config.Room[room.ConfigId]; hasConfRoom { - if confAward, hasConfAward := confRoom.Awards[utstring.IntToString(rank)]; hasConfAward { + if confAward, hasConfAward := confRoom.Awards[zconvert.IntToStr(rank)]; hasConfAward { node.Award = confAward } } diff --git a/service/roomrank/room.go b/service/roomrank/room.go index c243915..611c916 100644 --- a/service/roomrank/room.go +++ b/service/roomrank/room.go @@ -1,7 +1,7 @@ package roomrank import ( - "apigame/configs/confroomrank" + "apigame/configs-db/confroomrank" "apigame/service-common/svcommon" "apigame/service-common/svmysql" "apigame/util/util-lx/lxalilog" diff --git a/util/utmap/map.go b/util/utmap/map.go deleted file mode 100644 index c617fd2..0000000 --- a/util/utmap/map.go +++ /dev/null @@ -1,66 +0,0 @@ -package utmap - -import ( - "apigame/util/uttype" - "math/rand" -) - -// Keys Keys切片 -func Keys[T1 comparable, T2 any](dict map[T1]T2) []T1 { - list := make([]T1, 0) - for k, _ := range dict { - list = append(list, k) - } - return list -} - -// Values Values切片 -func Values[T1 comparable, T2 any](dict map[T1]T2) []T2 { - list := make([]T2, 0) - for _, v := range dict { - list = append(list, v) - } - return list -} - -// ContainValue 值等于 -func ContainValue[T1 comparable, T2 comparable](dict map[T1]T2, value T2) bool { - for _, v := range dict { - if v == value { - return true - } - } - return false -} - -// ContainValueEquals 值等于 -func ContainValueEquals[T1 comparable, T2 uttype.EqualAble](dict map[T1]T2, value T2) bool { - for _, v := range dict { - if v.Equals(value) { - return true - } - } - return false -} - -// ContainValueBy 值符合 -func ContainValueBy[T1 comparable, T2 any](dict map[T1]T2, value T2, equals func(v1 T2, v2 T2) bool) bool { - for _, v := range dict { - if equals(v, value) { - return true - } - } - return false -} - -// RandomOne 随机一个值 -func RandomOne[T1 comparable, T2 any](dict map[T1]T2) T2 { - if len(dict) <= 0 { - return *new(T2) - } - list := make([]T1, 0) - for i, _ := range dict { - list = append(list, i) - } - return dict[list[rand.Intn(len(list))]] -} diff --git a/util/utmisc/goroutine.go b/util/utmisc/goroutine.go deleted file mode 100644 index 1bdcb56..0000000 --- a/util/utmisc/goroutine.go +++ /dev/null @@ -1,15 +0,0 @@ -package utmisc - -import ( - "fmt" - "runtime" -) - -// GetGoroutineID 获取携程ID -func GetGoroutineID() int { - var buf [64]byte - runtime.Stack(buf[:], false) - var id int - fmt.Sscanf(string(buf[:]), "goroutine %d", &id) - return id -} diff --git a/util/utmisc/random.go b/util/utmisc/random.go deleted file mode 100644 index 958433d..0000000 --- a/util/utmisc/random.go +++ /dev/null @@ -1,21 +0,0 @@ -package utmisc - -import "math/rand" - -func RandomMultiple(count, minNum, maxNum int) []int { - list := make([]int, 0) - if maxNum > minNum { - if count > maxNum-minNum { - count = maxNum - minNum - } - m := make(map[int]struct{}) - for len(m) < count { - v := minNum + rand.Intn(maxNum-minNum) - if _, ok := m[v]; !ok { - m[v] = struct{}{} - list = append(list, v) - } - } - } - return list -} diff --git a/util/utslice/slice.go b/util/utslice/slice.go deleted file mode 100644 index 6a6fe88..0000000 --- a/util/utslice/slice.go +++ /dev/null @@ -1,161 +0,0 @@ -package utslice - -import ( - "apigame/util/uttype" - "math/rand" -) - -// Contains 判断切片是否包含某元素 -func Contains[T comparable](list []T, value T) bool { - for _, v := range list { - if v == value { - return true - } - } - return false -} - -// RandomOne 随机一个元素 -func RandomOne[T any](list []T) T { - if len(list) <= 0 { - return *new(T) - } - return list[rand.Intn(len(list))] -} - -// Remove 切片删除一个元素 -func Remove[T comparable](list []T, item T) []T { - for i := 0; i < len(list); i++ { - if item == list[i] { - list = append(list[:i], list[i+1:]...) - i = i - 1 - } - } - return list -} - -// RemoveList 切片删除多个元素 -func RemoveList[T comparable](list []T, items []T) []T { - dMap := make(map[T]bool) - for _, s := range items { - dMap[s] = true - } - - for i := 0; i < len(list); i++ { - if _, ok := dMap[list[i]]; ok { - list = append(list[:i], list[i+1:]...) - i = i - 1 - } - } - return list -} - -// Sum 求和 -func Sum[T uttype.UtNumber](list []T) T { - var result T = 0 - for _, v := range list { - result += v - } - return result -} - -// Any 其中有一个元素符合就返回true -func Any[T uttype.UtNumber](list []T, value T) bool { - for _, v := range list { - if v == value { - return true - } - } - return false -} - -// AnyEquals 其中有一个元素符合就返回true -func AnyEquals[T uttype.EqualAble](list []T, value T) bool { - for _, v := range list { - if v.Equals(value) { - return true - } - } - return false -} - -// AnyBy 其中有一个元素符合就返回true -func AnyBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool { - for _, v := range list { - if equals(v, value) { - return true - } - } - return false -} - -// All 所有元素符合就返回true -func All[T uttype.UtNumber](list []T, value T) bool { - for _, v := range list { - if v != value { - return false - } - } - return true -} - -// AllEquals 所有元素符合就返回true -func AllEquals[T uttype.EqualAble](list []T, value T) bool { - for _, v := range list { - if !v.Equals(value) { - return false - } - } - return true -} - -// AllBy 所有元素符合就返回true -func AllBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool { - for _, v := range list { - if !equals(v, value) { - return false - } - } - return true -} - -// Filter 过滤 -func Filter[T comparable](list []T, value T) []T { - result := make([]T, 0) - for _, v := range list { - if v == value { - result = append(result, v) - } - } - return result -} - -// FilterEquals 过滤 -func FilterEquals[T uttype.EqualAble](list []T, value T) []T { - result := make([]T, 0) - for _, v := range list { - if v.Equals(value) { - result = append(result, v) - } - } - return result -} - -// FilterBy 过滤 -func FilterBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) []T { - result := make([]T, 0) - for _, v := range list { - if equals(v, value) { - result = append(result, v) - } - } - return result -} - -// Shuffle 打乱 -func Shuffle[T any](list []T) { - for i := len(list) - 1; i > 0; i-- { - j := rand.Intn(i + 1) - list[i], list[j] = list[j], list[i] - } -} diff --git a/util/utstring/list.go b/util/utstring/list.go deleted file mode 100644 index d111dfd..0000000 --- a/util/utstring/list.go +++ /dev/null @@ -1,51 +0,0 @@ -package utstring - -import "strings" - -func ListStringToListInt(list []string) []int { - result := make([]int, 0) - for _, v := range list { - result = append(result, StringToInt(v)) - } - return result -} -func ListStringToListInt64(list []string) []int64 { - result := make([]int64, 0) - for _, v := range list { - result = append(result, StringToInt64(v)) - } - return result -} -func StringToListString(str string, sep string) []string { - return strings.Split(str, sep) -} -func StringToListInt(str string, sep string) []int { - return ListStringToListInt(strings.Split(str, sep)) -} -func StringToListListString(str string, sep1, sep2 string) [][]string { - result := make([][]string, 0) - list1 := strings.Split(str, sep1) - for _, v := range list1 { - list2 := strings.Split(v, sep2) - result = append(result, list2) - } - return result -} -func StringToListListInt(str string, sep1, sep2 string) [][]int { - result := make([][]int, 0) - list1 := strings.Split(str, sep1) - for _, v := range list1 { - list2 := strings.Split(v, sep2) - result = append(result, ListStringToListInt(list2)) - } - return result -} -func StringToListListInt64(str string, sep1, sep2 string) [][]int64 { - result := make([][]int64, 0) - list1 := strings.Split(str, sep1) - for _, v := range list1 { - list2 := strings.Split(v, sep2) - result = append(result, ListStringToListInt64(list2)) - } - return result -} diff --git a/util/utstring/string.go b/util/utstring/string.go deleted file mode 100644 index 6fd261d..0000000 --- a/util/utstring/string.go +++ /dev/null @@ -1,30 +0,0 @@ -package utstring - -import ( - "strconv" -) - -func StringToInt(str string) int { - if value, err := strconv.Atoi(str); err == nil { - return value - } - return 0 -} -func StringToInt32(str string) int32 { - return int32(StringToInt(str)) -} -func StringToInt64(str string) int64 { - if value, err := strconv.ParseInt(str, 10, 64); err == nil { - return value - } - return 0 -} -func IntToString(value int) string { - return strconv.Itoa(value) -} -func Int32ToString(value int32) string { - return IntToString(int(value)) -} -func Int64ToString(value int64) string { - return strconv.FormatInt(value, 10) -} diff --git a/util/uttype/equals.go b/util/uttype/equals.go deleted file mode 100644 index 4e4be35..0000000 --- a/util/uttype/equals.go +++ /dev/null @@ -1,8 +0,0 @@ -package uttype - -// EqualAble 可比较的 -type EqualAble interface { - Equals(T EqualAble) bool -} - -type FuncEquals[T any] func(v1 T, v2 T) bool diff --git a/util/uttype/type.go b/util/uttype/type.go deleted file mode 100644 index a2e10ea..0000000 --- a/util/uttype/type.go +++ /dev/null @@ -1,21 +0,0 @@ -package uttype - -type UtInt interface { - ~int | ~int8 | ~int16 | ~int32 | ~int64 -} - -type UtUint interface { - ~uint | ~uint8 | ~uint16 | ~uint32 -} - -type UtFloat interface { - ~float32 | ~float64 -} - -type UtNumber interface { - UtInt | UtUint | UtFloat -} - -type UtBase interface { - UtNumber | string -} diff --git a/util/utuuid/uuid.go b/util/utuuid/uuid.go deleted file mode 100644 index 9f2b9e8..0000000 --- a/util/utuuid/uuid.go +++ /dev/null @@ -1,7 +0,0 @@ -package utuuid - -import "github.com/google/uuid" - -func GetUint32() uint32 { - return uuid.New().ID() -} diff --git a/util/zconvert/list.go b/util/zconvert/list.go new file mode 100644 index 0000000..26e8f44 --- /dev/null +++ b/util/zconvert/list.go @@ -0,0 +1,109 @@ +package zconvert + +import ( + "apigame/util/ztype" + "strings" +) + +/* ----- list -> list ----- */ + +func ListNumberToListNumber[T1 ztype.UtNumber, T2 ztype.UtNumber](in []T1) (out []T2) { + for _, t1 := range in { + out = append(out, T2(t1)) + } + return +} + +/* ----- list -> list ----- */ + +func ListStrToListNumber[T ztype.UtNumber](list []string) []T { + result := make([]T, 0) + for _, v := range list { + result = append(result, T(ToInt64(v))) + } + return result +} +func ListStrToListInt(list []string) []int { + result := make([]int, 0) + for _, v := range list { + result = append(result, ToInt(v)) + } + return result +} +func ListStrToListInt32(list []string) []int32 { + result := make([]int32, 0) + for _, v := range list { + result = append(result, ToInt32(v)) + } + return result +} +func ListStrToListInt64(list []string) []int64 { + result := make([]int64, 0) + for _, v := range list { + result = append(result, ToInt64(v)) + } + return result +} + +/* ----- string -> list ----- */ + +func ToListStr(str string, sep string) []string { + return strings.Split(str, sep) +} +func ToListNumber[T ztype.UtNumber](str string, sep string) []T { + return ListStrToListNumber[T](strings.Split(str, sep)) +} +func ToListInt(str string, sep string) []int { + return ListStrToListInt(strings.Split(str, sep)) +} +func ToListInt32(str string, sep string) []int32 { + return ListStrToListInt32(strings.Split(str, sep)) +} + +/* ----- string -> list> ----- */ + +func ToListListStr(str string, sep1, sep2 string) [][]string { + result := make([][]string, 0) + list1 := strings.Split(str, sep1) + for _, v := range list1 { + list2 := strings.Split(v, sep2) + result = append(result, list2) + } + return result +} +func ToListListNumber[T ztype.UtNumber](str string, sep1, sep2 string) [][]T { + result := make([][]T, 0) + list1 := strings.Split(str, sep1) + for _, v := range list1 { + list2 := strings.Split(v, sep2) + result = append(result, ListStrToListNumber[T](list2)) + } + return result +} +func ToListListInt(str string, sep1, sep2 string) [][]int { + result := make([][]int, 0) + list1 := strings.Split(str, sep1) + for _, v := range list1 { + list2 := strings.Split(v, sep2) + result = append(result, ListStrToListInt(list2)) + } + return result +} +func ToListListInt32(str string, sep1, sep2 string) [][]int32 { + result := make([][]int32, 0) + list1 := strings.Split(str, sep1) + for _, v := range list1 { + list2 := strings.Split(v, sep2) + result = append(result, ListStrToListInt32(list2)) + } + return result +} +func ToListListInt64(str string, sep1, sep2 string) [][]int64 { + result := make([][]int64, 0) + list1 := strings.Split(str, sep1) + for _, v := range list1 { + list2 := strings.Split(v, sep2) + result = append(result, ListStrToListInt64(list2)) + } + return result +} diff --git a/util/zconvert/map.go b/util/zconvert/map.go new file mode 100644 index 0000000..71f983d --- /dev/null +++ b/util/zconvert/map.go @@ -0,0 +1,25 @@ +package zconvert + +/* ----- string -> map ----- */ + +func ToMapStr(str string, sep1, sep2 string) map[string]string { + result := make(map[string]string) + list := ToListListStr(str, sep1, sep2) + for _, i2 := range list { + if len(i2) >= 2 { + result[i2[0]] = i2[1] + } + } + return result +} + +func ToMapInt32(str string, sep1, sep2 string) map[int32]int32 { + result := make(map[int32]int32) + list := ToListListInt32(str, sep1, sep2) + for _, i2 := range list { + if len(i2) >= 2 { + result[i2[0]] = i2[1] + } + } + return result +} diff --git a/util/zconvert/number.go b/util/zconvert/number.go new file mode 100644 index 0000000..d391f6d --- /dev/null +++ b/util/zconvert/number.go @@ -0,0 +1,45 @@ +package zconvert + +import ( + "apigame/util/ztype" + "strconv" +) + +/* -----泛型----- */ + +func ToStr[T ztype.UtInteger](t T) string { + return strconv.FormatInt(int64(t), 10) +} +func IToStr[T ztype.UtInt](t T) string { + return strconv.FormatInt(int64(t), 10) +} +func UToStr[T ztype.UtUint](t T) string { + return strconv.FormatUint(uint64(t), 10) +} + +/* ----- string -> number ----- */ + +func ToInt(str string) int { + if value, err := strconv.Atoi(str); err == nil { + return value + } + return 0 +} +func ToInt32(str string) int32 { + return int32(ToInt(str)) +} +func ToInt64(str string) int64 { + if value, err := strconv.ParseInt(str, 10, 64); err == nil { + return value + } + return 0 +} +func IntToStr(value int) string { + return strconv.Itoa(value) +} +func Int32ToStr(value int32) string { + return IntToStr(int(value)) +} +func Int64ToStr(value int64) string { + return strconv.FormatInt(value, 10) +} diff --git a/util/zmap/map.go b/util/zmap/map.go new file mode 100644 index 0000000..40ff299 --- /dev/null +++ b/util/zmap/map.go @@ -0,0 +1,66 @@ +package zmap + +import ( + "apigame/util/ztype" + "math/rand" +) + +// Keys Keys切片 +func Keys[T1 comparable, T2 any](dict map[T1]T2) []T1 { + list := make([]T1, 0) + for k, _ := range dict { + list = append(list, k) + } + return list +} + +// Values Values切片 +func Values[T1 comparable, T2 any](dict map[T1]T2) []T2 { + list := make([]T2, 0) + for _, v := range dict { + list = append(list, v) + } + return list +} + +// ContainValue 值等于 +func ContainValue[T1 comparable, T2 comparable](dict map[T1]T2, value T2) bool { + for _, v := range dict { + if v == value { + return true + } + } + return false +} + +// ContainValueEquals 值等于 +func ContainValueEquals[T1 comparable, T2 ztype.EqualAble](dict map[T1]T2, value T2) bool { + for _, v := range dict { + if v.Equals(value) { + return true + } + } + return false +} + +// ContainValueBy 值符合 +func ContainValueBy[T1 comparable, T2 any](dict map[T1]T2, value T2, equals func(v1 T2, v2 T2) bool) bool { + for _, v := range dict { + if equals(v, value) { + return true + } + } + return false +} + +// RandomOne 随机一个值 +func RandomOne[T1 comparable, T2 any](dict map[T1]T2) T2 { + if len(dict) <= 0 { + return *new(T2) + } + list := make([]T1, 0) + for i, _ := range dict { + list = append(list, i) + } + return dict[list[rand.Intn(len(list))]] +} diff --git a/util/zmisc/goroutine.go b/util/zmisc/goroutine.go new file mode 100644 index 0000000..54a9536 --- /dev/null +++ b/util/zmisc/goroutine.go @@ -0,0 +1,15 @@ +package zmisc + +import ( + "fmt" + "runtime" +) + +// GetGoroutineID 获取携程ID +func GetGoroutineID() int { + var buf [64]byte + runtime.Stack(buf[:], false) + var id int + fmt.Sscanf(string(buf[:]), "goroutine %d", &id) + return id +} diff --git a/util/zmisc/random.go b/util/zmisc/random.go new file mode 100644 index 0000000..b2c65ee --- /dev/null +++ b/util/zmisc/random.go @@ -0,0 +1,21 @@ +package zmisc + +import "math/rand" + +func RandomMultiple(count, minNum, maxNum int) []int { + list := make([]int, 0) + if maxNum > minNum { + if count > maxNum-minNum { + count = maxNum - minNum + } + m := make(map[int]struct{}) + for len(m) < count { + v := minNum + rand.Intn(maxNum-minNum) + if _, ok := m[v]; !ok { + m[v] = struct{}{} + list = append(list, v) + } + } + } + return list +} diff --git a/util/zslice/slice.go b/util/zslice/slice.go new file mode 100644 index 0000000..4d55904 --- /dev/null +++ b/util/zslice/slice.go @@ -0,0 +1,161 @@ +package zslice + +import ( + "apigame/util/ztype" + "math/rand" +) + +// Contains 判断切片是否包含某元素 +func Contains[T comparable](list []T, value T) bool { + for _, v := range list { + if v == value { + return true + } + } + return false +} + +// RandomOne 随机一个元素 +func RandomOne[T any](list []T) T { + if len(list) <= 0 { + return *new(T) + } + return list[rand.Intn(len(list))] +} + +// Remove 切片删除一个元素 +func Remove[T comparable](list []T, item T) []T { + for i := 0; i < len(list); i++ { + if item == list[i] { + list = append(list[:i], list[i+1:]...) + i = i - 1 + } + } + return list +} + +// RemoveList 切片删除多个元素 +func RemoveList[T comparable](list []T, items []T) []T { + dMap := make(map[T]bool) + for _, s := range items { + dMap[s] = true + } + + for i := 0; i < len(list); i++ { + if _, ok := dMap[list[i]]; ok { + list = append(list[:i], list[i+1:]...) + i = i - 1 + } + } + return list +} + +// Sum 求和 +func Sum[T ztype.UtNumber](list []T) T { + var result T = 0 + for _, v := range list { + result += v + } + return result +} + +// Any 其中有一个元素符合就返回true +func Any[T ztype.UtNumber](list []T, value T) bool { + for _, v := range list { + if v == value { + return true + } + } + return false +} + +// AnyEquals 其中有一个元素符合就返回true +func AnyEquals[T ztype.EqualAble](list []T, value T) bool { + for _, v := range list { + if v.Equals(value) { + return true + } + } + return false +} + +// AnyBy 其中有一个元素符合就返回true +func AnyBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool { + for _, v := range list { + if equals(v, value) { + return true + } + } + return false +} + +// All 所有元素符合就返回true +func All[T ztype.UtNumber](list []T, value T) bool { + for _, v := range list { + if v != value { + return false + } + } + return true +} + +// AllEquals 所有元素符合就返回true +func AllEquals[T ztype.EqualAble](list []T, value T) bool { + for _, v := range list { + if !v.Equals(value) { + return false + } + } + return true +} + +// AllBy 所有元素符合就返回true +func AllBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) bool { + for _, v := range list { + if !equals(v, value) { + return false + } + } + return true +} + +// Filter 过滤 +func Filter[T comparable](list []T, value T) []T { + result := make([]T, 0) + for _, v := range list { + if v == value { + result = append(result, v) + } + } + return result +} + +// FilterEquals 过滤 +func FilterEquals[T ztype.EqualAble](list []T, value T) []T { + result := make([]T, 0) + for _, v := range list { + if v.Equals(value) { + result = append(result, v) + } + } + return result +} + +// FilterBy 过滤 +func FilterBy[T any](list []T, value T, equals func(v1 T, v2 T) bool) []T { + result := make([]T, 0) + for _, v := range list { + if equals(v, value) { + result = append(result, v) + } + } + return result +} + +// Shuffle 打乱 +func Shuffle[T any](list []T) { + for i := len(list) - 1; i > 0; i-- { + j := rand.Intn(i + 1) + list[i], list[j] = list[j], list[i] + } +} diff --git a/util/ztype/compare.go b/util/ztype/compare.go new file mode 100644 index 0000000..bd8b063 --- /dev/null +++ b/util/ztype/compare.go @@ -0,0 +1,17 @@ +package ztype + +// Min 最小值 +func Min[T UtNumber](v1, v2 T) T { + if v1 < v2 { + return v1 + } + return v2 +} + +// Max 最大值 +func Max[T UtNumber](v1, v2 T) T { + if v1 > v2 { + return v1 + } + return v2 +} diff --git a/util/ztype/equals.go b/util/ztype/equals.go new file mode 100644 index 0000000..447247a --- /dev/null +++ b/util/ztype/equals.go @@ -0,0 +1,8 @@ +package ztype + +// EqualAble 可比较的 +type EqualAble interface { + Equals(T EqualAble) bool +} + +type FuncEquals[T any] func(v1 T, v2 T) bool diff --git a/util/ztype/type.go b/util/ztype/type.go new file mode 100644 index 0000000..e252c70 --- /dev/null +++ b/util/ztype/type.go @@ -0,0 +1,25 @@ +package ztype + +type UtInt interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +type UtUint interface { + ~uint | ~uint8 | ~uint16 | ~uint32 +} + +type UtFloat interface { + ~float32 | ~float64 +} + +type UtInteger interface { + UtInt | UtUint +} + +type UtNumber interface { + UtInt | UtUint | UtFloat +} + +type UtBase interface { + UtNumber | string +} diff --git a/util/zuuid/uuid.go b/util/zuuid/uuid.go new file mode 100644 index 0000000..9f2b9e8 --- /dev/null +++ b/util/zuuid/uuid.go @@ -0,0 +1,7 @@ +package utuuid + +import "github.com/google/uuid" + +func GetUint32() uint32 { + return uuid.New().ID() +} -- libgit2 0.21.0