|
|
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/finder"
|
|
|
"joybuywork/internal/repository/model"
|
|
|
"joybuywork/internal/repository/mtype"
|
|
|
"joybuywork/internal/repository/withdefault"
|
|
|
"joybuywork/internal/service/cmm"
|
|
|
"joybuywork/internal/service/provider"
|
|
|
"joybuywork/internal/service/provider/award"
|
|
|
"joybuywork/internal/service/provider/fissionaction"
|
|
|
"joybuywork/internal/utils"
|
|
|
"joybuywork/internal/utils/lockdo"
|
|
|
"joybuywork/internal/utils/verify"
|
|
|
"joybuywork/proto/go_proto/workerr"
|
|
|
"fmt"
|
|
|
"time"
|
|
|
|
|
|
"gits.branchcn.com/backend/microcode/plugins/lucky"
|
|
|
"gorm.io/gen/field"
|
|
|
)
|
|
|
|
|
|
type rollData struct {
|
|
|
MarkType int8 // 格子类型
|
|
|
Step int32 // 下标数据
|
|
|
RewardId int64 // 活动奖品id
|
|
|
MapId int64 // 地图int类型id
|
|
|
MapHashId string // 地图hash_id
|
|
|
RewardTitle string // 奖品名称
|
|
|
ImgUrl string // 奖品地址
|
|
|
Intact bool // 合成了奖品
|
|
|
Lack bool // 缺库存
|
|
|
}
|
|
|
|
|
|
const (
|
|
|
diceFailTypeNone = iota // 没有错误
|
|
|
diceFailTypeLack // 缺骰子数
|
|
|
diceFailTypeProps // 道具不足
|
|
|
)
|
|
|
|
|
|
// Dice 金币池交互逻辑
|
|
|
type Dice struct {
|
|
|
Player
|
|
|
player *model.FissionDice
|
|
|
conf *model.FissionCampaignDice
|
|
|
run *model.FissionDiceRun
|
|
|
|
|
|
fissionPlayerSetInitOnceKey string
|
|
|
diceOnceKey string
|
|
|
}
|
|
|
|
|
|
func NewDice(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Dice, err error) {
|
|
|
player = &Dice{}
|
|
|
|
|
|
err = player.Init(ctx, user, consts.IdDice, opts...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
err = player.initPlayer()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) PointsUse() (status int32, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
logM := s.GetDao().FissionDiceRecord
|
|
|
|
|
|
status, deduct, err := s.pointsUse(mtype.FissionPointsLogSourceDice, logM.TableName(), mtype.PointsLogOther{
|
|
|
PlayerId: player.ID,
|
|
|
}, []*pointsUseCond{
|
|
|
{
|
|
|
Field: logM.Mark.ColumnName().String(),
|
|
|
Value: mtype.FissionDiceRecordMarkPointsUse,
|
|
|
},
|
|
|
})
|
|
|
defer s.pointsUseOk(deduct)
|
|
|
|
|
|
if status != pointsUseOk || err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionDice
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.Chance.Add(1))
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
log := withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
CampaignID: player.CampaignID,
|
|
|
UserID: player.UserID,
|
|
|
Mark: mtype.FissionDiceRecordMarkPointsUse,
|
|
|
Data: "",
|
|
|
})
|
|
|
|
|
|
log.SetData(&mtype.DiceRecord{
|
|
|
Chance: 1,
|
|
|
PointsNum: deduct.Num,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// ReceiveReward 手动领取奖励
|
|
|
func (s *Dice) ReceiveReward(taskRewards ...*model.FissionUserTaskReward) (chance, fixChance int32, reward *award.RewardRes, err error) {
|
|
|
|
|
|
err = s._receiveReward(taskRewards, func(tasks []*model.FissionCampaignTask, records []*award.RewardRes) error {
|
|
|
chance, fixChance, 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 *Dice) FinishTask(tasks ...*model.FissionCampaignTask) (err error) {
|
|
|
_, _, err = s.taskFinish(tasks, true)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 完成任务
|
|
|
func (s *Dice) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance, fixChance int32, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
var logs []*model.FissionDiceRecord
|
|
|
for _, task := range tasks {
|
|
|
if checkManual && task.AwardMode == mtype.FissionCampaignTaskAwardModeManual {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
log := withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
CampaignID: player.CampaignID,
|
|
|
UserID: player.UserID,
|
|
|
})
|
|
|
|
|
|
val := &mtype.DiceRecord{
|
|
|
TaskId: task.ID,
|
|
|
Chance: task.Chance,
|
|
|
}
|
|
|
|
|
|
switch task.TaskType {
|
|
|
case mtype.FissionCampaignTaskTypeRegister:
|
|
|
log.Mark = mtype.FissionDiceRecordMarkGetRollRegister
|
|
|
case mtype.FissionCampaignTaskTypeInstall:
|
|
|
log.Mark = mtype.FissionDiceRecordMarkGetRollInstall
|
|
|
case mtype.FissionCampaignTaskTypeCondAll:
|
|
|
log.Mark = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionDiceRecordMarkGetManualRollAll, mtype.FissionDiceRecordMarkGetRollAll)
|
|
|
case mtype.FissionCampaignTaskTypeCondOne:
|
|
|
log.Mark = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionDiceRecordMarkGetManualRollTask, mtype.FissionDiceRecordMarkGetRollTask)
|
|
|
val.CondId = utils.FissionCampaignTaskMarkCondOneCondId(task.TaskMark)
|
|
|
}
|
|
|
|
|
|
log.SetData(val)
|
|
|
|
|
|
switch task.PropMark {
|
|
|
case mtype.FissionCampaignTaskPropMarkChance:
|
|
|
chance += task.Chance
|
|
|
case mtype.FissionCampaignTaskPropMarkFixedRoll:
|
|
|
log.Mark = mtype.FissionDiceRecordMarkGetLucky
|
|
|
fixChance += task.Chance
|
|
|
}
|
|
|
|
|
|
logs = append(logs, log)
|
|
|
}
|
|
|
|
|
|
if chance > 0 {
|
|
|
m := s.GetDao().FissionDice
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.TaskChance.Add(chance), m.Chance.Add(chance))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if fixChance > 0 {
|
|
|
var prop *model.FissionDiceProp
|
|
|
prop, err = s._propOrCreate(mtype.FissionDicePropMarkFixedRoll)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionDiceProp
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(prop.ID)).UpdateSimple(m.Num.Add(fixChance), m.TotalNum.Add(fixChance))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.appTrack().GetProp(time.Now().Unix(), consts.PropNameFixedDice, fixChance)
|
|
|
}
|
|
|
|
|
|
err = s._addLog(logs...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
type RollRes struct {
|
|
|
FailType int32
|
|
|
MarkType int32
|
|
|
MapHashId string
|
|
|
RewardTitle string
|
|
|
ImgUrl string
|
|
|
IsIntact bool
|
|
|
RollNum int32
|
|
|
Lack bool
|
|
|
RewardId int64
|
|
|
}
|
|
|
|
|
|
// Roll 普通掷骰子
|
|
|
func (s *Dice) Roll() (res RollRes, err error) {
|
|
|
s.Tran()
|
|
|
defer func() {
|
|
|
s.TranCommit(err)
|
|
|
s.AfterDo(err)
|
|
|
}()
|
|
|
|
|
|
player := s.GetPlayer()
|
|
|
if player.Chance <= 0 {
|
|
|
res.FailType = diceFailTypeLack
|
|
|
return
|
|
|
}
|
|
|
|
|
|
step := int(utils.RandNumber(6))
|
|
|
|
|
|
win, err := s._rollMap(step, false)
|
|
|
if err != nil || win == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 不是预览用户要减次数,并且不是再来一次就减一次
|
|
|
if !s.IsView() && win.MarkType != mtype.FissionDiceMapMarkTypeChance {
|
|
|
m := s.GetDao().FissionDice
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.Chance.Sub(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 记录日志
|
|
|
err = s._rollDiceRecord(win, false)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return s._rollRes(win)
|
|
|
}
|
|
|
|
|
|
// FixRoll 使用幸运骰子
|
|
|
func (s *Dice) FixRoll(rollVal string) (res RollRes, err error) {
|
|
|
s.Tran()
|
|
|
defer func() {
|
|
|
s.TranCommit(err)
|
|
|
s.AfterDo(err)
|
|
|
}()
|
|
|
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
m := s.GetDao().FissionDiceProp
|
|
|
prop, err := m.WithContext(s.Ctx).Where(m.UserID.Eq(player.UserID), m.Mark.Eq(mtype.FissionDicePropMarkFixedRoll)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if prop == nil || prop.Num <= 0 {
|
|
|
res.FailType = diceFailTypeProps
|
|
|
return
|
|
|
}
|
|
|
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(prop.ID)).UpdateSimple(m.Num.Sub(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
step := utils.StrToInt(rollVal) - 1
|
|
|
|
|
|
win, err := s._rollMap(step, true)
|
|
|
if err != nil || win == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 记录日志
|
|
|
err = s._rollDiceRecord(win, true)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 使用道具埋点
|
|
|
fissionaction.NewMarkPoint(s.Ctx).InApp(s.user).UseProp(time.Now().Unix(), consts.PropNameFixedDice)
|
|
|
|
|
|
return s._rollRes(win)
|
|
|
}
|
|
|
|
|
|
type DiceMapOne struct {
|
|
|
MapHashId string `json:"map_hash_id"`
|
|
|
MarkType int32 `json:"mark_type"`
|
|
|
RewardTitle string `json:"reward_title"`
|
|
|
ImgUrl string `json:"img_url"`
|
|
|
RewardId int64 `json:"reward_id"`
|
|
|
}
|
|
|
|
|
|
func (s *Dice) DiceMap(mapHashId string, showStep int64, prefixStep int32) (maps []*DiceMapOne, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
run, err := s._runMap()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionDiceMap
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID), m.DmgID.Eq(run.DmgID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(list) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
maps = make([]*DiceMapOne, 0, 54)
|
|
|
|
|
|
var point = run.MapID
|
|
|
if mapHashId != "" {
|
|
|
var dm *model.FissionDiceMap
|
|
|
dm, err = m.WithContext(s.Ctx).Where(m.HashID.Eq(mapHashId)).Take()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if dm != nil {
|
|
|
point = dm.ID
|
|
|
}
|
|
|
}
|
|
|
|
|
|
rewardMap, err := cmm.NewCMM(s.Ctx, s.GetDao()).UserAppRewardInfo(s.cpn, s.user)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var add = func(i int) {
|
|
|
v := list[i]
|
|
|
one := &DiceMapOne{
|
|
|
MapHashId: v.HashID,
|
|
|
MarkType: int32(v.MarkType),
|
|
|
RewardTitle: "",
|
|
|
ImgUrl: "",
|
|
|
}
|
|
|
|
|
|
if reward, ok := rewardMap[v.RewardID]; ok {
|
|
|
one.RewardTitle = reward.Title
|
|
|
one.ImgUrl = reward.ImgUrl
|
|
|
one.RewardId = reward.RewardId
|
|
|
}
|
|
|
|
|
|
maps = append(maps, one)
|
|
|
}
|
|
|
|
|
|
if point == 0 || (showStep > 0 && run.GoStep <= showStep) {
|
|
|
maps = append(maps, &DiceMapOne{
|
|
|
MapHashId: "",
|
|
|
MarkType: -1,
|
|
|
RewardTitle: "GO",
|
|
|
ImgUrl: "",
|
|
|
})
|
|
|
|
|
|
for i := 0; i < 53; i++ {
|
|
|
add(i)
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 在第几格
|
|
|
var idx int
|
|
|
for i, v := range list {
|
|
|
if v.ID == point {
|
|
|
idx = i
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 走了超过12步
|
|
|
var mapL = len(list)
|
|
|
var start = idx - utils.Ternary(mapHashId == "", int(prefixStep), -1)
|
|
|
start = utils.Ternary(start < 0, 0, start)
|
|
|
var end = 54 + start
|
|
|
if end > mapL {
|
|
|
end = mapL
|
|
|
}
|
|
|
|
|
|
for i := start; i < end; i++ {
|
|
|
add(i)
|
|
|
}
|
|
|
|
|
|
// 如果超过了地图最大长度,从头再来
|
|
|
var resLen = len(maps)
|
|
|
for i := 0; i < 54-resLen; i++ {
|
|
|
add(i)
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// SetInit 获得初始次数
|
|
|
func (s *Dice) 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().FissionDice
|
|
|
_, 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.DiceRecord{
|
|
|
Chance: conf.InitChance,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
Mark: mtype.FissionDiceRecordMarkGetRollSys,
|
|
|
Data: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.player.Chance += conf.InitChance
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
type MixRewardRes struct {
|
|
|
Lack bool //奖品无库存
|
|
|
RewardId int64 //奖品ID
|
|
|
RewardTitle string //奖品名称
|
|
|
ImgUrl string //奖品图片
|
|
|
ReceiveType int32 //发放类型(0-无操作,1-系统发放,2-联系客服,3-客户端推送)
|
|
|
KvData []*mtype.RewardKV //键值数据
|
|
|
Contact string //联系方式
|
|
|
RewardHashId string //领取的用户奖品hash_id
|
|
|
OpenToUse int32 //开启去使用(0-否,1-是)
|
|
|
WebUrl string //Web端的跳转地址
|
|
|
AppParam string //App端的跳转参数
|
|
|
PcParam string //pc端的跳转参数
|
|
|
}
|
|
|
|
|
|
func (s *Dice) MixReward(rewardId int64) (res MixRewardRes, err error) {
|
|
|
s.Tran()
|
|
|
defer func() {
|
|
|
s.TranCommit(err)
|
|
|
}()
|
|
|
|
|
|
user := s.user
|
|
|
|
|
|
m := s.GetDao().FissionDiceCollect
|
|
|
collect, err := m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID), m.RewardID.Eq(rewardId)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if collect == nil || collect.RecordID == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
rewardM := s.GetDao().FissionCampaignReward
|
|
|
reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(collect.RewardID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var upData = []field.AssignExpr{
|
|
|
m.IntactNum.Add(1),
|
|
|
m.Num.Sub(reward.CollectNum),
|
|
|
m.RecordID.Value(0),
|
|
|
}
|
|
|
|
|
|
cr := reward.GetCollectRule()
|
|
|
if cr.Open == mtype.Yes && cr.ResetType == mtype.FissionCampaignRewardCollectRuleResetGet {
|
|
|
upData = append(upData, m.SignNum.Value(0))
|
|
|
}
|
|
|
|
|
|
// 完整度+1
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(collect.ID)).UpdateSimple(upData...)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
recordM := s.GetDao().FissionRewardRecord.SubTable(user.CampaignID)
|
|
|
record, err := recordM.WithContext(s.Ctx).Where(recordM.ID.Eq(collect.RecordID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var lack bool
|
|
|
if record.FailType == mtype.FissionRewardRecordFailTypeCli && record.FailMsg == mtype.FissionRewardRecordFailTypeCliLackMsg {
|
|
|
lack = true
|
|
|
}
|
|
|
|
|
|
// 骰子记录
|
|
|
var diceRecord = withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
CreatedAt: record.CreatedAt,
|
|
|
CampaignID: user.CampaignID,
|
|
|
UserID: user.ID,
|
|
|
Mark: mtype.FissionDiceRecordMarkReward,
|
|
|
Data: "",
|
|
|
})
|
|
|
|
|
|
diceRecord.SetData(&mtype.DiceRecord{
|
|
|
RewardId: record.RewardID,
|
|
|
RecordId: record.ID,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(diceRecord)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
preward, err := provider.NewRewards(s.Ctx, s.cpn.ProjectID, record.BaseRewardID)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
info, _ := preward.InfoAutoLang(record.BaseRewardID, user.LangMark)
|
|
|
|
|
|
res = MixRewardRes{
|
|
|
Lack: lack,
|
|
|
RewardId: record.RewardID,
|
|
|
RewardTitle: info.Title,
|
|
|
ImgUrl: info.ImgUrl,
|
|
|
ReceiveType: info.ReceiveType,
|
|
|
KvData: info.KvData,
|
|
|
Contact: info.Contact,
|
|
|
RewardHashId: record.HashID,
|
|
|
OpenToUse: info.OpenToUse,
|
|
|
WebUrl: info.WebUrl,
|
|
|
AppParam: info.AppParam,
|
|
|
PcParam: info.PcParam,
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
type DiceStatus struct {
|
|
|
Stat *model.FissionUserStat
|
|
|
Run *model.FissionDiceRun
|
|
|
CollectMap map[int64]int32
|
|
|
PropMap map[string]int32
|
|
|
FixedRollTaskFinish int64
|
|
|
}
|
|
|
|
|
|
func (s *Dice) Status() (status DiceStatus, err error) {
|
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
|
|
|
|
// 统计数据
|
|
|
status.Stat, err = cmm.NewFirstCreate(s.Ctx, s.GetDao()).FissionUserStat(s.user)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 用户当前所在地图的信息
|
|
|
status.Run, err = s._runMap()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
collectM := s.GetDao().FissionDiceCollect
|
|
|
collects, err := collectM.WithContext(s.Ctx).Where(collectM.UserID.Eq(player.UserID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
status.CollectMap = make(map[int64]int32)
|
|
|
for _, v := range collects {
|
|
|
status.CollectMap[v.RewardID] = v.Num
|
|
|
}
|
|
|
|
|
|
propM := s.GetDao().FissionDiceProp
|
|
|
props, err := propM.WithContext(s.Ctx).Where(propM.UserID.Eq(player.UserID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
status.PropMap = make(map[string]int32)
|
|
|
for _, prop := range props {
|
|
|
status.PropMap[prop.Mark] = prop.Num
|
|
|
}
|
|
|
|
|
|
if conf.FixDice == mtype.No {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
taskM := s.GetDao().FissionCampaignTask
|
|
|
task, err := taskM.WithContext(s.Ctx).Where(
|
|
|
taskM.CampaignID.Eq(player.CampaignID),
|
|
|
taskM.PropMark.Eq(mtype.FissionCampaignTaskPropMarkFixedRoll),
|
|
|
taskM.IsDel.Eq(mtype.No),
|
|
|
).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if task == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
taskRecordM := s.GetDao().FissionUserTaskRecord
|
|
|
status.FixedRollTaskFinish, err = taskRecordM.WithContext(s.Ctx).Where(taskRecordM.UserID.Eq(player.UserID), taskRecordM.TaskID.Eq(task.ID)).Count()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if task.ChanceLimit > 0 && int64(task.ChanceLimit) < status.FixedRollTaskFinish {
|
|
|
status.FixedRollTaskFinish = int64(task.ChanceLimit)
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// Sign 签到
|
|
|
func (s *Dice) Sign() (err error) {
|
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
|
|
|
|
signOk, lastSign := s._lastSign(player.LastSign)
|
|
|
if !signOk {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
playerM := s.GetDao().FissionDice
|
|
|
var upData []field.AssignExpr
|
|
|
upData = append(upData, playerM.LastSign.Value(lastSign))
|
|
|
if conf.DayChance > 0 {
|
|
|
|
|
|
upData = append(upData,
|
|
|
playerM.Chance.Add(conf.DayChance),
|
|
|
playerM.DayChance.Add(conf.DayChance),
|
|
|
)
|
|
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.DiceRecord{
|
|
|
Chance: conf.DayChance,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
Mark: mtype.FissionDiceRecordMarkSign,
|
|
|
Data: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.player.Chance = player.Chance + conf.DayChance
|
|
|
}
|
|
|
|
|
|
scrIds, err := s._signCollectReward()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(scrIds) > 0 {
|
|
|
var addSignIds []int64
|
|
|
for _, id := range scrIds {
|
|
|
var collect *model.FissionDiceCollect
|
|
|
collect, err = s._rewardCollect(id)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
addSignIds = append(addSignIds, collect.ID)
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionDiceCollect
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.In(addSignIds...)).UpdateSimple(m.SignNum.Add(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(upData...)
|
|
|
if err != nil {
|
|
|
return s.BE().MysqlError(err)
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// GetConf 获取玩法配置
|
|
|
func (s *Dice) GetConf() *model.FissionCampaignDice {
|
|
|
if s.conf == nil {
|
|
|
s.conf, _ = cache.NewCampaignDice(s.Ctx).FindByCampaignId(s.user.CampaignID)
|
|
|
}
|
|
|
|
|
|
return s.conf
|
|
|
}
|
|
|
|
|
|
// GetPlayer 获取玩家基础数据
|
|
|
func (s *Dice) GetPlayer() *model.FissionDice {
|
|
|
return s.player
|
|
|
}
|
|
|
|
|
|
// 玩家
|
|
|
func (s *Dice) 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)
|
|
|
s.diceOnceKey = ckey.FissionDiceOnce(player.UserID)
|
|
|
}()
|
|
|
|
|
|
if player != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
player, err = s.firstOrCreate()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 创建玩家基础数据
|
|
|
func (s *Dice) firstOrCreate() (player *model.FissionDice, 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 *Dice) _dbFirst() (*model.FissionDice, error) {
|
|
|
playerM := dao.FissionDice
|
|
|
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 *Dice) createPlayer() (player *model.FissionDice, err error) {
|
|
|
playerM := dao.FissionDice
|
|
|
player = withdefault.FissionDice(&model.FissionDice{
|
|
|
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 *Dice) _addLog(logs ...*model.FissionDiceRecord) (err error) {
|
|
|
err = s.GetDao().FissionDiceRecord.WithContext(s.Ctx).Create(logs...)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _signCollectReward() (ids []int64, err error) {
|
|
|
rewards, err := cmm.NewUserAppReward(s.Ctx).Get(s.GetDao(), s.user)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, reward := range rewards {
|
|
|
cr := reward.GetCollectRule()
|
|
|
if cr.Open == mtype.Yes {
|
|
|
ids = append(ids, reward.ID)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _rewardCollect(rewardId int64) (collect *model.FissionDiceCollect, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
err = lockdo.FindNilDo(
|
|
|
s.Ctx,
|
|
|
ckey.FissionUserCreateRewardCollect(player.UserID, rewardId),
|
|
|
func() (none bool, err error) {
|
|
|
m := s.GetDao().FissionDiceCollect
|
|
|
collect, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(player.UserID), m.RewardID.Eq(rewardId)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return collect == nil, nil
|
|
|
},
|
|
|
func() (err error) {
|
|
|
collect = withdefault.FissionDiceCollect(&model.FissionDiceCollect{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
RewardID: rewardId,
|
|
|
})
|
|
|
|
|
|
err = s.GetDao().FissionDiceCollect.WithContext(s.Ctx).Create(collect)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _runMap() (run *model.FissionDiceRun, err error) {
|
|
|
if s.run != nil {
|
|
|
return s.run, nil
|
|
|
}
|
|
|
|
|
|
user := s.user
|
|
|
m := s.GetDao().FissionDiceMapGroup
|
|
|
dmg, err := m.WithContext(s.Ctx).Where(
|
|
|
m.CampaignID.Eq(user.CampaignID),
|
|
|
m.LangMark.Eq(user.UserLang),
|
|
|
m.LevelID.Eq(user.UserLevel),
|
|
|
m.CountryMark.Eq(user.UserCountry),
|
|
|
).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if dmg == nil {
|
|
|
err = workerr.NotFound("not found dice map")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
lc := app.NewFollower(s.Ctx, ckey.FissionUserRunCreateOnce(user.ID)).Lock()
|
|
|
defer lc.Release()
|
|
|
if lc.Error() != nil {
|
|
|
err = workerr.BusyError
|
|
|
return
|
|
|
}
|
|
|
|
|
|
runM := s.GetDao().FissionDiceRun
|
|
|
run, err = runM.WithContext(s.Ctx).Where(runM.UserID.Eq(user.ID), runM.DmgID.Eq(dmg.ID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if run == nil {
|
|
|
run = withdefault.FissionDiceRun(&model.FissionDiceRun{
|
|
|
CampaignID: user.CampaignID,
|
|
|
UserID: user.ID,
|
|
|
DmgID: dmg.ID,
|
|
|
})
|
|
|
|
|
|
if err = runM.WithContext(s.Ctx).Create(run); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
s.run = run
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _rollMap(idx int, isFixRoll bool) (res *rollData, err error) {
|
|
|
run, err := s._runMap()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionDiceMap
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(run.CampaignID), m.DmgID.Eq(run.DmgID), m.ID.Gt(run.MapID)).Limit(6).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(list) < 6 {
|
|
|
|
|
|
back := 6 - len(list)
|
|
|
var backList []*model.FissionDiceMap
|
|
|
backList, err = m.WithContext(s.Ctx).Where(m.CampaignID.Eq(run.CampaignID), m.DmgID.Eq(run.DmgID)).Limit(back).Order(m.ID).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range backList {
|
|
|
list = append(list, v)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(list) == 0 {
|
|
|
app.Logger.Error(s.Ctx, fmt.Sprintf("活动[%d]地图生成异常, 用户id[%d]", run.CampaignID, run.UserID))
|
|
|
err = workerr.ServerError
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var loseMap = make(map[int]*model.FissionDiceMap)
|
|
|
for i, v := range list {
|
|
|
if verify.InArray(v.MarkType, mtype.FissionDiceMapMarkTypeNone, mtype.FissionDiceMapMarkTypeChance, mtype.FissionDiceMapMarkTypeFixedRoll) {
|
|
|
loseMap[i] = v
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var win, lose *rollData
|
|
|
|
|
|
for i, v := range loseMap {
|
|
|
switch v.MarkType {
|
|
|
case mtype.FissionDiceMapMarkTypeNone, mtype.FissionDiceMapMarkTypeChance:
|
|
|
lose = &rollData{
|
|
|
MarkType: v.MarkType,
|
|
|
Step: int32(i),
|
|
|
RewardId: v.RewardID,
|
|
|
MapId: v.ID,
|
|
|
MapHashId: v.HashID,
|
|
|
}
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
win = &rollData{
|
|
|
MarkType: list[idx].MarkType,
|
|
|
Step: int32(idx),
|
|
|
RewardId: list[idx].RewardID,
|
|
|
MapId: list[idx].ID,
|
|
|
MapHashId: list[idx].HashID,
|
|
|
}
|
|
|
|
|
|
// 预览用户直接返回结果
|
|
|
if s.IsView() {
|
|
|
return s._viewWin(win)
|
|
|
}
|
|
|
|
|
|
// 不是固定骰子,要看看走不走概率
|
|
|
if !isFixRoll {
|
|
|
confM := s.GetDao().FissionCampaignDice
|
|
|
var conf *model.FissionCampaignDice
|
|
|
conf, err = confM.WithContext(s.Ctx).Where(confM.CampaignID.Eq(run.CampaignID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 走概率发奖
|
|
|
if conf.AwardType == mtype.FissionCampaignDiceAwardTypeOdds {
|
|
|
|
|
|
winner, _ := lucky.NewDiscrete(s.Ctx, []lucky.Reward{
|
|
|
{Share: int(conf.Odds), Mark: true},
|
|
|
{Share: 1000 - int(conf.Odds), Mark: false},
|
|
|
}).Lottery()
|
|
|
|
|
|
// 赢不了
|
|
|
if !winner.Bool() {
|
|
|
return lose, nil
|
|
|
}
|
|
|
|
|
|
return s._odds(list, win, lose, isFixRoll)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 如果都没中奖品,那就不用做奖品处理
|
|
|
if !verify.InArray(win.MarkType, mtype.FissionDiceMapMarkTypeNormal, mtype.FissionDiceMapMarkTypeSuper) {
|
|
|
return win, nil
|
|
|
}
|
|
|
|
|
|
res, err = s._reward(win, lose, isFixRoll)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 预览用户返回的数据
|
|
|
func (s *Dice) _viewWin(rd *rollData) (win *rollData, err error) {
|
|
|
win = rd
|
|
|
|
|
|
if win.RewardId == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionCampaignReward
|
|
|
reward, err := m.WithContext(s.Ctx).Where(m.ID.Eq(win.RewardId)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
preward, err := provider.NewRewards(s.Ctx, s.cpn.ProjectID, reward.RewardID)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
info := preward.AutoLang(reward.RewardID, s.user.LangMark)
|
|
|
|
|
|
win.RewardTitle = info.Title
|
|
|
win.ImgUrl = info.ImgUrl
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 概率获取奖品
|
|
|
func (s *Dice) _odds(diceMaps []*model.FissionDiceMap, win, lose *rollData, isFixRoll bool) (res *rollData, err error) {
|
|
|
var rewardMap = make(map[int64]*model.FissionCampaignReward)
|
|
|
var ids []int64
|
|
|
var mapIdx = make(map[int]*model.FissionDiceMap)
|
|
|
for idx, v := range diceMaps {
|
|
|
if _, ok := rewardMap[v.RewardID]; !ok {
|
|
|
ids = append(ids, v.RewardID)
|
|
|
rewardMap[v.RewardID] = nil
|
|
|
}
|
|
|
mapIdx[idx] = v
|
|
|
}
|
|
|
|
|
|
if len(ids) == 0 {
|
|
|
return win, nil
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionCampaignReward
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.ID.In(ids...)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var signIds []int64
|
|
|
var signMap = make(map[int64]mtype.CollectRule)
|
|
|
for _, v := range list {
|
|
|
cr := v.GetCollectRule()
|
|
|
if cr.Open == mtype.Yes && cr.SignDay > 0 {
|
|
|
signIds = append(signIds, v.ID)
|
|
|
signMap[v.ID] = cr
|
|
|
}
|
|
|
}
|
|
|
|
|
|
filterMap, err := s._filterCollect(signIds, signMap)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var allOdds int
|
|
|
var prize []lucky.Reward
|
|
|
for _, v := range list {
|
|
|
|
|
|
if _, ok := filterMap[v.ID]; ok {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
odds := int(v.Odds)
|
|
|
prize = append(prize, lucky.Reward{
|
|
|
Share: odds,
|
|
|
Mark: v.ID,
|
|
|
})
|
|
|
|
|
|
allOdds = allOdds + odds
|
|
|
rewardMap[v.ID] = v
|
|
|
}
|
|
|
|
|
|
if len(prize) == 0 {
|
|
|
return lose, nil
|
|
|
}
|
|
|
|
|
|
reward, err := lucky.NewDiscrete(s.Ctx, prize).Lottery()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
id := reward.Int64()
|
|
|
|
|
|
// 概率中奖了,就走到那个中奖的格子
|
|
|
for idx, diceMap := range mapIdx {
|
|
|
if diceMap.RewardID == id {
|
|
|
win = &rollData{
|
|
|
MarkType: diceMap.MarkType,
|
|
|
Step: int32(idx),
|
|
|
RewardId: diceMap.RewardID,
|
|
|
MapId: diceMap.ID,
|
|
|
MapHashId: diceMap.HashID,
|
|
|
}
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
collect, err := s._rewardCollect(id)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return s._rewardInDb(rewardMap[id], collect, win, lose, isFixRoll)
|
|
|
}
|
|
|
|
|
|
// 奖品入库
|
|
|
func (s *Dice) _rewardInDb(reward *model.FissionCampaignReward, collect *model.FissionDiceCollect, win, lose *rollData, isFixRoll bool) (res *rollData, err error) {
|
|
|
var intact bool
|
|
|
var lack bool
|
|
|
if reward.CollectNum == collect.Num+1 {
|
|
|
|
|
|
//中奖了
|
|
|
var check bool
|
|
|
check, err = award.NewAwardIssVerify(s.Ctx, s.user, reward).DeductStock().RuleFilter().IsOK()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if !check && !isFixRoll {
|
|
|
return lose, nil
|
|
|
}
|
|
|
|
|
|
intact = true
|
|
|
lack = !check
|
|
|
}
|
|
|
|
|
|
cpn, err := finder.Campaign(s.Ctx, reward.CampaignID)
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
preward, err := provider.NewRewards(s.Ctx, cpn.ProjectID, reward.RewardID)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
info := preward.AutoLang(reward.RewardID, s.user.LangMark)
|
|
|
|
|
|
collectM := s.GetDao().FissionDiceCollect
|
|
|
var up []field.AssignExpr
|
|
|
var record *model.FissionRewardRecord
|
|
|
if intact {
|
|
|
record, err = s._intactReward(reward, lack)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if lack { // 没有库存,那就不让客户看动画了
|
|
|
up = append(up, collectM.Num.Value(0), collectM.IntactNum.Add(1))
|
|
|
|
|
|
// 骰子记录
|
|
|
var diceRecord = withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
CreatedAt: record.CreatedAt,
|
|
|
CampaignID: record.CampaignID,
|
|
|
UserID: record.UserID,
|
|
|
Mark: mtype.FissionDiceRecordMarkReward,
|
|
|
Data: "",
|
|
|
})
|
|
|
|
|
|
diceRecord.SetData(&mtype.DiceRecord{
|
|
|
RewardId: record.RewardID,
|
|
|
RecordId: record.ID,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(diceRecord)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
} else { // 有库存,让用户看到合成动画
|
|
|
up = append(up, collectM.Num.Add(1), collectM.RecordID.Value(record.ID))
|
|
|
}
|
|
|
|
|
|
} else { // 没有收集完碎片,碎片数 +1
|
|
|
up = append(up, collectM.Num.Add(1))
|
|
|
}
|
|
|
|
|
|
_, err = collectM.WithContext(s.Ctx).Where(collectM.ID.Eq(collect.ID)).UpdateSimple(up...)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
win.RewardTitle = info.Title
|
|
|
win.ImgUrl = info.ImgUrl
|
|
|
win.Intact = intact
|
|
|
win.Lack = lack
|
|
|
|
|
|
return win, nil
|
|
|
}
|
|
|
|
|
|
// 完整的奖品处理
|
|
|
func (s *Dice) _intactReward(reward *model.FissionCampaignReward, lack bool) (record *model.FissionRewardRecord, err error) {
|
|
|
var opts []award.RecordOption
|
|
|
if lack {
|
|
|
opts = append(opts, award.RewardRecordStatus(
|
|
|
mtype.FissionRewardRecordStatusFail,
|
|
|
mtype.FissionRewardRecordFailTypeCli,
|
|
|
mtype.FissionRewardRecordFailTypeCliLackMsg,
|
|
|
))
|
|
|
}
|
|
|
|
|
|
record, _, async, err := award.NewAwardReward(s.Ctx, s.GetDao(), s.cpn.ProjectID, s.user).One(reward, false, opts...)
|
|
|
if lack {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.AddOkDone(func() {
|
|
|
for _, fn := range async {
|
|
|
fn()
|
|
|
}
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 加骰子记录
|
|
|
func (s *Dice) _rollDiceRecord(win *rollData, luckyProp bool) (err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
record := withdefault.FissionDiceRecord(&model.FissionDiceRecord{
|
|
|
CampaignID: player.CampaignID,
|
|
|
UserID: player.UserID,
|
|
|
})
|
|
|
|
|
|
data := &mtype.DiceRecord{
|
|
|
Point: win.Step + 1,
|
|
|
RewardId: win.RewardId,
|
|
|
}
|
|
|
|
|
|
// 使用幸运骰子道具
|
|
|
if luckyProp {
|
|
|
|
|
|
switch win.MarkType {
|
|
|
case mtype.FissionDiceMapMarkTypeNone:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkLucky
|
|
|
case mtype.FissionDiceMapMarkTypeChance:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkLuckyChance
|
|
|
data.Chance = 1
|
|
|
default:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkLuckyCollect
|
|
|
}
|
|
|
|
|
|
record.SetData(data)
|
|
|
|
|
|
return s._addLog(record)
|
|
|
}
|
|
|
|
|
|
switch win.MarkType {
|
|
|
case mtype.FissionDiceMapMarkTypeNone:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkRoll
|
|
|
case mtype.FissionDiceMapMarkTypeChance:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkRollChance
|
|
|
data.Chance = 1
|
|
|
default:
|
|
|
record.Mark = mtype.FissionDiceRecordMarkRollCollect
|
|
|
}
|
|
|
|
|
|
record.SetData(data)
|
|
|
|
|
|
return s._addLog(record)
|
|
|
}
|
|
|
|
|
|
// 结果处理
|
|
|
func (s *Dice) _rollRes(win *rollData) (res RollRes, err error) {
|
|
|
run, err := s._runMap()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 更新地图信息
|
|
|
runM := s.GetDao().FissionDiceRun
|
|
|
_, err = runM.WithContext(s.Ctx).Where(runM.ID.Eq(run.ID)).UpdateSimple(
|
|
|
runM.MapID.Value(win.MapId),
|
|
|
runM.MapHashID.Value(win.MapHashId),
|
|
|
runM.GoStep.Add(int64(win.Step)+1),
|
|
|
)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
res.MarkType = int32(win.MarkType)
|
|
|
res.MapHashId = win.MapHashId
|
|
|
res.RewardTitle = win.RewardTitle
|
|
|
res.ImgUrl = win.ImgUrl
|
|
|
res.IsIntact = win.Intact
|
|
|
res.RollNum = win.Step + 1
|
|
|
res.Lack = win.Lack
|
|
|
res.RewardId = win.RewardId
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _reward(win, lose *rollData, isFixRoll bool) (res *rollData, err error) {
|
|
|
m := s.GetDao().FissionCampaignReward
|
|
|
reward, err := m.WithContext(s.Ctx).Where(m.ID.Eq(win.RewardId)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if reward == nil || reward.IsDel == mtype.Yes {
|
|
|
return lose, nil
|
|
|
}
|
|
|
|
|
|
collect, err := s._rewardCollect(reward.ID)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
cr := reward.GetCollectRule()
|
|
|
if cr.Open == mtype.Yes {
|
|
|
collectNum := cr.InitCollect + ((collect.SignNum / cr.SignDay) * cr.AddCollect)
|
|
|
if collect.Num >= collectNum {
|
|
|
return lose, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return s._rewardInDb(reward, collect, win, lose, isFixRoll)
|
|
|
}
|
|
|
|
|
|
// 用户道具
|
|
|
func (s *Dice) _propOrCreate(mark string) (prop *model.FissionDiceProp, err error) {
|
|
|
user := s.user
|
|
|
m := s.GetDao().FissionDiceProp
|
|
|
err = lockdo.FindNilDo(
|
|
|
s.Ctx,
|
|
|
ckey.FissionUserCreateDicePropOnce(user.ID, mark),
|
|
|
func() (none bool, err error) {
|
|
|
prop, err = m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID), m.Mark.Eq(mark)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return prop == nil, nil
|
|
|
},
|
|
|
func() (err error) {
|
|
|
prop = withdefault.FissionDiceProp(&model.FissionDiceProp{
|
|
|
UserID: user.ID,
|
|
|
CampaignID: user.CampaignID,
|
|
|
Mark: mark,
|
|
|
Num: 0,
|
|
|
TotalNum: 0,
|
|
|
})
|
|
|
if err = m.WithContext(s.Ctx).Create(prop); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Dice) _filterCollect(ids []int64, signMap map[int64]mtype.CollectRule) (filter map[int64]struct{}, err error) {
|
|
|
filter = make(map[int64]struct{})
|
|
|
|
|
|
if len(ids) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
player := s.GetPlayer()
|
|
|
m := s.GetDao().FissionDiceCollect
|
|
|
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.UserID.Eq(player.UserID), m.RewardID.In(ids...)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
cr := signMap[v.RewardID]
|
|
|
collectNum := cr.InitCollect + ((v.SignNum / cr.SignDay) * cr.AddCollect)
|
|
|
if v.Num >= collectNum {
|
|
|
filter[v.RewardID] = struct{}{}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|