game_sync/worldsrv/coinscenepool_base.go

259 lines
7.0 KiB
Go

package main
import (
"sort"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/game/common"
"mongo.games.com/game/model"
"mongo.games.com/game/protocol/gamehall"
)
const (
MatchTrueManForbid int32 = -1 //禁止匹配真人
MatchTrueManPriority = 1 //优先匹配真人
)
type BaseCoinScenePool struct {
}
func (this *BaseCoinScenePool) New() interface{} {
return nil
}
// CanEnter 检查入场条件
func (this *BaseCoinScenePool) CanEnter(pool *CoinScenePool, p *Player) gamehall.OpResultCode {
// 具体场次的入场规则
canEnterFunc := GetCoinSceneCanEnterFunc(int(pool.dbGameFree.GetGameId()))
if canEnterFunc != nil {
ret := canEnterFunc(pool, p)
if ret != gamehall.OpResultCode_OPRC_Sucess {
return ret
}
}
// 通用入场检测
if pool.dbGameFree.GetLimitCoin() != 0 && int64(pool.dbGameFree.GetLimitCoin()) > p.Coin {
return gamehall.OpResultCode_OPRC_CoinNotEnough
}
if pool.dbGameFree.GetMaxCoinLimit() != 0 && int64(pool.dbGameFree.GetMaxCoinLimit()) < p.Coin && !p.IsRob {
return gamehall.OpResultCode_OPRC_CoinTooMore
}
return gamehall.OpResultCode_OPRC_Sucess
}
func (this *BaseCoinScenePool) CanAudienceEnter(pool *CoinScenePool, p *Player) gamehall.OpResultCode {
return gamehall.OpResultCode_OPRC_Sucess
}
// PlayerEnter 玩家进入房间池
func (this *BaseCoinScenePool) PlayerEnter(pool *CoinScenePool, p *Player, exclude []int32, ischangeroom bool) (ret gamehall.OpResultCode, scene *Scene) {
// 配房规则
// 如果全局为限制则看具体的游戏是否限制,如果全局为不限制则不考虑具体的游戏。
sameIpLimit := !model.GameParamData.SameIpNoLimit
if sameIpLimit && pool.dbGameFree.GetSameIpLimit() == 0 {
sameIpLimit = false
}
// 通用匹配规则过滤
matchTrueManRule := pool.dbGameFree.GetMatchTrueMan()
scenes := make(map[int]*Scene)
for sceneId, s := range pool.scenes {
if s == nil || s.IsFull() || s.deleting {
continue
}
if !common.Config.IsDevMode {
// 禁止真人匹配
if matchTrueManRule == MatchTrueManForbid && !p.IsRob && s.GetTruePlayerCnt() != 0 {
continue
}
// 排除不能进的房间
if common.InSliceInt32(exclude, int32(s.sceneId)) {
continue
}
// 规避同ip的用户在一个房间内(GM除外)
if sameIpLimit && p.GMLevel == 0 && s.HasSameIp(p.Ip) {
continue
}
// 多少局只能禁止再配对
if s.dbGameFree.GetSamePlaceLimit() > 0 && sceneLimitMgr.LimitSamePlace(p, s) {
continue
}
// 牌局开始后禁止进入
if sp, ok := s.sp.(*ScenePolicyData); ok {
if s.starting && !sp.EnterAfterStart {
continue
}
}
}
scenes[sceneId] = s
}
//优先黑白名单
if scene == nil && len(scenes) != 0 {
gameId := pool.dbGameFree.GetGameId()
if p.WBLevel < 0 { //黑名单玩家
var cntWhite int
var cntLose int
var whiteScene *Scene
var loseScene *Scene
for _, s := range scenes {
if s != nil {
if sceneLimitMgr.LimitAvgPlayer(s, len(pool.players)) {
continue
}
cnt := s.GetWhitePlayerCnt()
if cnt > cntWhite {
cntWhite = cnt
whiteScene = s
}
cnt = s.GetLostPlayerCnt()
if cnt > cntLose {
cntLose = cnt
loseScene = s
}
}
}
if whiteScene != nil {
scene = whiteScene
} else if loseScene != nil {
scene = loseScene
}
} else if p.WBLevel > 0 { //白名单玩家
var cntBlack int
var cntWin int
var blackScene *Scene
var winScene *Scene
for _, s := range scenes {
if s != nil {
if sceneLimitMgr.LimitAvgPlayer(s, len(pool.players)) {
continue
}
cnt := s.GetBlackPlayerCnt()
if cnt > cntBlack {
cntBlack = cnt
blackScene = s
}
cnt = s.GetWinPlayerCnt()
if cnt > cntWin {
cntWin = cnt
winScene = s
}
}
}
if blackScene != nil {
scene = blackScene
} else if winScene != nil {
scene = winScene
}
} else { //按类型匹配
//优先真人
if scene == nil && len(scenes) != 0 && matchTrueManRule == MatchTrueManPriority {
var selScene []*Scene
for _, value := range scenes {
if value != nil {
if value.GetTruePlayerCnt() > 0 && !value.IsFull() && !value.deleting {
selScene = append(selScene, value)
}
}
}
if len(selScene) > 0 {
sort.Slice(selScene, func(i, j int) bool {
return selScene[i].GetTruePlayerCnt() > selScene[j].GetTruePlayerCnt()
})
scene = selScene[0]
}
}
if scene == nil && len(scenes) != 0 {
//1.其次游戏的配桌规则
if scene == nil {
matchFunc := GetCoinSceneMatchFunc(int(gameId))
if matchFunc != nil {
scene = matchFunc(pool, p, scenes, sameIpLimit, exclude)
return gamehall.OpResultCode_OPRC_Sucess, scene
}
}
}
}
// 随机
if scene == nil {
for _, v := range scenes {
scene = v
break
}
}
}
return gamehall.OpResultCode_OPRC_Sucess, scene
}
func (this *BaseCoinScenePool) AudienceEnter(pool *CoinScenePool, p *Player, exclude []int32, ischangeroom bool) (ret gamehall.OpResultCode, scene *Scene) {
for _, s := range pool.scenes {
if s != nil && len(s.players) != 0 && !s.deleting && !common.InSliceInt32(exclude, int32(s.sceneId)) {
scene = s
break
}
}
return gamehall.OpResultCode_OPRC_Sucess, scene
}
func (this *BaseCoinScenePool) OnPlayerEnter(pool *CoinScenePool, p *Player, scene *Scene) {}
func (this *BaseCoinScenePool) PlayerLeave(pool *CoinScenePool, p *Player, reason int) bool {
return true
}
func (this *BaseCoinScenePool) AudienceLeave(pool *CoinScenePool, p *Player, reason int) bool {
return true
}
func (this *BaseCoinScenePool) OnPlayerLeave(pool *CoinScenePool, s *Scene, p *Player) {}
func (this *BaseCoinScenePool) NewScene(pool *CoinScenePool, p *Player) *Scene {
gameId := int(pool.dbGameRule.GetGameId())
gs := GameSessMgrSington.GetMinLoadSess(gameId)
if gs == nil {
logger.Logger.Errorf("Get %v game min session failed.", gameId)
return nil
}
gameMode := pool.dbGameRule.GetGameMode()
params := common.CopySliceInt32ToInt64(pool.dbGameRule.GetParams())
var platformName string
limitPlatform := PlatformMgrSingleton.GetPlatform(pool.platform)
if limitPlatform == nil || !limitPlatform.Isolated {
limitPlatform = PlatformMgrSingleton.GetPlatform(DefaultPlatform)
platformName = DefaultPlatform
} else {
platformName = limitPlatform.IdStr
}
sceneId := SceneMgrSingleton.GenOneCoinSceneId()
scene := SceneMgrSingleton.CreateScene(0, 0, sceneId, gameId, int(gameMode), int(common.SceneMode_Public),
1, -1, params, gs, limitPlatform, pool.groupId, pool.dbGameFree, int32(pool.id))
if scene != nil {
scene.hallId = pool.id
scene.csp = pool
if pool.groupId != 0 {
CoinSceneMgrSingleton.groupOfScene[int32(sceneId)] = pool.groupId
} else {
CoinSceneMgrSingleton.platformOfScene[int32(sceneId)] = platformName
}
return scene
}
return nil
}
func (this *BaseCoinScenePool) NewPreCreateScene(pool *CoinScenePool) *Scene {
return this.NewScene(pool, nil)
}
func (this *BaseCoinScenePool) OnDestroyScene(pool *CoinScenePool, sceneId int) {}