From 899742d4ffbe932024bce897aca1a1c22883c036 Mon Sep 17 00:00:00 2001 From: zhora Date: Fri, 24 Oct 2025 15:39:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=85=A5pgsoft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/provider.go | 1 + modules/web/providers/all/all.go | 3 + modules/web/providers/pg4/api.go | 147 ++++++++++++++++++++++++++ modules/web/providers/pg4/base.go | 79 ++++++++++++++ modules/web/providers/pg4/handler.go | 151 +++++++++++++++++++++++++++ modules/web/providers/pg4/sign.go | 17 +++ modules/web/providers/pg4/values.go | 27 +++++ 7 files changed, 425 insertions(+) create mode 100644 modules/web/providers/pg4/api.go create mode 100644 modules/web/providers/pg4/base.go create mode 100644 modules/web/providers/pg4/handler.go create mode 100644 modules/web/providers/pg4/sign.go create mode 100644 modules/web/providers/pg4/values.go diff --git a/common/provider.go b/common/provider.go index 5f1e4c3..99373e1 100644 --- a/common/provider.go +++ b/common/provider.go @@ -41,6 +41,7 @@ const ( ProviderJin ProviderJin2 ProviderSn + ProviderPG4 ProviderAll ) diff --git a/modules/web/providers/all/all.go b/modules/web/providers/all/all.go index f433834..e1231c1 100644 --- a/modules/web/providers/all/all.go +++ b/modules/web/providers/all/all.go @@ -12,6 +12,7 @@ import ( "server/modules/web/providers/jin2" "server/modules/web/providers/pg2" "server/modules/web/providers/pg3" + "server/modules/web/providers/pg4" "server/modules/web/providers/pgsoft" "server/modules/web/providers/sn" "server/modules/web/providers/tada" @@ -59,6 +60,7 @@ type AllProvider struct { Jin func(b *base.Base) Jin2 func(b *base.Base) Sn func(b *base.Base) + PG4 func(b *base.Base) } var All = &AllProvider{} @@ -105,6 +107,7 @@ func initAll() { All.Jin = jin.NewSub All.Jin2 = jin2.NewSub All.Sn = sn.NewSub + All.PG4 = pg4.NewSub } func InitRouter(r *gin.RouterGroup) { diff --git a/modules/web/providers/pg4/api.go b/modules/web/providers/pg4/api.go new file mode 100644 index 0000000..7c7fb9b --- /dev/null +++ b/modules/web/providers/pg4/api.go @@ -0,0 +1,147 @@ +package pg4 + +import ( + "fmt" + "server/common" + "server/db" + "server/util" + "strconv" + "time" +) + +const ( + ErrCodeSuccess = 0 + ErrCodePlayerNotFound = 2000 // 玩家不存在 + ErrCodePlayerToken = 2001 // Token错误 + ErrCodeInvalidGameID = 102 // 无效的GameDI + ErrCodeInternalError = 3000 // 内部错误 + ErrCodeInsufficientBal = 2010 // 投注失败,如余额不足 +) + +type GameListResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data GameListData `json:"data"` +} + +type GameListData struct { + GameList []GameListItem `json:"glist"` +} + +type GameListItem struct { + Icon string `json:"icon"` + MapID string `json:"mapid"` + Name string `json:"name"` + Site string `json:"site"` + GameID string `json:"gameid"` +} + +// EnterGameRequest 进入游戏 +type EnterGameRequest struct { + Uname string `json:"uname"` // 用户名,最长30个字节 + GameID string `json:"gameid"` // 所进游戏的编码 + Token string `json:"token,omitempty"` // 用户验证token,最长120个字节,用于单一钱包的身份验证接口 + Lang string `json:"lang,omitempty"` // 游戏语言,默认为en + Nick string `json:"nick,omitempty"` // 用户昵称,最长40个字节 + TotalRecharge int64 `json:"totalRecharge"` // 总充值 + TotalBet int64 `json:"totalBet"` // 总下注 + Balance int64 `json:"balance"` // 金额 + TotalWithdraw int64 `json:"totalWithdraw"` // 总提现(已提现+提现打款中+玩家审核) +} +type EnterGameResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data struct { + GameURL string `json:"gameurl"` + } `json:"data"` +} + +// PlaceBetRequest 下注 +type PlaceBetRequest struct { + Uname string `json:"uname"` + Token string `json:"token"` + BetID string `json:"betid"` + SessionID string `json:"sessionid"` + GameID string `json:"gameid"` + Bet float64 `json:"bet"` + Award float64 `json:"award"` + IsEndRound bool `json:"is_end_round"` + Ctime int64 `json:"ctime"` +} + +type PlaceBetResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data struct { + Uname string `json:"uname"` + BetID string `json:"betid"` + Balance float64 `json:"balance"` + } `json:"data"` +} + +type VerifySessionReq struct { + Uname string `json:"uname"` + Token string `json:"token"` +} + +type VerifySessionResp struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data struct { + Uname string `json:"uname"` + Balance float64 `json:"balance"` + } `json:"data"` +} + +type GetBalanceRequest struct { + GameId string `json:"gameid"` + Uname string `json:"uname"` +} + +type GetBalanceResponse struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data struct { + Uname string `json:"uname"` + Balance float64 `json:"balance"` + } `json:"data"` +} + +func GetGameList() { + API = APITest + AgentMap = AgentMapTest + url := fmt.Sprintf("%s/api/game/loadlist", APITest) + mchid := AgentMap.MchId + key := AgentMap.Key + timestamp := time.Now().Unix() + headers := map[string]string{ + "X-Game-Mchid": mchid, + "X-Game-Timestamp": strconv.FormatInt(timestamp, 10), + "Content-Type": "application/json;charset=UTF-8", + } + type empty struct{} + var e empty + // Generate sign + emptyBody := "{}" + sign := GenerateSign(emptyBody, timestamp, key) + headers["X-Game-Sign"] = sign + + var response GameListResponse + err := util.HttpPost(url, e, &response, headers) + if err != nil { + return + } + + var gameList []*common.ConfigGameList + for _, item := range response.Data.GameList { + id, _ := strconv.Atoi(item.MapID) + gameList = append(gameList, &common.ConfigGameList{ + GameProvider: common.ProviderPG4, + GameID: id, + GameCode: item.GameID, + Icon: item.Icon, + Name: item.Name, + }) + } + db.Mysql().Create(gameList) +} diff --git a/modules/web/providers/pg4/base.go b/modules/web/providers/pg4/base.go new file mode 100644 index 0000000..820ea3b --- /dev/null +++ b/modules/web/providers/pg4/base.go @@ -0,0 +1,79 @@ +package pg4 + +import ( + "encoding/json" + "fmt" + "server/call" + "server/common" + "server/config" + "server/modules/web/providers/base" + utils "server/util" + "strconv" + "time" + + "github.com/liangdas/mqant/log" +) + +type Sub struct { + Base *base.Base +} + +func NewSub(base *base.Base) { + base.Sub = &Sub{Base: base} + base.SubInitRouter = PG +} + +func (s *Sub) Init() { + API = APITest + AgentMap = AgentMapTest + if config.GetBase().Release { + API = APIRelease + AgentMap = AgentMapRelease + } +} + +func (s *Sub) EnterGame() string { + url := fmt.Sprintf("%s/api/usr/ingame", API) + timestamp := time.Now().Unix() + uid := s.Base.EnterGameReq.UID + token := s.Base.EnterGameReq.Token + providerID := s.Base.EnterGameReq.ProviderID + gameID := s.Base.EnterGameReq.GameID + mchid := AgentMap.MchId + key := AgentMap.Key + headers := map[string]string{ + "X-Game-Mchid": mchid, + "X-Game-Timestamp": strconv.FormatInt(timestamp, 10), + "Content-Type": "application/json;charset=UTF-8", + } + rechargeInfo := call.GetRechargeInfo(uid) + balance := call.GetUserCurrency(uid, common.CurrencyINR) + playerProfile := call.GetPlayerProfile(uid) + game := call.GetConfigGameListByID(providerID, gameID) + if game == nil { + return "" + } + request := EnterGameRequest{ + Uname: common.GetProviderUserName(fmt.Sprintf("%d", uid)), + GameID: game.GameCode, + Token: common.GetProviderUserToken(token), + Lang: "pt", + Nick: "", + TotalRecharge: rechargeInfo.TotalRecharge, + TotalWithdraw: rechargeInfo.TotalWithdraw + rechargeInfo.TotalWithdrawing, + TotalBet: playerProfile.TotalBet, + Balance: balance / common.DecimalDigits, + } + body, _ := json.Marshal(request) + sign := GenerateSign(string(body), timestamp, key) + headers["X-Game-Sign"] = sign + // Decode response + var response EnterGameResponse + err := utils.HttpPost(url, request, &response, headers) + if err != nil { + log.Error("err:%v", err) + return "" + } + + return response.Data.GameURL +} diff --git a/modules/web/providers/pg4/handler.go b/modules/web/providers/pg4/handler.go new file mode 100644 index 0000000..8fb0be1 --- /dev/null +++ b/modules/web/providers/pg4/handler.go @@ -0,0 +1,151 @@ +package pg4 + +import ( + "server/call" + "server/common" + "server/db" + "server/modules/web/app" + "server/modules/web/providers/base" + "server/util" + "strconv" + "time" + + "github.com/gin-gonic/gin" + "github.com/liangdas/mqant/log" +) + +func PG(e *gin.RouterGroup) { + e.POST("/VerifySession", VerifySession) + e.POST("/Cash/Get", GetPlayerBalance) + e.POST("/Cash/Bet", PlaceBet) +} + +func GetGameID(providerID int, gameCode string) int { + game := call.GetConfigGameListByCode(providerID, gameCode) + if game != nil { + return game.GameID + } + return 0 +} + +func VerifySession(c *gin.Context) { + a := app.NewApp(c) + defer func() { + a.ResponseB() + }() + req := &VerifySessionReq{} + resp := &VerifySessionResp{} + a.RetData = resp + if !a.SB(req) { + resp.Code = ErrCodeInternalError + return + } + log.Debug("VerifySession req:%+v", req) + + if a.ShouldRoute(req, "Uname", common.ProviderAPITypeJson) { + return + } + + uid, err := strconv.Atoi(req.Uname) + if err != nil { + log.Error("err:%v", err) + resp.Code = ErrCodePlayerNotFound + return + } + + resp.Data.Balance = call.GetUserCurrencyFloat(uid, common.CurrencyINR, common.DecimalDigits) + log.Debug("VerifySession resp:%+v", *resp) + a.Data = resp +} + +func GetPlayerBalance(c *gin.Context) { + a := app.NewApp(c) + defer func() { + a.ResponseB() + }() + req := &GetBalanceRequest{} + resp := &GetBalanceResponse{} + a.RetData = resp + if !a.SB(req) { + resp.Code = ErrCodeInternalError + return + } + log.Debug("GetPlayerBalance req:%+v", req) + + if a.ShouldRoute(req, "Uname", common.ProviderAPITypeJson) { + return + } + + uid, err := strconv.Atoi(req.Uname) + if err != nil { + log.Error("err:%v", err) + resp.Code = ErrCodePlayerNotFound + return + } + + resp.Data.Uname = req.Uname + resp.Data.Balance = call.GetUserCurrencyFloat(uid, common.CurrencyINR, common.DecimalDigits) + a.Data = resp + + log.Debug("GetPlayerBalance resp:%+v", resp) +} + +func PlaceBet(c *gin.Context) { + a := app.NewApp(c) + defer func() { + a.ResponseB() + }() + req := &PlaceBetRequest{} + resp := &PlaceBetResponse{} + a.RetData = resp + if !a.SB(req) { + resp.Code = ErrCodeInternalError + return + } + log.Debug("PlaceBet:%+v", req) + + if a.ShouldRoute(req, "Token", common.ProviderAPITypeJson) { + return + } + + // 验证token + uid, _ := db.Redis().GetInt(common.GetRedisKeyToken(req.Token)) + if uid == 0 { + resp.Code = ErrCodePlayerNotFound + return + } + + provider := call.GetConfigGameProvider(common.ProviderPG4) + now := time.Now().Unix() + 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.ProviderPG4, 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 { + resp.Code = ErrCodeInternalError + } else if betResp.Code == base.CodeNotEnoughAmount { + resp.Code = ErrCodeInsufficientBal + } + 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) + } + + a.Data = resp +} diff --git a/modules/web/providers/pg4/sign.go b/modules/web/providers/pg4/sign.go new file mode 100644 index 0000000..c88c65d --- /dev/null +++ b/modules/web/providers/pg4/sign.go @@ -0,0 +1,17 @@ +package pg4 + +import ( + "crypto/md5" + "encoding/hex" + "strconv" + "strings" + + "github.com/liangdas/mqant/log" +) + +func GenerateSign(body string, timestamp int64, key string) string { + data := body + strconv.FormatInt(timestamp, 10) + key + log.Info("data:%v", data) + hash := md5.Sum([]byte(data)) + return strings.ToUpper(hex.EncodeToString(hash[:])) +} diff --git a/modules/web/providers/pg4/values.go b/modules/web/providers/pg4/values.go new file mode 100644 index 0000000..07ec572 --- /dev/null +++ b/modules/web/providers/pg4/values.go @@ -0,0 +1,27 @@ +package pg4 + +const ( + APIRelease = "https://pggame.ux7k.com" + APITest = "https://pggame.1iibet.com" + LaunchGameURL = "/api/usr/ingame" + GetGameListURL = "/api/game/loadlist" + Lang = "en" +) + +type Agent struct { + MchId string `json:"mch_id"` + Key string `json:"key"` +} + +var ( + API = "" + AgentMap Agent + AgentMapTest = Agent{ + "10087", + "12DD45A2758A9AEA0224DB8B7F8A36E3", + } + AgentMapRelease = Agent{ + "10088", + "E21B1CFF68CD984C6ADB25554BAF16C3", + } +)