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.
371 lines
7.6 KiB
Go
371 lines
7.6 KiB
Go
package players
|
|
|
|
import (
|
|
"context"
|
|
"joybuywork/internal/app"
|
|
"joybuywork/internal/consts"
|
|
"joybuywork/internal/consts/ckey"
|
|
"joybuywork/internal/plugins/jsonm"
|
|
"joybuywork/internal/repository/cache"
|
|
"joybuywork/internal/repository/dao"
|
|
"joybuywork/internal/repository/dbcheck"
|
|
"joybuywork/internal/repository/model"
|
|
"joybuywork/internal/repository/mtype"
|
|
"joybuywork/internal/repository/withdefault"
|
|
"joybuywork/internal/service/provider"
|
|
"joybuywork/internal/service/provider/award"
|
|
"joybuywork/proto/go_proto/workerr"
|
|
)
|
|
|
|
// Blind 盲盒交互逻辑
|
|
type Blind struct {
|
|
Player
|
|
player *model.FissionBlind
|
|
conf *model.FissionCampaignBlind
|
|
|
|
fissionPlayerSetInitOnceKey string
|
|
}
|
|
|
|
func NewBlind(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Blind, err error) {
|
|
player = &Blind{}
|
|
|
|
err = player.Init(ctx, user, consts.IdBlindBox, opts...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = player.initPlayer()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Sign 签到
|
|
func (s *Blind) Sign() (err error) {
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
if conf.DayChance == 0 {
|
|
return
|
|
}
|
|
|
|
signOk, lastSign := s._lastSign(player.LastSign)
|
|
if !signOk {
|
|
return
|
|
}
|
|
|
|
playerM := s.GetDao().FissionBlind
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(
|
|
playerM.Chance.Add(conf.DayChance),
|
|
playerM.DayChance.Add(conf.DayChance),
|
|
playerM.LastSign.Value(lastSign),
|
|
)
|
|
if err != nil {
|
|
return s.BE().MysqlError(err)
|
|
}
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.LotteryLogVal{
|
|
Chance: conf.DayChance,
|
|
})
|
|
|
|
log := withdefault.FissionBlindLog(&model.FissionBlindLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
BlindID: player.ID,
|
|
Type: mtype.LotteryFissionTypeAdd,
|
|
Source: mtype.FissionLogSourceSign,
|
|
Val: val,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.player.Chance = player.Chance + conf.DayChance
|
|
|
|
return
|
|
}
|
|
|
|
// ReceiveReward 手动领取奖励
|
|
func (s *Blind) ReceiveReward(taskRewards ...*model.FissionUserTaskReward) (chance int32, reward *award.RewardRes, err error) {
|
|
|
|
err = s._receiveReward(taskRewards, func(tasks []*model.FissionCampaignTask, records []*award.RewardRes) error {
|
|
chance, err = s.taskFinish(tasks, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(records) == 0 {
|
|
return nil
|
|
}
|
|
|
|
reward = records[0]
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// FinishTask 完成任务
|
|
func (s *Blind) FinishTask(tasks ...*model.FissionCampaignTask) (err error) {
|
|
_, err = s.taskFinish(tasks, true)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// 完成任务
|
|
func (s *Blind) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance int32, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
var logs []*model.FissionBlindLog
|
|
for _, task := range tasks {
|
|
|
|
next, t, source, lotteryVal := s._lotteryTask(checkManual, task)
|
|
if next {
|
|
continue
|
|
}
|
|
|
|
val, _ := jsonm.MarshalToString(lotteryVal)
|
|
log := withdefault.FissionBlindLog(&model.FissionBlindLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
BlindID: player.ID,
|
|
Type: t,
|
|
Source: source,
|
|
Val: val,
|
|
})
|
|
|
|
switch task.PropMark {
|
|
case mtype.FissionCampaignTaskPropMarkChance:
|
|
chance += task.Chance
|
|
}
|
|
|
|
logs = append(logs, log)
|
|
}
|
|
|
|
if chance > 0 {
|
|
m := s.GetDao().FissionBlind
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.TaskChance.Add(chance), m.Chance.Add(chance))
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
err = s._addLog(logs...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Lottery 抽奖
|
|
func (s *Blind) Lottery() (reward *model.FissionCampaignReward, info provider.RewardAutoLang, record *model.FissionRewardRecord, err error) {
|
|
player := s.GetPlayer()
|
|
if player.Chance <= 0 {
|
|
err = workerr.CChanceNoneError
|
|
return
|
|
}
|
|
|
|
// 抽奖
|
|
reward, err = s._lottery()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if s.IsView() {
|
|
preward, _ := provider.NewRewards(s.Ctx, s.cpn.ProjectID, reward.RewardID)
|
|
info, _ = preward.InfoAutoLang(reward.RewardID, s.user.LangMark)
|
|
return
|
|
}
|
|
|
|
record, info, _, err = award.NewAwardReward(s.Ctx, s.GetDao(), s.cpn.ProjectID, s.user).One(reward, true)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 抽奖数减1
|
|
playerM := s.GetDao().FissionBlind
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.Chance.Sub(1))
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.LotteryLogVal{
|
|
Chance: 1,
|
|
RewardId: record.RewardID,
|
|
RecordId: record.ID,
|
|
})
|
|
|
|
log := withdefault.FissionBlindLog(&model.FissionBlindLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
BlindID: player.ID,
|
|
Type: mtype.LotteryFissionTypeDecr,
|
|
Source: mtype.FissionLogSourceLottery,
|
|
Val: val,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// SetInit 获得初始次数
|
|
func (s *Blind) SetInit() (err error) {
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
if player.SetInit == mtype.Yes || conf.InitChance == 0 {
|
|
return
|
|
}
|
|
|
|
key := s.fissionPlayerSetInitOnceKey
|
|
|
|
if !app.NewRedisLock(s.Ctx, key).SoftLock() {
|
|
return
|
|
}
|
|
|
|
m := s.GetDao().FissionBlind
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.SetInit.Value(mtype.Yes), m.Chance.Add(conf.InitChance))
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.LotteryLogVal{
|
|
Chance: conf.InitChance,
|
|
})
|
|
|
|
log := withdefault.FissionBlindLog(&model.FissionBlindLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
BlindID: player.ID,
|
|
Type: mtype.LotteryFissionTypeAdd,
|
|
Source: mtype.FissionLogSourceInit,
|
|
Val: val,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.player.Chance += conf.InitChance
|
|
|
|
return
|
|
}
|
|
|
|
// GetConf 获取玩法配置
|
|
func (s *Blind) GetConf() *model.FissionCampaignBlind {
|
|
if s.conf == nil {
|
|
s.conf, _ = cache.NewCampaignBlind(s.Ctx).FindByCampaignId(s.user.CampaignID)
|
|
}
|
|
|
|
return s.conf
|
|
}
|
|
|
|
// GetPlayer 获取玩家基础数据
|
|
func (s *Blind) GetPlayer() *model.FissionBlind {
|
|
return s.player
|
|
}
|
|
|
|
// 玩家
|
|
func (s *Blind) initPlayer() (err error) {
|
|
player, err := s._dbFirst()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
defer func() {
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.player = player
|
|
s.fissionPlayerSetInitOnceKey = ckey.FissionPlayerSetInitOnce(player.UserID)
|
|
}()
|
|
|
|
if player != nil {
|
|
return
|
|
}
|
|
|
|
player, err = s.firstOrCreate()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 创建玩家基础数据
|
|
func (s *Blind) firstOrCreate() (player *model.FissionBlind, err error) {
|
|
lc := app.NewFollower(s.Ctx, ckey.FissionUserCreatePlayerOnce(s.user.ID)).Lock()
|
|
defer lc.Release()
|
|
if lc.Error() != nil {
|
|
err = lc.Error()
|
|
return
|
|
}
|
|
|
|
player, err = s._dbFirst()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if player != nil {
|
|
return
|
|
}
|
|
|
|
return s.createPlayer()
|
|
}
|
|
|
|
// 数据库查询
|
|
func (s *Blind) _dbFirst() (*model.FissionBlind, error) {
|
|
playerM := dao.FissionBlind
|
|
player, err := playerM.WithContext(s.Ctx).Where(playerM.UserID.Eq(s.user.ID)).Take()
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
return nil, s.BE().MysqlError(err)
|
|
}
|
|
|
|
return player, nil
|
|
}
|
|
|
|
// 创建一个玩家
|
|
func (s *Blind) createPlayer() (player *model.FissionBlind, err error) {
|
|
playerM := dao.FissionBlind
|
|
player = withdefault.FissionBlind(&model.FissionBlind{
|
|
CampaignID: s.user.CampaignID,
|
|
UserID: s.user.ID,
|
|
})
|
|
|
|
err = playerM.WithContext(s.Ctx).Create(player)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Blind) _addLog(logs ...*model.FissionBlindLog) (err error) {
|
|
if len(logs) == 0 {
|
|
return
|
|
}
|
|
err = s.GetDao().FissionBlindLog.WithContext(s.Ctx).Create(logs...)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
return
|
|
}
|