game_sync/worldsrv/platformmgr.go

599 lines
17 KiB
Go

package main
import (
"strconv"
"time"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/module"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/core/utils"
srvlibproto "mongo.games.com/goserver/srvlib/protocol"
"mongo.games.com/game/common"
"mongo.games.com/game/model"
"mongo.games.com/game/proto"
hallproto "mongo.games.com/game/protocol/gamehall"
loginproto "mongo.games.com/game/protocol/login"
serverproto "mongo.games.com/game/protocol/server"
webapiproto "mongo.games.com/game/protocol/webapi"
"mongo.games.com/game/srvdata"
)
const (
DefaultPlatform = "0"
DefaultPlatformInt = 0
)
type PlatformObserver interface {
OnPlatformCreate(p *Platform)
OnPlatformDestroy(p *Platform)
OnPlatformChangeDisabled(p *Platform, disabled bool)
OnPlatformGameFreeUpdate(p *Platform, oldCfg, newCfg *webapiproto.GameFree)
OnPlatformDestroyByGameFreeId(p *Platform, gameFreeId int32)
}
var PlatformMgrSingleton = &PlatformMgr{
platforms: make(map[string]*Platform),
ConfigMgr: model.NewConfigMgr(),
}
type PlatformMgr struct {
common.BaseClockSinker
*model.ConfigMgr
platforms map[string]*Platform
observers []PlatformObserver
}
func (pm *PlatformMgr) RegisterObserver(observer PlatformObserver) {
for _, ob := range pm.observers {
if ob == observer {
return
}
}
pm.observers = append(pm.observers, observer)
}
func (pm *PlatformMgr) UnregisterObserver(observer PlatformObserver) {
for i, ob := range pm.observers {
if ob == observer {
pm.observers = append(pm.observers[:i], pm.observers[i+1:]...)
break
}
}
}
// GetPlatforms 获取所有平台
func (pm *PlatformMgr) GetPlatforms() []*Platform {
var ret []*Platform
for _, v := range pm.platforms {
if v != nil {
ret = append(ret, v)
}
}
return ret
}
// CreateDefaultPlatform 创建默认平台
func (pm *PlatformMgr) CreateDefaultPlatform() {
//默认平台数据
defaultPlatform := pm.CreatePlatform(DefaultPlatformInt, false)
defaultPlatform.Disable = false
//默认平台配置
list := defaultPlatform.GameConfig
if list != nil {
for _, value := range srvdata.PBDB_GameFreeMgr.Datas.Arr {
if value.GetGameId() > 0 {
list.gameFreeId[value.GetId()] = &webapiproto.GameFree{
Status: true,
DbGameFree: value,
}
}
}
list.Init()
}
}
// CreatePlatform 创建平台
func (pm *PlatformMgr) CreatePlatform(id int32, isolated bool) *Platform {
pltId := strconv.Itoa(int(id))
p := NewPlatform(id, isolated)
pm.platforms[pltId] = p
pm.OnPlatformCreate(p)
return p
}
// UpsertPlatform 更新或新增平台
func (pm *PlatformMgr) UpsertPlatform(name string, isolated, disable bool, id int32, url string,
bindOption int32, serviceFlag bool, upgradeAccountGiveCoin, newAccountGiveCoin, perBankNoLimitAccount, exchangeMin,
exchangeLimit, exchangeTax, exchangeFlow, exchangeFlag, spreadConfig int32, vipRange []int32, otherParam string,
ccf *ClubConfig, verifyCodeType int32, thirdState map[int32]int32, customType int32, needDeviceInfo bool,
needSameName bool, exchangeForceTax int32, exchangeGiveFlow int32, exchangeVer int32, exchangeBankMax int32,
exchangeAlipayMax int32, dgHboCfg int32, PerBankNoLimitName int32, isCanUserBindPromoter bool,
userBindPromoterPrize int32, spreadWinLose bool, exchangeMultiple int32, registerVerifyCodeSwitch bool, merchantKey string,
bindTelReward map[int32]int64) *Platform {
pltId := strconv.Itoa(int(id))
p := pm.platforms[pltId]
if p == nil {
p = pm.CreatePlatform(id, isolated)
}
//oldIsolated := p.Isolated
//oldBindPromoter := p.IsCanUserBindPromoter
oldDisabled := p.Disable
//oldBindOption := p.BindOption
p.Id = id
p.Name = name
p.IdStr = pltId
p.ServiceUrl = url
p.BindOption = bindOption
p.ServiceFlag = serviceFlag
p.CustomType = customType
p.UpgradeAccountGiveCoin = upgradeAccountGiveCoin
p.NewAccountGiveCoin = newAccountGiveCoin
p.PerBankNoLimitAccount = perBankNoLimitAccount
p.ExchangeMin = exchangeMin
p.ExchangeLimit = exchangeLimit
p.SpreadConfig = spreadConfig
p.ExchangeTax = exchangeTax
p.ExchangeVer = exchangeVer
p.ExchangeForceTax = exchangeForceTax
p.ExchangeFlow = exchangeFlow
p.ExchangeFlag = exchangeFlag
p.VipRange = vipRange
p.OtherParams = otherParam
p.VerifyCodeType = verifyCodeType
p.RegisterVerifyCodeSwitch = registerVerifyCodeSwitch
p.ThirdGameMerchant = thirdState
//p.NeedDeviceInfo = needDeviceInfo
p.NeedSameName = needSameName
p.PerBankNoLimitName = PerBankNoLimitName
p.ExchangeGiveFlow = exchangeGiveFlow
p.ExchangeBankMax = exchangeBankMax
p.ExchangeAlipayMax = exchangeAlipayMax
p.DgHboConfig = dgHboCfg
p.IsCanUserBindPromoter = isCanUserBindPromoter
p.UserBindPromoterPrize = userBindPromoterPrize
p.SpreadWinLose = spreadWinLose
p.ExchangeMultiple = exchangeMultiple
p.MerchantKey = merchantKey
p.BindTelReward = bindTelReward
if p.ExchangeFlag&ExchangeFlag_Flow == 0 { //修正下
p.ExchangeFlow = 0
}
//if oldIsolated != isolated {
// pm.ChangeIsolated(name, isolated)
//}
if oldDisabled != disable {
pm.ChangeDisabled(name, disable)
}
//if oldBindPromoter != isCanUserBindPromoter {
// pm.ChangeIsCanBindPromoter(name, isCanUserBindPromoter)
//}
if ccf != nil {
p.ClubConfig = ccf
}
return p
}
// GetEntrySwitch 获取入口开关
func (pm *PlatformMgr) GetEntrySwitch(plt string) map[int32]*webapiproto.EntrySwitch {
return pm.GetConfig(plt).EntrySwitch
}
// GetCommonNotices 获取公告
func (pm *PlatformMgr) GetCommonNotices(plt string) *webapiproto.CommonNoticeList {
return pm.GetConfig(plt).CommonNotices
}
// SyncGameFree 通知游戏配置更新
func (pm *PlatformMgr) SyncGameFree(platform string, data *webapiproto.GameFree) {
packSgf := &loginproto.SCSyncGameFree{}
gc := &loginproto.GameConfig{
GameId: proto.Int32(data.DbGameFree.GetGameId()),
GameMode: proto.Int32(data.DbGameFree.GetGameMode()),
LogicId: proto.Int32(data.DbGameFree.GetId()),
State: proto.Bool(data.Status),
LimitCoin: proto.Int64(data.DbGameFree.GetLimitCoin()),
MaxCoinLimit: proto.Int64(data.DbGameFree.GetMaxCoinLimit()),
BaseScore: proto.Int32(data.DbGameFree.GetBaseScore()),
BetScore: proto.Int32(data.DbGameFree.GetBetLimit()),
OtherIntParams: data.DbGameFree.GetOtherIntParams(),
MaxBetCoin: data.DbGameFree.GetMaxBetCoin(),
MatchMode: proto.Int32(data.DbGameFree.GetMatchMode()),
}
if data.DbGameFree.GetLottery() != 0 {
gc.LotteryCfg = data.DbGameFree.LotteryConfig
}
packSgf.Data = append(packSgf.Data, gc)
if len(packSgf.Data) > 0 {
PlayerMgrSington.BroadcastMessageToPlatform(platform, int(loginproto.LoginPacketID_PACKET_SC_SYNCGAMEFREE), packSgf)
}
}
// UpsertGameFree 更新场次配置
func (pm *PlatformMgr) UpsertGameFree(platform string, data *webapiproto.GameFree) {
p := pm.GetPlatform(platform)
if p != nil {
pgc := p.GameConfig
if pgc != nil {
dbGameFree := srvdata.PBDB_GameFreeMgr.GetData(data.DbGameFree.Id)
if dbGameFree == nil {
return
}
if data.GetDbGameFree() == nil { //数据容错
data.DbGameFree = dbGameFree
} else {
CopyDBGameFreeField(dbGameFree, data.DbGameFree)
}
old, ok := pgc.gameFreeId[data.DbGameFree.Id]
pgc.gameFreeId[data.DbGameFree.Id] = data
found := false
if ok && old != nil {
if c, ok := pgc.gameId[data.DbGameFree.Id]; ok {
for i := 0; i < len(c); i++ {
if c[i].DbGameFree.Id == data.DbGameFree.Id {
c[i] = data
found = true
break
}
}
}
}
if !found {
pgc.gameId[data.DbGameFree.Id] = append(pgc.gameId[data.DbGameFree.Id], data)
}
// 新增的场次不会通知
if ok && old != nil && !CompareGameFreeConfigChanged(old, data) {
pm.OnPlatformGameFreeUpdate(p, old, data)
pm.SyncGameFree(p.IdStr, data)
}
}
}
}
func (pm *PlatformMgr) OnPlatformCreate(p *Platform) {
for _, observer := range pm.observers {
observer.OnPlatformCreate(p)
}
}
func (pm *PlatformMgr) OnPlatformGameFreeUpdate(p *Platform, oldCfg, newCfg *webapiproto.GameFree) {
for _, observer := range pm.observers {
observer.OnPlatformGameFreeUpdate(p, oldCfg, newCfg)
}
}
func (pm *PlatformMgr) OnPlatformDestroyByGameFreeId(p *Platform, gameFreeId int32) {
for _, observer := range pm.observers {
observer.OnPlatformDestroyByGameFreeId(p, gameFreeId)
}
}
func (pm *PlatformMgr) OnPlatformChangeDisabled(p *Platform, disable bool) {
for _, observer := range pm.observers {
observer.OnPlatformChangeDisabled(p, disable)
}
}
// ChangeDisabled 平台开关状态切换
func (pm *PlatformMgr) ChangeDisabled(name string, disable bool) {
if p := pm.GetPlatform(name); p != nil {
if p.ChangeDisabled(disable) {
pm.OnPlatformChangeDisabled(p, disable)
}
}
}
func (pm *PlatformMgr) GetPlatform(platform string) *Platform {
return pm.platforms[platform]
}
// Broadcast 给玩家发消息
func (pm *PlatformMgr) Broadcast(packetid int, packet interface{}, players map[int32]*Player, exclude int32) {
mgs := make(map[*netlib.Session][]*srvlibproto.MCSessionUnion)
for _, p := range players {
if p != nil && p.gateSess != nil && p.IsOnLine() && exclude != p.SnId {
mgs[p.gateSess] = append(mgs[p.gateSess], &srvlibproto.MCSessionUnion{
Mccs: &srvlibproto.MCClientSession{
SId: p.sid,
},
})
}
}
for gateSess, v := range mgs {
if gateSess != nil && len(v) != 0 {
pack, err := common.CreateMulticastPacket(packetid, packet, v...)
if err == nil {
gateSess.Send(int(srvlibproto.SrvlibPacketID_PACKET_SS_MULTICAST), pack)
}
}
}
}
func (this *PlatformMgr) GetPackageTag(tag string) *webapiproto.AppInfo {
logger.Logger.Tracef("Get %v platform.", tag)
if pt, ok := this.GetGlobalConfig().PackageList[tag]; ok {
return pt
}
return nil
}
func (this *PlatformMgr) GetPlatformByPackageTag(tag string) (int32, int32, int32, int32, int32) {
logger.Logger.Tracef("Get %v platform.", tag)
if pt, ok := this.GetGlobalConfig().PackageList[tag]; ok {
return pt.PlatformId, 0, 0, 0, 0
} else {
return int32(DefaultPlatformInt), 0, 0, 0, 0
}
}
func (this *PlatformMgr) GetCurrencyByPackageTag(tag string) (string, int32) {
logger.Logger.Tracef("Get %v CurrencyRatio.", tag)
if pt, ok := this.GetGlobalConfig().PackageList[tag]; ok && pt.CurrencyType != "" && pt.CurrencyRatio != 0 {
return pt.CurrencyType, pt.CurrencyRatio
}
return "USD", 1
}
// GetGameFrees 获取平台游戏配置
func (this *PlatformMgr) GetGameFrees(platform string) map[int32]*webapiproto.GameFree {
p := this.GetPlatform(platform)
if p == nil {
return nil
}
data := make(map[int32]*webapiproto.GameFree)
for id, val := range p.GameConfig.gameFreeId {
if !val.Status || !this.GetGlobalConfig().GameStatus[id] {
continue
}
if val.GroupId != 0 {
cfg := PlatformGameGroupMgrSington.GetGameGroup(val.GroupId)
if cfg != nil {
temp := &webapiproto.GameFree{
GroupId: cfg.GetId(),
Status: val.Status,
DbGameFree: cfg.GetDbGameFree(),
}
data[id] = temp
}
} else {
data[id] = val
}
}
return data
}
// GetGameFree 获取平台游戏配置
func (this *PlatformMgr) GetGameFree(platform string, gameFreeId int32) *webapiproto.GameFree {
p := this.GetPlatform(platform)
if p == nil {
return nil
}
gf := p.GameConfig.GetGameConfig(gameFreeId)
if gf == nil {
return nil
}
if !this.GetGlobalConfig().GameStatus[gameFreeId] || !gf.GetStatus() {
return nil
}
return gf
}
// CheckGameState 场次开关状态
func (this *PlatformMgr) CheckGameState(platform string, gameFreeId int32) bool {
gf := this.GetGameFree(platform, gameFreeId)
if gf == nil {
return false
}
return gf.Status
}
func (this *PlatformMgr) GetGameFreeGroup(platform string, gameFreeId int32) int32 {
c := this.GetGameFree(platform, gameFreeId)
if c != nil {
return c.GroupId
}
return 0
}
func (this *PlatformMgr) GetCommonNotice(plt string) *webapiproto.CommonNoticeList {
logger.Logger.Tracef("GetCommonNotice %v platform.", plt)
if cfg := this.GetCommonNotices(plt); cfg != nil {
//now := time.Now().Unix()
re := &webapiproto.CommonNoticeList{
Platform: cfg.Platform,
List: cfg.List,
}
//for _, v := range pt.List {
// if v.GetEndTime() > now && v.GetStartTime() < now {
// re.List = append(re.List, v)
// }
//}
return re
}
return nil
}
// ChangeGameStatus 后台切换超管游戏开关
func (this *PlatformMgr) ChangeGameStatus(cfgs []*hallproto.GameConfig1) {
//向所有玩家发送状态变化协议
pack := &hallproto.SCChangeGameStatus{}
for _, p := range this.GetPlatforms() {
for _, cfg := range cfgs {
gameFreeId := cfg.LogicId
data, ok := p.GameConfig.gameFreeId[gameFreeId]
if data != nil && ok && data.Status { //自身有这个游戏,且处于开启状态
if !cfg.Status { //全局关,销毁游戏
pack.GameCfg = append(pack.GameCfg, cfg)
this.OnPlatformDestroyByGameFreeId(p, gameFreeId)
} else {
lgc := &hallproto.GameConfig1{
LogicId: proto.Int32(data.DbGameFree.Id),
LimitCoin: proto.Int64(data.DbGameFree.GetLimitCoin()),
MaxCoinLimit: proto.Int64(data.DbGameFree.GetMaxCoinLimit()),
BaseScore: proto.Int32(data.DbGameFree.GetBaseScore()),
BetScore: proto.Int32(data.DbGameFree.GetBetLimit()),
OtherIntParams: data.DbGameFree.GetOtherIntParams(),
MaxBetCoin: data.DbGameFree.GetMaxBetCoin(),
MatchMode: proto.Int32(data.DbGameFree.GetMatchMode()),
Status: data.Status,
}
if data.DbGameFree.GetLottery() != 0 { //彩金池
//lgc.LotteryCfg = data.DBGameFree.LotteryConfig
//_, gl := LotteryMgrSington.FetchLottery(plf, data.DBGameFree.GetId(), data.DBGameFree.GetGameId())
//if gl != nil {
// lgc.LotteryCoin = proto.Int64(gl.Value)
//}
}
pack.GameCfg = append(pack.GameCfg, lgc)
}
}
}
if len(pack.GameCfg) > 0 {
PlayerMgrSington.BroadcastMessageToPlatform(p.IdStr, int(hallproto.GameHallPacketID_PACKET_SC_CHANGEGAMESTATUS), pack)
}
}
}
// ChangeEntrySwitch 修改客户端游戏入口状态
func (this *PlatformMgr) ChangeEntrySwitch(platform string, cfg *webapiproto.EntrySwitch) {
p := PlatformMgrSingleton.GetPlatform(platform)
if p == nil {
return
}
pack := &hallproto.SCChangeEntrySwitch{
Index: cfg.GetIndex(),
Switch: cfg.GetSwitch(),
}
PlayerMgrSington.BroadcastMessageToPlatform(platform, int(hallproto.GameHallPacketID_PACKET_SC_CHANGEENTRYSWITCH), pack)
}
func (this *PlatformMgr) ModuleName() string {
return "PlatformMgr"
}
func (this *PlatformMgr) Init() {
}
func (this *PlatformMgr) Update() {
}
func (this *PlatformMgr) Shutdown() {
module.UnregisteModule(this)
}
func (this *PlatformMgr) InterestClockEvent() int {
return 1<<common.ClockEventHour | 1<<common.ClockEventDay
}
func (this *PlatformMgr) OnDayTimer() {
for _, platform := range this.GetPlatforms() {
utils.CatchPanic(func() {
platform.OnDayTimer()
})
}
}
func (this *PlatformMgr) OnHourTimer() {
for _, platform := range this.GetPlatforms() {
utils.CatchPanic(func() {
platform.OnHourTimer()
})
}
}
// CopyDBGameFreeField 需要使用本地配置的属性
// src 本地场次配置
// dst 后台场次配置
func CopyDBGameFreeField(src, dst *serverproto.DB_GameFree) {
dst.Id = src.Id
dst.Name = src.Name
dst.Title = src.Title
dst.ShowType = src.ShowType
dst.SubShowType = src.SubShowType
dst.Flag = src.Flag
dst.GameRule = src.GameRule
dst.TestTakeCoin = src.TestTakeCoin
dst.SceneType = src.SceneType
dst.GameType = src.GameType
dst.GameId = src.GameId
dst.GameMode = src.GameMode
dst.ShowId = src.ShowId
dst.ServiceFee = src.ServiceFee
dst.Turn = src.Turn
dst.BetDec = src.BetDec
//dst.CorrectNum = src.CorrectNum
//dst.CorrectRate = src.CorrectRate
//dst.Deviation = src.Deviation
//dst.Ready = src.Ready
dst.Ai = src.Ai
dst.Jackpot = src.Jackpot
//dst.ElementsParams = src.ElementsParams
//dst.OtherElementsParams = src.OtherElementsParams
//dst.DownRiceParams = src.DownRiceParams
//dst.InitValue = src.InitValue
//dst.LowerLimit = src.LowerLimit
//dst.UpperLimit = src.UpperLimit
//dst.UpperOffsetLimit = src.UpperOffsetLimit
//dst.MaxOutValue = src.MaxOutValue
//dst.ChangeRate = src.ChangeRate
//dst.MinOutPlayerNum = src.MinOutPlayerNum
//dst.UpperLimitOfOdds = src.UpperLimitOfOdds
if len(dst.RobotNumRng) < 2 {
dst.RobotNumRng = src.RobotNumRng
}
//dst.SameIpLimit = src.SameIpLimit
//dst.BaseRate = src.BaseRate
//dst.CtroRate = src.CtroRate
//dst.HardTimeMin = src.HardTimeMin
//dst.HardTimeMax = src.HardTimeMax
//dst.NormalTimeMin = src.NormalTimeMin
//dst.NormalTimeMax = src.NormalTimeMax
//dst.EasyTimeMin = src.EasyTimeMin
//dst.EasyTimeMax = src.EasyTimeMax
//dst.EasrierTimeMin = src.EasrierTimeMin
//dst.EasrierTimeMax = src.EasrierTimeMax
dst.GameType = src.GameType
dst.GameDif = src.GameDif
dst.GameClass = src.GameClass
dst.PlatformName = src.PlatformName
dst.IsDrop = src.IsDrop
if len(dst.MaxBetCoin) == 0 {
dst.MaxBetCoin = src.MaxBetCoin
}
//预创建房间数量走后台配置
//dst.CreateRoomNum = src.CreateRoomNum
//后台功能做上后,优先使用后台的配置,默认直接用表格种配好的
//if !model.GameParamData.MatchTrueManUseWeb {
// dst.MatchTrueMan = src.MatchTrueMan
//}
////默认走本地配置
//if dst.PlayerWaterRate == nil {
// tv := src.GetPlayerWaterRate()
// dst.PlayerWaterRate = &tv
//}
//
//if dst.BetWaterRate == nil {
// tv := src.GetBetWaterRate()
// dst.BetWaterRate = &tv
//}
}
func init() {
common.ClockMgrSingleton.RegisterSinker(PlatformMgrSingleton)
module.RegisteModule(PlatformMgrSingleton, time.Hour, 0)
}