1505 lines
42 KiB
Go
1505 lines
42 KiB
Go
package chesstitians
|
||
|
||
import (
|
||
"math/rand"
|
||
"time"
|
||
|
||
"mongo.games.com/goserver/core"
|
||
"mongo.games.com/goserver/core/logger"
|
||
|
||
"mongo.games.com/game/common"
|
||
rule "mongo.games.com/game/gamerule/chess"
|
||
"mongo.games.com/game/gamesrv/base"
|
||
"mongo.games.com/game/model"
|
||
"mongo.games.com/game/proto"
|
||
"mongo.games.com/game/protocol/chesstitians"
|
||
)
|
||
|
||
var ScenePolicyEntitySingleton = &ScenePolicyEntity{}
|
||
|
||
type ScenePolicyEntity struct {
|
||
base.BaseScenePolicy
|
||
states [rule.SceneStateMax]base.SceneState
|
||
}
|
||
|
||
// 创建场景扩展数据
|
||
func (this *ScenePolicyEntity) CreateSceneExData(s *base.Scene) interface{} {
|
||
sceneEx := NewSceneEx(s)
|
||
if sceneEx != nil {
|
||
if sceneEx.init() {
|
||
sceneEx.Clear()
|
||
s.SetExtraData(sceneEx)
|
||
}
|
||
}
|
||
return sceneEx
|
||
}
|
||
|
||
// 创建玩家扩展数据
|
||
func (this *ScenePolicyEntity) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} {
|
||
playerEx := &PlayerEx{Player: p}
|
||
if playerEx != nil {
|
||
playerEx.init()
|
||
p.SetExtraData(playerEx)
|
||
}
|
||
return playerEx
|
||
}
|
||
|
||
// 场景开启事件
|
||
func (this *ScenePolicyEntity) OnStart(s *base.Scene) {
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnStart, GetSceneId()=", s.GetSceneId())
|
||
|
||
sceneEx := NewSceneEx(s)
|
||
if sceneEx != nil {
|
||
if sceneEx.init() {
|
||
sceneEx.Clear()
|
||
s.SetExtraData(sceneEx)
|
||
s.ChangeSceneState(rule.SceneStateWaitPlayer)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 场景心跳事件
|
||
func (this *ScenePolicyEntity) OnTick(s *base.Scene) {
|
||
if s == nil {
|
||
return
|
||
}
|
||
if s.GetSceneState() != nil {
|
||
s.GetSceneState().OnTick(s)
|
||
}
|
||
}
|
||
|
||
// 玩家进入事件
|
||
func (this *ScenePolicyEntity) OnPlayerEnter(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerEnter, GetSceneId()=", s.GetSceneId(), " player=", p.GetName())
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
|
||
//自动带入金币
|
||
pos := sceneEx.FindOnePos()
|
||
if p.Pos != rule.InvalidPos && sceneEx.seats[p.Pos] == nil {
|
||
pos = p.Pos
|
||
}
|
||
if pos < 0 || pos > 1 || sceneEx.seats[pos] != nil {
|
||
p.MarkFlag(base.PlayerState_EnterSceneFailed)
|
||
cnt := len(sceneEx.players)
|
||
logger.Logger.Warnf("ScenePolicyEntity.OnPlayerEnter(scene:%v, player:%v) no found fit GetPos(), current player count:%v NumOfGames:%v", s.GetSceneId(), p.SnId, cnt, sceneEx.NumOfGames)
|
||
return
|
||
}
|
||
|
||
playerEx := &PlayerEx{Player: p}
|
||
playerEx.init()
|
||
playerEx.SetPos(pos)
|
||
if sceneEx.GetGaming() {
|
||
playerEx.MarkFlag(base.PlayerState_WaitNext)
|
||
}
|
||
p.SetExtraData(playerEx)
|
||
sceneEx.seats[pos] = playerEx
|
||
sceneEx.players[p.SnId] = playerEx
|
||
|
||
if sceneEx.GetSeatPlayerCnt() == 1 {
|
||
sceneEx.masterSnId = playerEx.SnId
|
||
sceneEx.BroadcastUpdateMasterSnId(false)
|
||
}
|
||
|
||
//广播个人信息
|
||
playerData := CreatePlayerData(p)
|
||
if sceneEx.IsMatchScene() && p.IsRob {
|
||
if len(p.MatchParams) > 2 {
|
||
if p.MatchParams[2] != 0 {
|
||
playerData.CopySnid = p.MatchParams[2]
|
||
}
|
||
}
|
||
if len(p.MatchParams) > 3 {
|
||
if p.MatchParams[3] != 0 {
|
||
playerData.CopyRoleId = p.MatchParams[3]
|
||
}
|
||
}
|
||
}
|
||
pack := &chesstitians.SCChesstitiansPlayerEnter{
|
||
Data: playerData,
|
||
}
|
||
proto.SetDefaults(pack)
|
||
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), pack, p.GetSid())
|
||
|
||
//给自己发送房间信息
|
||
SendRoomInfo(s, p, sceneEx, playerEx)
|
||
|
||
s.FirePlayerEvent(p, base.PlayerEventEnter, nil)
|
||
}
|
||
}
|
||
|
||
// 玩家离开事件
|
||
func (this *ScenePolicyEntity) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerLeave, GetSceneId()=", s.GetSceneId(), " player=", p.SnId)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
|
||
if this.CanChangeCoinScene(s, p) {
|
||
LeavePlayerSnid := playerEx.SnId
|
||
|
||
sceneEx.OnPlayerLeave(p, reason)
|
||
s.FirePlayerEvent(p, base.PlayerEventLeave, []int64{int64(reason)})
|
||
|
||
if LeavePlayerSnid == sceneEx.masterSnId {
|
||
findOne := false
|
||
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
|
||
playerExSeat := sceneEx.seats[i]
|
||
if playerExSeat != nil && playerExSeat.SnId != sceneEx.masterSnId {
|
||
sceneEx.masterSnId = playerExSeat.SnId
|
||
sceneEx.BroadcastUpdateMasterSnId(true)
|
||
findOne = true
|
||
break
|
||
}
|
||
}
|
||
if !findOne {
|
||
sceneEx.masterSnId = 0
|
||
sceneEx.BroadcastUpdateMasterSnId(false)
|
||
}
|
||
}
|
||
|
||
if !playerEx.IsRob { //真人离开
|
||
hadSeat := false
|
||
for _, seat := range sceneEx.seats {
|
||
if seat != nil {
|
||
hadSeat = true
|
||
break
|
||
}
|
||
}
|
||
if !hadSeat { //座位上没有人了,把观众踢出去
|
||
audiences := sceneEx.GetAudiences()
|
||
for _, audience := range audiences {
|
||
if audience != nil {
|
||
s.AudienceLeave(audience, common.PlayerLeaveReason_RoomClose)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
// 玩家掉线
|
||
func (this *ScenePolicyEntity) OnPlayerDropLine(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerDropLine, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
|
||
s.FirePlayerEvent(p, base.PlayerEventDropLine, nil)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if sceneEx.GetGaming() {
|
||
if s.IsMatchScene() || s.IsCoinScene() {
|
||
p.MarkFlag(base.PlayerState_Auto)
|
||
p.SyncFlag()
|
||
}
|
||
return
|
||
}
|
||
s.PlayerLeave(p, common.PlayerLeaveReason_DropLine, true)
|
||
}
|
||
}
|
||
|
||
// 玩家重连
|
||
func (this *ScenePolicyEntity) OnPlayerRehold(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerRehold, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
|
||
if p.IsMarkFlag(base.PlayerState_Auto) {
|
||
p.UnmarkFlag(base.PlayerState_Auto)
|
||
p.SyncFlag()
|
||
}
|
||
|
||
//发送房间信息给自己
|
||
SendRoomInfo(s, p, sceneEx, playerEx)
|
||
s.FirePlayerEvent(p, base.PlayerEventRehold, nil)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 返回房间
|
||
func (this *ScenePolicyEntity) OnPlayerReturn(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerReturn, GetSceneId()=", s.GetSceneId(), " player=", p.Name)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if playerEx, ok := p.GetExtraData().(*PlayerEx); ok {
|
||
if p.IsMarkFlag(base.PlayerState_Auto) {
|
||
p.UnmarkFlag(base.PlayerState_Auto)
|
||
p.SyncFlag()
|
||
}
|
||
|
||
//发送房间信息给自己
|
||
SendRoomInfo(s, p, sceneEx, playerEx)
|
||
s.FirePlayerEvent(p, base.PlayerEventReturn, nil)
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if s == nil || p == nil {
|
||
return false
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerOp, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " opcode=", opcode, " params=", params)
|
||
if s.GetSceneState() != nil {
|
||
if s.GetSceneState().OnPlayerOp(s, p, opcode, params) {
|
||
p.LastOPTimer = time.Now()
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnPlayerDevOp(s *base.Scene, p *base.Player, opcode int, paramStr []string, param int64) bool {
|
||
if s == nil || p == nil {
|
||
return false
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerDevOp, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " opcode=", opcode, " paramsStr=", paramStr, " param=", param)
|
||
sceneEx, _ := s.GetExtraData().(*SceneEx)
|
||
sceneEx.chess.SetChess(paramStr)
|
||
//sceneEx.opPos = int32(param)
|
||
|
||
snid := int32(param)
|
||
|
||
for idx, seat := range sceneEx.seats {
|
||
if seat.GetSnId() == snid {
|
||
sceneEx.opPos = idx
|
||
break
|
||
}
|
||
}
|
||
|
||
sceneEx.lastMove = []int32{}
|
||
|
||
//playerEx, _ := p.GetExtraData().(*PlayerEx)
|
||
|
||
//pack := CreateRoomInfoPacket(s, p, sceneEx, playerEx)
|
||
//s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack, 0)
|
||
|
||
for _, seat := range sceneEx.seats {
|
||
if seat != nil {
|
||
pack := CreateRoomInfoPacket(s, seat.Player, sceneEx, seat)
|
||
ok := seat.Player.SendToClient(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack)
|
||
logger.Logger.Trace("SCChesstitiansSendRoomInfo isok : ", ok, ",pack", pack)
|
||
}
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("(this *ScenePolicyEntity) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.GetName(), " eventcode=", evtcode, " params=", params)
|
||
if s.GetSceneState() != nil {
|
||
s.GetSceneState().OnPlayerEvent(s, p, evtcode, params)
|
||
}
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnAudienceEnter(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("ScenePolicyEntity OnAudienceEnter, sceneId=", s.SceneId, " player=", p.SnId)
|
||
this.BaseScenePolicy.OnAudienceEnter(s, p)
|
||
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
|
||
//给自己发送房间信息
|
||
p.UnmarkFlag(base.PlayerState_Leave)
|
||
SendRoomInfo(s, p, sceneEx, nil)
|
||
sceneEx.BroadcastAudienceNum(p)
|
||
}
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnAudienceLeave(s *base.Scene, p *base.Player, reason int) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("ScenePolicyEntity OnAudienceLeave, sceneId=", s.SceneId, " player=", p.SnId, " reason=", reason)
|
||
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
|
||
sceneEx.BroadcastAudienceNum(p)
|
||
}
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnAudienceSit(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("ScenePolicyEntity OnAudienceSit, sceneId=", s.SceneId, " player=", p.SnId)
|
||
sceneEx, ok := s.GetExtraData().(*SceneEx)
|
||
if !ok {
|
||
return
|
||
}
|
||
if s.Gaming && !s.GetBEnterAfterStart() {
|
||
return
|
||
}
|
||
|
||
//自动带入金币
|
||
pos := sceneEx.FindOnePos()
|
||
if pos < 0 || pos > 3 || sceneEx.seats[pos] != nil {
|
||
p.MarkFlag(base.PlayerState_EnterSceneFailed)
|
||
cnt := len(sceneEx.players)
|
||
logger.Logger.Warnf("ScenePolicyEntity.OnAudienceSit(scene:%v, player:%v) no found fit GetPos(), current player count:%v NumOfGames:%v", s.GetSceneId(), p.SnId, cnt, sceneEx.NumOfGames)
|
||
return
|
||
}
|
||
|
||
playerEx := &PlayerEx{Player: p}
|
||
playerEx.init()
|
||
playerEx.SetPos(pos)
|
||
p.UnmarkFlag(base.PlayerState_Audience)
|
||
p.UnmarkFlag(base.PlayerState_Leave)
|
||
if sceneEx.GetGaming() {
|
||
playerEx.MarkFlag(base.PlayerState_WaitNext)
|
||
p.SyncFlag()
|
||
}
|
||
|
||
p.SetExtraData(playerEx)
|
||
sceneEx.seats[pos] = playerEx
|
||
sceneEx.players[p.SnId] = playerEx
|
||
//logger.Logger.Trace("广播个人信息,curSeatsNum: ", sceneEx.GetSeatPlayerCnt())
|
||
if sceneEx.GetSeatPlayerCnt() == 1 {
|
||
sceneEx.masterSnId = playerEx.SnId
|
||
sceneEx.BroadcastUpdateMasterSnId(false)
|
||
}
|
||
|
||
//广播个人信息
|
||
playerData := CreatePlayerData(p)
|
||
pack := &chesstitians.SCChesstitiansPlayerEnter{
|
||
Data: playerData,
|
||
}
|
||
proto.SetDefaults(pack)
|
||
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansPlayerEnter), pack, p.GetSid())
|
||
|
||
//给自己发送房间信息
|
||
SendRoomInfo(s, p, sceneEx, playerEx)
|
||
sceneEx.BroadcastAudienceNum(p)
|
||
|
||
s.FirePlayerEvent(p, base.PlayerEventEnter, nil)
|
||
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) OnAudienceDropLine(s *base.Scene, p *base.Player) {
|
||
if s == nil || p == nil {
|
||
return
|
||
}
|
||
logger.Logger.Trace("ScenePolicyEntity OnAudienceDropLine, sceneId=", s.SceneId, " player=", p.SnId)
|
||
s.AudienceLeave(p, common.PlayerLeaveReason_DropLine)
|
||
if sceneEx, ok := s.ExtraData.(*SceneEx); ok {
|
||
sceneEx.BroadcastAudienceNum(p)
|
||
}
|
||
}
|
||
|
||
// 是否完成了整个牌局
|
||
func (this *ScenePolicyEntity) IsCompleted(s *base.Scene) bool {
|
||
if s == nil {
|
||
return false
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 是否可以强制开始
|
||
func (this *ScenePolicyEntity) IsCanForceStart(s *base.Scene) bool {
|
||
return false
|
||
}
|
||
|
||
// 当前状态能否换桌
|
||
func (this *ScenePolicyEntity) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
|
||
if s == nil || p == nil {
|
||
return false
|
||
}
|
||
if s.GetSceneState() != nil {
|
||
return s.GetSceneState().CanChangeCoinScene(s, p)
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) ForceStart(s *base.Scene) {
|
||
s.ChangeSceneState(rule.SceneStateWaitStart)
|
||
}
|
||
|
||
func CreatePlayerData(p *base.Player) *chesstitians.ChesstitiansPlayerData {
|
||
pd := &chesstitians.ChesstitiansPlayerData{
|
||
Name: proto.String(p.Name),
|
||
SnId: proto.Int32(p.SnId),
|
||
Head: proto.Int32(p.Head),
|
||
Sex: proto.Int32(p.Sex),
|
||
Coin: proto.Int64(p.GetCoin()),
|
||
Flag: proto.Int(p.GetFlag()),
|
||
Longitude: proto.Int32(p.Longitude),
|
||
Latitude: proto.Int32(p.Latitude),
|
||
City: proto.String(p.City),
|
||
VIP: proto.Int32(p.VIP),
|
||
HeadOutLine: proto.Int32(p.HeadOutLine),
|
||
NiceId: proto.Int32(p.NiceId),
|
||
Pos: proto.Int(p.GetPos()),
|
||
ChessGrade: proto.Int64(p.ChessGrade),
|
||
IsRob: proto.Bool(p.IsRob),
|
||
}
|
||
ex, ok := p.GetExtraData().(*PlayerEx)
|
||
if ok {
|
||
pd.IsWin = ex.isWin
|
||
pd.WinTimes = ex.winTimes
|
||
pd.OtherScore = ex.otherScore
|
||
pd.NextRank = ex.nextRank
|
||
pd.WinScore = ex.winScore
|
||
pd.WinCoin = ex.winCoin
|
||
pd.OldChessGrade = ex.oldGrade
|
||
pd.TotalTime = ex.GetTotalTime()
|
||
}
|
||
if p.Roles != nil {
|
||
pd.RoleId = proto.Int32(p.Roles.ModId)
|
||
}
|
||
if p.Items != nil {
|
||
pd.Items = make(map[int32]int32)
|
||
for id, num := range p.Items {
|
||
pd.Items[id] = proto.Int32(num)
|
||
}
|
||
}
|
||
if len(p.MatchParams) > 0 {
|
||
pd.MatchRankId = p.MatchParams[0]
|
||
}
|
||
if len(p.MatchParams) > 1 {
|
||
pd.Lv = p.MatchParams[1]
|
||
}
|
||
logger.Logger.Trace("ChesstitiansCreatePlayerData pd : ", pd)
|
||
|
||
return pd
|
||
}
|
||
|
||
func CreateRoomInfoPacket(s *base.Scene, p *base.Player, sceneEx *SceneEx, playerEx *PlayerEx) *chesstitians.SCChesstitiansRoomInfo {
|
||
pack := &chesstitians.SCChesstitiansRoomInfo{
|
||
RoomId: proto.Int(s.GetSceneId()),
|
||
Creator: proto.Int32(s.GetCreator()),
|
||
GameId: proto.Int(s.GetGameId()),
|
||
RoomMode: proto.Int(s.GetSceneMode()),
|
||
Params: s.GetParams(),
|
||
State: proto.Int32(int32(s.GetSceneState().GetState())),
|
||
TimeOut: proto.Int(s.GetSceneState().GetTimeout(s)),
|
||
NumOfGames: proto.Int(sceneEx.NumOfGames),
|
||
TotalOfGames: proto.Int(sceneEx.TotalOfGames),
|
||
CurOpIdx: proto.Int(-1),
|
||
MasterSnid: proto.Int32(sceneEx.masterSnId),
|
||
AudienceNum: proto.Int(s.GetAudiencesNum()),
|
||
BaseScore: proto.Int32(s.BaseScore),
|
||
MaxPlayerNum: proto.Int(s.GetPlayerNum()),
|
||
GameFreeId: proto.Int32(s.GetDBGameFree().GetId()),
|
||
SceneType: proto.Int32(s.GetDBGameFree().GetSceneType()),
|
||
// 比赛场相关
|
||
Round: proto.Int32(s.MatchRound),
|
||
CurPlayerNum: proto.Int32(s.MatchCurPlayerNum),
|
||
NextNeed: proto.Int32(s.MatchNextNeed),
|
||
// 计步
|
||
StepSnId: proto.Int32(sceneEx.stepSnId),
|
||
StepNum: int64(sceneEx.stepNum),
|
||
StepLimit: int64(sceneEx.stepLimit),
|
||
// 求和
|
||
DrawSnId: proto.Int32(sceneEx.drawSnId),
|
||
// 发起再来一局的玩家
|
||
NextSnId: proto.Int32(sceneEx.nextSnId),
|
||
}
|
||
|
||
pack.Variant = int32(sceneEx.chess.GetVariant())
|
||
|
||
// 生成棋数据
|
||
pack.Chess = sceneEx.chess.GetChess()
|
||
pack.Act = sceneEx.chess.GetAct()
|
||
|
||
pack.Castling = sceneEx.chess.GetCastling()
|
||
pack.CambodianMove = sceneEx.chess.GetCambodianMove()
|
||
|
||
pack.Enpassant = int32(sceneEx.chess.GetEnPassant())
|
||
pack.ChessRound = int32(sceneEx.chess.GetRound())
|
||
|
||
pack.Check = sceneEx.chess.GetCheck()
|
||
pack.Checkmate = sceneEx.chess.GetCheckmate()
|
||
|
||
for _, v := range sceneEx.lastMove {
|
||
pack.LastMove = append(pack.LastMove, int32(v))
|
||
}
|
||
|
||
pack.IsMatch = int32(0)
|
||
// 0.普通场 1.锦标赛 2.冠军赛 3.vip专属
|
||
if s.IsMatchScene() {
|
||
pack.IsMatch = s.MatchType
|
||
}
|
||
pack.MatchFinals = 0
|
||
if s.MatchFinals {
|
||
pack.MatchFinals = 1
|
||
if s.NumOfGames >= 2 {
|
||
pack.MatchFinals = 2
|
||
}
|
||
}
|
||
if s.GetSceneState().GetState() == rule.SceneStateBilled {
|
||
sceneEx.opPos = -1
|
||
pack.CurOpIdx = proto.Int32(-1)
|
||
}
|
||
if s.GetSceneState().GetState() >= rule.SceneStatePlayerOp {
|
||
pack.CurOpIdx = proto.Int32(int32(sceneEx.opPos))
|
||
}
|
||
//玩家信息.第一个必然是自己
|
||
pd := CreatePlayerData(p)
|
||
if playerEx != nil {
|
||
// 是黑棋的标记?1黑棋,0白棋
|
||
if playerEx.isBlack {
|
||
pd.IsBlack = proto.Int32(1)
|
||
} else {
|
||
pd.IsBlack = proto.Int32(0)
|
||
}
|
||
}
|
||
pack.Players = append(pack.Players, pd)
|
||
|
||
//剩下的按座位排序
|
||
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
|
||
nowPlayer := sceneEx.seats[i]
|
||
if nowPlayer != nil {
|
||
if nowPlayer.SnId != p.SnId {
|
||
pd1 := CreatePlayerData(nowPlayer.Player)
|
||
if sceneEx.IsMatchScene() && nowPlayer.IsRob {
|
||
if len(nowPlayer.MatchParams) > 2 {
|
||
if nowPlayer.MatchParams[2] != 0 {
|
||
pd1.CopySnid = nowPlayer.MatchParams[2]
|
||
}
|
||
}
|
||
if len(nowPlayer.MatchParams) > 3 {
|
||
if nowPlayer.MatchParams[3] != 0 {
|
||
pd1.CopyRoleId = nowPlayer.MatchParams[3]
|
||
}
|
||
}
|
||
}
|
||
// 是黑棋的标记?1黑棋,0白棋
|
||
if nowPlayer.isBlack {
|
||
pd1.IsBlack = proto.Int32(1)
|
||
} else {
|
||
pd1.IsBlack = proto.Int32(0)
|
||
}
|
||
pack.Players = append(pack.Players, pd1)
|
||
}
|
||
}
|
||
}
|
||
proto.SetDefaults(pack)
|
||
return pack
|
||
}
|
||
|
||
func SendRoomInfo(s *base.Scene, p *base.Player, sceneEx *SceneEx, playerEx *PlayerEx) {
|
||
pack := CreateRoomInfoPacket(s, p, sceneEx, playerEx)
|
||
ok := p.SendToClient(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomInfo), pack)
|
||
logger.Logger.Trace("SCChesstitiansSendRoomInfo isok : ", ok, ",pack", pack)
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStateBase 状态基类
|
||
//=====================================
|
||
|
||
type SceneStateBase struct {
|
||
}
|
||
|
||
func (this *SceneStateBase) GetTimeout(s *base.Scene) int {
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
return int(time.Now().Sub(sceneEx.StateStartTime) / time.Second)
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (this *SceneStateBase) CanChangeTo(s base.SceneState) bool {
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStateBase) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
|
||
return !p.IsGameing() || s.GetDestroyed()
|
||
}
|
||
|
||
func (this *SceneStateBase) OnEnter(s *base.Scene) {
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
sceneEx.StateStartTime = time.Now()
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateBase) OnLeave(s *base.Scene) {}
|
||
|
||
func (this *SceneStateBase) OnTick(s *base.Scene) {
|
||
}
|
||
|
||
func (this *SceneStateBase) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
logger.Logger.Trace("SceneBaseStateChesstitians.", " s.GetSceneId() : ", s.GetSceneId(), " p.SnId : ", p.SnId, " opcode : ", opcode, " params ", params)
|
||
|
||
sceneEx, _ := s.GetExtraData().(*SceneEx)
|
||
if sceneEx == nil {
|
||
return true
|
||
}
|
||
playerEx, _ := p.GetExtraData().(*PlayerEx)
|
||
if playerEx == nil {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *SceneStateBase) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
}
|
||
|
||
// BroadcastRoomState 广播房间状态
|
||
func (this *SceneStateBase) BroadcastRoomState(s *base.Scene, state int, params ...int64) {
|
||
pack := &chesstitians.SCChesstitiansRoomState{
|
||
State: proto.Int(state),
|
||
Params: params,
|
||
}
|
||
proto.SetDefaults(pack)
|
||
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansRoomState), pack, 0)
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStateWaitPlayer 等待玩家进入
|
||
//=====================================
|
||
|
||
type SceneStateWaitPlayer struct {
|
||
SceneStateBase
|
||
}
|
||
|
||
func (this *SceneStateWaitPlayer) GetState() int {
|
||
return rule.SceneStateWaitPlayer
|
||
}
|
||
|
||
func (this *SceneStateWaitPlayer) CanChangeTo(s base.SceneState) bool {
|
||
switch s.GetState() {
|
||
case rule.SceneStateWaitStart:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateWaitPlayer) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
|
||
if s.IsMatchScene() {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStateWaitPlayer) OnEnter(s *base.Scene) {
|
||
this.SceneStateBase.OnEnter(s)
|
||
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
sceneEx.Clear()
|
||
sceneEx.SetGaming(false)
|
||
this.BroadcastRoomState(s, this.GetState())
|
||
}
|
||
}
|
||
|
||
// 状态离开时
|
||
func (this *SceneStateWaitPlayer) OnLeave(s *base.Scene) {
|
||
this.SceneStateBase.OnLeave(s)
|
||
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
|
||
}
|
||
|
||
// 玩家操作
|
||
func (this *SceneStateWaitPlayer) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
|
||
return true
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 玩家事件
|
||
func (this *SceneStateWaitPlayer) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
logger.Logger.Trace("(this *SceneWaitPlayerStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
|
||
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
|
||
|
||
if _, ok := p.GetExtraData().(*PlayerEx); ok {
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
switch evtcode {
|
||
case base.PlayerEventEnter:
|
||
// 段位等级没有设置不能玩游戏,不应该有这个错误的
|
||
if len(sceneEx.ChessRank) == 0 && s.GetGameId() != common.GameId_ChesstitiansCambodianRobot {
|
||
logger.Logger.Errorf("ChessRank not found Platform:%v", sceneEx.Platform)
|
||
sceneEx.SceneDestroy(true)
|
||
return
|
||
}
|
||
|
||
//如果有人进入, 检查在线人是否能够开启游戏,够的话,切换到延迟开启状态
|
||
if sceneEx.CanStart() {
|
||
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnPlayerEvent s.ChangeSceneState(SceneStateWaitStart) %v", s.GetSceneId())
|
||
s.ChangeSceneState(rule.SceneStateWaitStart)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateWaitPlayer) OnTick(s *base.Scene) {
|
||
this.SceneStateBase.OnTick(s)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if s.CheckNeedDestroy() {
|
||
sceneEx.SceneDestroy(true)
|
||
return
|
||
}
|
||
if sceneEx.CanStart() {
|
||
logger.Logger.Tracef("(this *SceneWaitPlayerStateChesstitians) OnTick s.ChangeSceneState(SceneStateWaitStart) %v", s.GetSceneId())
|
||
s.ChangeSceneState(rule.SceneStateWaitStart)
|
||
} else if !s.GetGaming() && s.GetRobotNum() == 1 {
|
||
tNow := time.Now()
|
||
for _, p := range s.Players {
|
||
if p.IsRob && tNow.Sub(p.GetLastOPTimer()) > time.Second*time.Duration(30+rand.Int63n(60)) {
|
||
//p.LastOPTimer = tNow.Add(time.Minute * 30)
|
||
s.PlayerLeave(p, common.PlayerLeaveReason_Normal, true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStateWaitStart 开始游戏
|
||
//=====================================
|
||
|
||
type SceneStateWaitStart struct {
|
||
SceneStateBase
|
||
}
|
||
|
||
func (this *SceneStateWaitStart) GetState() int {
|
||
return rule.SceneStateWaitStart
|
||
}
|
||
|
||
func (this *SceneStateWaitStart) CanChangeTo(s base.SceneState) bool {
|
||
switch s.GetState() {
|
||
case rule.SceneStateWaitPlayer, rule.SceneStateWaitStart, rule.SceneStateChessInit:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
// 当前状态能否换桌
|
||
func (this *SceneStateWaitStart) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
|
||
if s.IsMatchScene() {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStateWaitStart) OnEnter(s *base.Scene) {
|
||
this.SceneStateBase.OnEnter(s)
|
||
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
sceneEx.Clear()
|
||
sceneEx.SetGaming(false)
|
||
this.BroadcastRoomState(s, this.GetState())
|
||
logger.Logger.Trace("(this *SceneWaitStartStateChesstitians) OnEnter", this.GetState())
|
||
}
|
||
}
|
||
|
||
// 状态离开时
|
||
func (this *SceneStateWaitStart) OnLeave(s *base.Scene) {
|
||
this.SceneStateBase.OnLeave(s)
|
||
logger.Logger.Tracef("(this *SceneWaitStartStateChesstitians) OnLeave", this.GetState())
|
||
}
|
||
|
||
// 玩家操作
|
||
func (this *SceneStateWaitStart) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
|
||
return true
|
||
}
|
||
sceneEx, _ := s.GetExtraData().(*SceneEx)
|
||
if sceneEx != nil {
|
||
playerEx, _ := p.GetExtraData().(*PlayerEx)
|
||
if playerEx != nil {
|
||
opRetCode := chesstitians.OpResultCode_OPRC_Error
|
||
if playerEx.SnId == sceneEx.masterSnId && this.GetState() == rule.SceneStateWaitStart {
|
||
if sceneEx.IsMatchScene() {
|
||
return false
|
||
}
|
||
switch int32(opcode) {
|
||
case rule.PlayerOpStart: //房主开始游戏
|
||
if sceneEx.CanStart() == false {
|
||
s.ChangeSceneState(rule.SceneStateWaitPlayer)
|
||
} else {
|
||
opRetCode = chesstitians.OpResultCode_OPRC_Sucess
|
||
s.ChangeSceneState(rule.SceneStateChessInit)
|
||
}
|
||
}
|
||
}
|
||
if opRetCode == chesstitians.OpResultCode_OPRC_Sucess {
|
||
sceneEx.OnPlayerSCOp(p, opcode, opRetCode, params)
|
||
} else {
|
||
logger.Logger.Tracef("SceneWaitStartStateChesstitians OnPlayerOp snid:%v, masterSnId:%v", playerEx.SnId, sceneEx.masterSnId)
|
||
}
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// 玩家事件
|
||
func (this *SceneStateWaitStart) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
logger.Logger.Trace("(this *SceneWaitStartStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
|
||
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
|
||
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
switch evtcode {
|
||
case base.PlayerEventLeave:
|
||
//如果有人退出, 检查在线人是否能够开启游戏,不够的话,切换到等待状态
|
||
if !sceneEx.CanStart() {
|
||
s.ChangeSceneState(rule.SceneStateWaitPlayer)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateWaitStart) OnTick(s *base.Scene) {
|
||
this.SceneStateBase.OnTick(s)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if sceneEx.IsMatchScene() {
|
||
delayT := time.Second * 2
|
||
if sceneEx.MatchRound != 1 { //第一轮延迟2s,其他延迟3s 配合客户端播放动画
|
||
delayT = time.Second * 4
|
||
}
|
||
if time.Now().Sub(sceneEx.StateStartTime) > delayT {
|
||
s.ChangeSceneState(rule.SceneStateChessInit) // 比赛场直接发牌
|
||
return
|
||
}
|
||
}
|
||
|
||
if time.Now().Sub(sceneEx.StateStartTime) > rule.WaitStartTimeout {
|
||
//开始前再次检查开始条件
|
||
if sceneEx.CanStart() {
|
||
s.ChangeSceneState(rule.SceneStateChessInit)
|
||
} else {
|
||
s.ChangeSceneState(rule.SceneStateWaitPlayer)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStateChessInit 棋盘初始化
|
||
//=====================================
|
||
|
||
type SceneStateChessInit struct {
|
||
SceneStateBase
|
||
}
|
||
|
||
func (this *SceneStateChessInit) GetState() int {
|
||
return rule.SceneStateChessInit
|
||
}
|
||
|
||
func (this *SceneStateChessInit) CanChangeTo(s base.SceneState) bool {
|
||
if s.GetState() == rule.SceneStatePlayerOp {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *SceneStateChessInit) OnEnter(s *base.Scene) {
|
||
this.SceneStateBase.OnEnter(s)
|
||
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
sceneEx.Clear()
|
||
sceneEx.SetGaming(true)
|
||
sceneEx.GameNowTime = time.Now()
|
||
sceneEx.AllPlayerEnterGame()
|
||
|
||
//参与游戏次数
|
||
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
|
||
playerEx := sceneEx.seats[i]
|
||
if playerEx != nil {
|
||
if playerEx.IsGameing() {
|
||
playerEx.GameTimes++
|
||
}
|
||
}
|
||
}
|
||
|
||
s.NumOfGames++
|
||
s.NotifySceneRoundStart(s.NumOfGames)
|
||
this.BroadcastRoomState(s, this.GetState(), int64(s.NumOfGames))
|
||
|
||
//同步防伙牌数据
|
||
sceneEx.SyncScenePlayer()
|
||
//发牌
|
||
sceneEx.ChessInit()
|
||
|
||
}
|
||
}
|
||
|
||
// 状态离开时
|
||
func (this *SceneStateChessInit) OnLeave(s *base.Scene) {
|
||
this.SceneStateBase.OnLeave(s)
|
||
|
||
logger.Logger.Tracef("(this *SceneHandCardStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
|
||
}
|
||
|
||
// 玩家操作
|
||
func (this *SceneStateChessInit) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
|
||
return true
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
// 玩家事件
|
||
func (this *SceneStateChessInit) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
logger.Logger.Trace("(this *SceneHandCardStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
|
||
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
|
||
}
|
||
|
||
func (this *SceneStateChessInit) OnTick(s *base.Scene) {
|
||
this.SceneStateBase.OnTick(s)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
if time.Now().Sub(sceneEx.StateStartTime) > rule.HandCardTimeout {
|
||
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
|
||
seat := sceneEx.seats[i]
|
||
if !seat.isBlack {
|
||
sceneEx.SetCurOpPos(seat.GetPos())
|
||
}
|
||
}
|
||
s.ChangeSceneState(rule.SceneStatePlayerOp)
|
||
}
|
||
}
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStatePlayerOp 玩家操作状态
|
||
//=====================================
|
||
|
||
type SceneStatePlayerOp struct {
|
||
SceneStateBase
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) GetState() int {
|
||
return rule.SceneStatePlayerOp
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) CanChangeTo(s base.SceneState) bool {
|
||
if s.GetState() == rule.SceneStateBilled {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) OnEnter(s *base.Scene) {
|
||
this.SceneStateBase.OnEnter(s)
|
||
this.BroadcastRoomState(s, this.GetState())
|
||
}
|
||
|
||
// 状态离开时
|
||
func (this *SceneStatePlayerOp) OnLeave(s *base.Scene) {
|
||
this.SceneStateBase.OnLeave(s)
|
||
|
||
logger.Logger.Tracef("(this *SceneHandCardStateChesstitians) OnLeave, sceneid=%v", s.GetSceneId())
|
||
}
|
||
|
||
// 玩家操作
|
||
func (this *SceneStatePlayerOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
|
||
return true
|
||
}
|
||
|
||
this.OnPlayerOpNormal(s, p, opcode, params)
|
||
this.OnPlayerOpAI(s, p, opcode, params)
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) OnPlayerOpNormal(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
sceneEx, ok := s.GetExtraData().(*SceneEx)
|
||
if !ok {
|
||
return true
|
||
}
|
||
if sceneEx == nil {
|
||
return true
|
||
}
|
||
playerEx, ok := p.GetExtraData().(*PlayerEx)
|
||
if !ok {
|
||
return true
|
||
}
|
||
if playerEx == nil {
|
||
return true
|
||
}
|
||
|
||
returnFunc := func(code chesstitians.OpResultCode) {
|
||
if code == chesstitians.OpResultCode_OPRC_Sucess {
|
||
// 可以成功行棋,则同步给所有的玩家
|
||
sceneEx.BroadcastPlayerSCOp(playerEx.SnId, opcode, code, params)
|
||
|
||
if sceneEx.winSnId != 0 {
|
||
sceneEx.ChangeSceneState(rule.SceneStateBilled)
|
||
}
|
||
} else {
|
||
// 若不能成功操作,仅发给操作的玩家
|
||
sceneEx.OnPlayerSCOp(p, opcode, code, params)
|
||
}
|
||
}
|
||
|
||
switch int32(opcode) {
|
||
case rule.PlayerOpPlay: // 玩家行棋
|
||
if sceneEx.GetCurOpPos() != playerEx.GetPos() {
|
||
return false
|
||
}
|
||
|
||
if len(params) != 2 {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
}
|
||
|
||
if sceneEx.PlayChess(params) {
|
||
// 轮换当前操作标记
|
||
sceneEx.NextOpPos()
|
||
sceneEx.StateStartTime = time.Now()
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
|
||
case rule.PlayerOpSurrender: // 投降
|
||
for _, seat := range sceneEx.seats {
|
||
if seat != nil {
|
||
if seat.GetSnId() != playerEx.GetSnId() {
|
||
sceneEx.winSnId = seat.GetSnId()
|
||
break
|
||
}
|
||
}
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
|
||
case rule.PlayerOpDraw: // 求和
|
||
if len(params) == 0 {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
}
|
||
|
||
switch params[0] {
|
||
case rule.RequestDraw:
|
||
if sceneEx.RequestDraw(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
|
||
case rule.CancelDraw:
|
||
if sceneEx.CancelDraw(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
|
||
case rule.RefuseDraw:
|
||
if sceneEx.RefuseDraw(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
|
||
case rule.AgreeDraw:
|
||
if sceneEx.AgreeDraw(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
}
|
||
|
||
case rule.PlayerOpStep: // 计步操作
|
||
// 参数校验
|
||
if len(params) == 0 {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
}
|
||
|
||
switch params[0] {
|
||
case rule.StepStart: // 开始计步
|
||
if sceneEx.StartStep(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
|
||
case rule.StepCancel: // 取消计步
|
||
if sceneEx.CancelStep(playerEx) {
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Error)
|
||
return true
|
||
}
|
||
|
||
case rule.PlayerOpTest: // 测试 强制同步给所有的玩家
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
return true
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) OnPlayerOpAI(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
return true
|
||
}
|
||
|
||
// 玩家事件
|
||
func (this *SceneStatePlayerOp) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
logger.Logger.Trace("(this *SceneHandCardStateChesstitians) OnPlayerEvent, GetSceneId()=", s.GetSceneId(), " player=", p.Name, " evtcode=", evtcode)
|
||
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
|
||
}
|
||
|
||
func (this *SceneStatePlayerOp) OnTick(s *base.Scene) {
|
||
this.SceneStateBase.OnTick(s)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
now := time.Now()
|
||
|
||
f := func() {
|
||
// 玩家操作超时,输
|
||
for k, v := range sceneEx.seats {
|
||
if k != sceneEx.GetCurOpPos() && v != nil {
|
||
sceneEx.winSnId = v.GetSnId()
|
||
sceneEx.ChangeSceneState(rule.SceneStateBilled)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
if now.Sub(sceneEx.StateStartTime) > rule.PlayerOpTimeout {
|
||
f()
|
||
}
|
||
|
||
curPlayer := sceneEx.seats[sceneEx.GetCurOpPos()]
|
||
if time.Duration(curPlayer.getTotalTime())*time.Second >= rule.PlayerTotalTime {
|
||
f()
|
||
}
|
||
}
|
||
}
|
||
|
||
//=====================================
|
||
// SceneStateBilled 结算
|
||
//=====================================
|
||
|
||
type SceneStateBilled struct {
|
||
SceneStateBase
|
||
}
|
||
|
||
func (this *SceneStateBilled) GetState() int {
|
||
return rule.SceneStateBilled
|
||
}
|
||
|
||
func (this *SceneStateBilled) CanChangeTo(s base.SceneState) bool {
|
||
switch s.GetState() {
|
||
case rule.SceneStateWaitPlayer, rule.SceneStateWaitStart:
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateBilled) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
|
||
return true
|
||
}
|
||
|
||
func (this *SceneStateBilled) OnEnter(s *base.Scene) {
|
||
this.SceneStateBase.OnEnter(s)
|
||
this.BroadcastRoomState(s, this.GetState())
|
||
|
||
sceneEx, ok := s.GetExtraData().(*SceneEx)
|
||
if !ok {
|
||
return
|
||
}
|
||
|
||
pack := &chesstitians.SCChesstitiansGameBilled{}
|
||
chessType := model.ChesstitiansType{
|
||
GameId: sceneEx.GameId,
|
||
RoomId: int32(sceneEx.GetSceneId()),
|
||
RoomType: int32(sceneEx.Scene.SceneType),
|
||
NumOfGames: int32(sceneEx.Scene.NumOfGames),
|
||
BankId: sceneEx.masterSnId,
|
||
PlayerCount: rule.MaxNumOfPlayer,
|
||
BaseScore: s.BaseScore,
|
||
TaxRate: s.DbGameFree.GetTaxRate(),
|
||
RoomMode: s.GetSceneMode(),
|
||
}
|
||
|
||
var winPlayer *PlayerEx
|
||
var losePlayer *PlayerEx
|
||
var draw bool
|
||
|
||
for _, seat := range sceneEx.seats {
|
||
if seat != nil {
|
||
if sceneEx.winSnId == seat.GetSnId() {
|
||
winPlayer = seat
|
||
} else {
|
||
losePlayer = seat
|
||
}
|
||
}
|
||
}
|
||
|
||
if winPlayer == nil {
|
||
draw = true
|
||
winPlayer = sceneEx.seats[0]
|
||
losePlayer = sceneEx.seats[1]
|
||
}
|
||
|
||
if draw { // 平局
|
||
billData, chessPerson := sceneEx.ToBilled(winPlayer, losePlayer, rule.Draw)
|
||
pack.Datas = append(pack.Datas, billData)
|
||
chessType.PlayerData = append(chessType.PlayerData, chessPerson)
|
||
|
||
//玩家2
|
||
billData1, chessPerson1 := sceneEx.ToBilled(losePlayer, winPlayer, rule.Draw)
|
||
pack.Datas = append(pack.Datas, billData1)
|
||
chessType.PlayerData = append(chessType.PlayerData, chessPerson1)
|
||
} else { // 有输赢
|
||
billData, chessPerson := sceneEx.ToBilled(winPlayer, losePlayer, rule.Win)
|
||
pack.Datas = append(pack.Datas, billData)
|
||
chessType.PlayerData = append(chessType.PlayerData, chessPerson)
|
||
|
||
// 输家
|
||
billData1, chessPerson1 := sceneEx.ToBilled(losePlayer, winPlayer, rule.Lose)
|
||
pack.Datas = append(pack.Datas, billData1)
|
||
chessType.PlayerData = append(chessType.PlayerData, chessPerson1)
|
||
}
|
||
|
||
proto.SetDefaults(pack)
|
||
s.Broadcast(int(chesstitians.ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled), pack, 0)
|
||
logger.Logger.Trace("ChesstitiansPacketID_PACKET_SCChesstitiansGameBilled gameFreeId:", sceneEx.GetGameFreeId(), ";pack:", pack)
|
||
|
||
info, err := model.MarshalGameNoteByFIGHT(&chessType)
|
||
if err == nil {
|
||
isSave := false
|
||
var logid string
|
||
for _, o_player := range chessType.PlayerData {
|
||
if !sceneEx.Testing && !o_player.IsRob {
|
||
if logid == "" {
|
||
logid, _ = model.AutoIncGameLogId()
|
||
}
|
||
var totalin, totalout int64
|
||
|
||
if o_player.GainCoin < 0 {
|
||
totalin -= (o_player.GainCoin + o_player.GainTaxCoin)
|
||
} else {
|
||
totalout += (o_player.GainCoin + o_player.GainTaxCoin)
|
||
}
|
||
|
||
validFlow := totalin + totalout
|
||
validBet := common.AbsI64(totalin - totalout)
|
||
sceneEx.SaveFriendRecord(o_player.UserId, o_player.IsWin, o_player.GainCoin, sceneEx.GetBaseScore())
|
||
|
||
// 游戏数据统计
|
||
sceneEx.Statistics(&base.StaticParam{
|
||
SnId: o_player.UserId,
|
||
Gain: o_player.GainCoin,
|
||
GainTax: o_player.GainTaxCoin,
|
||
IsAddTimes: true,
|
||
HasRobotGaming: sceneEx.GetGamingRobotCnt() > 0,
|
||
})
|
||
|
||
// 玩家游戏记录
|
||
sceneEx.SaveGamePlayerListLog(o_player.UserId,
|
||
base.GetSaveGamePlayerListLogParam(o_player.Platform, o_player.Channel, o_player.Promoter,
|
||
o_player.PackageTag, logid, o_player.InviterId, totalin, totalout, o_player.GainTaxCoin,
|
||
0, 0, o_player.GainCoin, validBet, validFlow, o_player.IsFirst, o_player.IsLeave))
|
||
isSave = true
|
||
}
|
||
}
|
||
if isSave {
|
||
// 牌局记录
|
||
sceneEx.SaveGameDetailedLog(logid, info, &base.GameDetailedParam{})
|
||
if !sceneEx.IsMatchScene() {
|
||
sceneEx.SetSystemCoinOut(sceneEx.SystemCoinOut())
|
||
base.CoinPoolMgr.PushCoin(sceneEx.GetCoinSceneTypeId(), sceneEx.GetGroupId(), sceneEx.GetPlatform(), sceneEx.GetSystemCoinOut())
|
||
}
|
||
}
|
||
}
|
||
sceneEx.NotifySceneRoundPause()
|
||
}
|
||
|
||
// 玩家操作
|
||
func (this *SceneStateBilled) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
|
||
if this.SceneStateBase.OnPlayerOp(s, p, opcode, params) {
|
||
return true
|
||
}
|
||
|
||
sceneEx, ok := s.GetExtraData().(*SceneEx)
|
||
if !ok {
|
||
return true
|
||
}
|
||
if sceneEx == nil {
|
||
return true
|
||
}
|
||
playerEx, ok := p.GetExtraData().(*PlayerEx)
|
||
if !ok {
|
||
return true
|
||
}
|
||
if playerEx == nil {
|
||
return true
|
||
}
|
||
|
||
returnFunc := func(code chesstitians.OpResultCode) {
|
||
if code == chesstitians.OpResultCode_OPRC_Sucess {
|
||
sceneEx.BroadcastPlayerSCOp(playerEx.SnId, opcode, code, params)
|
||
} else {
|
||
// 若不能成功操作,仅发给操作的玩家
|
||
sceneEx.OnPlayerSCOp(p, opcode, code, params)
|
||
}
|
||
}
|
||
|
||
switch int32(opcode) {
|
||
case rule.PlayerOpNextPlay: // 再来一局
|
||
if playerEx.nextPlay {
|
||
return false
|
||
}
|
||
playerEx.nextPlay = true
|
||
returnFunc(chesstitians.OpResultCode_OPRC_Sucess)
|
||
|
||
if sceneEx.nextSnId == 0 {
|
||
sceneEx.nextSnId = playerEx.GetSnId()
|
||
}
|
||
|
||
if sceneEx.seats[0].nextPlay && sceneEx.seats[1].nextPlay ||
|
||
sceneEx.GetGameId() == common.GameId_ChesstitiansCambodianRobot {
|
||
s.ChangeSceneState(rule.SceneStateWaitStart)
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
// 玩家事件
|
||
func (this *SceneStateBilled) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
|
||
this.SceneStateBase.OnPlayerEvent(s, p, evtcode, params)
|
||
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
switch evtcode {
|
||
case base.PlayerEventLeave:
|
||
// 有人离开,解散房间
|
||
for _, v := range sceneEx.seats {
|
||
if v != nil {
|
||
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *SceneStateBilled) OnTick(s *base.Scene) {
|
||
this.SceneStateBase.OnTick(s)
|
||
|
||
sceneEx, ok := s.GetExtraData().(*SceneEx)
|
||
if !ok {
|
||
return
|
||
}
|
||
|
||
// 有机器人,让机器人离开
|
||
for _, v := range sceneEx.seats {
|
||
if v != nil && v.IsRob {
|
||
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
|
||
}
|
||
}
|
||
|
||
if sceneEx.GetRealPlayerNum() == 1 {
|
||
for _, v := range sceneEx.seats {
|
||
if v != nil {
|
||
sceneEx.PlayerLeave(v.Player, common.PlayerLeaveReason_OnBilled, true)
|
||
}
|
||
}
|
||
}
|
||
|
||
if sceneEx.GetPlayerCnt() == 0 {
|
||
sceneEx.SceneDestroy(true)
|
||
}
|
||
}
|
||
|
||
// 状态离开时
|
||
func (this *SceneStateBilled) OnLeave(s *base.Scene) {
|
||
this.SceneStateBase.OnLeave(s)
|
||
if sceneEx, ok := s.GetExtraData().(*SceneEx); ok {
|
||
sceneEx.SetGaming(false)
|
||
|
||
switch sceneEx.GetGameId() {
|
||
case common.GameId_Chesstitians, common.GameId_ChesstitiansMakruk, common.GameId_ChesstitiansCambodian:
|
||
hasLeave := false
|
||
//剔除下线玩家
|
||
for i := 0; i < sceneEx.GetPlayerNum(); i++ {
|
||
playerEx := sceneEx.seats[i]
|
||
if playerEx == nil {
|
||
continue
|
||
}
|
||
playerEx.Clear()
|
||
if sceneEx.IsMatchScene() {
|
||
continue
|
||
}
|
||
if !playerEx.IsOnLine() {
|
||
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_DropLine, true)
|
||
hasLeave = true
|
||
continue
|
||
}
|
||
// 机器人金币离场检查
|
||
if playerEx.IsRob {
|
||
if s.CoinOverMaxLimit(playerEx.GetCoin(), playerEx.Player) {
|
||
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_Normal, true)
|
||
hasLeave = true
|
||
continue
|
||
}
|
||
}
|
||
// 低于进场限额
|
||
if !s.CoinInLimit(playerEx.GetCoin()) {
|
||
sceneEx.PlayerLeave(playerEx.Player, s.NotCoinInLimitType(playerEx.GetCoin()), true)
|
||
hasLeave = true
|
||
continue
|
||
}
|
||
}
|
||
|
||
if !hasLeave && !sceneEx.IsRobFightGame() && !sceneEx.IsMatchScene() {
|
||
s.TryDismissRob()
|
||
}
|
||
case common.GameId_ChesstitiansCambodianRobot:
|
||
sceneEx.SceneDestroy(true)
|
||
return
|
||
}
|
||
|
||
if s.CheckNeedDestroy() || (s.IsMatchScene() && (!s.MatchFinals || (s.MatchFinals && s.NumOfGames >= 2))) { // 非决赛打一场 决赛打两场
|
||
sceneEx.SceneDestroy(true)
|
||
}
|
||
s.TryRelease()
|
||
}
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) RegisteSceneState(state base.SceneState) {
|
||
if state == nil {
|
||
return
|
||
}
|
||
stateId := state.GetState()
|
||
if stateId < 0 || stateId >= rule.SceneStateMax {
|
||
return
|
||
}
|
||
this.states[stateId] = state
|
||
}
|
||
|
||
func (this *ScenePolicyEntity) GetSceneState(s *base.Scene, stateId int) base.SceneState {
|
||
if stateId >= 0 && stateId < rule.SceneStateMax {
|
||
return this.states[stateId]
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func init() {
|
||
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateWaitPlayer{})
|
||
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateWaitStart{})
|
||
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateChessInit{})
|
||
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStatePlayerOp{})
|
||
ScenePolicyEntitySingleton.RegisteSceneState(&SceneStateBilled{})
|
||
|
||
core.RegisteHook(core.HOOK_BEFORE_START, func() error {
|
||
base.RegisteScenePolicy(common.GameId_Chesstitians, 0, ScenePolicyEntitySingleton)
|
||
base.RegisteScenePolicy(common.GameId_ChesstitiansMakruk, 0, ScenePolicyEntitySingleton)
|
||
base.RegisteScenePolicy(common.GameId_ChesstitiansCambodian, 0, ScenePolicyEntitySingleton)
|
||
base.RegisteScenePolicy(common.GameId_ChesstitiansCambodianRobot, 0, ScenePolicyEntitySingleton)
|
||
return nil
|
||
})
|
||
}
|