You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

288 lines
6.2 KiB
Go

package games
import (
"joybuywork/internal/app"
"joybuywork/internal/consts"
"joybuywork/internal/consts/ckey"
"joybuywork/internal/plugins/hashid"
"joybuywork/internal/plugins/jsonm"
"joybuywork/internal/repository/cache"
"joybuywork/internal/repository/dbcheck"
"joybuywork/internal/repository/model"
"joybuywork/internal/repository/mtype"
"joybuywork/internal/repository/withdefault"
"joybuywork/internal/service/queue/producer"
"joybuywork/internal/service/queue/types"
"joybuywork/internal/utils"
"joybuywork/internal/utils/logic"
pb "joybuywork/proto/go_proto/w_games"
"joybuywork/proto/go_proto/workerr"
"fmt"
"math/rand"
"time"
c_fuserpb "gits.branchcn.com/backend/certified/proto/go_proto/c_fuser"
c_guserpb "gits.branchcn.com/backend/certified/proto/go_proto/c_guser"
)
type Visit struct {
logic.Logic
Req *pb.VisitReq
Res *pb.VisitRes
}
func (s *Visit) Run() error {
return logic.Run(s)
}
func (s *Visit) Data() (data jsonm.JsonM) {
data, _ = jsonm.Marshal(s.Req)
return
}
func (s *Visit) Exec() (err error) {
project, err := s.project()
if err != nil {
return
}
link, err := s.link()
if err != nil {
return
}
user, err := s.user(project, link)
if err != nil {
return
}
err = s.token(user, link.ID)
if err != nil {
return
}
s.trace(user, link)
return
}
func (s *Visit) project() (project *model.Project, err error) {
project, err = cache.NewProject(s.Ctx).FindByHashId(s.Req.GetProjectHashId())
if err != nil {
return
}
if project == nil {
err = s.BE().VerifyError("not found project")
return
}
return
}
func (s *Visit) link() (link *model.GameLink, err error) {
m := s.GetDao().GameLink
link, err = m.WithContext(s.Ctx).Where(m.HashID.Eq(s.Req.GetLinkHashId())).First()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if link == nil {
err = s.BE().VerifyError("not found link")
return
}
return
}
func (s *Visit) user(project *model.Project, link *model.GameLink) (user *model.GameUser, err error) {
err = s._cert(project.ID)
if err != nil {
return
}
if s._isView() {
return &model.GameUser{
ID: rand.Int63(),
HashID: hashid.Id()[3:],
ProjectID: project.ID,
GameID: link.GameID,
}, nil
}
if s.Req.GetUid() != "" {
user, err = s._uid(project, link)
if err != nil || user != nil {
return
}
}
user, err = s._iovd(project, link)
if err != nil {
return
}
return
}
func (s *Visit) _uid(project *model.Project, link *model.GameLink) (user *model.GameUser, err error) {
m := s.GetDao().GameUser
user, err = m.WithContext(s.Ctx).Where(m.ProjectID.Eq(project.ID), m.GameID.Eq(link.GameID), m.SubUserID.Eq(s.Req.GetUid())).Take()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if user != nil {
return
}
user, err = s._iovd(project, link)
if err != nil {
return
}
if user != nil && user.SubUserID == "" {
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(user.ID)).UpdateSimple(m.SubUserID.Value(s.Req.GetUid()))
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
user = withdefault.GameUser(&model.GameUser{
ProjectID: project.ID,
GameID: link.GameID,
IP: s.Req.GetIp(),
Os: s.Req.GetOs(),
Ver: s.Req.GetOsVersion(),
DModel: s.Req.GetDeviceModel(),
SubUserID: s.Req.GetUid(),
IovdMark: s._iovdMark(),
})
err = s.GetDao().GameUser.WithContext(s.Ctx).Create(user)
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
func (s *Visit) _iovd(project *model.Project, link *model.GameLink) (user *model.GameUser, err error) {
m := s.GetDao().GameUser
user, err = m.WithContext(s.Ctx).Where(m.ProjectID.Eq(project.ID), m.GameID.Eq(link.GameID), m.IovdMark.Eq(s._iovdMark())).Last()
if err = dbcheck.DbError(err); err != nil {
err = s.BE().MysqlError(err)
return
}
if user != nil {
return
}
user = withdefault.GameUser(&model.GameUser{
ProjectID: project.ID,
GameID: link.GameID,
IP: s.Req.GetIp(),
Os: s.Req.GetOs(),
Ver: s.Req.GetOsVersion(),
DModel: s.Req.GetDeviceModel(),
IovdMark: s._iovdMark(),
})
err = s.GetDao().GameUser.WithContext(s.Ctx).Create(user)
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
func (s *Visit) token(user *model.GameUser, linkId int64) (err error) {
res, err := app.NewCertifiedGUser().Token(s.Ctx, &c_guserpb.TokenReq{
Id: user.ID,
GameId: user.GameID,
ProjectId: user.ProjectID,
LinkId: linkId,
IsView: s._isView(),
})
if err != nil {
return
}
s.Res.Id = user.ID
s.Res.HashId = user.HashID
s.Res.Token = res.GetToken()
s.Res.Expired = res.GetExpired()
s.Res.IsView = utils.Ternary[int32](s._isView(), mtype.Yes, mtype.No)
return
}
func (s *Visit) _cert(projectId int64) (err error) {
if s._isView() {
return
}
// 数据验签
cert, err := app.NewCertifiedFUser().CertUser(s.Ctx, &c_fuserpb.CertUserReq{
ProjectId: projectId,
UserId: s.Req.GetUid(),
Lv: s.Req.GetLv(),
Lang: s.Req.GetLang(),
Time: s.Req.GetCert().GetTime(),
Blackbox: s.Req.GetCert().GetBlackbox(),
Version: s.Req.GetCert().GetVersion(),
Platform: s.Req.GetCert().GetPlatform(),
Token: s.Req.GetCert().GetToken(),
})
if err != nil || !cert.GetOk() {
err = workerr.UnauthorizedError
return
}
return
}
func (s *Visit) _isView() bool {
return s.Req.GetUid() == consts.FissionViewer
}
func (s *Visit) trace(user *model.GameUser, link *model.GameLink) {
if s._isView() {
return
}
app.Redis.Cache.Del(s.Ctx, ckey.GameActionStayId(user.ID, link.ID))
producer.NewCampaignNotice(s.Ctx).GameAction(types.GameAction{
ID: hashid.IdBigint(),
ProjectId: user.ProjectID,
GameId: user.GameID,
UserId: user.ID,
LinkId: link.ID,
Type: mtype.GameActionTypeVisit,
ActionTime: time.Now().Unix(),
Dimension: mtype.GameDimension{
GameDimensionOption: mtype.GameDimensionOption{
Ip: s.Req.GetIp(),
Os: s.Req.GetOs(),
OsVersion: s.Req.GetOsVersion(),
DeviceModel: s.Req.GetDeviceModel(),
},
},
})
}
func (s *Visit) _iovdMark() string {
return utils.Md5String(fmt.Sprintf("%s:%s:%s:%s", s.Req.GetIp(), s.Req.GetOs(), s.Req.GetOsVersion(), s.Req.GetDeviceModel()))
}