diff --git a/modules/battle/module.go b/modules/battle/module.go index b48a7924d..fe6d35579 100644 --- a/modules/battle/module.go +++ b/modules/battle/module.go @@ -225,9 +225,11 @@ func (this *Battle) CreateBattleServer(req *pb.BattleInfo) (code pb.ErrorCode) { this.Debug("CreateBattleServer", log.Field{Key: "req", Value: req}) var ( resp *pb.BattleCreateServerResp + ctx context.Context err error ) - if resp, err = this.clientmgr.CreateBattle(context.Background(), &pb.BattleCreateServerReq{Info: req}); err != nil { + ctx, _ = context.WithTimeout(context.Background(), time.Second*5) + if resp, err = this.clientmgr.CreateBattle(ctx, &pb.BattleCreateServerReq{Info: req}); err != nil { this.Errorln(err) code = pb.ErrorCode_RpcFuncExecutionError } @@ -240,9 +242,11 @@ func (this *Battle) CreateBattleServer(req *pb.BattleInfo) (code pb.ErrorCode) { func (this *Battle) InCmdBattle(req *pb.BattleInCmdReq) (code pb.ErrorCode) { var ( resp *pb.BattleInCmdResp + ctx context.Context err error ) - if resp, err = this.clientmgr.InCmdBattle(context.Background(), req); err != nil { + ctx, _ = context.WithTimeout(context.Background(), time.Second*5) + if resp, err = this.clientmgr.InCmdBattle(ctx, req); err != nil { this.Errorln(err) code = pb.ErrorCode_RpcFuncExecutionError } @@ -272,6 +276,7 @@ func (this *Battle) ConcedeBattle(req *pb.BattleConcedeReq) (code pb.ErrorCode) func (this *Battle) CheckBattleReport(session comm.IUserSession, report *pb.BattleReport) (code pb.ErrorCode, iswin bool) { var ( reply *pb.BattleCheckResults + ctx context.Context err error ) if report == nil { @@ -281,7 +286,8 @@ func (this *Battle) CheckBattleReport(session comm.IUserSession, report *pb.Batt if this.options.OpenCheck { stime := time.Now() - if reply, err = this.clientmgr.CheckBattle(context.Background(), report); err != nil || !reply.Ischeck { + ctx, _ = context.WithTimeout(context.Background(), time.Second*5) + if reply, err = this.clientmgr.CheckBattle(ctx, report); err != nil || !reply.Ischeck { code = pb.ErrorCode_BattleValidationFailed this.Error("[Battle Check]", log.Field{Key: "t", Value: time.Since(stime).Milliseconds()}, diff --git a/modules/pvp/api_formation.go b/modules/pvp/api_formation.go index 9faf325a0..dfff7601a 100644 --- a/modules/pvp/api_formation.go +++ b/modules/pvp/api_formation.go @@ -2,6 +2,7 @@ package pvp import ( "go_dreamfactory/comm" + "go_dreamfactory/lego/sys/timewheel" "go_dreamfactory/pb" "google.golang.org/protobuf/proto" @@ -33,6 +34,7 @@ func (this *apiComp) Formation(session comm.IUserSession, req *pb.PvpFormationRe } if battle.Redformation != nil && battle.Blueformation != nil { //都设置了战斗阵型 battle.State = pb.PvpState_battle + timewheel.Remove(battle.readytimer) go this.module.startBattle(battle) } battle.lock.Unlock() diff --git a/modules/pvp/api_incmd.go b/modules/pvp/api_incmd.go index a2d3e9927..cf97c1558 100644 --- a/modules/pvp/api_incmd.go +++ b/modules/pvp/api_incmd.go @@ -2,6 +2,7 @@ package pvp import ( "go_dreamfactory/comm" + "go_dreamfactory/lego/sys/timewheel" "go_dreamfactory/pb" "google.golang.org/protobuf/proto" @@ -37,6 +38,8 @@ func (this *apiComp) InCmd(session comm.IUserSession, req *pb.PvpInCmdReq) (code In: req.Cmd, }); code != pb.ErrorCode_Success { return + } else { + timewheel.Remove(battle.operatetimer) } } else { code = pb.ErrorCode_BattleInCmdFailed diff --git a/modules/pvp/core.go b/modules/pvp/core.go index f0682b548..9aef45f4c 100644 --- a/modules/pvp/core.go +++ b/modules/pvp/core.go @@ -9,19 +9,19 @@ import ( ///Pvp 战斗对象 type BattleItem struct { - Id string //战斗id - Ptype pb.PvpType //pvp类型 - State pb.PvpState //战斗状态 - Red *pb.PvpUserInfo //红方id - RedSession comm.IUserSession //红方连接对象 - Redformation *pb.BattleFormation //红方阵型列表 - RedOffline bool //红方离线 - Blue *pb.PvpUserInfo //蓝方id - BlueSession comm.IUserSession //蓝方连接对象 - Blueformation *pb.BattleFormation //蓝方阵型列表 - BlueOffline bool //蓝方离线 - readytimer *timewheel.Task //准备倒计时定时器 - operatetimer *timewheel.Task //操作倒计时定时器 - curroperate int32 //当前操作玩家 1 红方 2 蓝方 - lock sync.Mutex //战斗锁 防止计时器和消息同时操作对象 + Id string //战斗id + Ptype pb.PvpType //pvp类型 + State pb.PvpState //战斗状态 + Red *pb.PvpUserInfo //红方id + RedSession comm.IUserSession //红方连接对象 + Redformation *pb.BattleFormation //红方阵型列表 + RedOffline bool //红方离线 + Blue *pb.PvpUserInfo //蓝方id + BlueSession comm.IUserSession //蓝方连接对象 + Blueformation *pb.BattleFormation //蓝方阵型列表 + BlueOffline bool //蓝方离线 + readytimer *timewheel.Task //准备倒计时定时器 + operatetimer *timewheel.Task //操作倒计时定时器 + curroperate *pb.ComWaitInputSkill //当前操作玩家 1 红方 2 蓝方 + lock sync.Mutex //战斗锁 防止计时器和消息同时操作对象 } diff --git a/modules/pvp/module.go b/modules/pvp/module.go index 99242c7df..55cd75756 100644 --- a/modules/pvp/module.go +++ b/modules/pvp/module.go @@ -14,6 +14,7 @@ import ( "time" "go.mongodb.org/mongo-driver/bson/primitive" + "google.golang.org/protobuf/proto" ) /* @@ -82,12 +83,13 @@ func (this *Pvp) CreatePvp(red, blue *pb.PvpUserInfo, ptype pb.PvpType) (battleI ) battleId = primitive.NewObjectID().Hex() battle = &BattleItem{ - Id: battleId, - Ptype: ptype, - State: pb.PvpState_ready, - Red: red, - Blue: blue, - readytimer: timewheel.Add(time.Second*60, this.readyTimeOut, battleId), + Id: battleId, + Ptype: ptype, + State: pb.PvpState_ready, + Red: red, + Blue: blue, + readytimer: timewheel.Add(time.Second*60, this.readyTimeOut, battleId), + curroperate: &pb.ComWaitInputSkill{}, } if battle.RedSession, ok = this.GetUserSession(red.Uid); !ok { @@ -120,6 +122,8 @@ func (this *Pvp) PvpOutCmdPush(out *pb.PvpOutCmdPush) { var ( battle *BattleItem ok bool + data []byte + code pb.ErrorCode err error ) this.lock.RLock() @@ -132,6 +136,45 @@ func (this *Pvp) PvpOutCmdPush(out *pb.PvpOutCmdPush) { }, battle.RedSession, battle.BlueSession); err != nil { this.Errorln(err) } + for _, v := range out.Cmd { + if v.Cmdtype == "ComWaitInputSkill" { + if err = proto.Unmarshal(v.Value, battle.curroperate); err != nil { + this.Errorln(err) + } + if battle.curroperate.Side == 1 && battle.RedOffline { //已经离线 + battle.curroperate.Auto = true + data, _ = proto.Marshal(battle.curroperate) + if code = this.battle.InCmdBattle(&pb.BattleInCmdReq{ + Battleid: battle.Id, + Side: battle.curroperate.Side, + In: &pb.BattleCmd{ + Cmdtype: "ComWaitInputSkill", + Value: data, + }, + }); code != pb.ErrorCode_Success { + return + } + return + } + if battle.curroperate.Side == 2 && battle.BlueOffline { //已经离线 + battle.curroperate.Auto = true + data, _ = proto.Marshal(battle.curroperate) + if code = this.battle.InCmdBattle(&pb.BattleInCmdReq{ + Battleid: battle.Id, + Side: battle.curroperate.Side, + In: &pb.BattleCmd{ + Cmdtype: "ComWaitInputSkill", + Value: data, + }, + }); code != pb.ErrorCode_Success { + return + } + return + } + battle.operatetimer = timewheel.Add(time.Second*60, this.operateTimeOut, battle.Id) + } + } + } } @@ -158,7 +201,7 @@ func (this *Pvp) PvpFinishPush(battleId string) { //准备超时 取消战斗 func (this *Pvp) readyTimeOut(task *timewheel.Task, args ...interface{}) { - this.Debug("PVPTimeOut", log.Field{Key: "args", Value: args}) + this.Debug("readyTimeOut", log.Field{Key: "args", Value: args}) var ( id string battle *BattleItem @@ -186,6 +229,37 @@ func (this *Pvp) readyTimeOut(task *timewheel.Task, args ...interface{}) { } } +//操作倒计时 +func (this *Pvp) operateTimeOut(task *timewheel.Task, args ...interface{}) { + this.Debug("operateTimeOut", log.Field{Key: "args", Value: args}) + var ( + id string + battle *BattleItem + ok bool + code pb.ErrorCode + data []byte + ) + id = args[0].(string) + this.lock.RLock() + battle, ok = this.battles[id] + this.lock.RUnlock() + if ok && battle.State == pb.PvpState_battle { + battle.curroperate.Auto = true + data, _ = proto.Marshal(battle.curroperate) + if code = this.battle.InCmdBattle(&pb.BattleInCmdReq{ + Battleid: battle.Id, + Side: battle.curroperate.Side, + In: &pb.BattleCmd{ + Cmdtype: "ComWaitInputSkill", + Value: data, + }, + }); code != pb.ErrorCode_Success { + return + } + + } +} + //开始战斗 func (this *Pvp) startBattle(battle *BattleItem) { this.Debug("PVPStart", log.Field{Key: "battleId", Value: battle.Id}) @@ -248,23 +322,35 @@ func (this *Pvp) startBattle(battle *BattleItem) { func (this *Pvp) useroffline(session comm.IUserSession) { var ( side int32 + data []byte + code pb.ErrorCode ) this.lock.RLock() for _, v := range this.battles { if v.Red.Uid == session.GetUserId() || v.Blue.Uid == session.GetUserId() { if session.GetUserId() == v.Red.Uid { side = 1 + v.RedOffline = true } else { side = 2 + v.BlueOffline = true } - v.lock.Lock() - if v.State == pb.PvpState_battle { - go this.battle.ConcedeBattle(&pb.BattleConcedeReq{ + + if v.curroperate.Side == side { + timewheel.Remove(v.operatetimer) + v.curroperate.Auto = true + data, _ = proto.Marshal(v.curroperate) + if code = this.battle.InCmdBattle(&pb.BattleInCmdReq{ Battleid: v.Id, - Side: side, - }) + Side: v.curroperate.Side, + In: &pb.BattleCmd{ + Cmdtype: "ComWaitInputSkill", + Value: data, + }, + }); code != pb.ErrorCode_Success { + return + } } - v.lock.Unlock() } } this.lock.RUnlock()