From 87bdf82aa6d997031220fdf09ad083398630290b Mon Sep 17 00:00:00 2001 From: mofangmin Date: Tue, 3 Sep 2024 17:54:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5pg=E5=92=8Cjili,rtp=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- call/config.go | 25 ++++++++ call/reload.go | 10 ++++ call/user.go | 26 +++++++++ common/activity.go | 13 +++++ common/config.go | 11 ++-- common/player.go | 10 ++++ .../backend/handler/guser/editGameUserGold.go | 21 +++++++ .../backend/handler/guser/getGameUserInfo.go | 5 ++ modules/backend/migrate.go | 2 + modules/backend/routers/routers_guser.go | 1 + modules/backend/values/gameuser.go | 6 ++ modules/backend/values/gm.go | 2 + modules/web/providers/base/base.go | 58 +++++++++++-------- modules/web/providers/jili2/api.go | 11 ++-- modules/web/providers/jili2/base.go | 13 +++-- modules/web/providers/jili2/handler.go | 48 ++++++++------- modules/web/providers/pg2/api.go | 11 ++-- modules/web/providers/pg2/base.go | 13 +++-- modules/web/providers/pg2/handler.go | 48 ++++++++------- modules/web/providers/pg2/values.go | 4 +- 20 files changed, 243 insertions(+), 95 deletions(-) diff --git a/call/config.go b/call/config.go index b5d1f7c..8c605fa 100644 --- a/call/config.go +++ b/call/config.go @@ -65,6 +65,7 @@ var ( configBetDraw []*common.ConfigActivityBetDraw configActivityPopup []*common.ConfigActivityPopup configDiscountTicket []common.ConfigDiscountTicket + configRtp []common.ConfigRtp // 客服 configCustomerRobot []*common.ConfigCustomerRobot customerOrderLabel []*common.CustomerOrderLabel @@ -1586,3 +1587,27 @@ func GetConfigDiscountTicketByAmount(amount int64) (ret common.ConfigDiscountTic } return } + +func LoadConfigRTP() (err error) { + var list []common.ConfigRtp + if _, err = db.Mysql().QueryAll("", "", &common.ConfigRtp{}, &list); err != nil { + log.Error("err:%v", err) + return err + } + configRtp = list + return nil +} + +func GetConfigRTP() []common.ConfigRtp { + return configRtp +} + +// GetConfigRTPByAmount +func GetConfigRTPByAmount(amount int64) (ret common.ConfigRtp) { + for _, item := range configRtp { + if amount >= item.MinRecharge && amount <= item.MinRecharge { + return item + } + } + return +} diff --git a/call/reload.go b/call/reload.go index c63050d..40933cc 100644 --- a/call/reload.go +++ b/call/reload.go @@ -476,6 +476,16 @@ func CommonReload(c map[int][]func(*pb.ReloadGameConfig) error) { return nil }} } + + if _, ok := c[common.ReloadConfigRTP]; !ok { + c[common.ReloadConfigRTP] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { + if err := LoadConfigRTP(); err != nil { + log.Error("error : [%s]", err.Error()) + return err + } + return nil + }} + } // 客服 if _, ok := c[common.ReloadConfigCustomerRobot]; !ok { c[common.ReloadConfigCustomerRobot] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { diff --git a/call/user.go b/call/user.go index 8300268..106c415 100644 --- a/call/user.go +++ b/call/user.go @@ -784,3 +784,29 @@ func GetPlayerFavoriteList(uid, num int) (gameList []*common.ConfigGameList) { } return } + +func GetUserRtp(uid int) *common.PlayerRtpData { + data := &common.PlayerRtpData{Uid: uid} + db.Mysql().Get(&data) + return data +} + +func GetRtpControl(uid int) int { + rechargeInfo := GetRechargeInfo(uid) + withdrawRechargePer := (rechargeInfo.TotalWithdraw + rechargeInfo.WithdrawingCash) / rechargeInfo.TotalRecharge + rtpConf := GetConfigRTPByAmount(rechargeInfo.TotalRecharge) + rtpData := GetUserRtp(uid) + // 1.优先玩家配置 + // 2.个控 + // 3.大盘 + rtp := GetConfigPlatform().Rtp + if rtpData.Id > 0 { + rtp = rtpData.Rtp + } + if rtp > 0 && rtpConf.Id > 0 { + if withdrawRechargePer >= int64(rtpConf.EnterPer) && withdrawRechargePer <= int64(rtpConf.ExitPer) { + rtp = rtpConf.Rtp + } + } + return rtp +} diff --git a/common/activity.go b/common/activity.go index 69ae928..b1af671 100644 --- a/common/activity.go +++ b/common/activity.go @@ -561,3 +561,16 @@ type ConfigDiscountTicket struct { func (m *ConfigDiscountTicket) TableName() string { return "config_discount_ticket" } + +type ConfigRtp struct { + Id int `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT" json:"id"` + MinRecharge int64 `gorm:"column:min_recharge;type:bigint(20);comment:最小充值" json:"min_recharge"` + MaxRecharge int64 `gorm:"column:max_recharge;type:bigint(20);comment:最小充值" json:"max_recharge"` + Rtp int `gorm:"column:rtp;type:int(11);comment:rtp" json:"rtp"` + EnterPer int `gorm:"column:enter_per;type:int(11);comment:进入提存比" json:"enter_per"` + ExitPer int `gorm:"column:exit_per;type:int(11);comment:退出提存比" json:"exit_per"` +} + +func (m *ConfigRtp) TableName() string { + return "config_rtp" +} diff --git a/common/config.go b/common/config.go index 8824ee1..eab6482 100644 --- a/common/config.go +++ b/common/config.go @@ -53,10 +53,10 @@ const ( ReloadConfigBetDraw // 下注抽奖 ReloadConfigActivityPopup // 活动弹窗 ReloadConfigDiscountTicket // 折扣券 - - ReloadConfigCustomerRobot // 客服系统机器人配置 - ReloadConfigCustomerLabel // 客服系统订单标签 - ReloadConfigCustomer // 客服系统订单标签 + ReloadConfigRTP // rtp配置 + ReloadConfigCustomerRobot // 客服系统机器人配置 + ReloadConfigCustomerLabel // 客服系统订单标签 + ReloadConfigCustomer // 客服系统订单标签 ) // GetConfigStructByType 获取相应配置的结构 @@ -150,6 +150,8 @@ func GetConfigStructByType(t int) (interface{}, interface{}) { return &ConfigActivityPopup{}, &[]ConfigActivityPopup{} case ReloadConfigDiscountTicket: return &ConfigDiscountTicket{}, &[]ConfigDiscountTicket{} + case ReloadConfigRTP: + return &ConfigRtp{}, &[]ConfigRtp{} default: return nil, nil } @@ -176,6 +178,7 @@ type ConfigPlatform struct { PayTips string `gorm:"column:pay_tips;type:varchar(256);default:'';comment:充值提示语" json:"PayTips" web:"pay_tips"` WithdrawTips string `gorm:"column:withdraw_tips;type:varchar(256);default:'';comment:tx提示语" json:"WithdrawTips" web:"withdraw_tips"` BlackList int `gorm:"column:black_list;type:int(11);default:0;comment:是否开启黑名单 0不开 1开启" json:"BlackList" web:"black_list"` + Rtp int `gorm:"column:rtp;type:int(11);default:0;comment:平台RTP" json:"Rtp" web:"rtp"` } func (c *ConfigPlatform) TableName() string { diff --git a/common/player.go b/common/player.go index 23de945..8b65cd7 100644 --- a/common/player.go +++ b/common/player.go @@ -311,3 +311,13 @@ type PlayerPayData struct { func (c *PlayerPayData) TableName() string { return "player_pay_data" } + +type PlayerRtpData struct { + Id int `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT" json:"id"` + Uid int `gorm:"column:uid;type:int(11)" json:"uid"` + Rtp int `gorm:"column:rtp;type:int(11)" json:"rtp"` +} + +func (c *PlayerRtpData) TableName() string { + return "player_rtp_data" +} diff --git a/modules/backend/handler/guser/editGameUserGold.go b/modules/backend/handler/guser/editGameUserGold.go index d86d7b9..20cb6f3 100644 --- a/modules/backend/handler/guser/editGameUserGold.go +++ b/modules/backend/handler/guser/editGameUserGold.go @@ -4,6 +4,7 @@ import ( "fmt" "server/call" "server/common" + "server/db" "server/modules/backend/app" "server/modules/backend/values" @@ -40,3 +41,23 @@ func EditGameUserGold(c *gin.Context) { } a.RecordEdit(values.PowerGUser, fmt.Sprintf("修改玩家%v金币:%v", req.UID, req.Amount)) } + +func EditGameUserRtp(c *gin.Context) { + a := app.NewApp(c) + defer func() { + a.Response() + }() + req := new(values.EditGameUserRtpReq) + if !a.S(req) { + return + } + err := db.Mysql().Update(&common.PlayerRtpData{Uid: req.UID}, map[string]interface{}{ + "rtp": req.Val, + }) + if err != nil { + a.Code = values.CodeRetry + a.Msg = "modify rtp error" + } + + a.RecordEdit(values.PowerGUser, fmt.Sprintf("修改玩家%vRtp:%v", req.UID, req.Val)) +} diff --git a/modules/backend/handler/guser/getGameUserInfo.go b/modules/backend/handler/guser/getGameUserInfo.go index 2d6aa73..f8437e9 100644 --- a/modules/backend/handler/guser/getGameUserInfo.go +++ b/modules/backend/handler/guser/getGameUserInfo.go @@ -93,6 +93,11 @@ func GetGameUserInfo(c *gin.Context) { // usdtInfo := call.GetPlayerRechargeInfoByCurrency(uid, common.CurrencyUSDT) resp.RechargeBrl = brlInfo.TotalRecharge resp.WithdrawBrl = brlInfo.TotalWithdraw + rtp := call.GetUserRtp(uid) + if rtp.Id == 0 { + db.Mysql().Create(rtp) + } + resp.Rtp = rtp.Rtp // resp.RechargeUsdt = usdtInfo.TotalRecharge // resp.WithdrawUsdt = usdtInfo.TotoalWithdraw diff --git a/modules/backend/migrate.go b/modules/backend/migrate.go index dfcefc9..3ea94ab 100644 --- a/modules/backend/migrate.go +++ b/modules/backend/migrate.go @@ -117,6 +117,8 @@ func MigrateDB() { new(common.SheetBroadcastConfig), new(common.SheetNoticeConfig), new(common.ConfigDiscountTicket), + new(common.ConfigRtp), + new(common.PlayerRtpData), ) if err != nil { panic("Migrate db fail") diff --git a/modules/backend/routers/routers_guser.go b/modules/backend/routers/routers_guser.go index bed36fe..600876a 100644 --- a/modules/backend/routers/routers_guser.go +++ b/modules/backend/routers/routers_guser.go @@ -19,6 +19,7 @@ func guser(e *gin.Engine) { e.POST("/guser/controlBalance", handler.GetGameUserControlBalance) // e.POST("/guser/controlCardData", handler.ControlCardData) e.POST("/guser/editGold", handler.EditGameUserGold) + e.POST("/guser/editRtp", handler.EditGameUserRtp) e.POST("/guser/editStatus", handler.EditGameUserStatus) e.POST("/guser/addUserTag", handler.AddUserTag) e.POST("/guser/deleteUserTag", handler.AddUserTag) diff --git a/modules/backend/values/gameuser.go b/modules/backend/values/gameuser.go index 8606ee8..58f5320 100644 --- a/modules/backend/values/gameuser.go +++ b/modules/backend/values/gameuser.go @@ -137,6 +137,7 @@ type GetGameUserInfoResp struct { OutputData map[string]string Gpsadid string SubAccount []int + Rtp int } type UserGameInfo struct { @@ -415,6 +416,11 @@ type EditGameUserGoldReq struct { Amount int64 `json:"Amount" binding:"required"` } +type EditGameUserRtpReq struct { + UID int `json:"UID" binding:"required"` + Val int +} + // EditGameUserGoldReq 修改玩家状态,解封/封禁 // UID 玩家uid // Status 修改的状态 1正常 2封禁 diff --git a/modules/backend/values/gm.go b/modules/backend/values/gm.go index eac185e..d11f128 100644 --- a/modules/backend/values/gm.go +++ b/modules/backend/values/gm.go @@ -164,6 +164,8 @@ func GetControlType(path string) int { return common.ReloadConfigActivityPopup case "discountTicket": return common.ReloadConfigDiscountTicket + case "configRtp": + return common.ReloadConfigRTP default: return 0 } diff --git a/modules/web/providers/base/base.go b/modules/web/providers/base/base.go index d8520cf..1bbd9a4 100644 --- a/modules/web/providers/base/base.go +++ b/modules/web/providers/base/base.go @@ -1,6 +1,7 @@ package base import ( + "errors" "fmt" "server/call" "server/common" @@ -366,33 +367,36 @@ func SessionBet(req *BetReq) (resp BetResp) { resp.MyUUID = uuid return } - pro := call.MineCurrencyProReal( - &common.UpdateCurrency{ - CurrencyBalance: &common.CurrencyBalance{ - UID: uid, - Type: ct, - Event: common.CurrencyEventGameBet, - Value: -betAmount, - Exi1: req.Provider.ProviderID, - Exi2: req.GameID, - Exs1: fmt.Sprintf("%d", uuid), - Exs2: req.BetID, - Exs3: req.SessionID, + if betAmount > 0 { + pro := call.MineCurrencyProReal( + &common.UpdateCurrency{ + CurrencyBalance: &common.CurrencyBalance{ + UID: uid, + Type: ct, + Event: common.CurrencyEventGameBet, + Value: -betAmount, + Exi1: req.Provider.ProviderID, + Exi2: req.GameID, + Exs1: fmt.Sprintf("%d", uuid), + Exs2: req.BetID, + Exs3: req.SessionID, + }, }, - }, - ) - if pro.Err != nil { - log.Error("err:%v", pro.Err) - resp.Code = CodeInnerError - if pro.Err == call.ErrNotEnoughBalance { - resp.Code = CodeNotEnoughAmount + ) + if pro.Err != nil { + log.Error("err:%v", pro.Err) + resp.Code = CodeInnerError + if errors.Is(pro.Err, call.ErrNotEnoughBalance) { + resp.Code = CodeNotEnoughAmount + } + } + if req.SessionType == SessionTypeBet { + resp.Balance = pro.Balance + resp.MyUUID = uuid + return } } - if req.SessionType == SessionTypeBet { - resp.Balance = pro.Balance - resp.MyUUID = uuid - return - } + var pro *call.ProRes setValue := settle + req.Preserve if setValue != 0 { cb := &common.CurrencyBalance{ @@ -430,7 +434,11 @@ func SessionBet(req *BetReq) (resp BetResp) { MyUUID: fmt.Sprintf("%d", uuid), }) }) - resp.Balance = pro.Balance + if pro != nil { + resp.Balance = pro.Balance + } else { + resp.Balance = call.GetUserCurrency(uid, ct) + } resp.MyUUID = uuid return } diff --git a/modules/web/providers/jili2/api.go b/modules/web/providers/jili2/api.go index d29c7f0..b216e37 100644 --- a/modules/web/providers/jili2/api.go +++ b/modules/web/providers/jili2/api.go @@ -38,11 +38,12 @@ type GameListItem struct { // EnterGameRequest 进入游戏 type EnterGameRequest struct { - Uname string `json:"uname"` - GameID string `json:"gameid"` - Token string `json:"token,omitempty"` - Lang string `json:"lang,omitempty"` - Nick string `json:"nick,omitempty"` + Uname string `json:"uname"` + GameID string `json:"gameid"` + Token string `json:"token,omitempty"` + Lang string `json:"lang,omitempty"` + Nick string `json:"nick,omitempty"` + RtpPool int `json:"rtp_pool"` } type EnterGameResponse struct { diff --git a/modules/web/providers/jili2/base.go b/modules/web/providers/jili2/base.go index b59169d..3906eb2 100644 --- a/modules/web/providers/jili2/base.go +++ b/modules/web/providers/jili2/base.go @@ -40,6 +40,8 @@ func (s *Sub) EnterGame() string { gameID := s.Base.EnterGameReq.GameID mchid := AgentMap.MchId key := AgentMap.Key + rtp := call.GetRtpControl(uid) + log.Info("uid:%v,rtp:%v", uid, rtp) headers := map[string]string{ "X-Atgame-Mchid": mchid, "X-Atgame-Timestamp": strconv.FormatInt(timestamp, 10), @@ -51,11 +53,12 @@ func (s *Sub) EnterGame() string { return "" } request := EnterGameRequest{ - Uname: fmt.Sprintf("%d", uid), - GameID: game.GameCode, - Token: token, - Lang: Lang, - Nick: "", + Uname: fmt.Sprintf("%d", uid), + GameID: game.GameCode, + Token: token, + Lang: Lang, + Nick: "", + RtpPool: rtp, } body, _ := json.Marshal(request) sign := GenerateSign(string(body), timestamp, key) diff --git a/modules/web/providers/jili2/handler.go b/modules/web/providers/jili2/handler.go index 99ef222..7c480f7 100644 --- a/modules/web/providers/jili2/handler.go +++ b/modules/web/providers/jili2/handler.go @@ -113,31 +113,35 @@ func PlaceBet(c *gin.Context) { provider := call.GetConfigGameProvider(common.ProviderJiLi2) now := time.Now().Unix() - betReq := &base.BetReq{ - UID: uid, - CurrencyType: common.CurrencyINR, - BetAmount: int64(req.Bet * common.DecimalDigits), - TurnOver: int64(req.Bet * common.DecimalDigits), - SettleAmount: int64(req.Award * common.DecimalDigits), - SessionType: common.SessionTypeSettle, - GameID: GetGameID(common.ProviderJiLi2, req.GameID), - GameName: req.GameID, - Provider: provider, - BetID: req.BetID, - SessionID: req.SessionID, - Time: now, - } - betResp := base.SessionBet(betReq) - if betResp.Code != base.CodeOk { - resp.Code = ErrCodeInternalError - if betResp.Code == base.CodeAccepted { + if req.Bet != 0 || req.Award != 0 { + betReq := &base.BetReq{ + UID: uid, + CurrencyType: common.CurrencyINR, + BetAmount: int64(req.Bet * common.DecimalDigits), + TurnOver: int64(req.Bet * common.DecimalDigits), + SettleAmount: int64(req.Award * common.DecimalDigits), + SessionType: common.SessionTypeSettle, + GameID: GetGameID(common.ProviderPG2, req.GameID), + GameName: req.GameID, + Provider: provider, + BetID: req.BetID, + SessionID: req.SessionID, + Time: now, + } + betResp := base.SessionBet(betReq) + if betResp.Code != base.CodeOk { resp.Code = ErrCodeInternalError - } else if betResp.Code == base.CodeNotEnoughAmount { - resp.Code = ErrCodeInsufficientBal + if betResp.Code == base.CodeAccepted { + resp.Code = ErrCodeInternalError + } else if betResp.Code == base.CodeNotEnoughAmount { + resp.Code = ErrCodeInsufficientBal + } + return } - return + resp.Data.Balance = util.Decimal(float64(betResp.Balance)/common.DecimalDigits, 2) + } else { + resp.Data.Balance = util.Decimal(float64(call.GetUserCurrency(uid, common.CurrencyINR))/common.DecimalDigits, 2) } - resp.Data.Balance = util.Decimal(float64(betResp.Balance)/common.DecimalDigits, 2) a.Data = resp } diff --git a/modules/web/providers/pg2/api.go b/modules/web/providers/pg2/api.go index 322f948..12e39fb 100644 --- a/modules/web/providers/pg2/api.go +++ b/modules/web/providers/pg2/api.go @@ -38,11 +38,12 @@ type GameListItem struct { // EnterGameRequest 进入游戏 type EnterGameRequest struct { - Uname string `json:"uname"` - GameID string `json:"gameid"` - Token string `json:"token,omitempty"` - Lang string `json:"lang,omitempty"` - Nick string `json:"nick,omitempty"` + Uname string `json:"uname"` + GameID string `json:"gameid"` + Token string `json:"token,omitempty"` + Lang string `json:"lang,omitempty"` + Nick string `json:"nick,omitempty"` + RtpPool int `json:"rtp_pool"` } type EnterGameResponse struct { diff --git a/modules/web/providers/pg2/base.go b/modules/web/providers/pg2/base.go index f131189..3a55ce5 100644 --- a/modules/web/providers/pg2/base.go +++ b/modules/web/providers/pg2/base.go @@ -40,6 +40,8 @@ func (s *Sub) EnterGame() string { gameID := s.Base.EnterGameReq.GameID mchid := AgentMap.MchId key := AgentMap.Key + rtp := call.GetRtpControl(uid) + log.Info("uid:%v,rtp:%v", uid, rtp) headers := map[string]string{ "X-Atgame-Mchid": mchid, "X-Atgame-Timestamp": strconv.FormatInt(timestamp, 10), @@ -51,11 +53,12 @@ func (s *Sub) EnterGame() string { return "" } request := EnterGameRequest{ - Uname: fmt.Sprintf("%d", uid), - GameID: game.GameCode, - Token: token, - Lang: Lang, - Nick: "", + Uname: fmt.Sprintf("%d", uid), + GameID: game.GameCode, + Token: token, + Lang: Lang, + Nick: "", + RtpPool: rtp, } body, _ := json.Marshal(request) sign := GenerateSign(string(body), timestamp, key) diff --git a/modules/web/providers/pg2/handler.go b/modules/web/providers/pg2/handler.go index 9a36947..d08b34d 100644 --- a/modules/web/providers/pg2/handler.go +++ b/modules/web/providers/pg2/handler.go @@ -113,31 +113,35 @@ func PlaceBet(c *gin.Context) { provider := call.GetConfigGameProvider(common.ProviderPG2) now := time.Now().Unix() - betReq := &base.BetReq{ - UID: uid, - CurrencyType: common.CurrencyINR, - BetAmount: int64(req.Bet * common.DecimalDigits), - TurnOver: int64(req.Bet * common.DecimalDigits), - SettleAmount: int64(req.Award * common.DecimalDigits), - SessionType: common.SessionTypeSettle, - GameID: GetGameID(common.ProviderPG2, req.GameID), - GameName: req.GameID, - Provider: provider, - BetID: req.BetID, - SessionID: req.SessionID, - Time: now, - } - betResp := base.SessionBet(betReq) - if betResp.Code != base.CodeOk { - resp.Code = ErrCodeInternalError - if betResp.Code == base.CodeAccepted { + if req.Bet != 0 || req.Award != 0 { + betReq := &base.BetReq{ + UID: uid, + CurrencyType: common.CurrencyINR, + BetAmount: int64(req.Bet * common.DecimalDigits), + TurnOver: int64(req.Bet * common.DecimalDigits), + SettleAmount: int64(req.Award * common.DecimalDigits), + SessionType: common.SessionTypeSettle, + GameID: GetGameID(common.ProviderPG2, req.GameID), + GameName: req.GameID, + Provider: provider, + BetID: req.BetID, + SessionID: req.SessionID, + Time: now, + } + betResp := base.SessionBet(betReq) + if betResp.Code != base.CodeOk { resp.Code = ErrCodeInternalError - } else if betResp.Code == base.CodeNotEnoughAmount { - resp.Code = ErrCodeInsufficientBal + if betResp.Code == base.CodeAccepted { + resp.Code = ErrCodeInternalError + } else if betResp.Code == base.CodeNotEnoughAmount { + resp.Code = ErrCodeInsufficientBal + } + return } - return + resp.Data.Balance = util.Decimal(float64(betResp.Balance)/common.DecimalDigits, 2) + } else { + resp.Data.Balance = util.Decimal(float64(call.GetUserCurrency(uid, common.CurrencyINR))/common.DecimalDigits, 2) } - resp.Data.Balance = util.Decimal(float64(betResp.Balance)/common.DecimalDigits, 2) a.Data = resp } diff --git a/modules/web/providers/pg2/values.go b/modules/web/providers/pg2/values.go index 227af42..2f246e3 100644 --- a/modules/web/providers/pg2/values.go +++ b/modules/web/providers/pg2/values.go @@ -17,8 +17,8 @@ var ( API = "" AgentMap Agent AgentMapTest = Agent{ - "10055", - "170779CCC5E9FE29DBB3F5FEDBB304A0", + "10071", + "E3D1A83FA82F04D9725ACB5A77578A65", } AgentMapRelease = Agent{} )