This commit is contained in:
liwei1dao 2022-07-15 16:15:04 +08:00
commit 840bc4c986
11 changed files with 167 additions and 117 deletions

12
cmd/robot/assistant.go Normal file
View File

@ -0,0 +1,12 @@
package robot
// 场景:在测试的接口中,输入参数为了能达到自动化,都是从业务中已有的协议中返回获取,作为下一个协议的输入参数。
// 但是会存在协议中的输入参数无法从上一个协议中获取比如添加好友协议输入参数是“目标玩家ID”为了能够动态
// 测试添加好友协议,如果专门为这个协议添加返回目标玩家的接口,显然有点不合适。一个方案是,设计一个助手,专门处
// 理这类问题,这个助手可以返回合适的数据,作为输入参数。
type assistant struct {
//TODO
}

View File

@ -95,13 +95,6 @@ var (
} }
}, },
}, {
desc: "删除黑名单",
mainType: string(comm.ModuleFriend),
subType: friend.FriendSubTypeDelBlack,
req: &pb.FriendDelBlackReq{},
rsp: &pb.FriendDelBlackResp{},
// enabled: true,
}, },
} }
) )

View File

@ -23,17 +23,18 @@ var (
// fmt.Printf("%d- %v\n", (i + 1), v) // fmt.Printf("%d- %v\n", (i + 1), v)
// } // }
// }, // },
enabled: true, // enabled: true,
next: func(robot *Robot, rsp proto.Message) { next: func(robot *Robot, rsp proto.Message) {
tcs := []*TestCase{} tcs := []*TestCase{}
if r, ok := rsp.(*pb.HeroListResp); ok { if r, ok := rsp.(*pb.HeroListResp); ok {
for _, v := range r.List { for _, v := range r.List {
heroId := v.Id
tc := &TestCase{ tc := &TestCase{
desc: "英雄详情", desc: "英雄详情",
mainType: string(comm.ModuleHero), mainType: string(comm.ModuleHero),
subType: hero.HeroSubTypeInfo, subType: hero.HeroSubTypeInfo,
req: &pb.HeroInfoReq{ req: &pb.HeroInfoReq{
HeroId: v.Id, HeroId: heroId,
}, },
rsp: &pb.HeroInfoResp{}, rsp: &pb.HeroInfoResp{},
enabled: true, enabled: true,
@ -48,10 +49,10 @@ var (
mainType: string(comm.ModuleHero), mainType: string(comm.ModuleHero),
subType: hero.Awaken, subType: hero.Awaken,
req: &pb.HeroAwakenReq{ req: &pb.HeroAwakenReq{
HeroObjID: v.Id, HeroObjID: heroId,
}, },
rsp: &pb.HeroAwakenResp{}, rsp: &pb.HeroAwakenResp{},
enabled: true, //enabled: true,
}, },
} }
robot.addBuilders(tcs) robot.addBuilders(tcs)
@ -59,19 +60,9 @@ var (
} }
tcs = append(tcs, tc) tcs = append(tcs, tc)
} }
robot.addBuilders(tcs) //这里一定要调用此方法才会发送请求
} }
robot.addBuilders(tcs)
}, },
}, {
desc: "英雄详情",
mainType: string(comm.ModuleHero),
subType: hero.HeroSubTypeInfo,
req: &pb.HeroInfoReq{
HeroId: "62c676d57deea8b9af8884a5",
},
rsp: &pb.HeroInfoResp{},
// enabled: true,
}, { }, {
desc: "抽卡", desc: "抽卡",
mainType: string(comm.ModuleHero), mainType: string(comm.ModuleHero),
@ -82,17 +73,45 @@ var (
rsp: &pb.HeroChoukaResp{}, rsp: &pb.HeroChoukaResp{},
// enabled: true, // enabled: true,
}, { }, {
desc: "英雄列表",
mainType: string(comm.ModuleHero), mainType: string(comm.ModuleHero),
subType: hero.StrengthenUpStar, subType: hero.HeroSubTypeList,
req: &pb.HeroStrengthenUpStarReq{ req: &pb.HeroListReq{},
HeroObjID: "62bd0489ff6632434a7d0d1f", rsp: &pb.HeroListResp{},
Hero: []*pb.CostCardData{ enabled: true,
{ next: func(robot *Robot, rsp proto.Message) {
CostCardObj: "", if r, ok := rsp.(*pb.HeroListResp); ok {
}, tcs := []*TestCase{}
}, selHero := r.List[0] //选中的英雄
for _, v := range r.List {
heroId := v.Id
tc := &TestCase{
desc: "英雄升星",
mainType: string(comm.ModuleHero),
subType: hero.StrengthenUpStar,
req: &pb.HeroStrengthenUpStarReq{
HeroObjID: selHero.Id,
HeroRace: []*pb.CostCardData{
{
CostCardObj: heroId,
},
},
Hero: []*pb.CostCardData{
{
CostCardObj: heroId,
},
},
},
rsp: &pb.HeroStrengthenUpStarResp{},
enabled: true,
}
tcs = append(tcs, tc)
}
robot.addBuilders(tcs)
}
}, },
rsp: &pb.HeroStrengthenUpStarResp{}, }, {
// enabled: true, // enabled: true,
}, { }, {
mainType: string(comm.ModuleHero), mainType: string(comm.ModuleHero),

View File

@ -120,18 +120,18 @@ func (r *Robot) Run() {
} }
type TestCase struct { type TestCase struct {
id string //用例ID 如果没有指定,会自动赋值uuid id string //用例ID 如果没有指定,会自动赋值uuid
desc string //用例描述 desc string //用例描述
mainType string //协议类型 L1 mainType string //协议类型 L1
subType string //协议类型 L2 subType string //协议类型 L2
req proto.Message //请求类型 req proto.Message //请求类型
rsp proto.Message //响应类型 rsp proto.Message //响应类型
enabled bool //是否启用 enabled bool //是否启用
start time.Time //启用时间 start time.Time //启用时间
hs time.Duration //耗时 hs time.Duration //耗时
requested bool //是否是请求的case // requested bool //是否是请求的case
print func(rsp proto.Message) //定义打印 print func(rsp proto.Message) //定义打印
next func(robot *Robot, rsp proto.Message) //处理下一层用例请求 next func(robot *Robot, rsp proto.Message) //处理下一层用例请求
} }
//添加测试用用例 //添加测试用用例
@ -160,7 +160,7 @@ func (r *Robot) handleReq() {
// go func() { // go func() {
for len(r.builderMap) > 0 { for len(r.builderMap) > 0 {
for _, b := range r.builderMap { for _, b := range r.builderMap {
if b.enabled && b.req != nil && !b.requested { if b.enabled && b.req != nil {
time.Sleep(time.Millisecond * 500) time.Sleep(time.Millisecond * 500)
// r.reqCh <- b.id // r.reqCh <- b.id
b.start = time.Now() b.start = time.Now()
@ -172,7 +172,6 @@ func (r *Robot) handleReq() {
delete(r.builderMap, b.id) delete(r.builderMap, b.id)
zlog.Errorf("send to client err:%v", err) zlog.Errorf("send to client err:%v", err)
} }
r.handleRsp(b.id) r.handleRsp(b.id)
} }
@ -201,6 +200,7 @@ func (r *Robot) handleNotify(uuid string, msg *pb.UserMessage) {
desc: "错误通知", desc: "错误通知",
mainType: comm.MainTypeNotify, mainType: comm.MainTypeNotify,
subType: comm.SubTypeErrorNotify, subType: comm.SubTypeErrorNotify,
req: rsp.Arg,
rsp: rsp, rsp: rsp,
} }
@ -232,7 +232,6 @@ func (r *Robot) handleRsp(id string) {
// uuid := <-r.reqCh // uuid := <-r.reqCh
r.handleNotify(uuid, msg) r.handleNotify(uuid, msg)
if v, ok := r.builderMap[uuid]; ok { if v, ok := r.builderMap[uuid]; ok {
if v.enabled && if v.enabled &&
(msg.MainType == v.mainType && (msg.MainType == v.mainType &&
msg.SubType == v.subType) { msg.SubType == v.subType) {
@ -423,7 +422,7 @@ func (r *Robot) printReply(msg *pb.UserMessage, tc *TestCase) {
// //
zlog.Debug("-------------------------------------") zlog.Debug("-------------------------------------")
zlog.Debugf("uuid%s", tc.id) // zlog.Debugf("uuid%s", tc.id)
zlog.Debugf("描述:%s", tc.desc) zlog.Debugf("描述:%s", tc.desc)
zlog.Debugf("协议:%s.%s", mainType, subType) zlog.Debugf("协议:%s.%s", mainType, subType)
zlog.Debugf("耗时:%v", tc.hs) zlog.Debugf("耗时:%v", tc.hs)

View File

@ -24,13 +24,27 @@ var user_builders = []*TestCase{
subType: "addres", subType: "addres",
req: &pb.UserAddResReq{ req: &pb.UserAddResReq{
Res: &pb.UserAssets{ Res: &pb.UserAssets{
A: "attr", A: "item",
T: "10001", T: "10011",
N: 12, N: 13,
}, },
}, },
rsp: &pb.UserAddResResp{}, rsp: &pb.UserAddResResp{},
enabled: true, //enabled: true,
},
{
desc: "添加资源",
mainType: string(comm.ModuleUser),
subType: "addres",
req: &pb.UserAddResReq{
Res: &pb.UserAssets{
A: "item",
T: "10001",
N: 1,
},
},
rsp: &pb.UserAddResResp{},
//enabled: true,
}, },
} }

View File

@ -20,7 +20,7 @@ const ( //消息回复的头名称
Resonance = "resonance" // 英雄共鸣属性 Resonance = "resonance" // 英雄共鸣属性
ResonanceReset = "resonancereset" // 共鸣重置 ResonanceReset = "resonancereset" // 共鸣重置
StrengthenUpSkill = "strengthenupskill" // 技能强化 StrengthenUpSkill = "strengthenupskill" // 技能强化
StrengthenUpStar = "strengthensupstar" // 英雄升星 StrengthenUpStar = "strengthenupstar" // 英雄升星
Awaken = "awaken" // 英雄觉醒 Awaken = "awaken" // 英雄觉醒
HeroLock = "lock" // 英雄锁定 HeroLock = "lock" // 英雄锁定
) )

View File

@ -86,6 +86,17 @@ func (this *apiComp) Awaken(session comm.IUserSession, req *pb.HeroAwakenReq) (c
property[awakenData.Phasebonus[0]] += int32(value) property[awakenData.Phasebonus[0]] += int32(value)
} }
this.module.modelHero.mergeMainProperty(session.GetUserId(), _hero.Id, property) this.module.modelHero.mergeMainProperty(session.GetUserId(), _hero.Id, property)
_heroMap := map[string]interface{}{
"juexingLv": _hero.JuexingLv + 1,
}
// 保存数据
err1 = this.module.modelHero.modifyHeroData(session.GetUserId(), _hero.Id, _heroMap)
if err1 != nil {
code = pb.ErrorCode_DBError
this.module.Errorf("update hero skill failed:%v", err1)
return
}
} }
err1 = this.module.modelHero.PushHeroProperty(session, _hero.Id) // 推送属性变化 err1 = this.module.modelHero.PushHeroProperty(session, _hero.Id) // 推送属性变化

View File

@ -14,18 +14,44 @@ func (this *apiComp) StrengthenUpStarCheck(session comm.IUserSession, req *pb.He
code = pb.ErrorCode_ReqParameterError code = pb.ErrorCode_ReqParameterError
} }
for _, v := range req.Hero {
if v.CostCardObj == req.HeroObjID { // 不允许消耗自己
code = pb.ErrorCode_ReqParameterError
return
}
}
for _, v := range req.HeroRace {
if v.CostCardObj == req.HeroObjID {
code = pb.ErrorCode_ReqParameterError
return
}
}
return return
} }
/// 英雄升星 /// 英雄升星
func (this *apiComp) StrengthenUpStar(session comm.IUserSession, req *pb.HeroStrengthenUpStarReq) (code pb.ErrorCode, data proto.Message) { func (this *apiComp) StrengthenUpStar(session comm.IUserSession, req *pb.HeroStrengthenUpStarReq) (code pb.ErrorCode, data proto.Message) {
var ( var (
target *cfg.Game_heroStarupData // 配置表目标升星英雄信息 target *cfg.Game_heroStarupData // 配置表目标升星英雄信息
costRaceCount int32 costNeedHeroCount int32 // 消耗指定英雄的数量
_hero *pb.DBHero // 目标英雄 costRaceHeroCount int32 // 消耗种族英雄的数量
raceHero *pb.DBHero // 消耗阵容的英雄 _hero *pb.DBHero // 目标英雄
tagHero *pb.DBHero // 消耗指定英雄 tagHero *pb.DBHero // 消耗指定英雄
mapCostHero map[string]int32 // 所有消耗英雄分类
bCheckNeedhero bool // 指定英雄校验
bCheckRacehero bool // 种族英雄校验
) )
mapCostHero = make(map[string]int32, 0)
for _, v := range req.Hero {
mapCostHero[v.CostCardObj] += v.Amount
costNeedHeroCount += v.Amount
}
for _, v := range req.HeroRace {
mapCostHero[v.CostCardObj] += v.Amount
costRaceHeroCount += v.Amount
}
code = this.StrengthenUpStarCheck(session, req) // check code = this.StrengthenUpStarCheck(session, req) // check
if code != pb.ErrorCode_Success { if code != pb.ErrorCode_Success {
return return
@ -43,68 +69,53 @@ func (this *apiComp) StrengthenUpStar(session comm.IUserSession, req *pb.HeroStr
} }
for _, value := range tagHeroConfig.GetDataList() { for _, value := range tagHeroConfig.GetDataList() {
if _hero.HeroID == value.Id && _hero.Star == value.Star && _hero.Lv == value.Maxlevel { // 找到了 满足升星条件 if _hero.HeroID == value.Id && _hero.Star == value.Star && _hero.Lv >= value.Maxlevel { // 找到了 满足升星条件
target = value target = value
break break
} }
} }
if target == nil { if target == nil {
code = pb.ErrorCode_HeroNoExist
return
}
// 优先校验数量对不对
if target.Needheronum != costNeedHeroCount || target.Needracenum != costRaceHeroCount {
code = pb.ErrorCode_ReqParameterError code = pb.ErrorCode_ReqParameterError
return return
} }
// 指定英雄消耗校验 // 遍历所有消耗英雄
for _, v := range req.Hero { for k, v := range mapCostHero {
if tagHero, code = this.module.GetHero(session.GetUserId(), v.CostCardObj); code != pb.ErrorCode_Success { if tagHero, code = this.module.GetHero(session.GetUserId(), k); code != pb.ErrorCode_Success { // 没有这个英雄
return return
} else { } else {
if tagHero.Block { // 锁定的卡不允许被消耗 if tagHero.Block { // 锁定的卡不允许被消耗
code = pb.ErrorCode_HeroIsLock code = pb.ErrorCode_HeroIsLock
return return
} }
if tagHero.SameCount < v.Amount { // 校验数量 if tagHero.SameCount < v { // 校验数量
code = pb.ErrorCode_ReqParameterError code = pb.ErrorCode_ReqParameterError
return return
} }
// 校验ID
if tagHero.HeroID != target.Needhero && tagHero.Star != target.Needherostar && tagHero.SameCount < target.Needheronum { if tagHero.HeroID == target.Needhero && tagHero.Star == target.Needherostar && tagHero.SameCount >= target.Needheronum {
code = pb.ErrorCode_ReqParameterError bCheckNeedhero = true
return
} }
}
}
// 校验阵容英雄消耗
for _, v := range req.HeroRace {
if raceHero, code = this.module.GetHero(session.GetUserId(), v.CostCardObj); code != pb.ErrorCode_Success {
return
} else {
if raceHero.Block { // 锁定的卡不允许被消耗
code = pb.ErrorCode_HeroIsLock
return
}
// 校验阵容信息
if raceHero.Star != target.Needracestar {
code = pb.ErrorCode_ReqParameterError
return
}
bFind := false
for _, value := range target.Needrace { // 阵营校验 for _, value := range target.Needrace { // 阵营校验
if raceHero.Formation == value { if tagHero.Formation == value {
bFind = true bCheckRacehero = true
break break
} }
} }
if !bFind {
code = pb.ErrorCode_ReqParameterError
return
}
}
costRaceCount += v.Amount this.module.Debugf("指定英雄校验结果:%b,种族英雄校验结果:%b", bCheckNeedhero, bCheckRacehero)
}
} }
if costRaceCount != target.Needracenum { // 数量不匹配 if !bCheckRacehero || !bCheckNeedhero {
code = pb.ErrorCode_ReqParameterError code = pb.ErrorCode_ReqParameterError
return return // 校验失败
} }
// 金币消耗判断 // 金币消耗判断
curGold := this.module.ModuleUser.QueryAttributeValue(session.GetUserId(), "gold") curGold := this.module.ModuleUser.QueryAttributeValue(session.GetUserId(), "gold")
if curGold < target.Gold { // 金币不足 if curGold < target.Gold { // 金币不足
@ -119,24 +130,15 @@ func (this *apiComp) StrengthenUpStar(session comm.IUserSession, req *pb.HeroStr
code = pb.ErrorCode_GoldNoEnough code = pb.ErrorCode_GoldNoEnough
return return
} }
// 消耗指定英雄 for k, v := range mapCostHero {
for _, v := range req.Hero { code = this.module.DelCard(session.GetUserId(), k, v)
code = this.module.DelCard(session.GetUserId(), v.CostCardObj, v.Amount)
if code != pb.ErrorCode_Success { if code != pb.ErrorCode_Success {
code = pb.ErrorCode_DBError code = pb.ErrorCode_DBError
this.module.Errorf("del hero err card:%s,count = %d", v.CostCardObj, v.Amount) this.module.Errorf("del hero err card:%s,count = %d", k, v)
return return
} }
} }
//消耗种族英雄
for _, v := range req.HeroRace {
code = this.module.DelCard(session.GetUserId(), v.CostCardObj, v.Amount)
if code != pb.ErrorCode_Success {
code = pb.ErrorCode_DBError
return
}
}
code = this.module.modelHero.HeroStarUp(session, _hero) // 执行升星操作 code = this.module.modelHero.HeroStarUp(session, _hero) // 执行升星操作
if code != pb.ErrorCode_Success { if code != pb.ErrorCode_Success {
return return

View File

@ -20,15 +20,6 @@ func (this *apiComp) AddRes(session comm.IUserSession, req *pb.UserAddResReq) (c
return return
} }
rsp := &pb.UserAddResResp{}
defer func() {
if err := session.SendMsg(string(this.module.GetType()), UserSubTypeAddRes, rsp); err != nil {
code = pb.ErrorCode_SystemError
return
}
}()
user := this.module.modelUser.GetUser(session.GetUserId()) user := this.module.modelUser.GetUser(session.GetUserId())
if user == nil { if user == nil {
code = pb.ErrorCode_UserSessionNobeing code = pb.ErrorCode_UserSessionNobeing
@ -42,6 +33,12 @@ func (this *apiComp) AddRes(session comm.IUserSession, req *pb.UserAddResReq) (c
} }
res = append(res, atn) res = append(res, atn)
code = this.module.DispenseRes(session.GetUserId(), res, true) code = this.module.DispenseRes(session.GetUserId(), res, true)
rsp.Res = req.Res if code == pb.ErrorCode_Success {
rsp := &pb.UserAddResResp{
Res: req.Res,
}
session.SendMsg(string(this.module.GetType()), UserSubTypeAddRes, rsp)
}
return return
} }

View File

@ -122,6 +122,8 @@ func (this *User) AddAttributeValue(uid string, attr string, add int32, bPush bo
} }
_change.Diamond += add _change.Diamond += add
update[comm.ResDiamond] = user.Diamond + add update[comm.ResDiamond] = user.Diamond + add
default:
code = pb.ErrorCode_Unknown
} }
if len(update) == 0 { if len(update) == 0 {

View File

@ -67,6 +67,7 @@ enum ErrorCode {
HeroMaxAwaken = 1312; // HeroMaxAwaken = 1312; //
HeroIsLock = 1313; // HeroIsLock = 1313; //
HeroMaxCount = 1314; // HeroMaxCount = 1314; //
HeroCostTypeErr = 1315; //
// equipment // equipment
EquipmentOnFoundEquipment = 1400; // EquipmentOnFoundEquipment = 1400; //