diff --git a/bin/json/game_dispatch_task.json b/bin/json/game_dispatch_task.json index c2f2f6602..71b84353a 100644 --- a/bin/json/game_dispatch_task.json +++ b/bin/json/game_dispatch_task.json @@ -2648,7 +2648,7 @@ }, "icon": "xmwg_rw_pt7", "taskcd": 200, - "tasktime": 162, + "tasktime": 65, "tasktxt": { "key": "Entrustment details of Shifu", "text": "这是属于师父的专属委托" diff --git a/comm/const.go b/comm/const.go index 75aa1c6d5..e6d41847e 100644 --- a/comm/const.go +++ b/comm/const.go @@ -84,6 +84,7 @@ const ( ModulePandaAtlas core.M_Modules = "atlas" //熊猫图鉴 ModuleParkour core.M_Modules = "parkour" //跑酷系统 ModuleTools core.M_Modules = "tools" //工具 + ModuleReputation core.M_Modules = "reputation" //阵营声望 ) // 数据表名定义处 @@ -242,6 +243,8 @@ const ( // 美食馆 图鉴 TableGourmetAtlas = "gourmetatlas" + // 声望 + TableReputation = "reputation" ///捕羊大赛 TableParkour = "parkour" diff --git a/comm/imodule.go b/comm/imodule.go index 1bee570c7..382b2312d 100644 --- a/comm/imodule.go +++ b/comm/imodule.go @@ -298,6 +298,9 @@ type ( QueryHeroFetter(uid string) (data []*pb.DBHeroFetter) // 查询所有的羁绊信息 AddHeroFetterData(uid string, heroConfId string) (code pb.ErrorCode) // 创建一条羁绊信息 SendRpcAddHero(uid string, heroConfId string, serverTag string) (err error) + + // 获取 某个阵营的羁绊数据 + QueryFavorabilityByRace(uid string, race int32) int32 } //月子秘境 IMoonFantasy interface { @@ -450,6 +453,9 @@ type ( AddItems(session IUserSession, items map[string]int32, bPush bool) (code pb.ErrorCode) //pvp切磋结果通知 ChallengeResults(bid, red, bule string, winSide int32) + + // 清除玩家踢馆状态 + CleanUpNpc(uid string) } //捕羊大赛 diff --git a/modules/comp_configure.go b/modules/comp_configure.go index adfae337b..86e0e1355 100644 --- a/modules/comp_configure.go +++ b/modules/comp_configure.go @@ -12,8 +12,6 @@ import ( ) const ( - game_global = "game_global.json" //全局配置表 - game_initial = "game_initial.json" //初始化表 game_gamecolor = "game_gamecolor.json" //颜色表 game_playerlv = "game_playerlv.json" //玩家等级 game_facemod = "game_facemod.json" //形象配置表 @@ -28,7 +26,6 @@ const ( game_equip = "game_equip.json" //装备信息表 - game_lottery = "game_lottery.json" ) ///配置管理基础组件 @@ -37,27 +34,11 @@ type MCompConfigure struct { hlock sync.RWMutex _dropMap map[int32][]*cfg.GameDropData // 掉落表 key 是DiropId _sign map[int32]*cfg.GameSignData - - _group map[int64][]int32 // key 小组ID value cid - - // 类型为1 的数据 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 - _lotteryType1 map[int32][]int32 // key 大组ID value cid - // 类型为2 的数据 有多个小组ID - _lotteryType2 map[int32][]int32 // key 大组ID value 小组ID - // 小组类型为1 - _groupType1 map[int64][]int32 //value cid - // 小组类型为2 - _groupType2 map[int64][]int32 //value cid - Btype map[int32]int32 - Stype map[int64]int32 // subtype - SNum map[int64]int32 // 小组产出数量 } //组件初始化接口 func (this *MCompConfigure) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { err = this.ModuleCompBase.Init(service, module, comp, options) - err = this.LoadConfigure(game_global, cfg.NewGameGlobal) - err = this.LoadConfigure(game_initial, cfg.NewGameInitial) err = this.LoadConfigure(game_gamecolor, cfg.NewGameGameColor) err = this.LoadConfigure(new_hero, cfg.NewGameHero) err = this.LoadConfigure(game_playerlv, cfg.NewGamePlayerlv) @@ -67,211 +48,11 @@ func (this *MCompConfigure) Init(service core.IService, module core.IModule, com //err = this.LoadConfigure(game_sign, cfg.NewGameSign) err = this.LoadConfigure(game_item, cfg.NewGameItem) err = this.LoadConfigure(game_vip, cfg.NewGameVip) - err = this.LoadConfigure(game_lottery, cfg.NewGameLottery) this._dropMap = make(map[int32][]*cfg.GameDropData, 0) this._sign = make(map[int32]*cfg.GameSignData, 0) configure.RegisterConfigure(game_drop, cfg.NewGameDrop, this.LoadDropData) configure.RegisterConfigure(game_sign, cfg.NewGameSign, this.LoadSignData) - this._group = make(map[int64][]int32, 0) - this._lotteryType1 = make(map[int32][]int32, 0) - this._lotteryType2 = make(map[int32][]int32, 0) - this._groupType1 = make(map[int64][]int32, 0) - this._groupType2 = make(map[int64][]int32, 0) - this.Btype = make(map[int32]int32, 0) - this.Stype = make(map[int64]int32, 0) - this.SNum = make(map[int64]int32, 0) - configure.RegisterConfigure(game_lottery, cfg.NewGameLottery, this.LoadGroupData) - - return -} - -func (this *MCompConfigure) LoadGroupData() { - if v, err := this.GetConfigure(game_lottery); err == nil { - if configure, ok := v.(*cfg.GameLottery); ok { - this.hlock.Lock() - defer this.hlock.Unlock() - this._group = make(map[int64][]int32, 0) - this._lotteryType1 = make(map[int32][]int32, 0) - this._lotteryType2 = make(map[int32][]int32, 0) - this._groupType1 = make(map[int64][]int32, 0) - this._groupType2 = make(map[int64][]int32, 0) - this.Btype = make(map[int32]int32, 0) - this.Stype = make(map[int64]int32, 0) - this.SNum = make(map[int64]int32, 0) - for _, value := range configure.GetDataList() { - key := int64(value.Lotteryid)<<31 + int64(value.Groupid) - this._group[key] = append(this._group[key], value.Id) - - if _, ok := this.Btype[value.Lotteryid]; !ok { - this.Btype[value.Lotteryid] = value.Type - } - - if _, ok := this.Stype[key]; !ok { - this.Stype[key] = value.Subtype - } - if _, ok := this.SNum[key]; !ok { - this.SNum[key] = value.Groupnum - } - if this.Btype[value.Lotteryid] == 1 { - this._lotteryType1[value.Lotteryid] = append(this._lotteryType1[value.Lotteryid], value.Id) - } else if this.Btype[value.Lotteryid] == 2 { - this._lotteryType2[value.Lotteryid] = append(this._lotteryType2[value.Lotteryid], value.Id) - } - - if this.Stype[key] == 1 { // 小组ID为1 - this._groupType1[key] = append(this._groupType1[key], value.Id) - } else if this.Stype[key] == 2 { - this._groupType2[key] = append(this._groupType2[key], value.Id) - } - } - return - } - } else { - log.Errorf("get LoadGroupData conf err:%v", err) - } - return -} - -// 实际掉落逻辑 (传入 掉落组ID vip等级 玩家等级 返回获得的道具) -func (this *MCompConfigure) GetGroupDataByLottery(lotteryId int32, vipLv int32, lv int32) (items []*cfg.Gameatn) { - - if _, ok := this._lotteryType1[lotteryId]; !ok { - if _, ok := this._lotteryType2[lotteryId]; !ok { - fmt.Printf("not found config lotterId:%d", lotteryId) - return - } - } - // 优先校验大组ID 的类型 - if this.Btype[lotteryId] == 1 { // 该大组中的小组为权重掉落,必定从N个小组中随机出1个小组 - var ( - szW []int32 // 权重数组 - szID []int32 // 小组ID 数组 - groupID int32 - gourp map[int32]int32 // key 小组ID value 权重 - ) - - gourp = make(map[int32]int32, 0) - // 随机小组id - for _, v := range this._lotteryType1[lotteryId] { - if _data := this.GetLotterConfById(v); _data != nil { - if (_data.Playerlvmax == 0 || _data.Playerlvmin <= lv && lv <= _data.Playerlvmax) && (_data.VIPmax == 0 || _data.VIPmin <= vipLv && vipLv <= _data.VIPmax) { // 过滤等级等条件 - if _, ok := gourp[_data.Groupid]; !ok { - gourp[_data.Groupid] = _data.Groupwt // 小组ID 权重赋值 - szW = append(szW, _data.Groupwt) - szID = append(szID, _data.Groupid) - } - } - } - } - - groupID = szID[comm.GetRandW(szW)] // 获得小组ID - fmt.Printf("大组类型为1的,获得小组ID :%d,dropID:%d", groupID, lotteryId) - key := int64(lotteryId)<<31 + int64(groupID) - // 小组ID 类型判断 - if this.Stype[key] == 1 { // 该小组的道具为权重掉落,必定从N个道具中随机出1个道具 - for i := 0; i < int(this.SNum[key]); i++ { - szW = make([]int32, 0) - szID = make([]int32, 0) - gourp = make(map[int32]int32, 0) - for _, v := range this._groupType1[key] { - if _data := this.GetLotterConfById(v); _data != nil { // 权重赋值 - if _, ok := gourp[_data.Groupid]; !ok { - szW = append(szW, _data.Itemwt) - szID = append(szID, _data.Id) - } - } - } - index := comm.GetRandW(szW) - _data := this.GetLotterConfById(szID[index]) - fmt.Printf("获得最终的道具 :%d", _data.Id) - count := comm.GetRandNum(_data.Min, _data.Max) - // 随机获得的数量 - items = append(items, &cfg.Gameatn{ - A: _data.Itemid.A, - T: _data.Itemid.T, - N: _data.Itemid.N * count, - }) - } - return - } else if this.Stype[key] == 2 { // 该小组中的道具为概率掉落,每个道具都会随机一次是否会掉落(单位为千分比) - for _, v := range this._groupType2[key] { - if _data := this.GetLotterConfById(v); _data != nil { // 权重赋值 - fmt.Printf("大组类型1小组类型2获得道具 :%v, 该道具Cid:%d", _data.Itemid, v) - if _data.Itemwt >= comm.GetRandNum(1, 1000) { // 命中 - count := comm.GetRandNum(_data.Min, _data.Max) - items = append(items, &cfg.Gameatn{ - A: _data.Itemid.A, - T: _data.Itemid.T, - N: _data.Itemid.N * count, // 小组产出数量 - }) - } - } - } - return - } - } else if this.Btype[lotteryId] == 2 { // 该大组中的小组为概率掉落,每个小组都会随机一次是否会掉落(单位为千分比) - // 每个小组id 都随机取一次 - var szGroupID []int32 // 获得的权重数组 - gourp := make(map[int32]*cfg.GameLotteryData, 0) // key 小组ID value 权重 - for _, v := range this._lotteryType2[lotteryId] { - if _data := this.GetLotterConfById(v); _data != nil { - if (_data.Playerlvmax == 0 || _data.Playerlvmin <= lv && lv <= _data.Playerlvmax) && (_data.VIPmax == 0 || _data.VIPmin <= vipLv && vipLv <= _data.VIPmax) { // 过滤等级等条件 - if _, ok := gourp[_data.Groupid]; !ok { - gourp[_data.Groupid] = _data // 小组ID 权重赋值 - } - } - } - } - - // 类型为2 可能会同时获得多个组id - for k, v := range gourp { - fmt.Printf("大组类型为2的,获得小组ID :%d,dropID:%d", k, v.Id) - if v.Itemwt >= comm.GetRandNum(0, 1000) { // 命中 - szGroupID = append(szGroupID, k) - key := int64(lotteryId)<<31 + int64(k) - if this.Stype[key] == 1 { // 随机一组数据 - for i := 0; i < int(this.SNum[key]); i++ { - szW := make([]int32, 0) - szID := make([]int32, 0) - gourp := make(map[int32]int32, 0) - for _, v := range this._groupType1[key] { - if _data := this.GetLotterConfById(v); _data != nil { // 权重赋值 - if _, ok := gourp[_data.Groupid]; !ok { - szW = append(szW, _data.Itemwt) - szID = append(szID, _data.Id) - } - } - } - index := comm.GetRandW(szW) - _data := this.GetLotterConfById(szID[index]) - fmt.Printf("获得最终的道具 :%d", _data.Id) - count := comm.GetRandNum(_data.Min, _data.Max) - // 随机获得的数量 - items = append(items, &cfg.Gameatn{ - A: _data.Itemid.A, - T: _data.Itemid.T, - N: _data.Itemid.N * count, - }) - } - } else if this.Stype[key] == 2 { - for _, v := range this._groupType2[key] { - if _data := this.GetLotterConfById(v); _data != nil { // 权重赋值 - fmt.Printf("大组类型2小组类型2获得道具 :%v,该道具Cid:%d", _data.Itemid, v) - if _data.Itemwt >= comm.GetRandNum(1, 1000) { // 命中 - count := comm.GetRandNum(_data.Min, _data.Max) - items = append(items, &cfg.Gameatn{ - A: _data.Itemid.A, - T: _data.Itemid.T, - N: _data.Itemid.N * count, // 小组产出数量 - }) - } - } - } - } - } - } - } return } @@ -323,38 +104,6 @@ func (this *MCompConfigure) GetConfigure(name string) (v interface{}, err error) return configure.GetConfigure(name) } -//全局配置 -// func (this *MCompConfigure) GetGlobalConf() *cfg.GameGlobalData { -// var ( -// configure *cfg.GameGlobal -// ok bool -// ) -// if v, err := this.GetConfigure(game_global); err != nil { -// log.Errorf("get global conf err:%v", err) -// return nil -// } else { -// if configure, ok = v.(*cfg.GameGlobal); !ok { -// log.Errorf("%T no is *cfg.Game_global", v) -// return nil -// } -// } -// return configure.GetDataList()[0] // 返回对象信息 -// } - -func (this *MCompConfigure) GetGlobalInitConf() (configure *cfg.GameInitial, err error) { - var ( - v interface{} - ok bool - ) - if v, err = this.GetConfigure(game_initial); err == nil { - if configure, ok = v.(*cfg.GameInitial); !ok { - err = fmt.Errorf("%T no is *cfg.Game_comInitial", v) - return - } - } - return -} - // 主角等级经验配置列表 func (this *MCompConfigure) GetPlayerlvConfList() (list []*cfg.GamePlayerlvData) { if v, err := this.GetConfigure(game_playerlv); err != nil { @@ -578,12 +327,3 @@ func (this *MCompConfigure) GetAllEquipmentConfigure() (configure []*cfg.GameEqu } return } - -func (this *MCompConfigure) GetLotterConfById(id int32) (data *cfg.GameLotteryData) { - if v, err := this.GetConfigure(game_lottery); err == nil { - if configure, ok := v.(*cfg.GameLottery); ok { - return configure.Get(id) - } - } - return -} diff --git a/modules/gm/api_cmd.go b/modules/gm/api_cmd.go index e04b85013..a5056ecc0 100644 --- a/modules/gm/api_cmd.go +++ b/modules/gm/api_cmd.go @@ -37,6 +37,7 @@ import ( 21、bingo:chat,1 22、bingo:itemtype,1,1 // 获取某种类型所有道具(道具类型,数量) 23、bingo:viplv,50 +24、bingo:cleannpc */ //参数校验 func (this *apiComp) CmdCheck(session comm.IUserSession, req *pb.GMCmdReq) (code pb.ErrorCode) { diff --git a/modules/gm/module.go b/modules/gm/module.go index 28b301e72..1301d8231 100644 --- a/modules/gm/module.go +++ b/modules/gm/module.go @@ -463,6 +463,18 @@ func (this *GM) CreateCmd(session comm.IUserSession, cmd string) (code pb.ErrorC log.Field{Key: "0", Value: datas[0]}, log.Field{Key: "N", Value: int32(num)}, ) + } else if len(datas) == 1 && (datas[0] == "cleannpc") { // 充值次数 + module1, err := this.service.GetModule(comm.ModulePractice) + if err != nil { + return + } + + module1.(comm.IPractice).CleanUpNpc(session.GetUserId()) + + this.Debug("使用bingo命令:uid = %s ", + log.Field{Key: "uid", Value: session.GetUserId()}, + log.Field{Key: "0", Value: datas[0]}, + ) } } } diff --git a/modules/library/module.go b/modules/library/module.go index 6bbdfc742..c6701c401 100644 --- a/modules/library/module.go +++ b/modules/library/module.go @@ -319,3 +319,11 @@ func (this *Library) TaskFinishNotify(uid string, taskId, fetterId int32) error } return nil } + +// 获取阵营的好感度 +func (this *Library) QueryFavorabilityByRace(uid string, race int32) int32 { + if rst, err := this.ModuleUser.GetUserExpand(uid); err == nil { // 统计主线进度 + return rst.Race[race] + } + return 0 +} diff --git a/modules/practice/api_npcbattklefinish.go b/modules/practice/api_npcbattklefinish.go index 3891fb8ef..3f0678e7c 100644 --- a/modules/practice/api_npcbattklefinish.go +++ b/modules/practice/api_npcbattklefinish.go @@ -42,8 +42,10 @@ func (this *apiComp) NPCBattkleFinish(session comm.IUserSession, req *pb.Practic if code = this.module.DispenseRes(session, conf.Award, true); code != pb.ErrorCode_Success { return } + room.Refresh = configure.Now().Unix() this.module.modelPandata.Change(session.GetUserId(), map[string]interface{}{ "npcstate": room.Npcstate, + "refresh": room.Refresh, }) } else { room.Npcstate = 1 diff --git a/modules/practice/api_npcdialog.go b/modules/practice/api_npcdialog.go index bf771aaee..fc5ed60e6 100644 --- a/modules/practice/api_npcdialog.go +++ b/modules/practice/api_npcdialog.go @@ -12,7 +12,7 @@ func (this *apiComp) NPCDialogCheck(session comm.IUserSession, req *pb.PracticeN return } -///npc 领取对白奖励 +///npc 此协议废弃 不用 func (this *apiComp) NPCDialog(session comm.IUserSession, req *pb.PracticeNPCDialogReq) (code pb.ErrorCode, data *pb.ErrorData) { var ( err error diff --git a/modules/practice/module.go b/modules/practice/module.go index 70b8acb85..71767bd3a 100644 --- a/modules/practice/module.go +++ b/modules/practice/module.go @@ -402,3 +402,19 @@ func (this *Practice) RPC_ModulePracticeUnLockPillar(ctx context.Context, args * // } return } + +// 一键踢馆 (跨服) +func (this *Practice) CleanUpNpc(uid string) { + conn_, _ := db.Cross() // 获取跨服数据库对象 + model := db.NewDBModel(comm.TablePandata, time.Hour, conn_) + result := &pb.DBPracticeRoom{} + if err := model.Get(uid, result); err != nil && err != mgo.MongodbNil { + return + } + + result.Refresh = configure.Now().Unix() + this.modelPandata.Change(uid, map[string]interface{}{ // 同步状态即可 + "npcstate": 3, + "refresh": result.Refresh, + }) +} diff --git a/modules/user/comp_configure.go b/modules/user/comp_configure.go index ef1d45dba..9033d2ba5 100644 --- a/modules/user/comp_configure.go +++ b/modules/user/comp_configure.go @@ -15,6 +15,7 @@ const ( game_sign = "game_sign.json" gameOpencond = "game_opencond.json" game_SignExtra = "game_signextra.json" + game_initial = "game_initial.json" //初始化表 ) ///配置管理基础组件 @@ -28,7 +29,7 @@ type configureComp struct { //组件初始化接口 func (this *configureComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { err = this.MCompConfigure.Init(service, module, comp, options) - + err = this.LoadConfigure(game_initial, cfg.NewGameInitial) this._sign = make(map[int32]*cfg.GameSignData, 0) configure.RegisterConfigure(game_sign, cfg.NewGameSign, this.LoadSignData) this.LoadConfigure(gameOpencond, cfg.NewGameOpencond) @@ -130,3 +131,17 @@ func (this *configureComp) GetSignExtarConf(day, group int32) *cfg.GameSignExtra } return nil } + +func (this *configureComp) GetGlobalInitConf() (configure *cfg.GameInitial, err error) { + var ( + v interface{} + ok bool + ) + if v, err = this.GetConfigure(game_initial); err == nil { + if configure, ok = v.(*cfg.GameInitial); !ok { + err = fmt.Errorf("%T no is *cfg.Game_comInitial", v) + return + } + } + return +} diff --git a/pb/library_db.pb.go b/pb/library_db.pb.go index 4f526bd36..0205777d6 100644 --- a/pb/library_db.pb.go +++ b/pb/library_db.pb.go @@ -28,7 +28,7 @@ type DBLibrary struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id" bson:"_id"` //ID Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid" bson:"uid"` //用户ID Fid int32 `protobuf:"varint,3,opt,name=fid,proto3" json:"fid"` // 配置表id 羁绊id - Hero map[string]int32 `protobuf:"bytes,4,rep,name=hero,proto3" json:"hero" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` // key: hid value: favorlv + Hero map[string]int32 `protobuf:"bytes,4,rep,name=hero,proto3" json:"hero" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` // key: hid value: id Prize map[int32]int32 `protobuf:"bytes,5,rep,name=prize,proto3" json:"prize" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` //是否领奖 key 好感度等级 Fetterlv int32 `protobuf:"varint,6,opt,name=fetterlv,proto3" json:"fetterlv"` // 当前羁绊等级 Storyid int32 `protobuf:"varint,7,opt,name=storyid,proto3" json:"storyid"` // 故事id 用来判断是否领奖 diff --git a/pb/troll_db.pb.go b/pb/troll_db.pb.go index 6670f630d..ce75ec07c 100644 --- a/pb/troll_db.pb.go +++ b/pb/troll_db.pb.go @@ -300,6 +300,180 @@ func (x *DBTrollRecord) GetTime() int64 { return 0 } +type DBGoods struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id" bson:"_id"` //ID + Period int32 `protobuf:"varint,2,opt,name=period,proto3" json:"period"` // 变动周期 + CurPeriod int32 `protobuf:"varint,3,opt,name=curPeriod,proto3" json:"curPeriod"` // 当前变动周期 + Weight int32 `protobuf:"varint,4,opt,name=weight,proto3" json:"weight"` // 周期权重 + Price int32 `protobuf:"varint,5,opt,name=price,proto3" json:"price"` // 当前价格 + Time int32 `protobuf:"varint,6,opt,name=time,proto3" json:"time"` // 刷新时间 +} + +func (x *DBGoods) Reset() { + *x = DBGoods{} + if protoimpl.UnsafeEnabled { + mi := &file_troll_troll_db_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DBGoods) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DBGoods) ProtoMessage() {} + +func (x *DBGoods) ProtoReflect() protoreflect.Message { + mi := &file_troll_troll_db_proto_msgTypes[2] + 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 DBGoods.ProtoReflect.Descriptor instead. +func (*DBGoods) Descriptor() ([]byte, []int) { + return file_troll_troll_db_proto_rawDescGZIP(), []int{2} +} + +func (x *DBGoods) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *DBGoods) GetPeriod() int32 { + if x != nil { + return x.Period + } + return 0 +} + +func (x *DBGoods) GetCurPeriod() int32 { + if x != nil { + return x.CurPeriod + } + return 0 +} + +func (x *DBGoods) GetWeight() int32 { + if x != nil { + return x.Weight + } + return 0 +} + +func (x *DBGoods) GetPrice() int32 { + if x != nil { + return x.Price + } + return 0 +} + +func (x *DBGoods) GetTime() int32 { + if x != nil { + return x.Time + } + return 0 +} + +type DBTroll struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id" bson:"_id"` //ID + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid" bson:"uid"` //用户ID + UseCount int32 `protobuf:"varint,3,opt,name=useCount,proto3" json:"useCount"` // 当前背包使用的数量 + Items map[int32]int32 `protobuf:"bytes,4,rep,name=items,proto3" json:"items" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` // 背包数据 + Goods map[int32]*DBGoods `protobuf:"bytes,5,rep,name=goods,proto3" json:"goods" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // 货物 key 货物ID + Lv int32 `protobuf:"varint,6,opt,name=lv,proto3" json:"lv"` // 商队等级 +} + +func (x *DBTroll) Reset() { + *x = DBTroll{} + if protoimpl.UnsafeEnabled { + mi := &file_troll_troll_db_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DBTroll) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DBTroll) ProtoMessage() {} + +func (x *DBTroll) ProtoReflect() protoreflect.Message { + mi := &file_troll_troll_db_proto_msgTypes[3] + 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 DBTroll.ProtoReflect.Descriptor instead. +func (*DBTroll) Descriptor() ([]byte, []int) { + return file_troll_troll_db_proto_rawDescGZIP(), []int{3} +} + +func (x *DBTroll) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *DBTroll) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *DBTroll) GetUseCount() int32 { + if x != nil { + return x.UseCount + } + return 0 +} + +func (x *DBTroll) GetItems() map[int32]int32 { + if x != nil { + return x.Items + } + return nil +} + +func (x *DBTroll) GetGoods() map[int32]*DBGoods { + if x != nil { + return x.Goods + } + return nil +} + +func (x *DBTroll) GetLv() int32 { + if x != nil { + return x.Lv + } + return 0 +} + var File_troll_troll_db_proto protoreflect.FileDescriptor var file_troll_troll_db_proto_rawDesc = []byte{ @@ -370,8 +544,36 @@ var file_troll_troll_db_proto_rawDesc = []byte{ 0x0a, 0x04, 0x67, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x67, 0x6f, 0x6c, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x07, 0x44, 0x42, 0x47, + 0x6f, 0x6f, 0x64, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x75, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x63, 0x75, 0x72, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xab, 0x02, 0x0a, + 0x07, 0x44, 0x42, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x75, 0x73, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x44, 0x42, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x12, 0x29, 0x0a, 0x05, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x44, 0x42, 0x54, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, 0x47, 0x6f, 0x6f, 0x64, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x6c, 0x76, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x6c, 0x76, 0x1a, 0x38, 0x0a, 0x0a, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x42, 0x0a, 0x0a, 0x47, 0x6f, 0x6f, 0x64, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x44, 0x42, 0x47, 0x6f, 0x6f, 0x64, 0x73, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, + 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -386,27 +588,34 @@ func file_troll_troll_db_proto_rawDescGZIP() []byte { return file_troll_troll_db_proto_rawDescData } -var file_troll_troll_db_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_troll_troll_db_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_troll_troll_db_proto_goTypes = []interface{}{ (*DBTrollTrain)(nil), // 0: DBTrollTrain (*DBTrollRecord)(nil), // 1: DBTrollRecord - nil, // 2: DBTrollTrain.ItemsEntry - nil, // 3: DBTrollTrain.PriceEntry - nil, // 4: DBTrollTrain.NpcRewardEntry - nil, // 5: DBTrollTrain.ShopEntry - nil, // 6: DBTrollTrain.SurpriseIDEntry + (*DBGoods)(nil), // 2: DBGoods + (*DBTroll)(nil), // 3: DBTroll + nil, // 4: DBTrollTrain.ItemsEntry + nil, // 5: DBTrollTrain.PriceEntry + nil, // 6: DBTrollTrain.NpcRewardEntry + nil, // 7: DBTrollTrain.ShopEntry + nil, // 8: DBTrollTrain.SurpriseIDEntry + nil, // 9: DBTroll.ItemsEntry + nil, // 10: DBTroll.GoodsEntry } var file_troll_troll_db_proto_depIdxs = []int32{ - 2, // 0: DBTrollTrain.items:type_name -> DBTrollTrain.ItemsEntry - 3, // 1: DBTrollTrain.price:type_name -> DBTrollTrain.PriceEntry - 4, // 2: DBTrollTrain.npcReward:type_name -> DBTrollTrain.NpcRewardEntry - 5, // 3: DBTrollTrain.shop:type_name -> DBTrollTrain.ShopEntry - 6, // 4: DBTrollTrain.surpriseID:type_name -> DBTrollTrain.SurpriseIDEntry - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 4, // 0: DBTrollTrain.items:type_name -> DBTrollTrain.ItemsEntry + 5, // 1: DBTrollTrain.price:type_name -> DBTrollTrain.PriceEntry + 6, // 2: DBTrollTrain.npcReward:type_name -> DBTrollTrain.NpcRewardEntry + 7, // 3: DBTrollTrain.shop:type_name -> DBTrollTrain.ShopEntry + 8, // 4: DBTrollTrain.surpriseID:type_name -> DBTrollTrain.SurpriseIDEntry + 9, // 5: DBTroll.items:type_name -> DBTroll.ItemsEntry + 10, // 6: DBTroll.goods:type_name -> DBTroll.GoodsEntry + 2, // 7: DBTroll.GoodsEntry.value:type_name -> DBGoods + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_troll_troll_db_proto_init() } @@ -439,6 +648,30 @@ func file_troll_troll_db_proto_init() { return nil } } + file_troll_troll_db_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DBGoods); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_troll_troll_db_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DBTroll); 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{ @@ -446,7 +679,7 @@ func file_troll_troll_db_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_troll_troll_db_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/pb/userexpand.pb.go b/pb/userexpand.pb.go index 2f94e09a3..6633de4c0 100644 --- a/pb/userexpand.pb.go +++ b/pb/userexpand.pb.go @@ -58,6 +58,7 @@ type DBUserExpand struct { Mline map[int32]int32 `protobuf:"bytes,34,rep,name=mline,proto3" json:"mline" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3" bson:"mline"` //主线关卡最大进度 key难度val是关卡ID SuiteId []int32 `protobuf:"varint,35,rep,packed,name=suiteId,proto3" json:"suiteId" bson:"suiteId"` // 套装Id Globalbuff int32 `protobuf:"varint,36,opt,name=globalbuff,proto3" json:"globalbuff" bson:"globalbuff"` // 全局buff + Race map[int32]int32 `protobuf:"bytes,37,rep,name=race,proto3" json:"race" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` // key 阵营ID 1~4 value 总好感度 } func (x *DBUserExpand) Reset() { @@ -316,11 +317,18 @@ func (x *DBUserExpand) GetGlobalbuff() int32 { return 0 } +func (x *DBUserExpand) GetRace() map[int32]int32 { + if x != nil { + return x.Race + } + return nil +} + var File_userexpand_proto protoreflect.FileDescriptor var file_userexpand_proto_rawDesc = []byte{ 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xac, 0x0a, 0x0a, 0x0c, 0x44, 0x42, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x70, + 0x74, 0x6f, 0x22, 0x92, 0x0b, 0x0a, 0x0c, 0x44, 0x42, 0x55, 0x73, 0x65, 0x72, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, @@ -395,16 +403,22 @@ var file_userexpand_proto_rawDesc = []byte{ 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x18, 0x23, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x73, 0x75, 0x69, 0x74, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x62, 0x75, 0x66, 0x66, 0x18, 0x24, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x62, 0x75, 0x66, 0x66, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, - 0x78, 0x70, 0x69, 0x74, 0x65, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x62, 0x75, 0x66, 0x66, 0x12, 0x2b, 0x0a, 0x04, 0x72, + 0x61, 0x63, 0x65, 0x18, 0x25, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x44, 0x42, 0x55, 0x73, + 0x65, 0x72, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x2e, 0x52, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x04, 0x72, 0x61, 0x63, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x69, + 0x74, 0x65, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x38, 0x0a, 0x0a, 0x4d, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x37, + 0x0a, 0x09, 0x52, 0x61, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x38, 0x0a, 0x0a, 0x4d, 0x6c, 0x69, 0x6e, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -419,20 +433,22 @@ func file_userexpand_proto_rawDescGZIP() []byte { return file_userexpand_proto_rawDescData } -var file_userexpand_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_userexpand_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_userexpand_proto_goTypes = []interface{}{ (*DBUserExpand)(nil), // 0: DBUserExpand nil, // 1: DBUserExpand.ExpitemEntry nil, // 2: DBUserExpand.MlineEntry + nil, // 3: DBUserExpand.RaceEntry } var file_userexpand_proto_depIdxs = []int32{ 1, // 0: DBUserExpand.expitem:type_name -> DBUserExpand.ExpitemEntry 2, // 1: DBUserExpand.mline:type_name -> DBUserExpand.MlineEntry - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 3, // 2: DBUserExpand.race:type_name -> DBUserExpand.RaceEntry + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_userexpand_proto_init() } @@ -460,7 +476,7 @@ func file_userexpand_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_userexpand_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 4, NumExtensions: 0, NumServices: 0, },