game_sync/worldsrv/gamesess.go

301 lines
8.1 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 {
if scene.IsMiniGameScene() {
} else {
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)
}
func (this *GameSession) AddScene(s *Scene) {
this.scenes[s.sceneId] = s
//send msg
msg := &server_proto.WGCreateScene{
SceneId: proto.Int(s.sceneId),
GameId: proto.Int(s.gameId),
GameMode: proto.Int(s.gameMode),
SceneMode: proto.Int(s.sceneMode),
Params: s.params,
ParamsEx: s.paramsEx,
Creator: proto.Int32(s.creator),
Agentor: proto.Int32(s.agentor),
HallId: proto.Int32(s.hallId),
ReplayCode: proto.String(s.replayCode),
GroupId: proto.Int32(s.groupId),
TotalOfGames: proto.Int32(s.totalRound),
BaseScore: proto.Int32(s.BaseScore),
PlayerNum: proto.Int(s.playerNum),
}
var platform *Platform
if s.limitPlatform != nil {
msg.Platform = proto.String(s.limitPlatform.IdStr)
platform = s.limitPlatform
} else {
msg.Platform = proto.String(DefaultPlatform)
platform = PlatformMgrSingleton.GetPlatform(DefaultPlatform)
}
if s.dbGameFree != nil {
msg.DBGameFree = s.dbGameFree
} else if platform != nil {
gps := PlatformMgrSingleton.GetGameFree(platform.IdStr, s.paramsEx[0])
if gps != nil {
if gps.GroupId == 0 {
msg.DBGameFree = gps.DbGameFree
} else {
pgg := PlatformGameGroupMgrSington.GetGameGroup(gps.GroupId)
if pgg != nil {
msg.DBGameFree = pgg.DbGameFree
}
}
}
}
if s.IsCoinScene() {
if sp, ok := s.sp.(*ScenePolicyData); ok {
msg.EnterAfterStart = proto.Bool(sp.EnterAfterStart)
}
}
//if s.ClubId > 0 {
// msg.Club = proto.Int32(s.ClubId)
// msg.ClubRoomId = proto.String(s.clubRoomID)
// msg.ClubRoomPos = proto.Int32(s.clubRoomPos)
// msg.ClubRate = proto.Int32(s.clubRoomTax)
//}
if s.IsHundredScene() {
//msg.RealCtrl = WBCtrlCfgMgr.GetRealCtrl(s.limitPlatform.IdStr)
}
// 象棋游戏添加段位配置
if s.dbGameFree != nil && s.dbGameFree.GameDif == common.GameDifChess && platform != nil {
msg.ChessRank = ChessRankMgrSington.GetChessRankArr(platform.Name, int32(s.gameId))
}
proto.SetDefaults(msg)
this.Send(int(server_proto.SSPacketID_PACKET_WG_CREATESCENE), msg)
logger.Logger.Trace("WGCreateScene:", msg)
}
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)
}
}