423 lines
11 KiB
Go
423 lines
11 KiB
Go
package main
|
|
|
|
import (
|
|
"math/rand"
|
|
"time"
|
|
|
|
"mongo.games.com/goserver/core/logger"
|
|
"mongo.games.com/goserver/core/module"
|
|
|
|
"mongo.games.com/game/common"
|
|
"mongo.games.com/game/model"
|
|
"mongo.games.com/game/proto"
|
|
gamehallproto "mongo.games.com/game/protocol/gamehall"
|
|
serverproto "mongo.games.com/game/protocol/server"
|
|
"mongo.games.com/game/protocol/webapi"
|
|
"mongo.games.com/game/srvdata"
|
|
)
|
|
|
|
const (
|
|
HundredSceneOPEnter int32 = iota //进入
|
|
HundredSceneOPLeave //离开
|
|
HundredSceneOPChange //换桌
|
|
)
|
|
|
|
var HundredSceneMgrSingleton = &HundredSceneMgr{
|
|
scenesOfPlatform: make(map[string]map[int32]*Scene),
|
|
}
|
|
|
|
type HundredSceneMgr struct {
|
|
scenesOfPlatform map[string]map[int32]*Scene // platform:gamefreeid:房间
|
|
}
|
|
|
|
// PlayerEnter 玩家进入场次
|
|
// id 场次id
|
|
func (this *HundredSceneMgr) PlayerEnter(p *Player, id int32) gamehallproto.OpResultCode_Hundred {
|
|
logger.Logger.Tracef("HundredSceneMgr PlayerEnter snid:%v gamefreeid:%v", p.SnId, id)
|
|
if p.isDelete {
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_RoomHadClosed_Hundred
|
|
}
|
|
|
|
if this.InHundredScene(p) {
|
|
logger.Logger.Warnf("HundredSceneMgr PlayerEnter snid:%v find in gamefreeid:%v roomId:%v", p.SnId, p.scene.dbGameFree.Id, p.scene.sceneId)
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_Error_Hundred
|
|
}
|
|
|
|
//多平台支持
|
|
platform := p.GetPlatform()
|
|
if platform == nil {
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_RoomHadClosed_Hundred
|
|
}
|
|
|
|
gps := PlatformMgrSingleton.GetGameFree(platform.IdStr, id)
|
|
if gps == nil {
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_RoomHadClosed_Hundred
|
|
}
|
|
|
|
//没有场景,尝试创建
|
|
if _, ok := this.scenesOfPlatform[platform.IdStr]; !ok {
|
|
this.scenesOfPlatform[platform.IdStr] = make(map[int32]*Scene)
|
|
}
|
|
ss := this.scenesOfPlatform[platform.IdStr]
|
|
if s, ok := ss[id]; !ok || s == nil {
|
|
s = this.CreateNewScene(id, gps.GroupId, platform, gps.DbGameFree)
|
|
if s != nil {
|
|
ss[id] = s
|
|
s.hp = this
|
|
logger.Logger.Infof("HundredSceneMgr PlayerEnter(platform=%v snid=%v) Create %v scene success.", platform.IdStr, p.SnId, id)
|
|
} else {
|
|
logger.Logger.Errorf("HundredSceneMgr PlayerEnter(platform=%v snid=%v) Create %v scene failed.", platform.IdStr, p.SnId, id)
|
|
}
|
|
}
|
|
//尝试进入
|
|
if s, ok := ss[id]; ok && s != nil {
|
|
if s.PlayerEnter(p, -1, true) {
|
|
logger.Logger.Infof("HundredSceneMgr PlayerEnter(platform=%v snid=%v) enter %v scene success.", platform.IdStr, p.SnId, id)
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_Sucess_Hundred
|
|
} else {
|
|
logger.Logger.Errorf("HundredSceneMgr PlayerEnter(platform=%v snid=%v) enter %v scene failed.", platform.IdStr, p.SnId, id)
|
|
}
|
|
} else {
|
|
logger.Logger.Errorf("HundredSceneMgr PlayerEnter(platform=%v) get %v scene failed.", platform.IdStr, id)
|
|
}
|
|
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_SceneServerMaintain_Hundred
|
|
}
|
|
|
|
// PlayerLeave 离开房间
|
|
// 游戏服通知玩家离开房间
|
|
func (this *HundredSceneMgr) PlayerLeave(p *Player, reason int) bool {
|
|
if p == nil || p.scene == nil || p.scene.hp == nil {
|
|
return false
|
|
}
|
|
|
|
p.scene.PlayerLeave(p, reason)
|
|
|
|
return false
|
|
}
|
|
|
|
// PlayerTryLeave 玩家尝试离开房间
|
|
// 给游戏服发离开消息
|
|
func (this *HundredSceneMgr) PlayerTryLeave(p *Player) gamehallproto.OpResultCode_Hundred {
|
|
if !this.InHundredScene(p) {
|
|
logger.Logger.Tracef("(this *HundredSceneMgr) PlayerTryLeave !csm.InCoinScene(p) snid:%v ", p.SnId)
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_Sucess_Hundred
|
|
}
|
|
|
|
pack := &gamehallproto.CSLeaveRoom{Mode: proto.Int(0)}
|
|
common.TransmitToServer(p.sid, int(gamehallproto.GameHallPacketID_PACKET_CS_LEAVEROOM), pack, p.scene.gameSess.Session)
|
|
return gamehallproto.OpResultCode_Hundred_OPRC_Sucess_Hundred // ???
|
|
}
|
|
|
|
// OnDestroyScene 房间销毁
|
|
func (this *HundredSceneMgr) OnDestroyScene(sceneId int) {
|
|
s := SceneMgrSingleton.GetScene(sceneId)
|
|
if s == nil {
|
|
return
|
|
}
|
|
plt := SceneMgrSingleton.GetPlatformBySceneId(sceneId)
|
|
if plt == "" {
|
|
return
|
|
}
|
|
if ss, ok := this.scenesOfPlatform[plt]; ok {
|
|
for id, scene := range ss {
|
|
if scene.sceneId == sceneId {
|
|
if scene != s {
|
|
logger.Logger.Errorf("bug")
|
|
}
|
|
|
|
//删除玩家
|
|
for _, v := range scene.players {
|
|
if v != nil {
|
|
if !v.IsRob {
|
|
ctx := scene.GetPlayerGameCtx(v.SnId)
|
|
if ctx != nil {
|
|
//发送一个探针,等待ack后同步金币
|
|
v.TryRetrieveLostGameCoin(sceneId)
|
|
logger.Logger.Warnf("(this *HundredSceneMgr) OnDestroyScene(sceneid:%v) snid:%v SyncGameCoin", sceneId, v.SnId)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
scene.hp = nil
|
|
delete(ss, id)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
this.tryCreateRoom(plt, s.dbGameFree.Id)
|
|
}
|
|
|
|
func (this *HundredSceneMgr) GetPlayerNums(p *Player, gameId, gameMode int32) []int32 {
|
|
//多平台支持
|
|
platform := p.GetPlatform()
|
|
var nums [10]int32
|
|
wantNum := [10]int32{80, 50, 30, 20, 10, 10, 10, 10, 10, 10}
|
|
for i := 0; i < 10; i++ {
|
|
if wantNum[i]/2 > 0 {
|
|
nums[i] = rand.Int31n(wantNum[i]/2) + wantNum[i]
|
|
}
|
|
}
|
|
if platform == nil {
|
|
return nums[:]
|
|
}
|
|
ids, _ := srvdata.GameFreeMgr.GetGameFreeIds(gameId, gameMode)
|
|
for _, id := range ids {
|
|
gps := PlatformMgrSingleton.GetGameFree(platform.IdStr, id)
|
|
if gps != nil {
|
|
if ss, ok := this.scenesOfPlatform[platform.IdStr]; ok {
|
|
if s, exist := ss[id]; exist && s.dbGameFree != nil {
|
|
sceneType := s.dbGameFree.GetSceneType() - 1
|
|
if sceneType >= 0 && int(sceneType) < len(nums) {
|
|
nums[sceneType] += int32(s.GetPlayerCnt())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(ids) <= 10 {
|
|
return nums[:len(ids)]
|
|
}
|
|
return nums[:]
|
|
}
|
|
|
|
func (this *HundredSceneMgr) InHundredScene(p *Player) bool {
|
|
if p == nil {
|
|
return false
|
|
}
|
|
if p.scene == nil {
|
|
return false
|
|
}
|
|
if p.scene.hp == nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (this *HundredSceneMgr) CreateNewScene(id, groupId int32, limitPlatform *Platform, dbGameFree *serverproto.DB_GameFree) *Scene {
|
|
if dbGameFree != nil {
|
|
dbGameRule := srvdata.PBDB_GameRuleMgr.GetData(dbGameFree.GetGameRule())
|
|
if dbGameRule != nil {
|
|
gameId := int(dbGameRule.GetGameId())
|
|
sceneId := SceneMgrSingleton.GenOneHundredSceneId()
|
|
params := common.CopySliceInt32ToInt64(dbGameRule.GetParams())
|
|
scene := SceneMgrSingleton.CreateScene(&CreateSceneParam{
|
|
RoomId: sceneId,
|
|
SceneMode: common.SceneMode_Public,
|
|
Params: params,
|
|
Platform: limitPlatform,
|
|
GF: dbGameFree,
|
|
})
|
|
if scene != nil {
|
|
logger.Logger.Infof("Create hundred scene %v-%v success.", gameId, sceneId)
|
|
scene.hp = this
|
|
return scene
|
|
} else {
|
|
logger.Logger.Errorf("Create hundred scene %v-%v failed.", gameId, sceneId)
|
|
}
|
|
} else {
|
|
logger.Logger.Errorf("Game rule data %v no found.", dbGameFree.GetGameRule())
|
|
}
|
|
} else {
|
|
logger.Logger.Errorf("Game free data %v no found.", id)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *HundredSceneMgr) tryCreateRoom(plt string, id ...int32) {
|
|
limitPlatform := PlatformMgrSingleton.GetPlatform(plt)
|
|
if limitPlatform == nil || !limitPlatform.Isolated {
|
|
limitPlatform = PlatformMgrSingleton.GetPlatform(DefaultPlatform)
|
|
}
|
|
if this.scenesOfPlatform[plt] == nil {
|
|
this.scenesOfPlatform[plt] = make(map[int32]*Scene)
|
|
}
|
|
if limitPlatform.IdStr == DefaultPlatform {
|
|
return
|
|
}
|
|
|
|
f := func(i int32) {
|
|
if this.scenesOfPlatform[plt][i] != nil {
|
|
return
|
|
}
|
|
gps := PlatformMgrSingleton.GetGameFree(plt, i)
|
|
if !common.IsHundredType(gps.GetDbGameFree().GetGameType()) {
|
|
return
|
|
}
|
|
scene := this.CreateNewScene(i, gps.GroupId, limitPlatform, gps.DbGameFree)
|
|
if scene != nil {
|
|
this.scenesOfPlatform[plt][i] = scene
|
|
scene.hp = this
|
|
logger.Logger.Infof("HundredSceneMgr PreCreateRoom Platform:%v Id:%v", plt, i)
|
|
}
|
|
}
|
|
|
|
if len(id) == 0 {
|
|
// 所有百人场
|
|
for _, vv := range srvdata.PBDB_GameFreeMgr.Datas.GetArr() {
|
|
f(vv.GetId())
|
|
}
|
|
} else {
|
|
for _, v := range id {
|
|
f(v)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TryCreateRoom 预创建房间
|
|
func (this *HundredSceneMgr) TryCreateRoom() {
|
|
if !model.GameParamData.HundredScenePreCreate {
|
|
return
|
|
}
|
|
|
|
for _, v := range PlatformMgrSingleton.GetPlatforms() {
|
|
this.tryCreateRoom(v.IdStr)
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformChangeIsolated(p *Platform, isolated bool) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
if isolated { //孤立
|
|
this.OnPlatformCreate(p) //预创建场景
|
|
} else {
|
|
this.OnPlatformDestroy(p)
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) GetPlatformSceneByGameFreeId(platform string, gameFreeIds []int32) []*Scene {
|
|
platformName := DefaultPlatform
|
|
platformData := PlatformMgrSingleton.GetPlatform(platform)
|
|
if platformData != nil && platformData.Isolated {
|
|
platformName = platformData.IdStr
|
|
} else if platform != DefaultPlatform {
|
|
platformData = PlatformMgrSingleton.GetPlatform(DefaultPlatform)
|
|
}
|
|
|
|
if platformData == nil {
|
|
return nil
|
|
}
|
|
|
|
var scenes []*Scene
|
|
for _, id := range gameFreeIds {
|
|
gps := PlatformMgrSingleton.GetGameFree(platformData.IdStr, id)
|
|
if gps != nil {
|
|
if ss, ok := this.scenesOfPlatform[platformName]; ok {
|
|
if s, exist := ss[id]; exist && s != nil {
|
|
scenes = append(scenes, s)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return scenes
|
|
}
|
|
|
|
func (this *HundredSceneMgr) GetPlatformScene(platform string, gameId int32) []*Scene {
|
|
gameFreeIds := gameStateMgr.gameIds[gameId]
|
|
gameScenes := this.GetPlatformSceneByGameFreeId(platform, gameFreeIds)
|
|
if len(gameScenes) != len(gameFreeIds) {
|
|
var createIds []int32
|
|
for _, gfi := range gameFreeIds {
|
|
bFind := false
|
|
for _, s := range gameScenes {
|
|
if s.dbGameFree.GetId() == gfi {
|
|
bFind = true
|
|
break
|
|
}
|
|
}
|
|
if !bFind {
|
|
createIds = append(createIds, gfi)
|
|
}
|
|
}
|
|
if len(createIds) > 0 {
|
|
this.tryCreateRoom(platform, createIds...)
|
|
gameScenes = this.GetPlatformSceneByGameFreeId(platform, gameFreeIds)
|
|
}
|
|
}
|
|
return gameScenes
|
|
}
|
|
|
|
func (this *HundredSceneMgr) ModuleName() string {
|
|
return "HundredSceneMgr"
|
|
}
|
|
|
|
func (this *HundredSceneMgr) Init() {
|
|
//this.TryCreateRoom()
|
|
}
|
|
|
|
func (this *HundredSceneMgr) Update() {
|
|
|
|
}
|
|
|
|
func (this *HundredSceneMgr) Shutdown() {
|
|
module.UnregisteModule(this)
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformCreate(p *Platform) {
|
|
if model.GameParamData.HundredScenePreCreate {
|
|
this.tryCreateRoom(p.IdStr)
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformDestroy(p *Platform) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
if ss, ok := this.scenesOfPlatform[p.IdStr]; ok {
|
|
var ids []int
|
|
for _, scene := range ss {
|
|
ids = append(ids, scene.sceneId)
|
|
}
|
|
SceneMgrSingleton.SendGameDestroy(ids, true)
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformChangeDisabled(p *Platform, disabled bool) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
if disabled {
|
|
this.OnPlatformDestroy(p)
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformGameFreeUpdate(p *Platform, oldCfg, newCfg *webapi.GameFree) {
|
|
if p == nil || newCfg == nil {
|
|
return
|
|
}
|
|
if scenes, exist := this.scenesOfPlatform[p.IdStr]; exist {
|
|
if s, ok := scenes[newCfg.DbGameFree.Id]; ok {
|
|
s.SendGameDestroy(false)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnGameGroupUpdate(oldCfg, newCfg *webapi.GameConfigGroup) {
|
|
|
|
}
|
|
|
|
func (this *HundredSceneMgr) OnPlatformDestroyByGameFreeId(p *Platform, gameFreeId int32) {
|
|
if p == nil {
|
|
return
|
|
}
|
|
if scenes, ok := this.scenesOfPlatform[p.IdStr]; ok {
|
|
var ids []int
|
|
for _, scene := range scenes {
|
|
if scene.dbGameFree.Id == gameFreeId {
|
|
ids = append(ids, scene.sceneId)
|
|
}
|
|
}
|
|
SceneMgrSingleton.SendGameDestroy(ids, true)
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
module.RegisteModule(HundredSceneMgrSingleton, time.Second*5, 0)
|
|
PlatformMgrSingleton.RegisterObserver(HundredSceneMgrSingleton)
|
|
PlatformGameGroupMgrSington.RegisteObserver(HundredSceneMgrSingleton)
|
|
}
|