288 lines
7.8 KiB
Go
288 lines
7.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"mongo.games.com/game/protocol/webapi"
|
|
"sync"
|
|
|
|
"mongo.games.com/game/common"
|
|
"mongo.games.com/game/model"
|
|
"mongo.games.com/game/proto"
|
|
gamehall_proto "mongo.games.com/game/protocol/gamehall"
|
|
server_proto "mongo.games.com/game/protocol/server"
|
|
"mongo.games.com/game/srvdata"
|
|
"mongo.games.com/goserver/core/logger"
|
|
"mongo.games.com/goserver/core/netlib"
|
|
"mongo.games.com/goserver/srvlib"
|
|
libproto "mongo.games.com/goserver/srvlib/protocol"
|
|
)
|
|
|
|
type GameSessionListener interface {
|
|
OnGameSessionRegiste(*GameSession)
|
|
OnGameSessionUnregiste(*GameSession)
|
|
}
|
|
|
|
var GameSessionListenerSet = new(sync.Map)
|
|
|
|
func RegisteGameSessionListener(listener GameSessionListener) {
|
|
GameSessionListenerSet.Store(listener, listener)
|
|
}
|
|
|
|
func UnregisteGameSessionListener(listener GameSessionListener) {
|
|
GameSessionListenerSet.Delete(listener)
|
|
}
|
|
|
|
type GameSession struct {
|
|
*netlib.Session
|
|
srvId int
|
|
srvType int
|
|
state common.GameSessState
|
|
players map[int32]*Player
|
|
scenes map[int]*Scene
|
|
cps map[string]*model.CoinPoolSetting
|
|
gameIds []int32
|
|
}
|
|
|
|
// 构造函数
|
|
func NewGameSession(srvId, srvType int, s *netlib.Session) *GameSession {
|
|
gs := &GameSession{
|
|
Session: s,
|
|
srvId: srvId,
|
|
srvType: srvType,
|
|
state: common.GAME_SESS_STATE_ON,
|
|
players: make(map[int32]*Player),
|
|
scenes: make(map[int]*Scene),
|
|
cps: make(map[string]*model.CoinPoolSetting),
|
|
}
|
|
return gs
|
|
}
|
|
|
|
func (this *GameSession) RebindPlayerSnId(oldSnId, newSnId int32) {
|
|
if p, exist := this.players[oldSnId]; exist {
|
|
delete(this.players, oldSnId)
|
|
this.players[newSnId] = p
|
|
}
|
|
}
|
|
|
|
func (this *GameSession) GetSrvId() int32 {
|
|
if this.Session == nil {
|
|
return 0
|
|
}
|
|
attr := this.GetAttribute(srvlib.SessionAttributeServerInfo)
|
|
if attr != nil {
|
|
if srvInfo, ok := attr.(*libproto.SSSrvRegiste); ok && srvInfo != nil {
|
|
return srvInfo.GetId()
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// 关闭其上的所有场景
|
|
func (this *GameSession) CloseAllScene() {
|
|
for sceneId, scene := range this.scenes {
|
|
scDestroyRoom := &gamehall_proto.SCDestroyRoom{
|
|
RoomId: proto.Int(sceneId),
|
|
OpRetCode: gamehall_proto.OpResultCode_Game_OPRC_Sucess_Game,
|
|
IsForce: proto.Int(1),
|
|
}
|
|
proto.SetDefaults(scDestroyRoom)
|
|
scene.Broadcast(int(gamehall_proto.GameHallPacketID_PACKET_SC_DESTROYROOM), scDestroyRoom, 0)
|
|
SceneMgrSingleton.DestroyScene(sceneId, true)
|
|
}
|
|
this.scenes = nil
|
|
this.players = nil
|
|
}
|
|
|
|
// 注册事件
|
|
func (this *GameSession) OnRegiste() {
|
|
GameSessionListenerSet.Range(func(key, val interface{}) bool {
|
|
if lis, ok := val.(GameSessionListener); ok {
|
|
lis.OnGameSessionRegiste(this)
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
// 注销事件
|
|
func (this *GameSession) OnUnregiste() {
|
|
//销毁比赛
|
|
//MatchMgrSington.DestroyAllMatchByGameSession(this)
|
|
//解散房间
|
|
this.CloseAllScene()
|
|
|
|
GameSessionListenerSet.Range(func(key, val interface{}) bool {
|
|
if lis, ok := val.(GameSessionListener); ok {
|
|
lis.OnGameSessionUnregiste(this)
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
// 负载因数
|
|
func (this *GameSession) GetLoadFactor() int {
|
|
return len(this.scenes)*20 + len(this.players)
|
|
}
|
|
|
|
// 设置状态
|
|
func (this *GameSession) SwitchState(state common.GameSessState) {
|
|
if state == this.state {
|
|
return
|
|
}
|
|
this.state = state
|
|
switch state {
|
|
case common.GAME_SESS_STATE_ON:
|
|
this.OnStateOn()
|
|
case common.GAME_SESS_STATE_OFF:
|
|
this.OnStateOff()
|
|
}
|
|
}
|
|
func (this *GameSession) OnStateOn() {
|
|
pack := &server_proto.ServerState{
|
|
SrvState: proto.Int(int(this.state)),
|
|
}
|
|
proto.SetDefaults(pack)
|
|
this.Send(int(server_proto.SSPacketID_PACKET_WG_SERVER_STATE), pack)
|
|
}
|
|
func (this *GameSession) OnStateOff() {
|
|
pack := &server_proto.ServerState{
|
|
SrvState: proto.Int(int(this.state)),
|
|
}
|
|
proto.SetDefaults(pack)
|
|
this.Send(int(server_proto.SSPacketID_PACKET_WG_SERVER_STATE), pack)
|
|
}
|
|
|
|
type AddSceneParam struct {
|
|
S *Scene
|
|
}
|
|
|
|
func (this *GameSession) AddScene(args *AddSceneParam) {
|
|
this.scenes[args.S.sceneId] = args.S
|
|
//send msg
|
|
msg := &server_proto.WGCreateScene{
|
|
Platform: args.S.limitPlatform.IdStr,
|
|
SceneId: int32(args.S.sceneId),
|
|
GameId: int32(args.S.gameId),
|
|
GameMode: int32(args.S.gameMode),
|
|
SceneMode: int32(args.S.sceneMode),
|
|
ReplayCode: args.S.replayCode,
|
|
DBGameFree: args.S.dbGameFree,
|
|
TotalOfGames: args.S.totalRound,
|
|
PlayerNum: int32(args.S.playerNum),
|
|
Creator: args.S.creator,
|
|
BaseScore: args.S.BaseScore,
|
|
Custom: args.S.CustomParam,
|
|
Match: args.S.MatchParam,
|
|
Params: args.S.params,
|
|
}
|
|
if args.S.GetRoomConfigId() != 0 {
|
|
cfg := PlatformMgrSingleton.GetConfig(args.S.limitPlatform.IdStr).RoomConfig[args.S.GetRoomConfigId()]
|
|
if cfg != nil {
|
|
for _, v := range cfg.GetReward() {
|
|
msg.Items = append(msg.Items, &server_proto.Item{
|
|
Id: v.GetItemId(),
|
|
Num: v.GetItemNum(),
|
|
})
|
|
}
|
|
for _, v := range cfg.GetCost() {
|
|
msg.CostItems = append(msg.CostItems, &server_proto.Item{
|
|
Id: v.GetItemId(),
|
|
Num: v.GetItemNum(),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
if sp, ok := args.S.sp.(*ScenePolicyData); ok {
|
|
msg.EnterAfterStart = proto.Bool(sp.EnterAfterStart)
|
|
}
|
|
// 象棋游戏添加段位配置
|
|
if args.S.dbGameFree != nil && srvdata.GameFreeMgr.IsGameDif(int32(args.S.gameId), common.GameDifChess) {
|
|
msg.ChessRank = ChessRankMgrSington.GetChessRankArr(args.S.limitPlatform.Name, int32(args.S.gameId))
|
|
}
|
|
this.Send(int(server_proto.SSPacketID_PACKET_WG_CREATESCENE), msg)
|
|
logger.Logger.Tracef("WGCreateScene: %v", msg)
|
|
|
|
// 初始化水池
|
|
if args.S.limitPlatform != nil && args.S.dbGameFree != nil {
|
|
this.DetectCoinPoolSetting(args.S.limitPlatform.IdStr, args.S.dbGameFree.GetId(), args.S.groupId)
|
|
}
|
|
}
|
|
|
|
func (this *GameSession) DelScene(s *Scene) {
|
|
delete(this.scenes, s.sceneId)
|
|
}
|
|
|
|
func (this *GameSession) AddPlayer(p *Player) {
|
|
this.players[p.SnId] = p
|
|
}
|
|
|
|
func (this *GameSession) DelPlayer(p *Player) {
|
|
delete(this.players, p.SnId)
|
|
}
|
|
|
|
func (this *GameSession) GenCoinPoolSettingKey(platform string, groupId, gamefreeid, srvid int32) string {
|
|
var key string
|
|
if groupId != 0 {
|
|
key = fmt.Sprintf("%v+%v_%v", gamefreeid, groupId, srvid)
|
|
} else {
|
|
key = fmt.Sprintf("%v_%v_%v", gamefreeid, platform, srvid)
|
|
}
|
|
return key
|
|
}
|
|
|
|
func (this *GameSession) DetectCoinPoolSetting(platform string, gamefreeid, groupId int32) bool {
|
|
srvid := this.GetSrvId()
|
|
key := this.GenCoinPoolSettingKey(platform, groupId, gamefreeid, srvid)
|
|
if _, exist := this.cps[key]; !exist {
|
|
data := model.GetCoinPoolSetting(gamefreeid, srvid, groupId, platform)
|
|
if data == nil {
|
|
dbGameCoinPool := srvdata.PBDB_GameCoinPoolMgr.GetData(gamefreeid)
|
|
if dbGameCoinPool != nil {
|
|
data = model.NewCoinPoolSetting(platform, groupId, gamefreeid, srvid, dbGameCoinPool)
|
|
if data != nil {
|
|
err := model.UpsertCoinPoolSetting(data, nil) // 入库
|
|
if err == nil {
|
|
model.ManageCoinPoolSetting(data)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if data != nil {
|
|
this.cps[key] = data
|
|
//send msg
|
|
msg := &webapi.CoinPoolSetting{
|
|
Platform: platform,
|
|
GameFreeId: gamefreeid,
|
|
ServerId: srvid,
|
|
GroupId: groupId,
|
|
InitValue: data.InitValue,
|
|
LowerLimit: data.LowerLimit,
|
|
UpperLimit: data.UpperLimit,
|
|
QuDu: data.QuDu,
|
|
UpperOdds: data.UpperOdds,
|
|
UpperOddsMax: data.UpperOddsMax,
|
|
LowerOdds: data.LowerOdds,
|
|
LowerOddsMax: data.LowerOddsMax,
|
|
ProfitRate: data.ProfitRate,
|
|
CtrlRate: data.CtrlRate,
|
|
InitNoviceValue: data.InitNoviceValue,
|
|
ResetTime: data.ResetTime,
|
|
Switch: data.Switch,
|
|
}
|
|
proto.SetDefaults(msg)
|
|
this.Send(int(server_proto.SSPacketID_PACKET_WG_COINPOOLSETTING), msg)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// SendToGame 给某个游戏服务发消息
|
|
func SendToGame(gameId int, packetId int, pack interface{}) {
|
|
gameServers := GameSessMgrSington.GetGameServerSess(gameId)
|
|
if len(gameServers) == 0 {
|
|
gameServers = GameSessMgrSington.GetGameServerSess(common.GameId_Unknow)
|
|
}
|
|
for _, value := range gameServers {
|
|
value.Send(packetId, pack)
|
|
}
|
|
}
|