diff --git a/bin/conf/web/conf.toml b/bin/conf/web/conf.toml index bc54d6e..d7dcfed 100644 --- a/bin/conf/web/conf.toml +++ b/bin/conf/web/conf.toml @@ -1,5 +1,5 @@ [Web] -Addr=":7615" +Addr=":9615" Release=true TLS=false CertFile="" diff --git a/common/provider.go b/common/provider.go index c66577a..adef847 100644 --- a/common/provider.go +++ b/common/provider.go @@ -37,6 +37,7 @@ const ( ProviderSBO ProviderPG2 ProviderJiLi2 + ProviderPG3 ProviderAll ) diff --git a/modules/web/handler/game.go b/modules/web/handler/game.go index b2073fe..9b19b87 100644 --- a/modules/web/handler/game.go +++ b/modules/web/handler/game.go @@ -98,23 +98,19 @@ func EnterGame(c *gin.Context) { } a.Data = resp // step:特殊逻辑处理 - providerId := 0 if req.Provider == common.ProviderPGSoft { - providerId = common.ProviderPG2 - } - if req.Provider == common.ProviderJili { - providerId = common.ProviderJiLi2 - } - if providerId > 0 { - provider = call.GetConfigGameProvider(providerId) - game := call.GetConfigGameListByID(providerId, req.GameID) + provider = call.GetConfigGameProvider(common.ProviderPG3) + game := call.GetConfigGameListByID(common.ProviderPG3, req.GameID) if game != nil && game.Open == 1 { - req.Provider = providerId + req.Provider = common.ProviderPG3 resp.Method = provider.Method } else { - a.Code = values.CodeParam - a.Msg = "Under Maintenance,please try later." - return + provider = call.GetConfigGameProvider(common.ProviderPG2) + game = call.GetConfigGameListByID(common.ProviderPG2, req.GameID) + if game != nil && game.Open == 1 { + req.Provider = common.ProviderPG2 + resp.Method = provider.Method + } } } diff --git a/modules/web/handler/recharge.go b/modules/web/handler/recharge.go index f87280f..cc1f3fc 100644 --- a/modules/web/handler/recharge.go +++ b/modules/web/handler/recharge.go @@ -216,11 +216,11 @@ func PlayerRecharge(c *gin.Context) { } }) - // if !config.GetBase().Release && req.PayChannel == config.GetConfig().Web.TestPay { - // util.Go(func() { - // call.RechargeCallback(payImp.Order, true, "", "") - // }) - // } + if !config.GetBase().Release { + util.Go(func() { + call.RechargeCallback(payImp.Order, true, "", "") + }) + } } func NewRechargeImp(req *values.RechargeReq, uid, cid int, ip string) *RechargeImp { diff --git a/modules/web/module.go b/modules/web/module.go index 396ddc2..e3527ad 100644 --- a/modules/web/module.go +++ b/modules/web/module.go @@ -10,6 +10,7 @@ import ( edb "server/db/es" mdb "server/db/mysql" rdb "server/db/redis" + "server/modules/web/providers/jili2" "server/modules/web/routers" "server/util" "time" @@ -52,7 +53,7 @@ func (w *Web) OnInit(app module.App, settings *conf.ModuleSettings) { // 自动初始化数据库 // MigrateDB() call.NewCaller(w) - + jili2.GetGameList() call.NewSnowflake(int64(config.GetConfig().WorkID)) // 创建一个随机数生成器 @@ -72,7 +73,7 @@ func (w *Web) OnInit(app module.App, settings *conf.ModuleSettings) { // 拉取缓存数据 util.Go(func() { - FetchDatas() + // FetchDatas() }) } diff --git a/modules/web/providers/all/all.go b/modules/web/providers/all/all.go index e85b9c1..22dcc48 100644 --- a/modules/web/providers/all/all.go +++ b/modules/web/providers/all/all.go @@ -9,6 +9,7 @@ import ( "server/modules/web/providers/gs" "server/modules/web/providers/jili2" "server/modules/web/providers/pg2" + "server/modules/web/providers/pg3" "server/modules/web/providers/pgsoft" "server/modules/web/providers/tada" @@ -51,6 +52,7 @@ type AllProvider struct { SBO func(b *base.Base) PG2 func(b *base.Base) Jili2 func(b *base.Base) + PG3 func(b *base.Base) } var All = &AllProvider{} @@ -93,6 +95,7 @@ func initAll() { All.SBO = gs.NewSub All.PG2 = pg2.NewSub All.Jili2 = jili2.NewSub + All.PG3 = pg3.NewSub } func InitRouter(r *gin.RouterGroup) { diff --git a/modules/web/providers/jili2/api.go b/modules/web/providers/jili2/api.go index b216e37..a66fa5a 100644 --- a/modules/web/providers/jili2/api.go +++ b/modules/web/providers/jili2/api.go @@ -6,6 +6,7 @@ import ( "server/db" "server/util" "strconv" + "strings" "time" ) @@ -133,13 +134,16 @@ func GetGameList() { var gameList []*common.ConfigGameList for _, item := range response.Data.GameList { id, _ := strconv.Atoi(item.MapID) - gameList = append(gameList, &common.ConfigGameList{ - GameProvider: common.ProviderJiLi2, - GameID: id, - GameCode: item.GameID, - Icon: item.Icon, - Name: item.Name, - }) + if strings.Contains(item.GameID, "jili") { + gameList = append(gameList, &common.ConfigGameList{ + GameProvider: common.ProviderJiLi2, + GameID: id, + GameCode: item.GameID, + Icon: item.Icon, + Name: item.Name, + }) + } + } db.Mysql().Create(gameList) } diff --git a/modules/web/providers/pg3/api.go b/modules/web/providers/pg3/api.go new file mode 100644 index 0000000..b77db1f --- /dev/null +++ b/modules/web/providers/pg3/api.go @@ -0,0 +1,145 @@ +package pg3 + +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"` + GameID string `json:"gameid"` + Token string `json:"token,omitempty"` + Lang string `json:"lang,omitempty"` + Nick string `json:"nick,omitempty"` + RtpPool int `json:"rtp_pool,omitempty"` +} + +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.ProviderPG2, + GameID: id, + GameCode: item.GameID, + Icon: item.Icon, + Name: item.Name, + }) + } + db.Mysql().Create(gameList) +} diff --git a/modules/web/providers/pg3/base.go b/modules/web/providers/pg3/base.go new file mode 100644 index 0000000..c4d610b --- /dev/null +++ b/modules/web/providers/pg3/base.go @@ -0,0 +1,78 @@ +package pg3 + +import ( + "encoding/json" + "fmt" + "server/call" + "server/common" + "server/config" + "server/db" + "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 = APIRlease + 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 + rtp := call.GetRtpControl(uid) + log.Info("uid:%v,rtp:%v", uid, rtp) + db.Redis().SetData(common.GetRedisKeyPlayerRtp(uid), rtp) + headers := map[string]string{ + "X-Game-Mchid": mchid, + "X-Game-Timestamp": strconv.FormatInt(timestamp, 10), + "Content-Type": "application/json;charset=UTF-8", + } + // Generate sign + 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: "", + RtpPool: rtp, + } + 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/pg3/handler.go b/modules/web/providers/pg3/handler.go new file mode 100644 index 0000000..082abf6 --- /dev/null +++ b/modules/web/providers/pg3/handler.go @@ -0,0 +1,164 @@ +package pg3 + +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 + } + + currency, err := db.Redis().GetInt(common.GetRedisKeyGameCurrency(uid)) + if err != nil { + log.Error("err:%v", err) + resp.Code = ErrCodeInternalError + return + } + + resp.Data.Balance = call.GetUserCurrencyFloat(uid, common.CurrencyType(currency), 2) + + 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 + } + + currency, err := db.Redis().GetInt(common.GetRedisKeyGameCurrency(uid)) + if err != nil { + log.Error("err:%v", err) + resp.Code = ErrCodeInternalError + return + } + resp.Data.Uname = req.Uname + resp.Data.Balance = call.GetUserCurrencyFloat(uid, common.CurrencyType(currency), 2) + 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.ProviderPG2) + 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.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 { + 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/pg3/sign.go b/modules/web/providers/pg3/sign.go new file mode 100644 index 0000000..405132d --- /dev/null +++ b/modules/web/providers/pg3/sign.go @@ -0,0 +1,14 @@ +package pg3 + +import ( + "crypto/md5" + "encoding/hex" + "strconv" + "strings" +) + +func GenerateSign(body string, timestamp int64, key string) string { + data := body + strconv.FormatInt(timestamp, 10) + key + hash := md5.Sum([]byte(data)) + return strings.ToUpper(hex.EncodeToString(hash[:])) +} diff --git a/modules/web/providers/pg3/values.go b/modules/web/providers/pg3/values.go new file mode 100644 index 0000000..1249dd8 --- /dev/null +++ b/modules/web/providers/pg3/values.go @@ -0,0 +1,27 @@ +package pg3 + +const ( + APIRlease = "https://openapi-ind.atgameapp.com/pub" + 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{ + "10025", + "E21B1CFF68CD984C6ADB25554BAF16C3", + } + AgentMapRelease = Agent{ + "10025", + "E21B1CFF68CD984C6ADB25554BAF16C3", + } +)