game_sync/worldsrv/customroommgr.go

360 lines
9.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"slices"
"time"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/module"
"mongo.games.com/goserver/core/timer"
"mongo.games.com/game/common"
"mongo.games.com/game/model"
"mongo.games.com/game/protocol/gamehall"
"mongo.games.com/game/protocol/server"
)
func init() {
RegisteGameSessionListener(CustomRoomMgrSingle)
module.RegisteModule(CustomRoomMgrSingle, time.Second*3, 0)
}
var CustomRoomMgrSingle = &CustomRoomMgr{
data: make(map[string]*CustomMgr),
list: make(map[string]map[int32]struct{}),
}
type CustomRoomInfo struct {
Platform string
SystemConfigId int32
Handle timer.TimerHandle
*gamehall.PrivateRoomInfo
*Scene
}
func (c *CustomRoomInfo) Notify(tp common.ListOpType) {
if c.PrivateRoomInfo == nil || c.Scene != nil {
return
}
pack := &gamehall.SCGetPrivateRoomList{
Tp: int32(tp),
Datas: []*gamehall.PrivateRoomInfo{c.PrivateRoomInfo},
}
PlayerNotifySingle.SendToClient(common.NotifyPrivateRoomList, c.Platform, int(gamehall.GameHallPacketID_PACKET_SC_GETPRIVATEROOMLIST), pack)
logger.Logger.Tracef("CustomRoomInfo NotifyPrivateRoom: %v", pack)
}
type CustomMgr struct {
List map[int32]*CustomRoomInfo // 满人房间假数据
DestroyTime map[int32]time.Time // 空房间最后解散时间配置id:解散时间
}
type CustomRoomMgr struct {
common.BaseClockSinker
data map[string]*CustomMgr
list map[string]map[int32]struct{}
}
func (c *CustomRoomMgr) ModuleName() string {
return "CustomRoomMgr"
}
func (c *CustomRoomMgr) Init() {
}
func (c *CustomRoomMgr) Update() {
for k, v := range c.list {
for kk := range v {
c.tryCreate(k, kk)
}
}
c.list = make(map[string]map[int32]struct{})
}
func (c *CustomRoomMgr) Shutdown() {
module.UnregisteModule(c)
}
func (c *CustomRoomMgr) OnGameSessionRegiste(session *GameSession) {
for _, v := range PlatformMgrSingleton.GetPlatforms() {
if v == nil {
continue
}
plt := PlatformMgrSingleton.GetPlatform(v.IdStr)
if plt == nil {
continue
}
for _, info := range PlatformMgrSingleton.GetConfig(plt.IdStr).RoomConfigSystem {
if info == nil {
continue
}
gf := PlatformMgrSingleton.GetGameFree(plt.IdStr, info.GetGameFreeId())
if gf == nil || !gf.GetStatus() || info.GetOn() == common.Off {
continue
}
roomConfig := PlatformMgrSingleton.GetConfig(plt.IdStr).RoomConfig[info.GetRoomConfigId()]
if roomConfig == nil || roomConfig.GetOn() == common.Off {
return
}
if len(session.gameIds) == 0 || slices.Contains(session.gameIds, gf.GetDbGameFree().GetGameId()) {
c.TouchCreate(plt.IdStr, info.GetId())
}
}
}
}
func (c *CustomRoomMgr) OnGameSessionUnregiste(session *GameSession) {
}
func (c *CustomRoomMgr) TouchCreate(plt string, configId int32) {
m := c.list[plt]
if m == nil {
m = make(map[int32]struct{})
c.list[plt] = m
}
c.list[plt][configId] = struct{}{}
}
func (c *CustomRoomMgr) GetRoomList(plt string) []*gamehall.PrivateRoomInfo {
d := c.data[plt]
if d == nil {
return nil
}
var ret []*gamehall.PrivateRoomInfo
for _, v := range d.List {
if v == nil || v.PrivateRoomInfo == nil {
continue
}
if !PlatformMgrSingleton.CustomIsOn(plt, v.RoomConfigId) {
continue
}
ret = append(ret, v.PrivateRoomInfo)
}
return ret
}
func (c *CustomRoomMgr) tryCreate(plt string, configId int32) {
logger.Logger.Debugf("尝试创建竞技馆系统房间 %v CloseCustomRoomCreate:%v", configId, model.GameParamData.CloseCustomRoomCreate)
cfg := PlatformMgrSingleton.GetConfig(plt).RoomConfigSystem[configId]
if model.GameParamData.CloseCustomRoomCreate || cfg == nil || cfg.GetOn() == common.Off {
return
}
c.TryDestroy(plt, configId)
m := c.data[plt]
if m == nil {
m = &CustomMgr{
List: make(map[int32]*CustomRoomInfo),
DestroyTime: make(map[int32]time.Time),
}
c.data[plt] = m
}
_, ok := m.List[cfg.GetId()]
if ok {
return
}
c.UpdateCreate(plt, cfg.GetId(), true)
}
func (c *CustomRoomMgr) TryDestroy(plt string, configId int32) {
logger.Logger.Debugf("尝试解散竞技馆系统房间 %v", configId)
cfg := PlatformMgrSingleton.GetConfig(plt).RoomConfigSystem[configId]
if cfg == nil {
return
}
v, ok := c.data[plt]
if !ok || v == nil {
return
}
info := v.List[configId]
if info != nil {
timer.StopTimer(info.Handle)
if info.Scene != nil && !info.deleting {
info.SendGameDestroy(true)
}
if info.Scene == nil {
c.Release(plt, configId)
}
}
if cfg.GetState() == 2 { // 假房间立刻删除
c.Release(plt, configId)
}
}
func (c *CustomRoomMgr) Release(plt string, configId int32) {
logger.Logger.Debugf("释放竞技馆房间创建记录 %v", configId)
v, ok := c.data[plt]
if !ok || v == nil {
return
}
info := v.List[configId]
if info != nil {
timer.StopTimer(info.Handle)
info.Notify(common.ListDel)
}
delete(v.List, configId)
v.DestroyTime[configId] = time.Now()
}
func (c *CustomRoomMgr) UpdateCreate(plt string, configId int32, mustCreate bool) {
cfg := PlatformMgrSingleton.GetConfig(plt).RoomConfigSystem[configId]
if cfg == nil {
return
}
gf := PlatformMgrSingleton.GetGameFree(plt, cfg.GetGameFreeId())
if gf == nil || !gf.GetStatus() || cfg.GetOn() == common.Off {
// 游戏没开
return
}
roomConfig := PlatformMgrSingleton.GetConfig(plt).RoomConfig[cfg.GetRoomConfigId()]
if roomConfig == nil || roomConfig.GetOn() == common.Off {
return
}
m := c.data[plt]
if m == nil {
m = &CustomMgr{
List: make(map[int32]*CustomRoomInfo),
DestroyTime: make(map[int32]time.Time),
}
c.data[plt] = m
}
_, ok := m.List[cfg.GetId()]
if ok {
return
}
info := &CustomRoomInfo{
Platform: plt,
SystemConfigId: cfg.GetId(),
}
m.List[cfg.GetId()] = info
destroyTime := m.DestroyTime[cfg.GetId()]
subTime := time.Duration(0)
if !destroyTime.IsZero() {
subTime = time.Duration(cfg.GetAutoCreateTime())*time.Second - time.Now().Sub(destroyTime)
}
if subTime < 0 || mustCreate {
subTime = 0
}
f := func(fn func()) {
b, _ := timer.AfterTimer(func(h timer.TimerHandle, ud interface{}) bool {
fn()
return true
}, nil, subTime)
m.List[cfg.GetId()].Handle = b
}
if cfg.GetAutoCreate() == 1 || mustCreate {
logger.Logger.Debugf("Update 竞技馆系统房间创建 %v", configId)
f(func() {
gf = PlatformMgrSingleton.GetGameFree(plt, cfg.GetGameFreeId())
if gf == nil || !gf.GetStatus() || cfg.GetOn() == common.Off {
c.Release(plt, cfg.GetId())
return
}
roomConfig = PlatformMgrSingleton.GetConfig(plt).RoomConfig[cfg.GetRoomConfigId()]
if roomConfig == nil || roomConfig.GetOn() == common.Off {
c.Release(plt, cfg.GetId())
return
}
cfg = PlatformMgrSingleton.GetConfig(plt).RoomConfigSystem[configId]
if cfg == nil || cfg.GetOn() == common.Off {
c.Release(plt, cfg.GetId())
return
}
switch cfg.GetState() {
case 1: // 系统房间
csp := CoinSceneMgrSingleton.GetCoinScenePool(cfg.GetPlatform(), cfg.GetGameFreeId())
roomId := SceneMgrSingleton.GenOnePrivateSceneId()
scene := SceneMgrSingleton.CreateScene(&CreateSceneParam{
CreateId: 0,
RoomId: roomId,
SceneMode: common.SceneModePrivateMatch,
TotalRound: int(cfg.GetRound()),
Params: common.CopySliceInt32ToInt64(csp.dbGameRule.GetParams()),
Platform: PlatformMgrSingleton.GetPlatform(cfg.GetPlatform()),
GF: csp.dbGameFree,
PlayerNum: cfg.GetPlayerNum(),
Channel: roomConfig.GetOnChannelName(),
CustomParam: &server.CustomParam{
RoomTypeId: roomConfig.GetRoomType(),
RoomConfigId: roomConfig.GetId(),
CostType: 1,
Voice: cfg.GetVoice(),
Price: roomConfig.GetPrice(),
ImageURL: roomConfig.GetImageURI(),
},
RoomConfigSystem: cfg,
IsRecruit: true,
})
if scene != nil {
logger.Logger.Debugf("竞技馆系统房间创建成功 roomId:%v", scene.sceneId)
csp.AddScene(scene)
info.Scene = scene
} else {
logger.Logger.Warnf("竞技馆系统房间创建失败 roomConfigSystemId:%v", cfg.GetId())
c.Release(plt, cfg.GetId())
}
default: // 假房间
roomId := SceneMgrSingleton.GenOnePrivateSceneId()
info.PrivateRoomInfo = &gamehall.PrivateRoomInfo{
GameFreeId: cfg.GetGameFreeId(),
GameId: gf.GetDbGameFree().GetGameId(),
RoomTypeId: roomConfig.GetRoomType(),
RoomConfigId: roomConfig.GetId(),
RoomId: int32(roomId),
NeedPassword: 0,
CurrRound: int32(common.RandInt(1, int(cfg.GetRound()))),
MaxRound: cfg.GetRound(),
CurrNum: cfg.GetPlayerNum(),
MaxPlayer: cfg.GetPlayerNum(),
CreateTs: time.Now().Unix(),
State: 1,
CostType: 1,
}
for i := 0; i < int(cfg.GetPlayerNum()); i++ {
info.PrivateRoomInfo.Players = append(info.PrivateRoomInfo.Players, &gamehall.PrivatePlayerInfo{
SnId: 0,
Name: "",
UseRoleId: common.RandInt32Slice(common.RolesIDs),
})
}
info.Notify(common.ListAdd)
logger.Logger.Debugf("竞技馆假房间创建成功 %v", info.PrivateRoomInfo)
if cfg.FullTime <= 0 {
cfg.FullTime = int32(model.GameParamData.SceneMaxIdle)
}
if cfg.FullTime < 3 {
cfg.FullTime = 3 // 至少3秒
}
b, _ := timer.AfterTimer(func(h timer.TimerHandle, ud interface{}) bool {
logger.Logger.Debugf("竞技馆假房间解散 %v", info)
c.Release(plt, configId)
c.UpdateCreate(plt, configId, false)
return true
}, nil, time.Duration(cfg.GetFullTime())*time.Second)
info.Handle = b
}
})
}
}