package main

import (
	"errors"
	"fmt"
	"math/rand"
	"time"

	webapi_proto "mongo.games.com/game/protocol/webapi"

	"mongo.games.com/game/common"
	"mongo.games.com/game/model"
	"mongo.games.com/game/proto"
	"mongo.games.com/game/protocol/gamehall"
	"mongo.games.com/game/protocol/player"
	"mongo.games.com/game/protocol/server"
	"mongo.games.com/game/srvdata"
	"mongo.games.com/game/webapi"
	"mongo.games.com/goserver/core/basic"
	"mongo.games.com/goserver/core/logger"
	"mongo.games.com/goserver/core/netlib"
	"mongo.games.com/goserver/core/task"
)

type CSEnterRoomPacketFactory struct {
}
type CSEnterRoomHandler struct {
}

func (this *CSEnterRoomPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSEnterRoom{}
	return pack
}
func (this *CSEnterRoomHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSEnterRoomHandler Process recv ", data)
	msg, ok := data.(*gamehall.CSEnterRoom)
	if !ok {
		return nil
	}

	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		return nil
	}

	var code = gamehall.OpResultCode_Game_OPRC_Sucess_Game
	var sp ScenePolicy
	var dbGameFree *server.DB_GameFree
	var roomId int
	var gameId int
	var gameMode int
	var cfg *webapi_proto.GameFree
	oldPlatform := p.Platform

	// 进入原来的房间
	scene := p.scene
	if scene != nil {
		code = gamehall.OpResultCode_Game_OPRC_GameStarting_Game
		roomId = scene.sceneId
		gameId = scene.gameId
		gameMode = scene.gameMode
		logger.Logger.Tracef("CSEnterRoomHandler had scene(%d)", scene.sceneId)
		goto failed
	}

	// 房间查询
	scene = SceneMgrSingleton.GetScene(int(msg.GetRoomId()))
	if scene == nil {
		code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
		logger.Logger.Trace("CSEnterRoomHandler scene == nil")
		goto failed
	}

	gameId = scene.gameId
	gameMode = scene.gameMode
	roomId = scene.sceneId
	if p.IsRob {
		p.Platform = scene.limitPlatform.IdStr
	}

	cfg = PlatformMgrSingleton.GetGameFree(p.Platform, scene.dbGameFree.Id)
	if cfg != nil && (cfg.GroupId != scene.groupId || cfg.GroupId == 0) {
		if scene.limitPlatform != nil {
			if scene.limitPlatform.Isolated && p.Platform != scene.limitPlatform.IdStr {
				code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
				logger.Logger.Tracef("CSEnterRoomHandler ScenePolicy(gameid:%v mode:%v) scene.limitPlatform.Isolated && p.Platform != scene.limitPlatform.Name", scene.gameId, scene.gameMode)
				goto failed
			}
		}
	}
	if scene.deleting {
		code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
		logger.Logger.Trace("CSEnterRoomHandler scene is deleting")
		goto failed
	}
	if scene.closed {
		code = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
		logger.Logger.Trace("CSEnterRoomHandler scene is closed")
		goto failed
	}

	dbGameFree = scene.dbGameFree
	if dbGameFree != nil {
		if common.IsLocalGame(scene.gameId) {
			if !p.IsRob {
				limitCoin := srvdata.CreateRoomMgrSington.GetLimitCoinByBaseScore(int32(scene.gameId), int32(scene.gameSite), scene.BaseScore)
				if p.Coin < limitCoin {
					code = gamehall.OpResultCode_Game_OPRC_CoinNotEnough_Game
					logger.Logger.Trace("CSEnterRoomHandler scene is closed")
					goto failed
				}
			}
		}
	}

	//检测房间状态是否开启
	if !scene.IsMatchScene() && !PlatformMgrSingleton.CheckGameState(scene.limitPlatform.IdStr, dbGameFree.Id) {
		code = gamehall.OpResultCode_Game_OPRC_GameHadClosed
		logger.Logger.Tracef("CSEnterRoomHandler SnId:%v GameFreeId:%v GameHadClosed", p.SnId, dbGameFree.Id)
		goto failed
	}

	sp = GetScenePolicy(scene.gameId, scene.gameMode)
	if sp == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSEnterRoomHandler ScenePolicy(gameid:%v mode:%v) not registe", scene.gameId, scene.gameMode)
		goto failed
	}

	if reason := sp.CanEnter(scene, p); reason != 0 {
		code = gamehall.OpResultCode_Game(reason)
		logger.Logger.Trace("CSEnterRoomHandler sp.CanEnter(scene, p) reason ", reason)
		goto failed
	}

	if scene.IsFull() {
		code = gamehall.OpResultCode_Game_OPRC_RoomIsFull_Game
		logger.Logger.Trace("CSEnterRoomHandler ScenePolicy.IsFull = true")
		goto failed
	}

	if scene.IsMatchScene() && p.IsRob {
		grade := int32(1000)
		snid := p.SnId
		ms := MatchSeasonMgrSington.GetMatchSeason(snid) // 玩家赛季信息
		lv := MatchSeasonRankMgrSington.CreateRobotLv()  //
		if ms != nil {
			lv = ms.Lv
		}
		roleId := int32(2000001)
		if p.Roles != nil {
			roleId = p.Roles.ModId
		}
		var tm *TmMatch
		if len(scene.params) > 3 {
			sortId := scene.params[0]
			tm = TournamentMgr.GetTm(sortId)
			if tm != nil && tm.copyRobotGrades != nil && len(tm.copyRobotGrades) > 0 {
				randIndex := rand.Intn(len(tm.copyRobotGrades))
				grade = tm.copyRobotGrades[randIndex].grade
				snid = tm.copyRobotGrades[randIndex].copySnid
				lv = tm.copyRobotGrades[randIndex].copyLv
				roleId = tm.copyRobotGrades[randIndex].copyRoleId
				tm.copyRobotGrades = append(tm.copyRobotGrades[:randIndex], tm.copyRobotGrades[randIndex+1:]...)
			}
		}
		mc := NewMatchContext(p, tm, grade, snid, lv, roleId, 0)
		if mc != nil {
			mc.gaming = true
			p.matchCtx = mc
		}
	}

	if !p.EnterScene(scene, true, -1) {
		code = gamehall.OpResultCode_Game_OPRC_Error_Game
	}

failed:
	if code != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
		resp := &gamehall.SCEnterRoom{
			GameId:    proto.Int(gameId),
			ModeType:  proto.Int(gameMode),
			RoomId:    proto.Int(roomId),
			OpRetCode: code,
		}
		p.Platform = oldPlatform
		proto.SetDefaults(resp)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERROOM), resp)
	}
	return nil
}

type CSAudienceEnterRoomHandler struct {
}

func (this *CSAudienceEnterRoomHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSAudienceEnterRoomHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSEnterRoom); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			return nil
		}
		var code = gamehall.OpResultCode_Game_OPRC_Sucess_Game
		var sp ScenePolicy
		var dbGameFree *server.DB_GameFree
		var cfg *webapi_proto.GameFree
		scene := SceneMgrSingleton.GetScene(int(msg.GetRoomId()))
		if scene == nil {
			code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
			logger.Logger.Trace("CSAudienceEnterRoomHandler scene == nil")
			goto failed
		}
		if scene.IsMatchScene() {
			code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
			logger.Logger.Tracef("CSAudienceEnterRoomHandler scene.IsMatchScene() %v", scene.sceneId)
			goto failed
		}
		if p.scene != nil {
			code = gamehall.OpResultCode_Game_OPRC_CannotWatchReasonInOther_Game
			logger.Logger.Trace("CSAudienceEnterRoomHandler p.scene != nil")
			goto failed
		}
		cfg = PlatformMgrSingleton.GetGameFree(p.Platform, scene.dbGameFree.Id)
		if cfg != nil && (cfg.GroupId != scene.groupId || cfg.GroupId == 0) {
			if scene.limitPlatform != nil {
				if scene.limitPlatform.Isolated && p.Platform != scene.limitPlatform.IdStr {
					code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
					logger.Logger.Tracef("CSEnterRoomHandler ScenePolicy(gameid:%v mode:%v) scene.limitPlatform.Isolated && p.Platform != scene.limitPlatform.Name", scene.gameId, scene.gameMode)
					goto failed
				}
			}
		}
		//if !scene.starting {
		//	code = gamehall.OpResultCode_Game_OPRC_CannotWatchReasonRoomNotStart_Game
		//	logger.Logger.Trace("CSAudienceEnterRoomHandler !scene.starting")
		//	goto failed
		//}
		if scene.deleting {
			code = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
			logger.Logger.Trace("CSAudienceEnterRoomHandler scene is deleting")
			goto failed
		}
		if scene.closed {
			code = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
			logger.Logger.Trace("CSAudienceEnterRoomHandler scene is closed")
			goto failed
		}
		//if scene.IsCoinScene() || scene.IsHundredScene() {
		//	code = gamehall.OpResultCode_Game_OPRC_Error_Game
		//	logger.Logger.Trace("CSAudienceEnterRoomHandler scene is IsCoinScene IsHundredScene")
		//	goto failed
		//}

		sp = GetScenePolicy(scene.gameId, scene.gameMode)
		if sp == nil {
			code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
			logger.Logger.Tracef("CSAudienceEnterRoomHandler ScenePolicy(gameid:%v mode:%v) not registe", scene.gameId, scene.gameMode)
			goto failed
		}
		dbGameFree = scene.dbGameFree
		code = gamehall.OpResultCode_Game(CoinSceneMgrSingleton.AudienceEnter(p, dbGameFree.GetId(), msg.GetRoomId(), nil, true))

	failed:
		if code != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			resp := &gamehall.SCEnterRoom{
				OpRetCode: code,
			}
			proto.SetDefaults(resp)
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERROOM), resp)
		}
	}
	return nil
}

type CSReturnRoomPacketFactory struct {
}
type CSReturnRoomHandler struct {
}

func (this *CSReturnRoomPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSReturnRoom{}
	return pack
}
func (this *CSReturnRoomHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSReturnRoomHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSReturnRoom); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			return nil
		}
		scene := p.scene
		pack := &gamehall.SCReturnRoom{}
		if scene == nil {
			//miniGameScene := MiniGameMgrSington.GetAllSceneByPlayer(p)
			isExist := false
			//for _, s := range miniGameScene {
			//	if s.sceneId == int(msg.GetRoomId()) {
			//		isExist = true
			//	}
			//}
			if isExist {
				//如果存在这尝试返回到房间内
				//MiniGameMgrSington.OnPlayerReturnScene(p)
			} else {
				pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
				//如果不存在则直接返回
				goto done
			}
		} else {
			pack.RoomId = proto.Int(scene.sceneId)
			pack.GameId = proto.Int(scene.gameId)
			pack.ModeType = proto.Int(scene.gameMode)
			pack.Params = scene.params
			pack.HallId = proto.Int32(scene.hallId)
			gameVers := srvdata.GetGameVers(p.PackageID)
			if ver, ok := gameVers[fmt.Sprintf("%v,%v", scene.gameId, p.Channel)]; ok {
				pack.MinApkVer = proto.Int32(ver.MinApkVer)
				pack.MinResVer = proto.Int32(ver.MinResVer)
				pack.LatestApkVer = proto.Int32(ver.LatestApkVer)
				pack.LatestResVer = proto.Int32(ver.LatestResVer)

				if msg.GetApkVer() < ver.MinApkVer {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_YourAppVerIsLow_Game
					goto done
				}

				if msg.GetResVer() < ver.MinResVer {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_YourResVerIsLow_Game
					goto done
				}
			}
			scene = p.ReturnScene(msg.GetIsLoaded())
			if scene == nil {
				pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_RoomNotExist_Game
			} else {
				//成功返回房间的消息在gamesrv上发送，为了确保房间消息的顺序
				return nil
				//pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
			}
		}
	done:
		proto.SetDefaults(pack)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_RETURNROOM), pack)
	}
	return nil
}

type CSJoinGamePacketFactory struct {
}
type CSJoinGameHandler struct {
}

func (this *CSJoinGamePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSJoinGame{}
	return pack
}
func (this *CSJoinGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSJoinGameHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSJoinGame); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSJoinGameHandler p == nil")
			return nil
		}
		if p.scene == nil {
			logger.Logger.Warn("CSJoinGameHandler scene == nil")
			return nil
		}

		newPlayer := PlayerMgrSington.GetPlayerBySnId(msg.GetSnId())
		if newPlayer != nil {
			pack := &gamehall.SCJoinGame{
				MsgType:   proto.Int32(msg.GetMsgType()),
				OpRetCode: gamehall.OpResultCode_Game(0),
			}
			if !p.scene.IsTestScene() {
				// 入场限额检查
				if p.scene.dbGameFree.GetLimitCoin() != 0 && int64(p.scene.dbGameFree.GetLimitCoin()) > p.Coin {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_MoneyNotEnough_Game
					newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_JOINGAME), pack)
					return nil
				}
				// 携带金币检查
				if p.scene.dbGameFree.GetMaxCoinLimit() != 0 && int64(p.scene.dbGameFree.GetMaxCoinLimit()) < p.Coin && !p.IsRob {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_CoinTooMore_Game
					newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_JOINGAME), pack)
					return nil
				}
			}
			// 是否还有空座位
			if p.scene.IsFull() {
				pack.OpRetCode = gamehall.OpResultCode_Game(1)
				newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_JOINGAME), pack)
				return nil
			}
			p.scene.AudienceSit(newPlayer, -1)
			newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_JOINGAME), pack)
		}
	}
	return nil
}

type CSGetDataLogPacketFactory struct {
}
type CSGetDataLogHandler struct {
}

func (this *CSGetDataLogPacketFactory) CreatePacket() interface{} {
	pack := &player.CSGetDataLog{}
	return pack
}

func (this *CSGetDataLogHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSGetDataLogHandler Process recv ", data)
	if msg, ok := data.(*player.CSGetDataLog); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSGetDataLogHandler p == nil")
			return nil
		}
		ts := int64(msg.GetVer())
		if ts == 0 {
			ts = time.Now().Unix()
		}
		type LogData struct {
			datas []model.CoinLog
			err   error
		}
		task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
			datas, err := model.GetCoinLogBySnidAndLessTs(p.Platform, p.SnId, ts)
			return &LogData{datas: datas, err: err}
		}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
			if d, ok := data.(*LogData); ok {
				if d != nil && d.err == nil {
					pack := &player.SCGetDataLog{
						DataType: msg.DataType,
					}
					ver := msg.GetVer()
					for i := 0; i < len(d.datas); i++ {
						ts := d.datas[i].Time.Unix()
						if int32(ts) < ver {
							ver = int32(ts)
						}
						pack.Datas = append(pack.Datas, &player.DataLog{
							LogType:     proto.Int32(d.datas[i].LogType),
							ChangeCount: proto.Int64(d.datas[i].Count),
							RestCount:   proto.Int64(d.datas[i].RestCount),
							Remark:      proto.String(d.datas[i].Remark),
							Ts:          proto.Int32(int32(ts)),
						})
					}
					pack.Ver = proto.Int32(ver)
					proto.SetDefaults(pack)
					p.SendToClient(int(player.PlayerPacketID_PACKET_SC_GETDATALOG), pack)
				}
			}
		}), "GetCoinLogBySnidAndLessTs").StartByFixExecutor("coinlog_r")
	}
	return nil
}

// 第三方-->系统
func _LeaveTransferThird2SystemTask(p *Player) {

	if p.thrscene == 0 {
		logger.Logger.Tracef("player snid=%v TransferThird2SystemTask p.thrscene == 0 return", p.SnId)
		return
	}

	//if p.thrscene.sceneMode != int(common.SceneMode_Thr) {
	//	logger.Logger.Infof("player snid=%v TransferThird2SystemTask p.scene == thrID return", p.SnId)
	//	return
	//}

	if p.thridBalanceRefreshReqing {
		logger.Logger.Tracef("player snid=%v TransferThird2SystemTask p.thridBalanceRefreshReqing == true return", p.SnId)
		return
	}
	gainway := common.GainWay_Transfer_Thrid2System
	plt := webapi.ThridPlatformMgrSington.FindPlatformByPlatformBaseGameId(p.thrscene)
	if plt == nil {
		logger.Logger.Tracef("player snid=%v TransferThird2SystemTask plt == nil return", p.SnId)
		return
	}

	oper := plt.GetPlatformBase().Name + "2System"
	amount := int64(0)
	timeStamp := time.Now().UnixNano()
	p.thridBalanceRefreshReqing = true
	//timeout := false
	task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
		for i := int32(0); i < model.GameParamData.ThirdPltTransferMaxTry; {
			var err error
			var coinLog *model.PayCoinLog
			var coinlogex *model.CoinLog
			//var apiHasTransfer = false
			remark := plt.GetPlatformBase().Name + "转出到系统"
			//allow := plt.ReqIsAllowTransfer(p.SnId, p.Platform, p.Channel)
			//if !allow {
			//	goto Rollback
			//}
			err, amount = plt.ReqLeaveGame(p.SnId, fmt.Sprintf("%v", p.thrscene), p.Ip, p.Platform, p.Channel)
			if err != nil {
				goto Rollback
			}
			if amount <= 0 {
				return nil
			}
			if plt.GetPlatformBase().TransferInteger {
				amount = (amount / 100) * 100
				if amount <= 0 {
					return nil
				}
			}
			timeStamp = time.Now().UnixNano()
			//如果請求超時的話資金就不能從三方出來，玩家的錢只會少
			//err, timeout = plt.ReqTransfer(p.SnId, -amount, strconv.FormatInt(timeStamp, 10), p.Platform, p.Channel, p.Ip)
			//if err != nil || timeout {
			//	goto Rollback
			//}
			//apiHasTransfer = true
			coinLog = model.NewPayCoinLog(timeStamp, int32(p.SnId), amount, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
			timeStamp = coinLog.TimeStamp
			err = model.InsertPayCoinLogs(p.Platform, coinLog)
			if err != nil {
				goto Rollback
			}
			coinlogex = model.NewCoinLogEx(&model.CoinLogParam{
				Platform:   p.Platform,
				SnID:       p.SnId,
				ChangeType: common.BillTypeCoin,
				ChangeNum:  amount,
				RemainNum:  p.Coin + amount,
				Add:        0,
				LogType:    int32(gainway),
				GameID:     0,
				GameFreeID: 0,
				BaseCoin:   0,
				Operator:   oper,
				Remark:     remark,
			})
			err = model.InsertCoinLog(coinlogex)
			if err != nil {
				goto Rollback
			}
			return nil
		Rollback:
			if coinLog != nil {
				model.RemovePayCoinLog(p.Platform, coinLog.LogId)
			}
			if coinlogex != nil {
				model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
			}
			//如果發現有任何一個超時，則就不在往下執行，因為不知道數據是否正確
			/*
				if timeout {
					logger.Logger.Errorf("player snid=%v third->system transfer %v timeout at try %v times,then stop try!", p.SnId, -amount, i+1)
					break
				}
				if apiHasTransfer {
					err, timeout = plt.ReqTransfer(p.SnId, amount, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
					if err != nil {
						logger.Logger.Errorf("player snid=%v third->system transfer rollback fail at try %v times", p.SnId, i+1)
					}
				}
				//如果发现有任何一個超时，則就不在往下执行，因为不知道数据是否在三方已经处理
				if timeout {
					logger.Logger.Errorf("player snid=%v third->system rollback transfer %v timeout at try %v times,then stop try!", p.SnId, amount, i+1)
					break
				}
			*/
			logger.Logger.Tracef("player snid=%v third->system transfer rollback at try %v times", p.SnId, i+1)
			i++
			if i < model.GameParamData.ThirdPltTransferMaxTry {
				time.Sleep(time.Duration(model.GameParamData.ThirdPltTransferInterval) * time.Second)
			}
		}
		return errors.New("third->system transfer error >max try times!")
	}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
		statePack := &gamehall.SCThridGameBalanceUpdateState{}
		if data != nil {
			p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = false
			p.thridBalanceReqIsSucces = false
			statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
			logger.Logger.Trace("SCThridAccountTransferHandler third->system transfer error:", data)
		} else {
			p.thridBalanceReqIsSucces = true
			statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
			// p.thrscene = nil
			p.Coin += amount
			p.SetPayTs(timeStamp)
			p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
			//ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, thirdBalance)
		}
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
		p.dirty = true

		if statePack.OpRetCode == gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			//退出成功 重置场景状态
			if p.thrscene != 0 {
				p.thrscene = 0
				p.scene = nil
			}
		}

		p.thridBalanceRefreshReqing = false
		p.diffData.Coin = -1 //强制更新金币
		p.SendDiffData()
		return
	}), "ThridAccountTransfer").Start()
}

// 进入三方
type CSEnterThridGamePacketFactory struct {
}
type CSEnterThridGameHandler struct {
}

func (this *CSEnterThridGamePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSEnterThridGame{}
	return pack
}

func (this *CSEnterThridGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSEnterThridGameHandler Process recv ", data)
	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		logger.Logger.Warn("CSEnterThridGameHandler p == nil")
		return nil
	}

	if msg, ok := data.(*gamehall.CSEnterThridGame); ok {
		// msg.ThridGameId = proto.Int32(9010001)
		returnErrorCodeFunc := func(code gamehall.OpResultCode_Game) {
			pack := &gamehall.SCEnterThridGame{}
			pack.OpRetCode = code
			pack.ThridGameId = msg.ThridGameId
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERTHRIDGAME), pack)
			logger.Trace(pack)
		}
		//正在请求刷新余额中不能进入三方
		if p.thridBalanceRefreshReqing {
			logger.Logger.Warn("CSEnterThridGameHandler client req thridBalanceRefreshReqing", p.SnId)
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_ThirdPltProcessing_Game)
			return nil
		}
		//msg.ThridGameId=proto.Int32(430010001)

		//找到对应的平台
		thridPltGameItem, plt := ThirdPltGameMappingConfig.FindThirdInfoBySystemGameId(msg.ThridGameId)
		if thridPltGameItem == nil || plt == nil {
			logger.Logger.Infof("Player %v no platform", p.SnId)
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
			return nil
		}

		if p.thrscene != 0 && p.thrscene != plt.GetPlatformBase().BaseGameID {
			logger.Logger.Infof("Player %v in game.", p.SnId)
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_ThirdPltProcessing_Game)
			return nil
		}
		if p.isDelete {
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
			return nil
		}
		//pt := PlatformMgrSingleton.GetPackageTag(p.PackageID)
		//if pt != nil && pt.IsForceBind == 1 {
		//	if p.BeUnderAgentCode == "" || p.BeUnderAgentCode == "0" {
		//		returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_MustBindPromoter_Game)
		//		return nil
		//	}
		//}

		//检测房间状态是否开启
		gps := PlatformMgrSingleton.GetGameFree(p.Platform, msg.GetThridGameId())
		if gps == nil {
			logger.Logger.Infof("Player %v no cfg room close", p.SnId)

			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
			return nil
		}
		dbGameFree := gps.DbGameFree
		if dbGameFree == nil {
			logger.Logger.Infof("Player %v no gamefree", p.SnId)
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
			return nil
		}
		pfConfig := PlatformMgrSingleton.GetPlatform(p.Platform)
		if pfConfig == nil || pfConfig.ThirdGameMerchant == nil || pfConfig.ThirdGameMerchant[int32(plt.GetPlatformBase().BaseGameID)] == 0 {
			logger.Logger.Infof("Player %v no pfcfg", p.SnId)

			//	returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
			//	return nil
		}

		//检查限额，金额不足
		if dbGameFree.GetLimitCoin() != 0 && p.GetCoin() < int64(dbGameFree.GetLimitCoin()) {
			returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_CoinNotEnough_Game)
			return nil
		}

		//检查平台配额是否足够
		/*if plt.GetPlatformBase().IsNeedCheckQuota {
			dgQuota := ThirdPlatformMgrSington.GetThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag)
			if dgQuota <= 0 || dgQuota <= p.GetCoin() {
				logger.Logger.Infof("Player snid %v %v platfrom Quota of game not enough.", p.SnId, plt.GetPlatformBase().Name)
				returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_Dg_QuotaNotEnough_Game)
				return nil
			}
		}*/

		//检查场景是否开放或者存在，预设数据
		//scene := SceneMgrSingleton.GetThirdScene(plt)
		//if scene != nil {
		p.thrscene = plt.GetPlatformBase().BaseGameID
		//检查场景是否开放或者存在，预设数据
		scene := SceneMgrSingleton.GetThirdScene(plt) //仅用于占位
		if scene != nil {
			p.scene = scene
		}
		//} else {
		//	logger.Logger.Infof("Player %v no scene", p.SnId)

		//	returnErrorCodeFunc(gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game)
		//	return nil
		//}

		AskEnterThridGame(p, plt, thridPltGameItem, s)
	}
	return nil
}
func AskEnterThridGame(p *Player, plt webapi.IThirdPlatform, thridPltGameItem *server.DB_ThirdPlatformGameMapping,
	s *netlib.Session) {
	pack := &gamehall.SCEnterThridGame{}
	pack.ThridGameId = thridPltGameItem.SystemGameID
	amount := p.GetCoin()
	if plt.GetPlatformBase().TransferInteger {
		amount = (amount / 100) * 100
	}
	p.Coin = p.GetCoin() - amount
	gainway := common.GainWay_Transfer_System2Thrid
	oper := "System2" + plt.GetPlatformBase().Name
	timeStamp := time.Now().UnixNano()
	p.thridBalanceRefreshReqing = true
	transferTimeOut := false
	task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
		var err error
		//var ok bool
		url := ""
		remark := "转入" + plt.GetPlatformBase().Name + thridPltGameItem.GetDesc()
		//thridPlatformCoin := int64(0)
		var coinLog *model.PayCoinLog
		var coinlogex *model.CoinLog
		/*err = ensureThridPltUserName(plt, p, amount, s.RemoteAddr())
		if err != nil && err != webapi.ErrNoCreated {
			goto Rollback
		}*/
		//ok = utils.RunPanicless(func() {
		err, url = enterThridPltUserName(plt, p, amount, thridPltGameItem.GetThirdGameID(), s.RemoteAddr())
		//err, url = plt.ReqEnterGame(p.SnId, thridGameId, s.RemoteAddr(), p.Platform, p.Channel, p.Ip)
		//})
		if err == webapi.ErrRequestTimeout { // 超时
			transferTimeOut = true
		}
		//ok = true
		if err != nil && !transferTimeOut {
			logger.Logger.Errorf("plt.ReqEnterGame() snid:%v error: %v", p.SnId, err)
			if thrErr, ok := err.(webapi.ThirdError); ok {
				if thrErr.IsClose() {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Thr_GameClose_Game
				} else {
					pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
				}
			} else {
				pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
			}
			goto Rollback
		}
		coinLog = model.NewPayCoinLog(timeStamp, int32(p.SnId), -amount, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
		timeStamp = coinLog.TimeStamp
		err = model.InsertPayCoinLogs(p.Platform, coinLog)
		if err != nil {
			goto Rollback
		}
		coinlogex = model.NewCoinLogEx(&model.CoinLogParam{
			Platform:   p.Platform,
			SnID:       p.SnId,
			ChangeType: common.BillTypeCoin,
			ChangeNum:  -amount,
			RemainNum:  p.Coin,
			Add:        0,
			LogType:    int32(gainway),
			GameID:     0,
			GameFreeID: 0,
			BaseCoin:   0,
			Operator:   oper,
			Remark:     remark,
		})
		err = model.InsertCoinLog(coinlogex)
		if err != nil {
			goto Rollback
		}
		//
		//err, transferTimeOut = plt.ReqTransfer(p.SnId, amount, strconv.FormatInt(timeStamp, 10), p.Platform, p.Channel, p.Ip)
		if transferTimeOut {
			logger.Logger.Errorf("plt.ReqTransfer() snid:%v error:%v", p.SnId, err)
			pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
			goto Rollback
		}
		pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
		pack.ScreenOrientationType = proto.Int32(thridPltGameItem.GetScreenOrientationType())
		pack.EnterUrl = proto.String(url)
		return nil
	Rollback:
		pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
		if coinLog != nil {
			model.RemovePayCoinLog(p.Platform, coinLog.LogId)
		}
		if coinlogex != nil {
			if transferTimeOut {
				err2 := model.UpdateCoinLogRemark(coinlogex.Platform, coinlogex.LogId, plt.GetPlatformBase().Name+"需人工处理")
				if err2 != nil {
					logger.Logger.Errorf("thr UpdateCoinLogRemark(%v) error: %v", coinlogex.LogId, err2)
				}
			} else {
				model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
			}

		}
		return errors.New("system->third transfer rollback!")
	}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
		if pack.GetOpRetCode() == gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			// ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, -amount)
			p.SetPayTs(timeStamp)
		} else {
			//如帐变出现问题，就在日志里面查下面的输出信息！！！
			//如果转账超时，三方的转账是否成功就是未知的，这时不能将金币再加到玩家身上。
			//如果出现超时问题，就需要人工对账。
			//注意：这个地方说的超时已经包含CG工程Check订单后的超时
			if transferTimeOut {
				logger.Logger.Errorf("CSEnterThridGameHandler player snid:%v transfer %v to %v timeout:", p.SnId, amount, plt.GetPlatformBase().Name)
			} else {
				p.Coin += amount
			}
			p.thrscene = 0
			pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
			logger.Logger.Trace("enterThridPltUserName system->third transfer error:", data)
		}
		p.dirty = true
		p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = false

		p.SendDiffData()
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERTHRIDGAME), pack)
		p.thridBalanceRefreshReqing = false
		logger.Logger.Trace("CSEnterThridGameHandler send client:", pack)
		return
	}), "CSEnterThridGameHandler").Start()
}

func ensureThridPltUserName(pltform webapi.IThirdPlatform, p *Player, amount int64, ip string) error {
	var err error
	err = pltform.ReqCreateAccount(p.SnId, p.Platform, p.Channel, p.GetIP())
	if err != nil {
		if err != webapi.ErrNoCreated {
			logger.Logger.Errorf("Snid=%v Plt=%v ReqCreateAccount error:%v", p.SnId, pltform.GetPlatformBase().Name, err)
		}
		return err
	}
	return nil
}

func enterThridPltUserName(pltform webapi.IThirdPlatform, p *Player, amount int64, gameId, ip string) (err error, url string) {
	// (snId int32, gameId string, clientIP string, platform, channel string, amount int64)
	err, url = pltform.ReqEnterGame(p.SnId, "", p.GetIP(), p.Platform, p.Channel, amount)
	if err != nil {
		if err != webapi.ErrNoCreated {
			logger.Logger.Errorf("Snid=%v Plt=%v ReqEnterGame error:%v", p.SnId, pltform.GetPlatformBase().Name, err)
		}
		return err, ""
	}
	return
}

// 离开三方
type CSLeaveThridGamePacketFactory struct {
}
type CSLeaveThridGameHandler struct {
}

func (this *CSLeaveThridGamePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSLeaveThridGame{}
	return pack
}

func (this *CSLeaveThridGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	if _, ok := data.(*gamehall.CSLeaveThridGame); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSLeaveThridGameHandler p == nil")
			return nil
		}
		logger.Logger.Trace("CSLeaveThridGameHandler Process recv ", p.SnId)
		_LeaveTransferThird2SystemTask(p)
		pack := &gamehall.SCLeaveThridGame{}
		pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_LEAVETHRIDGAME), pack)
	}
	return nil
}

// 刷新
type CSThridBalanceRefreshPacketFactory struct {
}
type CSThridBalanceRefreshHandler struct {
}

func (this *CSThridBalanceRefreshPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSThridGameBalanceUpdate{}
	return pack
}
func (this *CSThridBalanceRefreshHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSThridBalanceRefreshHandler Process recv ", data)
	if _, ok := data.(*gamehall.CSThridGameBalanceUpdate); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSThridBalanceRefreshHandler p == nil")
			return nil
		}
		//if p.scene != nil {
		//	logger.Logger.Tracef("player snid=%v CSThridBalanceRefreshHandler p.scene != nil return", p.SnId)
		//	return nil
		//}

		//请求太快，不做处理，给API减轻一些压力
		if p.thridBalanceRefreshReqing {
			logger.Logger.Warn("CSThridBalanceRefreshHandler client req too fast")
			pack := &gamehall.SCThridGameBalanceUpdate{
				OpRetCode: gamehall.OpResultCode_Game_OPRC_Error_Game,
			}
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
			return nil
		}
		// p.thridBalanceRefreshReqing = true
		RefreshTransferThird2SystemTask(p)
		/*
			gainway := common.GainWay_Transfer_Thrid2System
			waitgroup := webapi.ThridPlatformMgrSington.AllPlatformCount()
			isSucces := true
			timeout := false

			webapi.ThridPlatformMgrSington.ThridPlatformMap.Range(func(key, value interface{}) bool {
				plt := value.(webapi.IThirdPlatform)
				if stateOk, exist := p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name]; exist && stateOk {
					waitgroup--
					if 0 == waitgroup {
						statePack := &gamehall.SCThridGameBalanceUpdateState{}
						pack := &gamehall.SCThridGameBalanceUpdate{}
						pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
						p.thridBalanceReqIsSucces = true
						statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
						p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
						pack.Coin = proto.Int64(p.Coin)
						p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
						p.thridBalanceRefreshReqing = false
					}
					return true
				}
				var tsk task.Task
				tsk = task.New(nil,
					task.CallableWrapper(func(o *basic.Object) interface{} {
						plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
						tsk.PutEnv("timeStamp", time.Now().UnixNano())
						var err error
						var coinLog *model.PayCoinLog
						var coinlogex *model.CoinLog
						var apiHasTransfer = false
						remark := "刷新" + plt.GetPlatformBase().Name + "转出到系统"
						thirdBalance := int64(0)
						//allow := false
						if plt == nil {
							logger.Logger.Tracef("player snid=%v CSThridBalanceRefreshHandler plt == nil return", p.SnId)
							return int64(-1)
						}

						pfConfig := PlatformMgrSingleton.GetPlatform(p.Platform)
						if pfConfig == nil {
							return int64(0)
						}

						if pfConfig.ThirdGameMerchant == nil || pfConfig.ThirdGameMerchant[int32(plt.GetPlatformBase().BaseGameID)] == 0 {
							return int64(0)
						}

						oper := plt.GetPlatformBase().Name + "2System"
						err = ensureThridPltUserName(plt, p, thirdBalance, s.RemoteAddr())
						if err != nil {
							if err == webapi.ErrNoCreated {
								return int64(0)
							}
							logger.Logger.Tracef("player snid=%v at %v ensureThridPltUserName() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
							goto Rollback
						}
						//allow = plt.ReqIsAllowTransfer(p.SnId, p.Platform, p.Channel)
						//if !allow {
						//	logger.Logger.Tracef("player snid=%v at %v is not allow Transfer", p.SnId, plt.GetPlatformBase().Name)
						//	goto Rollback
						//}
						err, thirdBalance = plt.ReqUserBalance(p.SnId, p.Platform, p.Channel, p.Ip)
						if err != nil {
							logger.Logger.Tracef("player snid=%v at %v plt.ReqUserBalance() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
							goto Rollback
						}
						if thirdBalance <= 0 {
							return int64(0)
						}
						if plt.GetPlatformBase().TransferInteger {
							thirdBalance = (thirdBalance / 100) * 100
							if thirdBalance <= 0 {
								return int64(0)
							}
						}
						err, timeout = plt.ReqTransfer(p.SnId, -thirdBalance, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
						if err != nil || timeout {
							logger.Logger.Tracef("player snid=%v at %v plt.ReqTransfer() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
							goto Rollback
						}
						apiHasTransfer = true
						coinLog = model.NewPayCoinLog(time.Now().UnixNano(), int32(p.SnId), thirdBalance, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
						tsk.PutEnv("timeStamp", coinLog.TimeStamp)
						err = model.InsertPayCoinLogs(p.Platform, coinLog)
						if err != nil {
							logger.Logger.Tracef("player snid=%v at %v model.InsertPayCoinLogs() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
							goto Rollback
						}
						coinlogex = model.NewCoinLogEx(p.SnId, thirdBalance, p.Coin+thirdBalance, p.SafeBoxCoin, 0, int32(gainway),
							0, oper, remark, p.Platform, p.Channel, p.BeUnderAgentCode, 0, p.PackageID, int32(plt.GetPlatformBase().VultGameID))
						err = model.InsertCoinLog(coinlogex)
						if err != nil {
							logger.Logger.Tracef("player snid=%v at %v model.InsertCoinLogs() err: %v", p.SnId, plt.GetPlatformBase().Name, err)
							goto Rollback
						}
						tsk.PutEnv("plt", plt)
						return thirdBalance
					Rollback:
						if coinLog != nil {
							model.RemovePayCoinLog(p.Platform, coinLog.LogId)
						}
						if coinlogex != nil {
							model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
						}
						if timeout {
							logger.Logger.Errorf("player snid=%v CSThridBalanceRefreshHandler transfer %v to %v timeout!", p.SnId, -thirdBalance, plt.GetPlatformBase().Name)
							return int64(-1)
						}
						if apiHasTransfer {
							err, timeout = plt.ReqTransfer(p.SnId, thirdBalance, strconv.FormatInt(time.Now().UnixNano(), 10), p.Platform, p.Channel, p.Ip)
							if timeout {
								logger.Logger.Errorf("player snid=%v CSThridBalanceRefreshHandler transfer rollback %v to %v timeout!", p.SnId, thirdBalance, plt.GetPlatformBase().Name)
							}
						}
						return int64(-1)
					}),
					task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
						thirdBalance := data.(int64)
						plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
						timeStamp := tsk.GetEnv("timeStamp").(int64)
						if thirdBalance < 0 {
							isSucces = false
							logger.Logger.Tracef("player snid=%v at platform=%v CSThridBalanceRefreshHandler third->system transfer fail", p.SnId, plt.GetPlatformBase().Name)
						} else if thirdBalance > 0 {
							p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
							p.Coin += thirdBalance
							p.SetPayTs(timeStamp)
							//ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, thirdBalance)
							p.dirty = true
							logger.Logger.Tracef("player snid=%v at platform=%v CSThridBalanceRefreshHandler third->system transfer succes", p.SnId, plt.GetPlatformBase().Name)
						} else {
							p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
						}
						if atomic.AddInt32(&waitgroup, -1) == 0 {
							p.diffData.Coin = -1
							p.SendDiffData()
							statePack := &gamehall.SCThridGameBalanceUpdateState{}
							pack := &gamehall.SCThridGameBalanceUpdate{}
							if isSucces {
								pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
								p.thridBalanceReqIsSucces = true
								statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
							} else {
								pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
								p.thridBalanceReqIsSucces = false
								statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
							}
							p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
							pack.Coin = proto.Int64(p.Coin)
							p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
							p.thridBalanceRefreshReqing = false
							logger.Logger.Tracef("SendToClient() player snid=%v at CSThridBalanceRefreshHandler() pack:%v", p.SnId, pack.String())
						}
					}), "ThridAccount")
				tsk.PutEnv("plt", value)
				tsk.Start()
				return true
			})*/
	}
	return nil
}

// 刷新 第三方-->系统
func RefreshTransferThird2SystemTask(p *Player) {

	/*if p.thrscene == 0 {
		logger.Logger.Tracef("player snid=%v RefreshTransferThird2SystemTask p.thrscene == 0 return", p.SnId)
		return
	}*/

	if p.thridBalanceRefreshReqing {
		logger.Logger.Tracef("player snid=%v RefreshTransferThird2SystemTask p.thridBalanceRefreshReqing == true return", p.SnId)
		return
	}
	gainway := common.GainWay_Transfer_Thrid2System

	amount := int64(0)
	timeStamp := time.Now().UnixNano()
	p.thridBalanceRefreshReqing = true
	//timeout := false
	webapi.ThridPlatformMgrSington.ThridPlatformMap.Range(func(key, value interface{}) bool {
		// plt := value.(webapi.IThirdPlatform)

		var tsk task.Task
		tsk = task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
			// plt := webapi.ThridPlatformMgrSington.FindPlatformByPlatformBaseGameId(p.thrscene)
			plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
			if plt == nil {
				logger.Logger.Tracef("player snid=%v RefreshTransferThird2SystemTask plt == nil return", p.SnId)
				return errors.New("third->system plt is nil")
			}
			for i := int32(0); i < model.GameParamData.ThirdPltTransferMaxTry; {
				var err error
				var coinLog *model.PayCoinLog
				var coinlogex *model.CoinLog

				oper := plt.GetPlatformBase().Name + "2System"
				remark := "刷新" + plt.GetPlatformBase().Name + "转出到系统"
				err, amount = plt.ReqUserBalance(p.SnId, p.Platform, p.Channel, p.Ip)

				// err, amount = plt.ReqLeaveGame(p.SnId, fmt.Sprintf("%v", p.thrscene), p.Ip, p.Platform, p.Channel)
				if err != nil {
					goto Rollback
				}
				if amount <= 0 {
					return nil
				}
				if plt.GetPlatformBase().TransferInteger {
					amount = (amount / 100) * 100
					if amount <= 0 {
						return nil
					}
				}
				timeStamp = time.Now().UnixNano()

				coinLog = model.NewPayCoinLog(timeStamp, int32(p.SnId), amount, int32(gainway), oper, model.PayCoinLogType_Coin, 0)
				timeStamp = coinLog.TimeStamp
				err = model.InsertPayCoinLogs(p.Platform, coinLog)
				if err != nil {
					goto Rollback
				}
				coinlogex = model.NewCoinLogEx(&model.CoinLogParam{
					Platform:   p.Platform,
					SnID:       p.SnId,
					ChangeType: common.BillTypeCoin,
					ChangeNum:  amount,
					RemainNum:  p.Coin + amount,
					Add:        0,
					LogType:    int32(gainway),
					GameID:     0,
					GameFreeID: 0,
					BaseCoin:   0,
					Operator:   oper,
					Remark:     remark,
				})
				err = model.InsertCoinLog(coinlogex)
				if err != nil {
					goto Rollback
				}
				return nil
			Rollback:
				if coinLog != nil {
					model.RemovePayCoinLog(p.Platform, coinLog.LogId)
				}
				if coinlogex != nil {
					model.RemoveCoinLogOne(coinlogex.Platform, coinlogex.LogId)
				}

				logger.Logger.Tracef("player snid=%v third->system transfer rollback at try %v times", p.SnId, i+1)
				i++
				if i < model.GameParamData.ThirdPltTransferMaxTry {
					time.Sleep(time.Duration(model.GameParamData.ThirdPltTransferInterval) * time.Duration(time.Second))
				}
			}
			return errors.New("third->system transfer error >max try times!")
		}), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) {
			statePack := &gamehall.SCThridGameBalanceUpdateState{}
			pack := &gamehall.SCThridGameBalanceUpdate{}
			plt := tsk.GetEnv("plt").(webapi.IThirdPlatform)
			if data != nil {
				p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = false
				p.thridBalanceReqIsSucces = false
				statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
				pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Error_Game
				logger.Logger.Trace("SCThridAccountTransferHandler third->system transfer error:", data)
			} else {
				p.thridBalanceReqIsSucces = true
				statePack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
				pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
				// p.thrscene = nil
				p.Coin += amount
				p.SetPayTs(timeStamp)
				p.thirdBalanceRefreshMark[plt.GetPlatformBase().Name] = true
				//ThirdPlatformMgrSington.AddThirdPlatformCoin(p.Platform, plt.GetPlatformBase().Tag, thirdBalance)
			}
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)

			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATESTATE), statePack)
			pack.Coin = proto.Int64(p.Coin)
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_THRIDGAMEBALANCEUPDATE), pack)
			p.dirty = true

			//这个地方虽然说拉取失败，但是为了不影响玩家玩其他的游戏，还是可以进入其它场景
			//后面玩家自己通过手动刷新余额
			if p.thrscene != 0 {
				p.thrscene = 0
				p.scene = nil
			}
			p.thridBalanceRefreshReqing = false
			p.diffData.Coin = -1 //强制更新金币
			p.SendDiffData()
			return
		}), "ThridAccountRefresh")
		tsk.PutEnv("plt", value)
		tsk.Start()
		return true
	})
}

type CSGetPrivateRoomHistoryPacketFactory struct {
}
type CSGetPrivateRoomHistoryHandler struct {
}

func (this *CSGetPrivateRoomHistoryPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSGetPrivateRoomHistory{}
	return pack
}

func (this *CSGetPrivateRoomHistoryHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSGetPrivateRoomHistoryHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSGetPrivateRoomHistory); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSGetPrivateRoomHistoryHandler p == nil")
			return nil
		}

		pps := PrivateSceneMgrSington.GetOrCreatePlayerPrivateScene(p)
		if pps == nil {
			logger.Logger.Warnf("CSGetPrivateRoomHistoryHandler PrivateSceneMgrSington.GetOrCreatePlayerPrivateScene(%v)", p.SnId)
			return nil
		}

		pps.LoadLogs(p, msg.GetQueryTime())
	}
	return nil
}

type CSQueryRoomInfoPacketFactory struct {
}
type CSQueryRoomInfoHandler struct {
}

func (this *CSQueryRoomInfoPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSQueryRoomInfo{}
	return pack
}

func (this *CSQueryRoomInfoHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	//msg, ok := data.(*gamehall.CSQueryRoomInfo)
	//if !ok {
	//	return nil
	//}
	//if len(msg.GetId()) > 0 {
	//	return this.ProcessId(s, packetid, data, sid)
	//}
	return this.ProcessLocalGame(s, packetid, data, sid)
}

func (this *CSQueryRoomInfoHandler) ProcessLocalGame(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSQueryRoomInfoHandler Process recv ProcessLocalGame", data)
	if msg, ok := data.(*gamehall.CSQueryRoomInfo); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSQueryRoomInfoHandler p == nil")
			return nil
		}
		pack := &gamehall.SCQueryRoomInfo{
			GameSite: proto.Int32(msg.GetGameSite()),
		}
		mapGameCfg := PlatformMgrSingleton.GetGameFrees(p.Platform)
		for _, gameid := range msg.GetGameIds() {
			pack.GameIds = append(pack.GameIds, gameid)
			scenes := SceneMgrSingleton.GetScenesByGame(int(gameid))
			for _, scene := range scenes {
				var isShow bool
				if mapGameCfg != nil {
					if cfg, have := mapGameCfg[scene.dbGameFree.Id]; have && cfg.GroupId != 0 && cfg.GroupId == scene.groupId {
						isShow = true
					}
				}
				if p.Platform == scene.limitPlatform.IdStr || isShow {
					if scene != nil && scene.sceneMode == common.SceneMode_Public && len(scene.players) != 0 {
						if scene.gameId == int(gameid) && scene.gameSite == int(msg.GetGameSite()) {
							roomInfo := &gamehall.QRoomInfo{
								GameFreeId: proto.Int32(scene.dbGameFree.GetId()),
								GameId:     proto.Int32(scene.dbGameFree.GetGameId()),
								RoomId:     proto.Int(scene.sceneId),
								BaseCoin:   proto.Int64(int64(scene.BaseScore)),
								LimitCoin:  proto.Int64(scene.dbGameFree.GetLimitCoin()),
								CurrNum:    proto.Int(scene.GetPlayerCnt()),
								MaxPlayer:  proto.Int(scene.playerNum),
								Creator:    proto.Int32(scene.creator),
								CreateTs:   proto.Int32(int32(scene.createTime.Unix())),
								Params:     scene.params,
							}
							pack.RoomInfo = append(pack.RoomInfo, roomInfo)
						}
					}
				}
			}
		}
		pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
		proto.SetDefaults(pack)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_QUERYROOMINFO), pack)
		logger.Logger.Trace("SCQueryRoomInfo: ", pack)
	}
	return nil
}

func (this *CSQueryRoomInfoHandler) ProcessId(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSQueryRoomInfoHandler Process recv ProcessId", data)
	if msg, ok := data.(*gamehall.CSQueryRoomInfo); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSQueryRoomInfoHandler p == nil")
			return nil
		}

		pack := &gamehall.SCQueryRoomInfo{}
		mapGameCfg := PlatformMgrSingleton.GetGameFrees(p.Platform)
		for _, v := range msg.GetId() {
			gameid := v / 10000
			pack.GameIds = append(pack.GameIds, gameid)
			scenes := SceneMgrSingleton.GetScenesByGame(int(gameid))
			for _, scene := range scenes {
				var isShow bool
				if mapGameCfg != nil {
					if cfg, have := mapGameCfg[scene.dbGameFree.Id]; have && cfg.GroupId != 0 && cfg.GroupId == scene.groupId {
						isShow = true
					}
				}
				if p.Platform == scene.limitPlatform.IdStr || isShow {
					if scene != nil && scene.sceneMode == common.SceneMode_Public && len(scene.players) != 0 {
						if scene.dbGameFree.Id == v {
							roomInfo := &gamehall.QRoomInfo{
								GameFreeId: proto.Int32(scene.dbGameFree.GetId()),
								GameId:     proto.Int32(scene.dbGameFree.GetGameId()),
								RoomId:     proto.Int(scene.sceneId),
								BaseCoin:   proto.Int64(int64(scene.BaseScore)),
								LimitCoin:  proto.Int64(scene.dbGameFree.GetLimitCoin()),
								CurrNum:    proto.Int(scene.GetPlayerCnt()),
								MaxPlayer:  proto.Int(scene.playerNum),
								Creator:    proto.Int32(scene.creator),
								CreateTs:   proto.Int32(int32(scene.createTime.Unix())),
								Params:     scene.params,
							}
							pack.RoomInfo = append(pack.RoomInfo, roomInfo)
						}
					}
				}
			}
		}

		pack.OpRetCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
		proto.SetDefaults(pack)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_QUERYROOMINFO), pack)
		logger.Logger.Trace("SCQueryRoomInfo: ", pack)
	}
	return nil
}

type CSLotteryLogPacketFactory struct {
}
type CSLotteryLogHandler struct {
}

func (this *CSLotteryLogPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSLotteryLog{}
	return pack
}

func (this *CSLotteryLogHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSLotteryLogHandler Process recv ", data)
	//if msg, ok := data.(*gamehall.CSLotteryLog); ok {
	//	p := PlayerMgrSington.GetPlayer(sid)
	//	if p == nil {
	//		logger.Logger.Warn("CSLotteryLogHandler p == nil")
	//		return nil
	//	}
	//
	//	LotteryMgrSington.FetchLotteryLog(p, msg.GetGameFreeId())
	//}
	return nil
}

// 获取指定游戏配置 包括分场信息
type CSGetGameConfigPacketFactory struct {
}
type CSGetGameConfigHandler struct {
}

func (this *CSGetGameConfigPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSGetGameConfig{}
	return pack
}

func (this *CSGetGameConfigHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSGetGameConfigHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSGetGameConfig); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSGetGameConfigHandler p == nil")
			return nil
		}

		plf := msg.GetPlatform()
		if plf == "" {
			logger.Logger.Warn("CSGetGameConfigHandler plf == ''")
			return nil
		}

		chl := msg.GetChannel()
		if chl == "" {
			logger.Logger.Warn("CSGetGameConfigHandler chl == ''")
			return nil
		}

		gameId := msg.GetGameId()
		if gameId == 0 {
			logger.Logger.Warn("CSGetGameConfigHandler gameId == 0")
			return nil
		}
		p.SendGameConfig(gameId, plf, chl)
	}
	return nil
}

// 进入游戏操作
type CSEnterGamePacketFactory struct {
}
type CSEnterGameHandler struct {
}

func (this *CSEnterGamePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSEnterGame{}
	return pack
}

func (this *CSEnterGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSEnterGameHandler Process recv ", data)
	msg, ok := data.(*gamehall.CSEnterGame)
	if !ok {
		return nil
	}

	gameId := msg.GetId() //gameid
	if gameId > 10000 {
		gameId = msg.GetId() / 10000 //gamefreeid
	}

	if common.IsLocalGame(int(gameId)) {
		return this.ProcessLocal(s, packetid, data, sid)
	}
	return this.ProcessNormal(s, packetid, data, sid)
}

func (this *CSEnterGameHandler) ProcessLocal(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSEnterGameHandler ProcessLocal recv ", data)
	msg, ok := data.(*gamehall.CSEnterGame)
	if !ok {
		return nil
	}
	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		return nil
	}

	// 返回消息
	var ret gamehall.OpResultCode_Game
	pack := &gamehall.SCEnterGame{
		Id: msg.Id,
	}
	oldPlatform := p.Platform
	sendEnterGame := func() {
		//机器人要避免身上的平台标记被污染
		if p.IsRob {
			if ret != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
				p.Platform = oldPlatform
			}
		}
		pack.OpCode = ret
		proto.SetDefaults(pack)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERGAME), pack)
	}

	// 进入原房间
	if p.scene != nil {
		if p.thrscene > 0 {
			ret = gamehall.OpResultCode_Game_OPRC_InOtherGameIng_Game
			sendEnterGame()
			return nil
		}
		logger.Logger.Warnf("CSEnterGameHandler  found snid:%v had in scene:%v gameid:%v", p.SnId, p.scene.sceneId, p.scene.gameId)
		p.ReturnScene(true)
		return nil
	}

	// 获取gameId
	gameId := msg.GetId() //gameid
	if gameId > 10000 {
		gameId = msg.GetId() / 10000 //gamefreeid
	}

	// 本地游戏入场规则
	playerTakeCoin := p.Coin
	gameSite := srvdata.CreateRoomMgrSington.GetGameSiteByGameId(gameId, playerTakeCoin)
	if gameSite == 0 {
		ret = gamehall.OpResultCode_Game_OPRC_CoinNotEnough_Game
		sendEnterGame()
		return nil
	}

	gamefreeid := gameId*10000 + gameSite
	gps := PlatformMgrSingleton.GetGameFree(p.Platform, gamefreeid)
	if gps == nil {
		ret = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
		sendEnterGame()
		return nil
	}

	dbGameFree := gps.DbGameFree
	var roomId int32
	params := msg.GetOpParams()

	if dbGameFree == nil {
		ret = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
		sendEnterGame()
		return nil
	}

	if len(params) != 0 {
		roomId = params[0]
		platformName := CoinSceneMgrSingleton.GetPlatformBySceneId(int(roomId))
		if p.IsRob {
			p.Platform = platformName
		} else if p.GMLevel > 0 && p.Platform == platformName { //允许GM直接按房间ID进场
			roomId = params[0]
		}
	}

	if len(msg.GetPlatform()) > 0 && p.IsRob {
		p.Platform = msg.GetPlatform()
	}

	if len(params) != 0 && (p.GMLevel > 0 || dbGameFree.GetCreateRoomNum() != 0) { //允许GM|或者可选房间的游戏直接按房间ID进场
		s := SceneMgrSingleton.GetScene(int(params[0]))
		if s != nil {
			if s.limitPlatform.IdStr == p.Platform || (gps.GroupId != 0 && s.groupId == gps.GroupId) {
				roomId = params[0]
			}
		}
	}

	excludeSceneIds := p.lastSceneId[gamefreeid]
	ret = gamehall.OpResultCode_Game(CoinSceneMgrSingleton.PlayerEnter(p, gamefreeid, roomId, excludeSceneIds, true))
	if p.scene != nil {
		pack.OpParams = append(pack.OpParams, int32(p.scene.sceneId))
		// 有房间还进入失败，尝试returnroom
		if ret != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			p.ReturnScene(true)
			return nil
		}
	}
	sendEnterGame()
	return nil
}

func (this *CSEnterGameHandler) ProcessNormal(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSEnterGameHandler ProcessNormal recv ", data)
	msg, ok := data.(*gamehall.CSEnterGame)
	if !ok {
		return nil
	}
	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		return nil
	}

	// 返回消息
	var ret gamehall.OpResultCode_Game
	pack := &gamehall.SCEnterGame{
		Id: msg.Id,
	}
	oldPlatform := p.Platform
	sendEnterGame := func() {
		//机器人要避免身上的平台标记被污染
		if p.IsRob {
			if ret != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
				p.Platform = oldPlatform
			}
		}
		pack.OpCode = ret
		proto.SetDefaults(pack)
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_ENTERGAME), pack)
	}

	// 进入原房间
	if p.scene != nil {
		if p.thrscene > 0 {
			ret = gamehall.OpResultCode_Game_OPRC_InOtherGameIng_Game
			sendEnterGame()
			return nil
		}
		logger.Logger.Warnf("CSEnterGameHandler  found snid:%v had in scene:%v gameid:%v", p.SnId, p.scene.sceneId, p.scene.gameId)
		p.ReturnScene(true)
		return nil
	}

	// 其他游戏入场规则
	gps := PlatformMgrSingleton.GetGameFree(p.Platform, msg.GetId())
	if gps == nil {
		ret = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
		sendEnterGame()
		return nil
	}

	dbGameFree := gps.DbGameFree
	if dbGameFree == nil {
		ret = gamehall.OpResultCode_Game_OPRC_RoomHadClosed_Game
		sendEnterGame()
		return nil
	}

	gameType := dbGameFree.GetGameType()
	var roomId int32
	params := msg.GetOpParams() // 0:房间id
	switch {
	case common.IsHundredType(gameType):
		if len(params) != 0 {
			roomId = params[0]
			name, ok := HundredSceneMgrSington.GetPlatformNameBySceneId(roomId)
			if p.IsRob {
				//机器人先伪装成对应平台的用户
				if ok {
					p.Platform = name
				}
			} else if p.GMLevel > 0 && p.Platform == name { //允许GM直接按房间ID进场
				roomId = params[0]
			}
		}

		if len(params) != 0 && p.GMLevel > 0 { //允许GM直接按房间ID进场
			s := SceneMgrSingleton.GetScene(int(params[0]))
			if s != nil {
				if s.limitPlatform.IdStr == p.Platform || (s.groupId != 0 && s.groupId == gps.GroupId) {
					roomId = params[0]
				}
			}
		}
		ret = gamehall.OpResultCode_Game(HundredSceneMgrSington.PlayerEnter(p, msg.GetId()))
		if p.scene != nil {
			pack.OpParams = append(pack.OpParams, msg.GetId())
			if ret != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
				p.ReturnScene(true)
				return nil
			}
		}

	case common.IsCoinSceneType(gameType):
		if len(params) != 0 {
			roomId = params[0]
			platformName := CoinSceneMgrSingleton.GetPlatformBySceneId(int(roomId))
			if p.IsRob {
				p.Platform = platformName
			} else if p.GMLevel > 0 && p.Platform == platformName { //允许GM直接按房间ID进场
				roomId = params[0]
			}
		}
		if len(msg.GetPlatform()) > 0 && p.IsRob {
			p.Platform = msg.GetPlatform()
		}

		if len(params) != 0 && (p.GMLevel > 0 || dbGameFree.GetCreateRoomNum() != 0) { //允许GM|或者可选房间的游戏直接按房间ID进场
			s := SceneMgrSingleton.GetScene(int(params[0]))
			if s != nil {
				if s.limitPlatform.IdStr == p.Platform || (gps.GroupId != 0 && s.groupId == gps.GroupId) {
					roomId = params[0]
				}
			}
		}

		excludeSceneIds := p.lastSceneId[msg.GetId()]
		ret = gamehall.OpResultCode_Game(CoinSceneMgrSingleton.PlayerEnter(p, msg.GetId(), roomId, excludeSceneIds, true))
		if p.scene != nil {
			pack.OpParams = append(pack.OpParams, int32(p.scene.sceneId))
			if ret != gamehall.OpResultCode_Game_OPRC_Sucess_Game {
				p.ReturnScene(true)
				return nil
			}
		}
	default:

	}
	sendEnterGame()
	return nil
}

// 退出游戏操作
type CSQuitGamePacketFactory struct {
}
type CSQuitGameHandler struct {
}

func (this *CSQuitGamePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSQuitGame{}
	return pack
}

func (this *CSQuitGameHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSQuitGameHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSQuitGame); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p != nil {
			var ret gamehall.OpResultCode_Game
			pack := &gamehall.SCQuitGame{
				Id: msg.Id,
			}

			dbGameFree := srvdata.PBDB_GameFreeMgr.GetData(msg.GetId())
			gameType := dbGameFree.GetGameType()
			if common.IsHundredType(gameType) {
				ret = gamehall.OpResultCode_Game(HundredSceneMgrSington.PlayerTryLeave(p))
			} else if common.IsCoinSceneType(gameType) {
				ret = gamehall.OpResultCode_Game(CoinSceneMgrSingleton.PlayerTryLeave(p, msg.IsAudience))
				if gamehall.OpResultCode_Game_OPRC_OpYield_Game == ret {
					return nil
				}
			}

			pack.OpCode = ret
			proto.SetDefaults(pack)
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_QUITGAME), pack)

		}
	}
	return nil
}

type CSCreateRoomPacketFactory struct {
}
type CSCreateRoomHandler struct {
}

func (this *CSCreateRoomPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSCreateRoom{}
	return pack
}

func (this *CSCreateRoomHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSCreateRoomHandler Process recv ", data)
	msg, ok := data.(*gamehall.CSCreateRoom)
	if !ok {
		return nil
	}

	switch {
	case common.IsLocalGame(int(msg.GetGameId())):
		return this.ProcessLocalGame(s, packetid, data, sid)
	default:
		logger.Logger.Errorf("CSCreateRoomHandler no create function %v", msg.GetGameId())
		return nil
	}
}

func (this *CSCreateRoomHandler) ProcessLocalGame(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	msg, ok := data.(*gamehall.CSCreateRoom)
	if !ok {
		return nil
	}
	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		return nil
	}

	var code gamehall.OpResultCode_Game
	var betRange []int32
	var inRange bool
	var dbCreateRoom *server.DB_Createroom
	var dbGameFree *server.DB_GameFree
	var dbGameRule *server.DB_GameRule
	var playerTakeCoin = p.GetCoin()
	var maxPlayerNum = int(msg.GetMaxPlayerNum())
	var gameId = msg.GetGameId()
	var params = msg.GetParams()
	var roomId int
	var scene *Scene
	var sp ScenePolicy
	var gamefreeId int32
	var gameSite int32
	var csp *CoinScenePool
	var baseScore int32
	var gps *webapi_proto.GameFree

	//根据携带金额取可创房间 DB_Createroom
	arrs := srvdata.PBDB_CreateroomMgr.Datas.Arr
	for i := len(arrs) - 1; i >= 0; i-- {
		if arrs[i].GetGameId() == msg.GetGameId() {
			goldRange := arrs[i].GoldRange
			if len(goldRange) == 0 {
				continue
			}
			if playerTakeCoin >= int64(goldRange[0]) {
				dbCreateRoom = arrs[i]
				break
			}
		}
	}
	if dbCreateRoom == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, dbCreateRoom)
		goto failed
	}

	//校验下gameid
	if dbCreateRoom.GetGameId() != gameId {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler PBDB_Createroom Id:%v GameId:%v not exist", dbCreateRoom.GetGameId(), gameId)
		goto failed
	}

	gameSite = dbCreateRoom.GetGameSite()
	gamefreeId = gameId*10000 + gameSite
	gps = PlatformMgrSingleton.GetGameFree(p.Platform, gamefreeId)
	if gps == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, gamefreeId)
		goto failed
	}

	dbGameFree = gps.DbGameFree
	//dbGameFree = srvdata.PBDB_GameFreeMgr.GetData(gamefreeId)
	if dbGameFree == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, gamefreeId)
		goto failed
	}

	//检测房间状态是否开启
	if !PlatformMgrSingleton.CheckGameState(p.Platform, dbGameFree.Id) {
		code = gamehall.OpResultCode_Game_OPRC_GameHadClosed
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v GameHadClosed", p.SnId, gamefreeId)
		goto failed
	}

	dbGameRule = srvdata.PBDB_GameRuleMgr.GetData(dbGameFree.GetGameRule())
	if dbGameRule == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v gamerule not exist", p.SnId, gamefreeId)
		goto failed
	}

	if len(params) == 0 {
		params = common.CopySliceInt32(dbGameRule.GetParams())
	}
	sp = GetScenePolicy(int(dbGameFree.GetGameId()), int(dbGameFree.GetGameMode()))
	if sp == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v ScenePolicy(gameid:%v mode:%v) not registe", p.SnId, dbGameFree.GetGameId(), dbGameFree.GetGameMode())
		goto failed
	}

	if p.scene != nil {
		code = gamehall.OpResultCode_Game_OPRC_RoomHadExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler had scene(%d)", p.scene.sceneId)
		goto failed
	}

	//校验底分
	betRange = dbCreateRoom.GetBetRange()
	inRange = false
	for _, bet := range betRange {
		if msg.GetBaseCoin() == bet {
			inRange = true
			break
		}
	}
	if !inRange || msg.GetBaseCoin() == 0 {
		code = gamehall.OpResultCode_Game_OPRC_Error_Game
		logger.Logger.Tracef("CSCreateRoomHandler BaseCoin:%v not in BetRange ", msg.GetBaseCoin())
		goto failed
	}
	//修正底注
	baseScore = msg.GetBaseCoin()

	// 如果人数为0，人数从建房参数中获取，如果没有就用gameconfig中的默认最大人数
	// 再添加新游戏人数放在建房参数params中
	//校验人数
	maxPlayerNum = int(msg.GetMaxPlayerNum())
	if maxPlayerNum != 4 && maxPlayerNum != 2 {
		code = gamehall.OpResultCode_Game_OPRC_Error_Game
		logger.Logger.Tracef("CSCreateRoomHandler GameId_TienLen_maxPlayerNum:%v ", maxPlayerNum)
		maxPlayerNum = 0
	}

	//创建房间
	csp = CoinSceneMgrSingleton.GetCoinScenePool(p.GetPlatform().IdStr, dbGameFree.GetId())
	roomId = SceneMgrSingleton.GenOneCoinSceneId()
	if roomId == common.RANDID_INVALID {
		code = gamehall.OpResultCode_Game_OPRC_AllocRoomIdFailed_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameId:%v sceneId == -1 ", p.SnId, gameId)
		goto failed
	}
	scene, code = p.CreateLocalGameScene(roomId, int(gameId), int(gameSite), int(msg.GetSceneMode()), maxPlayerNum,
		params, dbGameFree, baseScore, csp.groupId)
	if scene != nil {
		if code == gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			logger.Logger.Tracef("CSCreateRoomHandler SnId:%v Create Sucess GameId:%v", p.SnId, gameId)
			// try enter scene
			csp.scenes[scene.sceneId] = scene
			scene.csp = csp
			if !p.EnterScene(scene, true, -1) {
				code = gamehall.OpResultCode_Game_OPRC_Error_Game
			}
		}
	}

failed:
	resp := &gamehall.SCCreateRoom{
		GameId:       msg.GetGameId(),
		BaseCoin:     msg.GetBaseCoin(),
		SceneMode:    msg.GetSceneMode(),
		MaxPlayerNum: msg.GetMaxPlayerNum(),
		Params:       msg.GetParams(),
		OpRetCode:    code,
	}
	proto.SetDefaults(resp)
	p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_CREATEROOM), resp)
	return nil
}

func (this *CSCreateRoomHandler) ProcessThirteen(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	msg, ok := data.(*gamehall.CSCreateRoom)
	if !ok {
		return nil
	}

	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		return nil
	}

	var code gamehall.OpResultCode_Game
	var dbGameFree *server.DB_GameFree
	var dbGameRule *server.DB_GameRule
	var params = msg.GetParams()
	var baseScore = msg.GetBaseCoin()
	var sp ScenePolicy
	var gamefreeId = msg.GetId()
	var gps *webapi_proto.GameFree
	var maxPlayerNum = int(msg.GetMaxPlayerNum())
	var csp *CoinScenePool
	var roomId int
	var scene *Scene
	var gameId = gamefreeId / 10000
	var spd *ScenePolicyData

	gps = PlatformMgrSingleton.GetGameFree(p.Platform, gamefreeId)
	if gps == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, gamefreeId)
		goto failed
	}

	dbGameFree = gps.DbGameFree
	if dbGameFree == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, gamefreeId)
		goto failed
	}

	//检测房间状态是否开启
	if !PlatformMgrSingleton.CheckGameState(p.Platform, dbGameFree.Id) {
		code = gamehall.OpResultCode_Game_OPRC_GameHadClosed
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v GameHadClosed", p.SnId, gamefreeId)
		goto failed
	}

	dbGameRule = srvdata.PBDB_GameRuleMgr.GetData(dbGameFree.GetGameRule())
	if dbGameRule == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v gamerule not exist", p.SnId, gamefreeId)
		goto failed
	}

	sp = GetScenePolicy(int(gameId), 0)
	if sp == nil {
		code = gamehall.OpResultCode_Game_OPRC_GameNotExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameFreeId:%v not exist", p.SnId, gamefreeId)
		goto failed
	}
	spd, ok = sp.(*ScenePolicyData)
	if ok {
		//todo 参数校验
		_ = spd

	}
	if p.scene != nil {
		code = gamehall.OpResultCode_Game_OPRC_RoomHadExist_Game
		logger.Logger.Tracef("CSCreateRoomHandler had scene(%d)", p.scene.sceneId)
		goto failed
	}

	//创建房间
	csp = CoinSceneMgrSingleton.GetCoinScenePool(p.GetPlatform().IdStr, dbGameFree.GetId())
	roomId = SceneMgrSingleton.GenOneCoinSceneId()
	if roomId == common.RANDID_INVALID {
		code = gamehall.OpResultCode_Game_OPRC_AllocRoomIdFailed_Game
		logger.Logger.Tracef("CSCreateRoomHandler SnId:%v GameId:%v sceneId == -1 ", p.SnId, gameId)
		goto failed
	}
	scene, code = p.CreateLocalGameScene(roomId, int(gameId), int(dbGameFree.GetSceneType()), int(msg.GetSceneMode()),
		maxPlayerNum, params, dbGameFree, baseScore, csp.groupId)
	if scene != nil {
		if code == gamehall.OpResultCode_Game_OPRC_Sucess_Game {
			logger.Logger.Tracef("CSCreateRoomHandler SnId:%v Create Sucess GameId:%v", p.SnId, gameId)
			// try enter scene
			csp.scenes[scene.sceneId] = scene
			scene.csp = csp
			if !p.EnterScene(scene, true, -1) {
				code = gamehall.OpResultCode_Game_OPRC_Error_Game
			}
		}
	}

failed:
	resp := &gamehall.SCCreateRoom{
		GameId:       msg.GetGameId(),
		BaseCoin:     msg.GetBaseCoin(),
		SceneMode:    msg.GetSceneMode(),
		MaxPlayerNum: msg.GetMaxPlayerNum(),
		Params:       msg.GetParams(),
		OpRetCode:    code,
	}
	proto.SetDefaults(resp)
	p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_CREATEROOM), resp)
	return nil
}

// 观众坐下
type CSAudienceSitPacketFactory struct {
}
type CSAudienceSitHandler struct {
}

func (this *CSAudienceSitPacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSAudienceSit{}
	return pack
}

func (this *CSAudienceSitHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSAudienceSitHandler Process recv ", data)
	if msg, ok := data.(*gamehall.CSAudienceSit); ok {
		p := PlayerMgrSington.GetPlayer(sid)
		if p == nil {
			logger.Logger.Warn("CSAudienceSitHandler p == nil")
			return nil
		}
		if p.scene == nil {
			logger.Logger.Warn("CSAudienceSitHandler scene == nil")
			return nil
		}
		if int32(p.scene.sceneId) != msg.GetRoomId() {
			logger.Logger.Warn("CSAudienceSitHandler sceneId != roomId")
			return nil
		}
		newPlayer := PlayerMgrSington.GetPlayerBySnId(p.SnId)
		if newPlayer != nil {
			pack := &gamehall.SCAudienceSit{
				RoomId: proto.Int32(msg.GetRoomId()),
			}
			if !p.scene.IsTestScene() {
				// 入场限额检查
				limitCoin := srvdata.CreateRoomMgrSington.GetLimitCoinByBaseScore(int32(p.scene.gameId), int32(p.scene.gameSite), p.scene.BaseScore)
				if p.Coin < limitCoin {
					pack.OpCode = gamehall.OpResultCode_Game_OPRC_MoneyNotEnough_Game
					newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_AUDIENCESIT), pack)
					return nil
				}
			}
			// 是否还有空座位
			if p.scene.IsFull() {
				pack.OpCode = gamehall.OpResultCode_Game_OPRC_RoomIsFull_Game
				newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_AUDIENCESIT), pack)
				return nil
			}
			p.scene.AudienceSit(newPlayer, -1)
			pack.OpCode = gamehall.OpResultCode_Game_OPRC_Sucess_Game
			newPlayer.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_AUDIENCESIT), pack)
		}
	}
	return nil
}

// 我的游戏信息及平台公告
type CSRecordAndNoticePacketFactory struct {
}
type CSRecordAndNoticeHandler struct {
}

func (this *CSRecordAndNoticePacketFactory) CreatePacket() interface{} {
	pack := &gamehall.CSRecordAndNotice{}
	return pack
}

func (this *CSRecordAndNoticeHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error {
	logger.Logger.Trace("CSRecordAndNoticeHandler Process recv ", data)
	msg, ok := data.(*gamehall.CSRecordAndNotice)
	if !ok {
		return nil
	}

	p := PlayerMgrSington.GetPlayer(sid)
	if p == nil {
		logger.Logger.Warn("CSRecordAndNoticeHandler p == nil")
		return nil
	}

	pack := &gamehall.SCRecordAndNotice{
		OpCode: gamehall.OpResultCode_Game_OPRC_Sucess_Game,
	}

	switch msg.GetOpt() {
	case 0:
		// 公告
		list := PlatformMgrSingleton.GetCommonNotice(p.Platform)
		if list != nil {
			for _, v := range list.List {
				pack.List = append(pack.List, &gamehall.CommonNotice{
					Sort:         v.Sort,             // 排序 第几位
					Title:        v.Title,            // 标题
					Content:      v.Content,          // 内容
					TypeName:     v.TypeName,         // 大标题
					Type:         v.Type,             // 大标题类型
					StartTime:    int32(v.StartTime), // 开始显示时间
					EndTime:      int32(v.EndTime),   // 结束显示时间
					CategoryType: v.CategoryType,
					ImgUrl:       v.ImgUrl,
					NoticeId:     v.NoticeId,
					IsLoop:       v.IsLoop,
					LoopTime:     v.LoopTime,
				})
			}
		}
		p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_COMNOTICE), pack)
		logger.Logger.Trace("CSRecordAndNoticeHandler Process send ", pack)

	case 1:
		// 战绩日期列表
		task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
			gdi := model.GetPlayerExistListByTs(p.SnId, p.Platform, msg.StartTime, 7)
			return &gdi
		}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
			if data != nil && data.(*[]int64) != nil {
				gamets := data.(*[]int64)
				pack.GlistTs = append(pack.GlistTs, *gamets...)

			} else {
				pack.OpCode = gamehall.OpResultCode_Game_OPRC_Error_Game
			}
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_COMNOTICE), pack)
		}), "SCRecordAndNotice").Start()

	case 2:
		// 当日战绩
		starttime := msg.StartTime
		time := time.Unix(starttime, 0)
		endtime := time.AddDate(0, 0, 1).Unix() - 1 //23:59:59
		var list model.GamePlayerListType
		task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
			list = model.GetPlayerListByHallExAPI(p.SnId, p.Platform, starttime, endtime, int(msg.PageNo), int(msg.PageSize))
			return nil
		}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
			for _, v := range list.Data {
				pack.Glist = append(pack.Glist, &gamehall.PlayerRecord{
					GameFreeid:        v.GameFreeid,
					GameDetailedLogId: v.GameDetailedLogId,
					TotalIn:           v.TotalIn,
					TotalOut:          v.TotalOut,
					Ts:                v.Ts,
					MatchType:         proto.Int32(v.MatchType),
				})
			}
			p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SC_COMNOTICE), pack)
		}), "SCRecordAndNotice").Start()
	}

	return nil
}

func init() {
	// 观众进入房间
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_AUDIENCE_ENTERROOM), &CSAudienceEnterRoomHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_AUDIENCE_ENTERROOM), &CSEnterRoomPacketFactory{})
	// 返回房间
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_RETURNROOM), &CSReturnRoomHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_RETURNROOM), &CSReturnRoomPacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_JOINGAME), &CSJoinGameHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_JOINGAME), &CSJoinGamePacketFactory{})

	common.RegisterHandler(int(player.PlayerPacketID_PACKET_CS_GETDATALOG), &CSGetDataLogHandler{})
	netlib.RegisterFactory(int(player.PlayerPacketID_PACKET_CS_GETDATALOG), &CSGetDataLogPacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_ENTERTHRIDGAME), &CSEnterThridGameHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_ENTERTHRIDGAME), &CSEnterThridGamePacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_LEAVETHRIDGAME), &CSLeaveThridGameHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_LEAVETHRIDGAME), &CSLeaveThridGamePacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_THRIDGAMEBALANCEUPDATE), &CSThridBalanceRefreshHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_THRIDGAMEBALANCEUPDATE), &CSThridBalanceRefreshPacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_GETPRIVATEROOMHISTORY), &CSGetPrivateRoomHistoryHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_GETPRIVATEROOMHISTORY), &CSGetPrivateRoomHistoryPacketFactory{})

	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_LOTTERYLOG), &CSLotteryLogHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_LOTTERYLOG), &CSLotteryLogPacketFactory{})
	//获取指定游戏配置 包括分场信息
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_GETGAMECONFIG), &CSGetGameConfigHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_GETGAMECONFIG), &CSGetGameConfigPacketFactory{})
	//玩家进入游戏
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_ENTERGAME), &CSEnterGameHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_ENTERGAME), &CSEnterGamePacketFactory{})
	//玩家进入房间
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_ENTERROOM), &CSEnterRoomHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_ENTERROOM), &CSEnterRoomPacketFactory{})
	//玩家退出游戏
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_QUITGAME), &CSQuitGameHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_QUITGAME), &CSQuitGamePacketFactory{})
	//创建房间
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_CREATEROOM), &CSCreateRoomHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_CREATEROOM), &CSCreateRoomPacketFactory{})
	//查询公共房间列表
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_QUERYROOMINFO), &CSQueryRoomInfoHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_QUERYROOMINFO), &CSQueryRoomInfoPacketFactory{})
	//观众坐下
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_AUDIENCESIT), &CSAudienceSitHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_AUDIENCESIT), &CSAudienceSitPacketFactory{})
	//我的游戏信息及平台公告
	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_COMNOTICE), &CSRecordAndNoticeHandler{})
	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_COMNOTICE), &CSRecordAndNoticePacketFactory{})
}
