From 8649fa66e4f99ceb15d4886c16595639e2bb9b15 Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Mon, 16 Dec 2024 10:18:07 +0800 Subject: [PATCH 1/7] =?UTF-8?q?fix:=E6=B8=B8=E6=88=8F=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gamesrv/base/player.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamesrv/base/player.go b/gamesrv/base/player.go index 1bcdf6e..11e63ce 100644 --- a/gamesrv/base/player.go +++ b/gamesrv/base/player.go @@ -658,7 +658,7 @@ func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEven isNew = 1 } - if param.GameTime < 0 { + if param.GameTime <= 0 { param.GameTime = int64(time.Now().Sub(this.scene.GameNowTime).Seconds()) } if param.GameTime < 0 { From 63f3d02349f91afa51793c3f7ed78eaa191cfc83 Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Mon, 16 Dec 2024 11:12:22 +0800 Subject: [PATCH 2/7] =?UTF-8?q?fix:=E6=B8=B8=E6=88=8F=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gamesrv/base/player.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamesrv/base/player.go b/gamesrv/base/player.go index 11e63ce..eee0f61 100644 --- a/gamesrv/base/player.go +++ b/gamesrv/base/player.go @@ -679,7 +679,7 @@ func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEven ModeId: this.scene.GameMode, Tax: param.Tax, Amount: param.Change, - CreateTime: this.CreateTime.Unix(), + CreateTime: time.Now().Unix(), CreateDayTime: tCreateDay.Unix(), Out: param.Out, In: param.In, From 59f772c519d91c425d960555e5aca8c8f9ee4b33 Mon Sep 17 00:00:00 2001 From: by <123456@qq.com> Date: Mon, 16 Dec 2024 10:16:55 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worldsrv/trascate_webapi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldsrv/trascate_webapi.go b/worldsrv/trascate_webapi.go index 9a6fb83..a2384c3 100644 --- a/worldsrv/trascate_webapi.go +++ b/worldsrv/trascate_webapi.go @@ -2258,7 +2258,7 @@ func init() { state = msg.GetState() player := PlayerMgrSington.GetPlayerBySnId(info.SnId) if player == nil { - if info.State == 1 { + if msg.State == 1 { state = 3 } } From 905ff11095c71453becaf53562efbdf56fbf3eff Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Tue, 17 Dec 2024 16:05:17 +0800 Subject: [PATCH 4/7] =?UTF-8?q?fix:=E9=82=80=E8=AF=B7=E5=AF=B9=E5=B1=80?= =?UTF-8?q?=E7=A9=BA=E6=8C=87=E9=92=88=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worldsrv/action_friend.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/worldsrv/action_friend.go b/worldsrv/action_friend.go index 1c304d3..9c84ae2 100644 --- a/worldsrv/action_friend.go +++ b/worldsrv/action_friend.go @@ -301,11 +301,13 @@ func (this *CSInviteFriendHandler) Process(s *netlib.Session, packetid int, data SrcHead: proto.Int32(p.Head), SrcHeadUrl: proto.String(p.HeadUrl), OpRetCode: opRetCode, - GameId: proto.Int(p.scene.gameId), - RoomId: proto.Int(p.scene.sceneId), Pos: proto.Int32(msg.GetPos()), RoleId: int32(roleId), } + if p.scene != nil { + pack.GameId = int32(p.scene.gameId) + pack.RoomId = int32(p.scene.sceneId) + } proto.SetDefaults(pack) player.SendToClient(int(friend.FriendPacketID_PACKET_SCInviteFriend), pack) logger.Logger.Trace("SCInviteFriendHandler: ", pack) From ba1b4ae7c7aa244f60331c28b8dd91fc556f743f Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Tue, 17 Dec 2024 16:28:55 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix:=E7=A9=BA=E6=8C=87=E9=92=88=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- worldsrv/coinscenemgr.go | 2 +- worldsrv/coinscenepool.go | 2 +- worldsrv/coinscenepool_local.go | 4 ++-- worldsrv/friendmgr.go | 2 +- worldsrv/scenemgr.go | 4 ++++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/worldsrv/coinscenemgr.go b/worldsrv/coinscenemgr.go index c84f6d1..dcfcc9d 100644 --- a/worldsrv/coinscenemgr.go +++ b/worldsrv/coinscenemgr.go @@ -330,7 +330,7 @@ func (m *CoinSceneMgr) TouchCreateRoom(platform string, gameFreeId int32) { return } gf := PlatformMgrSingleton.GetGameFree(platform, gameFreeId) - if gf.Status && gf.DbGameFree.GetCreateRoomNum() > 0 { + if gf != nil && gf.GetDbGameFree().GetCreateRoomNum() > 0 { logger.Logger.Tracef("TouchCreateRoom platform:%v gameFreeId:%v", platform, gameFreeId) m.delayCache = append(m.delayCache, &CreateRoomCache{ platformName: platform, diff --git a/worldsrv/coinscenepool.go b/worldsrv/coinscenepool.go index a8c6526..605e50d 100644 --- a/worldsrv/coinscenepool.go +++ b/worldsrv/coinscenepool.go @@ -270,7 +270,7 @@ func (csp *CoinScenePool) playerEnter(p *Player, roomId int32, exclude []int32, logger.Logger.Infof("(csp *CoinScenePool) PlayerEnter create new scene:%v snid:%v gamefreeid:%v", scene.sceneId, p.SnId, csp.ID()) csp.AddScene(scene) } else { - logger.Logger.Errorf("Create %v scene failed.", csp.ID()) + logger.Logger.Warnf("Create %v scene failed.", csp.ID()) } } diff --git a/worldsrv/coinscenepool_local.go b/worldsrv/coinscenepool_local.go index 5094717..ccbcd4c 100644 --- a/worldsrv/coinscenepool_local.go +++ b/worldsrv/coinscenepool_local.go @@ -212,14 +212,14 @@ func (l *CoinScenePoolLocal) NewScene(pool *CoinScenePool, p *Player) *Scene { } } if dbCreateRoom == nil { - logger.Logger.Tracef("CoinScenePool CreateLocalGameNewScene failed! playerTakeCoin:%v ", playerTakeCoin) + logger.Logger.Errorf("CoinScenePool CreateLocalGameNewScene failed! playerTakeCoin:%v ", playerTakeCoin) return nil } if len(dbCreateRoom.GetBetRange()) != 0 && dbCreateRoom.GetBetRange()[0] != 0 { baseScore = common.RandInt32Slice(dbCreateRoom.GetBetRange()) } if baseScore == 0 { - logger.Logger.Tracef("CoinScenePool CreateLocalGameNewScene failed! BaseScore==0") + logger.Logger.Errorf("CoinScenePool CreateLocalGameNewScene failed! BaseScore==0") return nil } scene := SceneMgrSingleton.CreateScene(&CreateSceneParam{ diff --git a/worldsrv/friendmgr.go b/worldsrv/friendmgr.go index c10caea..3c9c8af 100644 --- a/worldsrv/friendmgr.go +++ b/worldsrv/friendmgr.go @@ -779,7 +779,7 @@ func (this *FriendMgr) FriendRefuse(p *Player, destP *model.BindFriend) { }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { //拒绝了不提醒 if data != nil { - logger.Logger.Error("FriendRefuse data:", data) + logger.Logger.Warn("FriendRefuse data:", data) SendToClick(friend.OpResultCode_OPRC_Error) return } diff --git a/worldsrv/scenemgr.go b/worldsrv/scenemgr.go index 4b5b962..3d52188 100644 --- a/worldsrv/scenemgr.go +++ b/worldsrv/scenemgr.go @@ -507,21 +507,25 @@ type CreateSceneParam struct { func (m *SceneMgr) CreateScene(args *CreateSceneParam) *Scene { logger.Logger.Tracef("SceneMgr NewScene %v", args) if args.GF == nil { + logger.Logger.Errorf("SceneMgr NewScene GameFree is nil") return nil } if args.Platform == nil { + logger.Logger.Errorf("SceneMgr NewScene Platform is nil") return nil } if args.GS == nil { args.GS = GameSessMgrSington.GetMinLoadSess(int(args.GF.GetGameId())) } if args.GS == nil { + logger.Logger.Errorf("SceneMgr NewScene GameServer is nil") return nil } // 创建房间 s := NewScene(args) if s == nil { + logger.Logger.Errorf("SceneMgr NewScene Scene is nil") return nil } m.scenes[args.RoomId] = s From 4d688b718c7f6f6bcab2c7dc3b937a3ff4f4c851 Mon Sep 17 00:00:00 2001 From: tomas Date: Sat, 21 Dec 2024 10:12:16 +0800 Subject: [PATCH 6/7] del free betlimit --- gamesrv/fortunedragon/scenepolicy_fortunedragon.go | 2 +- gamesrv/fortunemouse/scenepolicy_fortunemouse.go | 2 +- gamesrv/fortuneox/scenepolicy_fortuneox.go | 2 +- gamesrv/fortunerabbit/scenepolicy_fortunerabbit.go | 2 +- gamesrv/fortunetiger/scenepolicy_fortunetiger.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gamesrv/fortunedragon/scenepolicy_fortunedragon.go b/gamesrv/fortunedragon/scenepolicy_fortunedragon.go index dd8da12..66ba425 100644 --- a/gamesrv/fortunedragon/scenepolicy_fortunedragon.go +++ b/gamesrv/fortunedragon/scenepolicy_fortunedragon.go @@ -380,7 +380,7 @@ func (this *SceneStateStartFortuneDragon) OnPlayerOp(s *base.Scene, p *base.Play playerEx.BetLineIndex = params[2] needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * float64(sceneEx.BetConfig.BetLines[params[2]]) - if needCoin > float64(playerEx.Coin) { + if needCoin > float64(playerEx.Coin) && !playerEx.isFree { pack := &protocol.SCFortuneDragonBilled{ OpRetCode: proto.Int32(1), } diff --git a/gamesrv/fortunemouse/scenepolicy_fortunemouse.go b/gamesrv/fortunemouse/scenepolicy_fortunemouse.go index 861f9fd..c3cb366 100644 --- a/gamesrv/fortunemouse/scenepolicy_fortunemouse.go +++ b/gamesrv/fortunemouse/scenepolicy_fortunemouse.go @@ -380,7 +380,7 @@ func (this *SceneStateStartFortuneMouse) OnPlayerOp(s *base.Scene, p *base.Playe //playerEx.BetMode = params[3] needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * float64(sceneEx.BetConfig.BetLines[params[2]]) - if needCoin > float64(playerEx.Coin) { + if needCoin > float64(playerEx.Coin) && !playerEx.isRespin { pack := &protocol.SCFortuneMouseBilled{ OpRetCode: proto.Int32(1), } diff --git a/gamesrv/fortuneox/scenepolicy_fortuneox.go b/gamesrv/fortuneox/scenepolicy_fortuneox.go index 184290b..f3ad7b2 100644 --- a/gamesrv/fortuneox/scenepolicy_fortuneox.go +++ b/gamesrv/fortuneox/scenepolicy_fortuneox.go @@ -380,7 +380,7 @@ func (this *SceneStateStartFortuneOx) OnPlayerOp(s *base.Scene, p *base.Player, //playerEx.BetMode = params[3] needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * float64(sceneEx.BetConfig.BetLines[params[2]]) - if needCoin > float64(playerEx.Coin) { + if needCoin > float64(playerEx.Coin) && !playerEx.isRespin { pack := &protocol.SCFortuneOxBilled{ OpRetCode: proto.Int32(1), } diff --git a/gamesrv/fortunerabbit/scenepolicy_fortunerabbit.go b/gamesrv/fortunerabbit/scenepolicy_fortunerabbit.go index 91991fd..652a11a 100644 --- a/gamesrv/fortunerabbit/scenepolicy_fortunerabbit.go +++ b/gamesrv/fortunerabbit/scenepolicy_fortunerabbit.go @@ -380,7 +380,7 @@ func (this *SceneStateStartFortuneRabbit) OnPlayerOp(s *base.Scene, p *base.Play //playerEx.BetMode = params[3] needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * float64(sceneEx.BetConfig.BetLines[params[2]]) - if needCoin > float64(playerEx.Coin) { + if needCoin > float64(playerEx.Coin) && !playerEx.isFree { pack := &protocol.SCFortuneRabbitBilled{ OpRetCode: proto.Int32(1), } diff --git a/gamesrv/fortunetiger/scenepolicy_fortunetiger.go b/gamesrv/fortunetiger/scenepolicy_fortunetiger.go index 5202fcc..2c2c28a 100644 --- a/gamesrv/fortunetiger/scenepolicy_fortunetiger.go +++ b/gamesrv/fortunetiger/scenepolicy_fortunetiger.go @@ -380,7 +380,7 @@ func (this *SceneStateStartFortuneTiger) OnPlayerOp(s *base.Scene, p *base.Playe //playerEx.BetMode = params[3] needCoin := sceneEx.BetConfig.BetSize[params[0]] * float64(sceneEx.BetConfig.BetLevel[params[1]]) * float64(sceneEx.BetConfig.BetLines[params[2]]) - if needCoin > float64(playerEx.Coin) { + if needCoin > float64(playerEx.Coin) && !playerEx.isRespin { pack := &protocol.SCFortuneTigerBilled{ OpRetCode: proto.Int32(1), } From cb6ab1f686a7359ff732bebf50243d96466fbdb5 Mon Sep 17 00:00:00 2001 From: sk <123456@qq.com> Date: Mon, 23 Dec 2024 11:26:47 +0800 Subject: [PATCH 7/7] =?UTF-8?q?modify=20tienlen=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gamesrv/tienlen/scenedata_tienlen.go | 4 + gamesrv/tienlen/scenepolicy_tienlen.go | 480 +++++++++++++------------ 2 files changed, 258 insertions(+), 226 deletions(-) diff --git a/gamesrv/tienlen/scenedata_tienlen.go b/gamesrv/tienlen/scenedata_tienlen.go index f5daa4b..28b20e9 100644 --- a/gamesrv/tienlen/scenedata_tienlen.go +++ b/gamesrv/tienlen/scenedata_tienlen.go @@ -174,6 +174,10 @@ func (this *TienLenSceneData) CanStart() bool { return false } +func (this *TienLenSceneData) IsFirst(pos int) bool { + return int32(pos) == this.lastOpPos || this.lastOpPos == rule.InvalidePos +} + func (this *TienLenSceneData) GetPlayerCnt() int { var cnt int for i := 0; i < this.GetPlayerNum(); i++ { diff --git a/gamesrv/tienlen/scenepolicy_tienlen.go b/gamesrv/tienlen/scenepolicy_tienlen.go index 2f29da4..47f7416 100644 --- a/gamesrv/tienlen/scenepolicy_tienlen.go +++ b/gamesrv/tienlen/scenepolicy_tienlen.go @@ -1160,242 +1160,270 @@ func (this *ScenePlayerOpStateTienLen) OnPlayerOp(s *base.Scene, p *base.Player, return true } - sceneEx, _ := s.GetExtraData().(*TienLenSceneData) - if sceneEx != nil { - playerEx, _ := p.GetExtraData().(*TienLenPlayerData) - if playerEx != nil { - if sceneEx.GetCurOpPos() != int32(playerEx.GetPos()) { - return false + sceneEx, ok := s.GetExtraData().(*TienLenSceneData) + if !ok { + return false + } + playerEx, ok := p.GetExtraData().(*TienLenPlayerData) + if !ok { + return false + } + + if sceneEx.GetCurOpPos() != int32(playerEx.GetPos()) { + return false + } + + opRetCode := tienlen.OpResultCode_OPRC_Error + + finishFunc := func() { + switch opRetCode { + case tienlen.OpResultCode_OPRC_Sucess: + this.BroadcastPlayerSToCOp(s, playerEx.SnId, playerEx.GetPos(), opcode, opRetCode, params) + + delCardNum := 0 + for _, hcard := range playerEx.cards { + if hcard == rule.InvalideCard { + delCardNum++ + } } - - opRetCode := tienlen.OpResultCode_OPRC_Error - switch int32(opcode) { - case rule.TienLenPlayerOpPlay: //出牌 - - delCards := []int32{} - for _, card := range params { - isHave := false - for _, hcard := range playerEx.cards { //去手牌里找找看有没有 - if int32(card) == hcard && hcard != rule.InvalideCard { - isHave = true - } - } - if isHave { - delCards = append(delCards, int32(card)) - } else { - opRetCode = tienlen.OpResultCode_OPRC_Error - break - } + if delCardNum == rule.Hand_CardNum { //牌出完了 + sceneEx.TrySmallGameBilled() + if !common.InSliceInt32(sceneEx.winSnids, playerEx.SnId) { + sceneEx.winSnids = append(sceneEx.winSnids, playerEx.SnId) } - if len(delCards) == len(params) && len(delCards) > 0 { - isRule, _ := rule.RulePopEnable(delCards) - ruleType := rule.Tienlen_Pass - if sceneEx.IsTienLenYule() { - isRule, ruleType = rule.RulePopEnable_yl(delCards) - } - //logger.Logger.Trace("ScenePlayerOpStateTienLen,2params:", params, " isRule:", isRule) - if isRule { //符合出牌规则 - if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos == rule.InvalidePos { //当前操作者和上一个操作者是同一个人,必出牌 - if ruleType == rule.Plane_Single { //飞机带单只能最后一手出 - haveCardNum := 0 - for _, hcard := range playerEx.cards { - if hcard != rule.InvalideCard { - haveCardNum++ - } - } - if len(delCards) != haveCardNum { - isRule = false - opRetCode = tienlen.OpResultCode_OPRC_Error - logger.Logger.Trace("Plane_Single, delCards:", delCards, " haveCardNum:", haveCardNum) - } - } - if isRule { - if sceneEx.lastOpPos == rule.InvalidePos { //首出玩家 - //有赢家,赢家先出,出牌不受限制 - //无赢家,手持最小牌先出,最小牌必先出 - winPos := sceneEx.FindWinPos() - //logger.Logger.Trace("ScenePlayerOpStateTienLen,8params:", params, " winPos:", winPos) - if winPos == -1 { //无赢家 - haveMinCard := false - for _, card := range delCards { - if card == sceneEx.curMinCard { //最小牌必先出 - haveMinCard = true - } - } - //logger.Logger.Trace("ScenePlayerOpStateTienLen,9params:", params, " curMinCard:", sceneEx.curMinCard, " haveMinCard", haveMinCard) - if haveMinCard { - isDel := sceneEx.DelCards(playerEx, delCards) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,3params:", params, " isDel:", isDel) - if isDel { - - playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) - - sceneEx.DoNext(int32(playerEx.GetPos())) - opRetCode = tienlen.OpResultCode_OPRC_Sucess - sceneEx.SetLastOpPos(int32(playerEx.GetPos())) - sceneEx.RefreshPlayerHandLimitTimeOut() - } - } - } else { - isDel := sceneEx.DelCards(playerEx, delCards) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,10params:", params, " isDel:", isDel) - if isDel { - - playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) - - sceneEx.DoNext(int32(playerEx.GetPos())) - opRetCode = tienlen.OpResultCode_OPRC_Sucess - sceneEx.SetLastOpPos(int32(playerEx.GetPos())) - sceneEx.RefreshPlayerHandLimitTimeOut() - } - } - } else { - isDel := sceneEx.DelCards(playerEx, delCards) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,4params:", params, " isDel:", isDel) - if isDel { - - playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) - - nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,4paramssss:", params, " nextPos:", nextPos) - if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { - sceneEx.UnmarkPass() - nextPos = sceneEx.DoNext(int32(playerEx.GetPos())) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,4paramssss:", params, " nextPos:", nextPos) - } - opRetCode = tienlen.OpResultCode_OPRC_Sucess - sceneEx.SetLastOpPos(int32(playerEx.GetPos())) - sceneEx.RefreshPlayerHandLimitTimeOut() - } - } - if opRetCode == tienlen.OpResultCode_OPRC_Sucess { - isBomb := rule.IsFourBomb(delCards) - if isBomb { - sceneEx.isKongBomb = true - } - } - sceneEx.UnmarkPass() - } - } else { //当前操作者和上一个操作者不是同一个人,必压制 - if !playerEx.isPass { - lastOpPlayer := sceneEx.GetLastOpPlayer() - //logger.Logger.Trace("ScenePlayerOpStateTienLen,5params:", params, " lastOpPlayer:", lastOpPlayer) - if lastOpPlayer != nil && len(lastOpPlayer.delCards) != 0 { - lastDelCards := lastOpPlayer.delCards[len(lastOpPlayer.delCards)-1] - canDel, isBomb, bombScore := rule.CanDel(lastDelCards, delCards, sceneEx.IsTienLenToEnd()) - if sceneEx.IsTienLenYule() { - canDel, isBomb, bombScore = rule.CanDel_yl(lastDelCards, delCards, sceneEx.IsTienLenToEnd()) - } - //logger.Logger.Trace("ScenePlayerOpStateTienLen,6params:", params, " canDel:", canDel, " lastDelCards:", lastDelCards) - if canDel { - if isBomb { - sceneEx.curBombPos = int32(playerEx.GetPos()) - sceneEx.lastBombPos = sceneEx.lastOpPos - sceneEx.roundScore += bombScore - } else { - sceneEx.curBombPos = rule.InvalidePos - sceneEx.lastBombPos = rule.InvalidePos - sceneEx.roundScore = 0 - } - isDel := sceneEx.DelCards(playerEx, delCards) - //logger.Logger.Trace("ScenePlayerOpStateTienLen,7params:", params, " isDel:", isDel) - if isDel { - - playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) - - nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) - if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { - sceneEx.UnmarkPass() - sceneEx.DoNext(int32(playerEx.GetPos())) - } - sceneEx.SetLastOpPos(int32(playerEx.GetPos())) - sceneEx.RefreshPlayerHandLimitTimeOut() - opRetCode = tienlen.OpResultCode_OPRC_Sucess - sceneEx.isKongBomb = false - } - } - } - } - } - } - } - case rule.TienLenPlayerOpPass: //过牌 - if int32(playerEx.GetPos()) == sceneEx.lastOpPos { //当前操作者和上一个操作者是同一个人,必出牌,不能过牌 - opRetCode = tienlen.OpResultCode_OPRC_Error - } else { - if sceneEx.lastOpPos != rule.InvalidePos { - - playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) - - sceneEx.card_play_action_seq = append(sceneEx.card_play_action_seq, fmt.Sprintf("%v-过", playerEx.GetPos())) - sceneEx.card_play_action_seq_int32 = append(sceneEx.card_play_action_seq_int32, []int32{-1}) - nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) - - if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { - sceneEx.UnmarkPass() - nextPos = sceneEx.DoNext(int32(playerEx.GetPos())) - sceneEx.SetLastOpPos(int32(nextPos)) - } - - sceneEx.RefreshPlayerHandLimitTimeOut() - opRetCode = tienlen.OpResultCode_OPRC_Sucess - playerEx.isPass = true - if nextPos == sceneEx.lastOpPos { //一轮都不出牌 - sceneEx.TrySmallGameBilled() - } - } - } - case rule.TienLenPlayerClientHintCards: - if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos == rule.InvalidePos { - logger.Logger.Trace("ScenePlayerOpStateTienLen,107 OPRC_Error:", params, " opcode:", opcode, " snid:", p.SnId, " pos:", playerEx.GetPos()) - } else { - if len(params) > 0 { - sceneEx.cHintCards = make([]int32, len(params)+1) - sceneEx.cHintCards[0] = p.SnId - copy(sceneEx.cHintCards[1:], common.Int64ToInt32(params)) - opRetCode = tienlen.OpResultCode_OPRC_Hint - } - } - default: - opRetCode = tienlen.OpResultCode_OPRC_Error - } - - //next - if opRetCode == tienlen.OpResultCode_OPRC_Sucess { - this.BroadcastPlayerSToCOp(s, playerEx.SnId, playerEx.GetPos(), opcode, opRetCode, params) - - delCardNum := 0 - for _, hcard := range playerEx.cards { - if hcard == rule.InvalideCard { - delCardNum++ - } - } - if delCardNum == rule.Hand_CardNum { //牌出完了 - sceneEx.TrySmallGameBilled() - if !common.InSliceInt32(sceneEx.winSnids, playerEx.SnId) { - sceneEx.winSnids = append(sceneEx.winSnids, playerEx.SnId) - } - if sceneEx.IsTienLenToEnd() { //打到底 - if sceneEx.GetGameingPlayerCnt()-1 == len(sceneEx.winSnids) { - sceneEx.ChangeSceneState(rule.TienLenSceneStateBilled) - } else { - playerEx.isDelAll = true - sceneEx.BroadcastOpPos() - } - } else { + if sceneEx.IsTienLenToEnd() { //打到底 + if sceneEx.GetGameingPlayerCnt()-1 == len(sceneEx.winSnids) { sceneEx.ChangeSceneState(rule.TienLenSceneStateBilled) + } else { + playerEx.isDelAll = true + sceneEx.BroadcastOpPos() } } else { - sceneEx.BroadcastOpPos() + sceneEx.ChangeSceneState(rule.TienLenSceneStateBilled) } - } else if opRetCode == tienlen.OpResultCode_OPRC_Error { - this.OnPlayerSToCOp(s, p, playerEx.GetPos(), opcode, opRetCode, params) - - logger.Logger.Trace("ScenePlayerOpStateTienLen,100 OPRC_Error:", params, " opcode:", opcode, " snid:", p.SnId, " pos:", playerEx.GetPos()) + } else { + sceneEx.BroadcastOpPos() } + case tienlen.OpResultCode_OPRC_Error: + this.OnPlayerSToCOp(s, p, playerEx.GetPos(), opcode, opRetCode, params) + logger.Logger.Trace("ScenePlayerOpStateTienLen,100 OPRC_Error:", params, " opcode:", opcode, " snid:", p.SnId, " pos:", playerEx.GetPos()) } } + switch int32(opcode) { + case rule.TienLenPlayerOpPlay: //出牌 + + var delCards []int32 + checkCardsFunc := func() bool { + for _, card := range params { + isHave := false + for _, card := range playerEx.cards { //去手牌里找找看有没有 + if card == card && card != rule.InvalideCard { + isHave = true + } + } + if isHave { + delCards = append(delCards, int32(card)) + } else { + return false + } + } + + return len(delCards) == len(params) && len(delCards) > 0 + } + + if !checkCardsFunc() { + logger.Logger.Errorf("出牌错误 snid:%v, pos:%v, cards:%v", p.SnId, playerEx.GetPos(), params) + finishFunc() + return true + } + + isRule, _ := rule.RulePopEnable(delCards) + ruleType := rule.Tienlen_Pass + if sceneEx.IsTienLenYule() { + isRule, ruleType = rule.RulePopEnable_yl(delCards) + } + + if !isRule { + logger.Logger.Errorf("出牌牌型错误 snid:%v, pos:%v, cards:%v", p.SnId, playerEx.GetPos(), params) + finishFunc() + return true + } + + switch { + case sceneEx.IsFirst(playerEx.GetPos()): + //当前操作者和上一个操作者是同一个人,必出牌 + if ruleType == rule.Plane_Single { //飞机带单只能最后一手出 + haveCardNum := 0 + for _, card := range playerEx.cards { + if card != rule.InvalideCard { + haveCardNum++ + } + } + if len(delCards) != haveCardNum { + logger.Logger.Trace("飞机带单只能最后一手出 Plane_Single, delCards:", delCards, " haveCardNum:", haveCardNum) + finishFunc() + return true + } + } + + if sceneEx.lastOpPos == rule.InvalidePos { //首出玩家 + //有赢家,赢家先出,出牌不受限制 + //无赢家,手持最小牌先出,最小牌必先出 + winPos := sceneEx.FindWinPos() + //logger.Logger.Trace("ScenePlayerOpStateTienLen,8params:", params, " winPos:", winPos) + if winPos == -1 { //无赢家 + haveMinCard := false + for _, card := range delCards { + if card == sceneEx.curMinCard { //最小牌必先出 + haveMinCard = true + } + } + //logger.Logger.Trace("ScenePlayerOpStateTienLen,9params:", params, " curMinCard:", sceneEx.curMinCard, " haveMinCard", haveMinCard) + if !haveMinCard { + finishFunc() + return true + } + } + isDel := sceneEx.DelCards(playerEx, delCards) + //logger.Logger.Trace("ScenePlayerOpStateTienLen,3params:", params, " isDel:", isDel) + if isDel { + playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) + + sceneEx.DoNext(int32(playerEx.GetPos())) + opRetCode = tienlen.OpResultCode_OPRC_Sucess + sceneEx.SetLastOpPos(int32(playerEx.GetPos())) + + sceneEx.RefreshPlayerHandLimitTimeOut() + } + } else { + isDel := sceneEx.DelCards(playerEx, delCards) + //logger.Logger.Trace("ScenePlayerOpStateTienLen,4params:", params, " isDel:", isDel) + if isDel { + playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) + + nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) + //logger.Logger.Trace("ScenePlayerOpStateTienLen,4paramssss:", params, " nextPos:", nextPos) + if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { + // 新一轮 + sceneEx.UnmarkPass() + nextPos = sceneEx.DoNext(int32(playerEx.GetPos())) + //logger.Logger.Trace("ScenePlayerOpStateTienLen,4paramssss:", params, " nextPos:", nextPos) + } + opRetCode = tienlen.OpResultCode_OPRC_Sucess + sceneEx.SetLastOpPos(int32(playerEx.GetPos())) + + sceneEx.RefreshPlayerHandLimitTimeOut() + } + } + if opRetCode == tienlen.OpResultCode_OPRC_Sucess { + isBomb := rule.IsFourBomb(delCards) + if isBomb { + sceneEx.isKongBomb = true + } + } + sceneEx.UnmarkPass() + + default: + //当前操作者和上一个操作者不是同一个人,必压制 + if playerEx.isPass { + finishFunc() + return true + } + + lastOpPlayer := sceneEx.GetLastOpPlayer() + //logger.Logger.Trace("ScenePlayerOpStateTienLen,5params:", params, " lastOpPlayer:", lastOpPlayer) + if lastOpPlayer == nil || len(lastOpPlayer.delCards) == 0 { + finishFunc() + return true + } + + lastDelCards := lastOpPlayer.delCards[len(lastOpPlayer.delCards)-1] + canDel, isBomb, bombScore := rule.CanDel(lastDelCards, delCards, sceneEx.IsTienLenToEnd()) + if sceneEx.IsTienLenYule() { + canDel, isBomb, bombScore = rule.CanDel_yl(lastDelCards, delCards, sceneEx.IsTienLenToEnd()) + } + //logger.Logger.Trace("ScenePlayerOpStateTienLen,6params:", params, " canDel:", canDel, " lastDelCards:", lastDelCards) + + if !canDel { + finishFunc() + return true + } + + if isBomb { + sceneEx.curBombPos = int32(playerEx.GetPos()) + sceneEx.lastBombPos = sceneEx.lastOpPos + sceneEx.roundScore += bombScore + } else { + sceneEx.curBombPos = rule.InvalidePos + sceneEx.lastBombPos = rule.InvalidePos + sceneEx.roundScore = 0 + } + + isDel := sceneEx.DelCards(playerEx, delCards) + //logger.Logger.Trace("ScenePlayerOpStateTienLen,7params:", params, " isDel:", isDel) + if !isDel { + finishFunc() + return true + } + + playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) + + nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) + if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { + sceneEx.UnmarkPass() + sceneEx.DoNext(int32(playerEx.GetPos())) + } + sceneEx.SetLastOpPos(int32(playerEx.GetPos())) + opRetCode = tienlen.OpResultCode_OPRC_Sucess + sceneEx.isKongBomb = false + + sceneEx.RefreshPlayerHandLimitTimeOut() + } + + case rule.TienLenPlayerOpPass: //过牌 + //当前操作者和上一个操作者是同一个人,必出牌,不能过牌 + if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos != rule.InvalidePos { + finishFunc() + return true + } + + playerEx.RefreshThinkLongCnt(time.Now().Sub(sceneEx.StateStartTime), false) + + sceneEx.card_play_action_seq = append(sceneEx.card_play_action_seq, fmt.Sprintf("%v-过", playerEx.GetPos())) + sceneEx.card_play_action_seq_int32 = append(sceneEx.card_play_action_seq_int32, []int32{-1}) + nextPos := sceneEx.DoNext(int32(playerEx.GetPos())) + + if sceneEx.IsTienLenToEnd() && nextPos == rule.InvalidePos { + sceneEx.UnmarkPass() + nextPos = sceneEx.DoNext(int32(playerEx.GetPos())) + sceneEx.SetLastOpPos(nextPos) + } + + sceneEx.RefreshPlayerHandLimitTimeOut() + opRetCode = tienlen.OpResultCode_OPRC_Sucess + playerEx.isPass = true + if nextPos == sceneEx.lastOpPos { //一轮都不出牌 + sceneEx.TrySmallGameBilled() + } + + case rule.TienLenPlayerClientHintCards: + if int32(playerEx.GetPos()) == sceneEx.lastOpPos || sceneEx.lastOpPos == rule.InvalidePos { + logger.Logger.Trace("ScenePlayerOpStateTienLen,107 OPRC_Error:", params, " opcode:", opcode, " snid:", p.SnId, " pos:", playerEx.GetPos()) + } else { + if len(params) > 0 { + sceneEx.cHintCards = make([]int32, len(params)+1) + sceneEx.cHintCards[0] = p.SnId + copy(sceneEx.cHintCards[1:], common.Int64ToInt32(params)) + opRetCode = tienlen.OpResultCode_OPRC_Hint + } + } + default: + opRetCode = tienlen.OpResultCode_OPRC_Error + } + + finishFunc() + return true }