352 lines
9.2 KiB
Go
352 lines
9.2 KiB
Go
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 {
|
||
ret = append(ret, v.PrivateRoomInfo)
|
||
}
|
||
}
|
||
return ret
|
||
}
|
||
|
||
func (c *CustomRoomMgr) tryCreate(plt string, configId int32) {
|
||
logger.Logger.Tracef("尝试创建竞技馆系统房间 %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.Tracef("尝试解散竞技馆系统房间 %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.Tracef("释放竞技馆房间创建记录 %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.Tracef("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(),
|
||
},
|
||
RoomConfigSystem: cfg,
|
||
})
|
||
if scene != nil {
|
||
logger.Logger.Tracef("竞技馆系统房间创建成功 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,
|
||
}
|
||
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.Tracef("竞技馆假房间创建成功 %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.Tracef("竞技馆假房间解散 %v", info)
|
||
c.Release(plt, configId)
|
||
c.UpdateCreate(plt, configId, false)
|
||
return true
|
||
}, nil, time.Duration(cfg.GetFullTime())*time.Second)
|
||
info.Handle = b
|
||
}
|
||
})
|
||
}
|
||
}
|