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.BindOption = bindOption 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<