package main import ( "context" "encoding/json" "go.etcd.io/etcd/client/v3" "mongo.games.com/game/common" "mongo.games.com/game/etcd" "mongo.games.com/game/model" "mongo.games.com/game/mq" hallproto "mongo.games.com/game/protocol/gamehall" loginproto "mongo.games.com/game/protocol/login" playerproto "mongo.games.com/game/protocol/player" serverproto "mongo.games.com/game/protocol/server" "mongo.games.com/game/protocol/webapi" "mongo.games.com/game/srvdata" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/task" "strconv" "strings" ) func init() { // 平台配置 etcd.Register(etcd.ETCDKEY_PLATFORM_PREFIX, webapi.Platform{}, platformConfigEvent) // 超管平台游戏开关 etcd.Register(etcd.ETCDKEY_GAME_CONFIG_GLOBAL, webapi.GameConfigGlobal{}, platformConfigEvent) // 游戏场次配置 etcd.Register(etcd.ETCDKEY_GAMECONFIG_PREFIX, webapi.GameFree{}, platformConfigEvent) // 平台包数据 etcd.Register(etcd.ETCDKEY_PACKAGE_PREFIX, webapi.AppInfo{}, platformConfigEvent) // 客户端游戏入口开关 etcd.Register(etcd.ETCDKEY_PACKAGE_ENTRYSWITCH, webapi.EntrySwitch{}, platformConfigEvent) // 公告 etcd.Register(etcd.ETCDKEY_GAME_NOTICE, webapi.CommonNoticeList{}, platformConfigEvent) // 比赛配置 etcd.Register(etcd.ETCDKEY_GAME_MATCH, webapi.GameMatchDateList{}, platformConfigEvent) // 比赛场类型 etcd.Register(etcd.ETCDKEY_GAME_MATCH_TYPE, webapi.GameMatchType{}, platformConfigEvent) // 个人水池配置 etcd.Register(etcd.ETCDKEY_PLAYERPOOL, webapi.PlayerPool{}, platformConfigEvent) // 商品兑换 etcd.Register(etcd.ETCDKEY_SHOP_EXCHANGE, webapi.ExchangeShopList{}, platformConfigEvent) // 商城商品 etcd.Register(etcd.ETCDKEY_SHOP_ITEM, webapi.ItemShopList{}, platformConfigEvent) // 集卡活动 etcd.Register(etcd.ETCDKEY_ACT_Collect, webapi.WelfareCollectConfig{}, platformConfigEvent) // 渠道开关 etcd.Register(etcd.ETCDKEY_ChannelSwitch, webapi.ChannelSwitchConfig{}, platformConfigEvent) // 组配置 etcd.Register(etcd.ETCDKEY_GROUPCONFIG_PREFIX, webapi.GameConfigGroup{}, platformConfigEvent) // 黑名单配置 etcd.Register(etcd.ETCDKEY_BLACKLIST_PREFIX, BlackInfoApi{}, handlerEvent) // 代理 etcd.Register(etcd.ETCDKEY_PROMOTER_PREFIX, PromoterConfig{}, handlerEvent) // 7日签到 etcd.Register(etcd.ETCDKEY_ACT_7SIGN, webapi.Welfare7SignDateList{}, platformConfigEvent) // 转盘 etcd.Register(etcd.ETCDKEY_ACT_TURNPLATE, webapi.WelfareTurnplateDateList{}, platformConfigEvent) // 盲盒 etcd.Register(etcd.ETCDKEY_ACT_BLINDBOX, webapi.WelfareBlindBoxDataList{}, platformConfigEvent) // 首充 etcd.Register(etcd.ETCDKEY_ACT_FIRSTPAY, webapi.WelfareFirstPayDataList{}, platformConfigEvent) // 连充 etcd.Register(etcd.ETCDKEY_ACT_CONTINUOUSPAY, webapi.WelfareContinuousPayDataList{}, platformConfigEvent) // VIP etcd.Register(etcd.ETCDKEY_VIP_CFG, webapi.VIPcfgDataList{}, platformConfigEvent) // 象棋段位 etcd.Register(etcd.ETCDKEY_CHESSRANK_CFG, webapi.ChessRankcfgData{}, platformConfigEvent) // 手机积分 etcd.Register(etcd.ETCDKEY_ACT_PHONELOTTERY, webapi.WelfarePhoneLotteryStatus{}, platformConfigEvent) // 邀请活动 etcd.Register(etcd.ETCDKEY_ACT_Invite, webapi.ActInviteConfig{}, platformConfigEvent) // 赛季通行证 etcd.Register(etcd.ETCDKEY_ACT_Permit, webapi.ActPermitConfig{}, platformConfigEvent) // 钻石抽奖 etcd.Register(etcd.ETCDKEY_DIAMOND_LOTTERY, webapi.DiamondLotteryConfig{}, platformConfigEvent) // 道具列表 etcd.Register(etcd.ETCDKEY_Item, webapi.ItemConfig{}, platformConfigEvent) // 皮肤配置 etcd.Register(etcd.ETCDKEY_SKin, webapi.SkinConfig{}, platformConfigEvent) //排行榜奖励配置 etcd.Register(etcd.ETCDKEY_RANK_TYPE, webapi.RankTypeConfig{}, platformConfigEvent) //获奖记录配置 etcd.Register(etcd.ETCDKEY_AWARD_CONFIG, webapi.AwardLogConfig{}, platformConfigEvent) // 新手引导 etcd.Register(etcd.ETCDKEY_GUIDE, webapi.GuideConfig{}, platformConfigEvent) // 比赛观众 etcd.Register(etcd.ETCDKEY_MatchAudience, webapi.MatchAudience{}, handlerEvent) // 小精灵配置 etcd.Register(etcd.ETCDKEY_Spirit, webapi.SpiritConfig{}, platformConfigEvent) // 竞技馆房间配置 etcd.Register(etcd.ETCDKEY_RoomConfig, webapi.RoomConfig{}, handlerEvent) // 竞技馆系统房间配置 etcd.Register(etcd.ETCDKEY_RoomConfigSystem, webapi.RoomConfigSystem{}, handlerEvent) // 竞技馆房间类型配置 etcd.Register(etcd.ETCDKEY_RoomType, webapi.RoomType{}, handlerEvent) //娃娃机配置 etcd.Register(etcd.ETCDKEY_MACHINE, webapi.MachineConfig{}, platformConfigEvent) //客户端升级奖励配置 etcd.Register(etcd.ETCDKEY_ClientUpgrade, webapi.ClientUpgrade{}, platformConfigEvent) //弹窗活动配置 etcd.Register(etcd.ETCDKEY_PopUpWindow, webapi.PopUpWindowConfig{}, platformConfigEvent) // 竞技馆抽奖配置 etcd.Register(etcd.ETCDKEY_LotteryConfig, webapi.LotteryConfig{}, platformConfigEvent) // 用户抽奖 etcd.Register(etcd.ETCDKEY_LotteryUser, webapi.UserLottery{}, handlerEvent) } func platformConfigEvent(ctx context.Context, completeKey string, isInit bool, event *clientv3.Event, data interface{}) { if event.Type == clientv3.EventTypeDelete { return } if data == nil { return } switch config := data.(type) { case *webapi.WelfareCollectConfig: WelfareMgrSington.UpdateCollectConfig(config) case *webapi.ItemShopList: ShopMgrSington.UpdateItemShop(config) case *webapi.ExchangeShopList: ShopMgrSington.UpExShop(config) case *webapi.PlayerPool: PlatformMgrSingleton.GetConfig(config.Platform).PlayerPool = config case *webapi.EntrySwitch: PlatformMgrSingleton.GetConfig(config.Platform).EntrySwitch[config.Index] = config PlatformMgrSingleton.ChangeEntrySwitch(config.Platform, config) case *webapi.CommonNoticeList: PlatformMgrSingleton.GetConfig(config.Platform).CommonNotices = config if !isInit { // 通知公共变更 PlayerMgrSington.BroadcastMessageToPlatform(config.Platform, int(hallproto.GameHallPacketID_PACKET_SC_NoticeChange), &hallproto.SCNoticeChange{}) } case *webapi.GameConfigGlobal: if isInit { for _, v := range config.GetGameStatus() { gameId := v.GetGameId() status := v.GetStatus() PlatformMgrSingleton.GetGlobalConfig().GameStatus[gameId] = status } } else { cfgs := make([]*hallproto.GameConfig1, 0) for _, v := range config.GetGameStatus() { gameId := v.GetGameId() // gamefreeid status := v.GetStatus() if PlatformMgrSingleton.GetGlobalConfig().GameStatus[gameId] != status { cfgs = append(cfgs, &hallproto.GameConfig1{ LogicId: gameId, Status: status, }) } PlatformMgrSingleton.GetGlobalConfig().GameStatus[gameId] = status } PlatformMgrSingleton.ChangeGameStatus(cfgs) } case *webapi.Platform: if isInit { PlatformMgrSingleton.CreateDefaultPlatform() } PlatformMgrSingleton.UpsertPlatform(config.PlatformName, config.Isolated, config.Disabled, config.Id, config.CustomService, config.BindOption, config.ServiceFlag, config.UpgradeAccountGiveCoin, config.NewAccountGiveCoin, config.PerBankNoLimitAccount, config.ExchangeMin, config.ExchangeLimit, config.ExchangeTax, config.ExchangeFlow, config.ExchangeFlag, config.SpreadConfig, config.VipRange, "", nil, config.VerifyCodeType, nil /*config.ThirdGameMerchant,*/, config.CustomType, false, config.NeedSameName, config.ExchangeForceTax, config.ExchangeGiveFlow, config.ExchangeVer, config.ExchangeBankMax, config.ExchangeAlipayMax, 0, config.PerBankNoLimitName, config.IsCanUserBindPromoter, config.UserBindPromoterPrize, false, config.ExchangeMultiple, false, config.MerchantKey, config.BindTelReward) case *webapi.GameFree: var err error s := strings.TrimPrefix(completeKey, etcd.ETCDKEY_GAMECONFIG_PREFIX) arr := strings.Split(s, "/") if len(arr) > 1 { pltId := arr[0] if err == nil { PlatformMgrSingleton.UpsertGameFree(pltId, config) } } case *webapi.AppInfo: if config.PlatformId == 0 { config.PlatformId = int32(DefaultPlatformInt) } PlatformMgrSingleton.GetGlobalConfig().PackageList[config.PackageName] = config PlatformMgrSingleton.GetGlobalConfig().PackageList[config.BundleId] = config case *webapi.GameMatchDateList: if isInit { TournamentMgr.UpdateData(true, config) } else { TournamentMgr.UpdateData(false, config) } case *webapi.GameMatchType: if isInit { TournamentMgr.UpdateTypeList(true, config) } else { TournamentMgr.UpdateTypeList(false, config) } case *webapi.ChannelSwitchConfig: PlatformMgrSingleton.GetConfig(config.Platform).ChannelSwitch[config.GetTp()] = config if !isInit { // 通知变更 PlayerMgrSington.BroadcastMessageToPlatform(config.Platform, int(playerproto.PlayerPacketID_PACKET_SCExchangeChannel), &playerproto.SCExchangeChannel{ Datas: []*playerproto.ChannelSwitch{{ Tp: config.Tp, OnChannelName: config.OnChannelName, }}, }) } case *webapi.GameConfigGroup: PlatformGameGroupMgrSington.UpsertGameGroup(config) case *webapi.Welfare7SignDateList: WelfareMgrSington.UpdateSign7(config) case *webapi.WelfareTurnplateDateList: WelfareMgrSington.UpdateTurnplate(config) case *webapi.WelfareBlindBoxDataList: WelfareMgrSington.UpdateBlindBox(config) case *webapi.WelfareFirstPayDataList: WelfareMgrSington.UpdateFirstPay(config) case *webapi.WelfareContinuousPayDataList: WelfareMgrSington.UpdateContinuousPay(config) case *webapi.VIPcfgDataList: VipMgrSington.UpdateVIPcfg(config) case *webapi.ChessRankcfgData: ChessRankMgrSington.UpdateChessRankConfig(config) case *webapi.WelfarePhoneLotteryStatus: WelfareMgrSington.UpdatePhoneLotteryStatus(config) case *webapi.DiamondLotteryConfig: WelfareMgrSington.UpdateDiamondLotteryConfig(config) case *webapi.ActInviteConfig: PlatformMgrSingleton.GetConfig(config.Platform).ActInviteConfig = config case *webapi.ActPermitConfig: PlatformMgrSingleton.GetConfig(config.Platform).ActPermitConfig = config st := new(model.PermitStartTs) permit := model.GetStrKVGameData(common.PermitStartTsKey + config.Platform) if permit != "" { if err := json.Unmarshal([]byte(permit), st); err != nil { logger.Logger.Errorf("permit startts error: %v", err) return } // 修改循环周期 endTs := st.StartTs + int64(config.GetDays()*24*3600) if st.StartTs > 0 && endTs != st.EndTs { st.EndTs = endTs } PlatformMgrSingleton.GetConfig(config.Platform).PermitStartTs = st.StartTs PlatformMgrSingleton.GetConfig(config.Platform).PermitEndTs = st.EndTs } else { startTs := common.GetDayStartTs(config.StartTs) endTs := startTs + int64(config.Days*24*3600) st.StartTs = startTs st.EndTs = endTs PlatformMgrSingleton.GetConfig(config.Platform).PermitStartTs = startTs PlatformMgrSingleton.GetConfig(config.Platform).PermitEndTs = endTs } f1 := func() { if st.StartTs <= 0 || st.EndTs <= 0 { return } b, err := json.Marshal(st) if err != nil { logger.Logger.Errorf("permit startts save error: %v", err) } else { logger.Logger.Infof("update permit startts: %v %v", st.StartTs, st.EndTs) err := model.UptStrKVGameData(common.PermitStartTsKey+config.Platform, string(b)) if err != nil { logger.Logger.Errorf("permit startts update error:%v", err) } } } f2 := func() { if st.StartTs > 0 { mq.Write(&model.BackendPermitCycle{ Platform: config.Platform, StartTs: st.StartTs, EndTs: st.EndTs - 1, }) } } if isInit { f1() f2() } else { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { f1() return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { f2() })).StartByExecutor("permit_start_ts") } case *webapi.ItemConfig: PlatformMgrSingleton.GetConfig(config.Platform).ItemConfig = config srvdata.GameItemMgr.SetConfig(config) if !isInit { var items []*serverproto.DB_GameItem for _, v := range config.GetItems() { items = append(items, &serverproto.DB_GameItem{ Id: v.GetId(), Name: v.GetName(), ShowLocation: v.GetShowLocation(), Classify: v.GetClassify(), Type: v.GetType(), Effect0: v.GetEffect0(), Effect: v.GetEffect(), SaleType: v.GetSaleType(), SaleGold: v.GetSaleGold(), Composition: v.GetComposition(), CompositionMax: v.GetCompositionMax(), Time: v.GetTime(), Location: v.GetLocation(), Describe: v.GetDescribe(), Num: v.GetNum(), Value: v.GetValue(), Entity: v.GetEntity(), Icon: v.GetIcon(), }) } if len(items) > 0 { PlayerMgrSington.BroadcastMessageToPlatform(config.Platform, int(playerproto.PlayerPacketID_PACKET_SCItem), &playerproto.SCItem{ Items: items, }) } } case *webapi.SkinConfig: PlatformMgrSingleton.GetConfig(config.Platform).SkinConfig = config case *webapi.RankTypeConfig: PlatformMgrSingleton.GetConfig(config.Platform).RankTypeConfig = config case *webapi.AwardLogConfig: PlatformMgrSingleton.GetConfig(config.Platform).AwardLogConfig = config case *webapi.GuideConfig: PlatformMgrSingleton.GetConfig(config.Platform).GuideConfig = config case *webapi.MachineConfig: PlatformMgrSingleton.GetConfig(config.Platform).MachineConfig = config case *webapi.SpiritConfig: PlatformMgrSingleton.GetConfig(config.Platform).SpiritConfig = config if !isInit { PlayerMgrSington.BroadcastDataConfigToPlatform(config.Platform, common.DataConfigSprite) } case *webapi.ClientUpgrade: PlatformMgrSingleton.GetConfig(config.Platform).ClientUpgrade = config case *webapi.PopUpWindowConfig: PlatformMgrSingleton.GetConfig(config.Platform).PopUpWindowConfig = config case *webapi.LotteryConfig: PlatformMgrSingleton.GetConfig(config.Platform).LotteryConfig = config LotteryMgrInst.UpdateConfig(config) default: logger.Logger.Errorf("etcd completeKey:%s, Not processed", completeKey) } } func handlerEvent(ctx context.Context, completeKey string, isInit bool, event *clientv3.Event, data interface{}) { var plt string var param []int equalFunc := func(key string) bool { plt = "" param = param[:0] if strings.HasPrefix(completeKey, key) { arr := strings.Split(strings.TrimPrefix(completeKey, key), "/") for k, v := range arr { if v == "" { continue } if len(v) > 0 { plt = v for _, v := range arr[k+1:] { n, err := strconv.Atoi(v) if err != nil { continue } param = append(param, n) } return true } } } return false } switch { case equalFunc(etcd.ETCDKEY_BLACKLIST_PREFIX): var config *BlackInfoApi if data != nil { config = data.(*BlackInfoApi) } if isInit { if config == nil { return } BlackListMgrSington.InitBlackInfo(config) } else { switch event.Type { case clientv3.EventTypeDelete: dirs := strings.Split(string(event.Kv.Key), "/") n := len(dirs) if n > 0 { last := dirs[n-1] id, err := strconv.Atoi(last) if err == nil { if value, exist := BlackListMgrSington.BlackList[int32(id)]; exist { BlackListMgrSington.RemoveBlackInfo(value.Id, value.Platform) } } } case clientv3.EventTypePut: if config == nil { return } BlackListMgrSington.UpsertBlackInfo(config) if (config.Space & int32(BlackState_Login)) != 0 { var targetPlayer []*Player //确定用户是否在线 for _, value := range PlayerMgrSington.players { _, ok := BlackListMgrSington.CheckPlayerInBlack(value.PlayerData, BlackState_Login) if ok { targetPlayer = append(targetPlayer, value) } } for _, p := range targetPlayer { if p.sid != 0 { p.Kick(int32(loginproto.SSDisconnectTypeCode_SSDTC_BlackList)) } else { LoginStateMgrSington.LogoutByAccount(p.AccountId) } } } } } case equalFunc(etcd.ETCDKEY_PROMOTER_PREFIX): var config *PromoterConfig if data != nil { config = data.(*PromoterConfig) } if isInit { if config == nil { return } PromoterMgrSington.AddConfig(config) } else { switch event.Type { case clientv3.EventTypeDelete: dirs := strings.Split(string(event.Kv.Key), "/") n := len(dirs) if n > 0 { promoterConfig := dirs[n-1] PromoterMgrSington.RemoveConfigByKey(promoterConfig) } case clientv3.EventTypePut: if config == nil { return } PromoterMgrSington.AddConfig(config) } } case equalFunc(etcd.ETCDKEY_MatchAudience): switch event.Type { case clientv3.EventTypePut: if data == nil { return } config := data.(*webapi.MatchAudience) PlatformMgrSingleton.AddMatchAudience(config) if !isInit { p := PlayerMgrSington.GetPlayerBySnId(config.GetSnId()) if p != nil { p.SCDataConfig(common.DataConfigMatchAudience) } } case clientv3.EventTypeDelete: if plt == "" || len(param) == 0 { return } PlatformMgrSingleton.DelMatchAudience(plt, int32(param[0])) if !isInit { p := PlayerMgrSington.GetPlayerBySnId(int32(param[0])) if p != nil { p.SCDataConfig(common.DataConfigMatchAudience) } } } case equalFunc(etcd.ETCDKEY_RoomType): switch event.Type { case clientv3.EventTypePut: if data == nil { return } config := data.(*webapi.RoomType) PlatformMgrSingleton.UpdateRoomType(config) if !isInit { //PlayerMgrSington.BroadcastMessageToPlatform(config.GetPlatform(), int(0), nil) } case clientv3.EventTypeDelete: if plt == "" || len(param) == 0 { return } PlatformMgrSingleton.DelRoomType(plt, int32(param[0])) if !isInit { //PlayerMgrSington.BroadcastMessageToPlatform(plt, int(0), nil) } } case equalFunc(etcd.ETCDKEY_RoomConfig): switch event.Type { case clientv3.EventTypePut: if data == nil { return } config := data.(*webapi.RoomConfig) PlatformMgrSingleton.UpdateRoomConfig(config) if !isInit { //PlayerMgrSington.BroadcastMessageToPlatform(config.GetPlatform(), int(0), nil) } case clientv3.EventTypeDelete: if plt == "" || len(param) == 0 { return } PlatformMgrSingleton.DelRoomConfig(plt, int32(param[0])) if !isInit { //PlayerMgrSington.BroadcastMessageToPlatform(plt, int(0), nil) } } case equalFunc(etcd.ETCDKEY_RoomConfigSystem): switch event.Type { case clientv3.EventTypePut: if data == nil { return } config := data.(*webapi.RoomConfigSystem) PlatformMgrSingleton.GetConfig(config.GetPlatform()).RoomConfigSystem[config.GetId()] = config switch config.GetOn() { case common.On: CustomRoomMgrSingle.TouchCreate(config.GetPlatform(), config.GetId()) case common.Off: if !isInit { CustomRoomMgrSingle.TryDestroy(config.GetPlatform(), config.GetId()) } } case clientv3.EventTypeDelete: if plt == "" || len(param) == 0 { return } if !isInit { CustomRoomMgrSingle.TryDestroy(plt, int32(param[0])) } delete(PlatformMgrSingleton.GetConfig(plt).RoomConfigSystem, int32(param[0])) } case equalFunc(etcd.ETCDKEY_LotteryUser): switch event.Type { case clientv3.EventTypePut: if data == nil { return } config := data.(*webapi.UserLottery) PlatformMgrSingleton.GetConfig(config.GetPlatform()).LotteryUser[config.GetId()] = config case clientv3.EventTypeDelete: if plt == "" || len(param) == 0 { return } delete(PlatformMgrSingleton.GetConfig(plt).LotteryUser, int64(param[0])) } default: logger.Logger.Errorf("etcd completeKey:%s, Not processed", completeKey) } }