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.

377 lines
7.7 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"
)
// Flip 翻牌交互逻辑
type Flip struct {
Player
player *model.FissionFlip
conf *model.FissionCampaignFlip
fissionPlayerSetInitOnceKey string
}
func NewFlip(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Flip, err error) {
player = &Flip{}
err = player.Init(ctx, user, consts.IdFlip, opts...)
if err != nil {
return
}
err = player.initPlayer()
if err != nil {
return
}
return
}
// Sign 签到
func (s *Flip) 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().FissionFlip
_, 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.FissionFlipLog(&model.FissionFlipLog{
UserID: player.UserID,
CampaignID: player.CampaignID,
FlipID: 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 *Flip) 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 *Flip) FinishTask(tasks ...*model.FissionCampaignTask) (err error) {
_, err = s.taskFinish(tasks, true)
if err != nil {
return
}
return
}
// 完成任务
func (s *Flip) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance int32, err error) {
player := s.GetPlayer()
var logs []*model.FissionFlipLog
for _, task := range tasks {
next, t, source, lotteryVal := s._lotteryTask(checkManual, task)
if next {
continue
}
val, _ := jsonm.MarshalToString(lotteryVal)
log := withdefault.FissionFlipLog(&model.FissionFlipLog{
UserID: player.UserID,
CampaignID: player.CampaignID,
FlipID: 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().FissionFlip
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.TaskChance.Add(chance), m.Chance.Add(chance))
if err != nil {
return
}
s.addChanceNotify(int64(chance))
}
err = s._addLog(logs...)
if err != nil {
return
}
return
}
// Lottery 抽奖
func (s *Flip) 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().FissionFlip
_, 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.FissionFlipLog(&model.FissionFlipLog{
UserID: player.UserID,
CampaignID: player.CampaignID,
FlipID: player.ID,
Type: mtype.LotteryFissionTypeDecr,
Source: mtype.FissionLogSourceLottery,
Val: val,
})
err = s._addLog(log)
if err != nil {
return
}
return
}
// SetInit 获得初始次数
func (s *Flip) 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().FissionFlip
_, 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.FissionFlipLog(&model.FissionFlipLog{
UserID: player.UserID,
CampaignID: player.CampaignID,
FlipID: 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 *Flip) GetConf() *model.FissionCampaignFlip {
if s.conf == nil {
s.conf, _ = cache.NewCampaignFlip(s.Ctx).FindByCampaignId(s.user.CampaignID)
}
return s.conf
}
// GetPlayer 获取玩家基础数据
func (s *Flip) GetPlayer() *model.FissionFlip {
return s.player
}
// 玩家
func (s *Flip) 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 *Flip) firstOrCreate() (player *model.FissionFlip, 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 *Flip) _dbFirst() (*model.FissionFlip, error) {
playerM := dao.FissionFlip
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 *Flip) createPlayer() (player *model.FissionFlip, err error) {
playerM := dao.FissionFlip
player = withdefault.FissionFlip(&model.FissionFlip{
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 *Flip) _addLog(logs ...*model.FissionFlipLog) (err error) {
if len(logs) == 0 {
return
}
err = s.GetDao().FissionFlipLog.WithContext(s.Ctx).Create(logs...)
if err != nil {
err = s.BE().MysqlError(err)
return
}
return
}
// 增加抽奖次数通知
func (s *Flip) addChanceNotify(chance int64) {
provider.NewFissionClue(s.Ctx, s.user.ID).AddChance(chance)
}