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.
1060 lines
23 KiB
Go
1060 lines
23 KiB
Go
package players
|
|
|
|
import (
|
|
"context"
|
|
"joybuywork/internal/app"
|
|
"joybuywork/internal/consts"
|
|
"joybuywork/internal/consts/ckey"
|
|
"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/internal/utils"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"gits.branchcn.com/backend/microcode/plugins/lucky"
|
|
)
|
|
|
|
const (
|
|
unoClaimStatusOk = iota
|
|
unoClaimStatusDoing // 正在收集中
|
|
unoClaimStatusDone // 已经收集完成了
|
|
)
|
|
|
|
const (
|
|
unoCollectStatusOk = iota
|
|
unoCollectStatusLack // 抽奖次数不足
|
|
unoCollectStatusPropLack // 道具不足
|
|
unoCollectStatusPropFail // 道具不存在
|
|
)
|
|
|
|
// Uno Uno卡牌交互逻辑
|
|
type Uno struct {
|
|
Player
|
|
player *model.FissionUno
|
|
conf *model.FissionCampaignUno
|
|
|
|
fissionPlayerSetInitOnceKey string
|
|
fissionUserUnoClaimOnceKey string
|
|
fissionUserUnoCollectOnceKey string
|
|
|
|
collectMap map[string]*model.FissionUnoCollect
|
|
collectUp map[string]bool
|
|
}
|
|
|
|
func NewUno(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Uno, err error) {
|
|
player = &Uno{}
|
|
|
|
err = player.Init(ctx, user, consts.IdUno, opts...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = player.initPlayer()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Uno) Claim(colorMark string) (status int32, info provider.RewardAutoLang, record *model.FissionRewardRecord, err error) {
|
|
s.Tran()
|
|
defer func() {
|
|
s.TranCommit(err)
|
|
s.AfterDo(err)
|
|
}()
|
|
|
|
lock := app.NewRedisLock(s.Ctx, s.fissionUserUnoClaimOnceKey)
|
|
defer lock.Release()
|
|
if !lock.SoftLock() {
|
|
status = unoClaimStatusDoing
|
|
return
|
|
}
|
|
|
|
player := s.GetPlayer()
|
|
m := s.GetDao().FissionUnoCollect
|
|
collect, err := m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID), m.Mark.Eq(colorMark)).Take()
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if collect == nil || collect.PreIntactNum <= 0 {
|
|
status = unoClaimStatusDone
|
|
return
|
|
}
|
|
|
|
groupM := s.GetDao().FissionCampaignUnoGroup
|
|
group, err := groupM.WithContext(s.Ctx).Where(groupM.CampaignID.Eq(player.CampaignID), groupM.Mark.Eq(colorMark)).Take()
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
rewardM := s.GetDao().FissionCampaignReward
|
|
reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(group.RewardID)).Take()
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
record, info, async, err := award.NewAwardReward(s.Ctx, s.GetDao(), s.cpn.ProjectID, s.user).One(reward, false)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.AddOkDone(func() {
|
|
for _, fn := range async {
|
|
fn()
|
|
}
|
|
})
|
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(collect.ID)).UpdateColumnSimple(
|
|
m.IntactNum.Add(1),
|
|
m.PreIntactNum.Sub(1),
|
|
)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
err = s._addLog(withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypeClaim,
|
|
Source: mtype.FissionUnoLogSourceClaim,
|
|
}, mtype.UnoLogVal{
|
|
RewardId: record.RewardID,
|
|
RecordId: record.ID,
|
|
}))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 收集卡牌埋点
|
|
s.appTrack().CollectUnoCard(time.Now().Unix(), colorMark)
|
|
|
|
return unoClaimStatusOk, info, record, nil
|
|
}
|
|
|
|
type UnoCollectCard struct {
|
|
Mark string
|
|
CardNo int32
|
|
}
|
|
|
|
func (s *Uno) _randMark(groups []*model.FissionCampaignUnoGroup) string {
|
|
var odds []string
|
|
for _, v := range groups {
|
|
odds = append(odds, v.Odds)
|
|
}
|
|
|
|
shares, _ := utils.NormalizeDecimalStrings(odds)
|
|
|
|
var marks []lucky.Reward
|
|
for i, v := range groups {
|
|
marks = append(marks, lucky.Reward{
|
|
Share: shares[i],
|
|
Mark: v.Mark,
|
|
})
|
|
}
|
|
|
|
// 抽奖
|
|
lcy, _ := lucky.NewDiscrete(s.Ctx, marks).Lottery()
|
|
|
|
return lcy.String()
|
|
}
|
|
|
|
func (s *Uno) _randCard(group *model.FissionCampaignUnoGroup) (card *UnoCollectCard, err error) {
|
|
collectMap, err := s._userCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
collect := collectMap[group.Mark]
|
|
|
|
cardInfo := collect.GetCardInfo()
|
|
var hasCardMap = make(map[int]struct{})
|
|
for i, cardNum := range cardInfo {
|
|
if cardNum > 0 {
|
|
hasCardMap[i+1] = struct{}{}
|
|
}
|
|
}
|
|
|
|
var unoCardMap = map[int]struct{}{1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {}}
|
|
|
|
switch group.OpenRule {
|
|
case mtype.No:
|
|
for k := range hasCardMap {
|
|
delete(unoCardMap, k)
|
|
}
|
|
case mtype.Yes:
|
|
rule := group.GetLimitRule()
|
|
num := int(rule.InitNum + rule.AddNum*(collect.SignNum/rule.SignDay))
|
|
|
|
if num >= 9 {
|
|
for k := range hasCardMap {
|
|
delete(unoCardMap, k)
|
|
}
|
|
} else {
|
|
|
|
var reset = make(map[int]struct{})
|
|
for k := range hasCardMap {
|
|
reset[k] = struct{}{}
|
|
}
|
|
|
|
hcmL := len(hasCardMap)
|
|
if hcmL > num {
|
|
idx := hcmL - num
|
|
for i := 0; i < 9; i++ {
|
|
if _, ok := hasCardMap[i+1]; ok {
|
|
delete(reset, i+1)
|
|
idx--
|
|
if idx <= 0 {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
} else if hcmL < num {
|
|
idx := num - hcmL
|
|
for k := range unoCardMap {
|
|
if _, ok := reset[k]; !ok {
|
|
reset[k] = struct{}{}
|
|
idx--
|
|
if idx <= 0 {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
unoCardMap = reset
|
|
}
|
|
|
|
}
|
|
|
|
var hasL = len(hasCardMap)
|
|
var cardNo, preIntactNum int32
|
|
for no := range unoCardMap {
|
|
cardNo = int32(no)
|
|
|
|
idx := no - 1
|
|
intactL := hasL + 1
|
|
if intactL < 9 {
|
|
cardInfo[idx]++
|
|
break
|
|
}
|
|
|
|
rewardM := s.GetDao().FissionCampaignReward
|
|
reward, _ := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(group.RewardID)).Take()
|
|
|
|
if reward == nil {
|
|
continue
|
|
}
|
|
|
|
issVr := award.NewAwardIssVerify(s.Ctx, s.user, reward)
|
|
ok1, _ := issVr.DeductStock().IsOK()
|
|
if !ok1 {
|
|
continue
|
|
}
|
|
|
|
preIntactNum++
|
|
for i := range cardInfo {
|
|
if i != idx {
|
|
cardInfo[i]--
|
|
}
|
|
}
|
|
|
|
break
|
|
}
|
|
|
|
if cardNo == 0 {
|
|
for no := range hasCardMap {
|
|
cardNo = int32(no)
|
|
}
|
|
}
|
|
|
|
collect.SetCardInfo(cardInfo)
|
|
collect.PreIntactNum += preIntactNum
|
|
if preIntactNum > 0 &&
|
|
group.OpenRule == mtype.Yes &&
|
|
group.GetLimitRule().ResetType == mtype.FissionCampaignUnoGroupResetTypeReward {
|
|
collect.SignNum = 0
|
|
}
|
|
|
|
s.collectUp[group.Mark] = true
|
|
|
|
card = &UnoCollectCard{
|
|
Mark: group.Mark,
|
|
CardNo: cardNo,
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Uno) Collect() (status int32, cards *UnoCollectCard, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
m := s.GetDao().FissionCampaignUnoGroup
|
|
groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find()
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
groupMap := make(map[string]*model.FissionCampaignUnoGroup)
|
|
for _, v := range groups {
|
|
groupMap[v.Mark] = v
|
|
}
|
|
|
|
mark := s._randMark(groups)
|
|
if s.IsView() {
|
|
return unoCollectStatusOk, &UnoCollectCard{
|
|
Mark: mark,
|
|
CardNo: rand.Int31n(8) + 1,
|
|
}, nil
|
|
}
|
|
|
|
if player.Chance <= 0 {
|
|
status = unoCollectStatusLack
|
|
return
|
|
}
|
|
|
|
randCard, err := s._randCard(groupMap[mark])
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
playerM := s.GetDao().FissionUno
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.Chance.Sub(1))
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
err = s._upCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypeDecr,
|
|
Source: mtype.FissionLogSourceLottery,
|
|
}, mtype.UnoLogVal{
|
|
Chance: 1,
|
|
Cards: []*mtype.UnoLogValCard{
|
|
{
|
|
CardNo: randCard.CardNo,
|
|
Mark: mark,
|
|
},
|
|
},
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return unoCollectStatusOk, randCard, nil
|
|
}
|
|
|
|
func (s *Uno) UseProp(propMark, colorMark string) (status int32, cards []*UnoCollectCard, err error) {
|
|
|
|
switch propMark {
|
|
case mtype.FissionCampaignUnoPropMarkThree:
|
|
return s._useThree()
|
|
case mtype.FissionCampaignUnoPropMarkFive:
|
|
return s._useFive()
|
|
case mtype.FissionCampaignUnoPropMarkFix:
|
|
return s._useFix(colorMark)
|
|
}
|
|
|
|
return unoCollectStatusPropFail, nil, nil
|
|
}
|
|
|
|
func (s *Uno) _useFix(colorMark string) (status int32, cards []*UnoCollectCard, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
m := s.GetDao().FissionCampaignUnoGroup
|
|
groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find()
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
groupMap := make(map[string]*model.FissionCampaignUnoGroup)
|
|
for _, v := range groups {
|
|
groupMap[v.Mark] = v
|
|
}
|
|
|
|
if s.IsView() {
|
|
return unoCollectStatusOk, []*UnoCollectCard{
|
|
{
|
|
Mark: colorMark,
|
|
CardNo: rand.Int31n(8) + 1,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
if player.FixNum <= 0 {
|
|
status = unoCollectStatusPropLack
|
|
return
|
|
}
|
|
|
|
randCard, err := s._randCard(groupMap[colorMark])
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
playerM := s.GetDao().FissionUno
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.FixNum.Sub(1))
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
err = s._upCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypePropUse,
|
|
Source: mtype.FissionUnoLogSourceFixUse,
|
|
}, mtype.UnoLogVal{
|
|
Chance: 1,
|
|
PropMark: mtype.FissionCampaignTaskPropMarkUnoFix,
|
|
Cards: []*mtype.UnoLogValCard{
|
|
{
|
|
CardNo: randCard.CardNo,
|
|
Mark: randCard.Mark,
|
|
},
|
|
},
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
cards = append(cards, randCard)
|
|
|
|
// 使用道具埋点
|
|
s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoFix)
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Uno) _useFive() (status int32, cards []*UnoCollectCard, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
m := s.GetDao().FissionCampaignUnoGroup
|
|
groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find()
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
groupMap := make(map[string]*model.FissionCampaignUnoGroup)
|
|
for _, v := range groups {
|
|
groupMap[v.Mark] = v
|
|
}
|
|
|
|
if s.IsView() {
|
|
cards = append(cards, &UnoCollectCard{})
|
|
|
|
for i := 0; i < 5; i++ {
|
|
cards = append(cards, &UnoCollectCard{
|
|
Mark: s._randMark(groups),
|
|
CardNo: rand.Int31n(8) + 1,
|
|
})
|
|
}
|
|
|
|
return unoCollectStatusOk, cards, nil
|
|
}
|
|
|
|
if player.FiveNum <= 0 {
|
|
status = unoCollectStatusPropLack
|
|
return
|
|
}
|
|
|
|
for i := 0; i < 5; i++ {
|
|
mark := s._randMark(groups)
|
|
var randCard *UnoCollectCard
|
|
randCard, err = s._randCard(groupMap[mark])
|
|
if err != nil {
|
|
return
|
|
}
|
|
cards = append(cards, randCard)
|
|
}
|
|
|
|
playerM := s.GetDao().FissionUno
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.FiveNum.Sub(1))
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
err = s._upCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var logCards []*mtype.UnoLogValCard
|
|
for _, v := range cards {
|
|
logCards = append(logCards, &mtype.UnoLogValCard{
|
|
CardNo: v.CardNo,
|
|
Mark: v.Mark,
|
|
})
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypePropUse,
|
|
Source: mtype.FissionUnoLogSourceFiveUse,
|
|
}, mtype.UnoLogVal{
|
|
Chance: 1,
|
|
PropMark: mtype.FissionCampaignTaskPropMarkUnoFive,
|
|
Cards: logCards,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoFive)
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Uno) _useThree() (status int32, cards []*UnoCollectCard, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
m := s.GetDao().FissionCampaignUnoGroup
|
|
groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
groupMap := make(map[string]*model.FissionCampaignUnoGroup)
|
|
for _, v := range groups {
|
|
groupMap[v.Mark] = v
|
|
}
|
|
|
|
if s.IsView() {
|
|
cards = append(cards, &UnoCollectCard{})
|
|
|
|
for i := 0; i < 3; i++ {
|
|
cards = append(cards, &UnoCollectCard{
|
|
Mark: s._randMark(groups),
|
|
CardNo: rand.Int31n(8) + 1,
|
|
})
|
|
}
|
|
|
|
return unoCollectStatusOk, cards, nil
|
|
}
|
|
|
|
if player.ThreeNum <= 0 {
|
|
status = unoCollectStatusPropLack
|
|
return
|
|
}
|
|
|
|
for i := 0; i < 3; i++ {
|
|
mark := s._randMark(groups)
|
|
var randCard *UnoCollectCard
|
|
randCard, err = s._randCard(groupMap[mark])
|
|
if err != nil {
|
|
return
|
|
}
|
|
cards = append(cards, randCard)
|
|
}
|
|
|
|
playerM := s.GetDao().FissionUno
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.ThreeNum.Sub(1))
|
|
if err != nil {
|
|
err = s.BE().CacheError(err)
|
|
return
|
|
}
|
|
|
|
err = s._upCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var logCards []*mtype.UnoLogValCard
|
|
for _, v := range cards {
|
|
logCards = append(logCards, &mtype.UnoLogValCard{
|
|
CardNo: v.CardNo,
|
|
Mark: v.Mark,
|
|
})
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypePropUse,
|
|
Source: mtype.FissionUnoLogSourceThreeUse,
|
|
}, mtype.UnoLogVal{
|
|
Chance: 1,
|
|
PropMark: mtype.FissionCampaignTaskPropMarkUnoThree,
|
|
Cards: logCards,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoThree)
|
|
|
|
return
|
|
}
|
|
|
|
type UnoCards struct {
|
|
CardNo int32 `json:"card_no"`
|
|
CardNum int32 `json:"card_num"`
|
|
}
|
|
|
|
func (s *Uno) Cards() (data map[string][]*UnoCards, err error) {
|
|
collectMap, err := s._userCollect()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
data = map[string][]*UnoCards{
|
|
mtype.FissionCampaignUnoGroupRed: {},
|
|
mtype.FissionCampaignUnoGroupBlue: {},
|
|
mtype.FissionCampaignUnoGroupYellow: {},
|
|
mtype.FissionCampaignUnoGroupGreen: {},
|
|
}
|
|
|
|
for k := range data {
|
|
collect := collectMap[k]
|
|
nums := collect.GetCardInfo()
|
|
data[k] = make([]*UnoCards, 9)
|
|
for i := 0; i < 9; i++ {
|
|
one := &UnoCards{
|
|
CardNo: int32(i) + 1,
|
|
CardNum: nums[i] + collect.PreIntactNum,
|
|
}
|
|
|
|
data[k][i] = one
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Sign 签到
|
|
func (s *Uno) Sign() (err error) {
|
|
player := s.GetPlayer()
|
|
|
|
signOk, lastSign := s._lastSign(player.LastSign)
|
|
if !signOk {
|
|
return
|
|
}
|
|
|
|
playerM := s.GetDao().FissionUno
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.LastSign.Value(lastSign))
|
|
if err != nil {
|
|
return s.BE().MysqlError(err)
|
|
}
|
|
|
|
m := s.GetDao().FissionUnoCollect
|
|
_, err = m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).UpdateSimple(m.SignNum.Add(1))
|
|
if err != nil {
|
|
return s.BE().MysqlError(err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// ReceiveReward 手动领取奖励
|
|
func (s *Uno) 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 *Uno) FinishTask(tasks ...*model.FissionCampaignTask) (err error) {
|
|
_, err = s.taskFinish(tasks, true)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// 完成任务
|
|
func (s *Uno) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance int32, err error) {
|
|
player := s.GetPlayer()
|
|
|
|
var lotteryChance, threeNum, fiveNum, fixNum int32
|
|
var logs []*model.FissionUnoLog
|
|
for _, task := range tasks {
|
|
if checkManual && task.AwardMode == mtype.FissionCampaignTaskAwardModeManual {
|
|
continue
|
|
}
|
|
|
|
val := mtype.UnoLogVal{
|
|
TaskId: task.ID,
|
|
Chance: task.Chance,
|
|
}
|
|
var logType int8
|
|
switch task.PropMark {
|
|
case mtype.FissionCampaignTaskPropMarkChance:
|
|
chance += task.Chance
|
|
lotteryChance += task.Chance
|
|
logType = mtype.FissionUnoLogTypeAdd
|
|
case mtype.FissionCampaignTaskPropMarkUnoFive:
|
|
chance += task.Chance
|
|
fiveNum += task.Chance
|
|
logType = mtype.FissionUnoLogTypeProp
|
|
case mtype.FissionCampaignTaskPropMarkUnoThree:
|
|
chance += task.Chance
|
|
threeNum += task.Chance
|
|
logType = mtype.FissionUnoLogTypeProp
|
|
case mtype.FissionCampaignTaskPropMarkUnoFix:
|
|
chance += task.Chance
|
|
fixNum += task.Chance
|
|
logType = mtype.FissionUnoLogTypeProp
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: logType,
|
|
}, val)
|
|
|
|
switch task.TaskType {
|
|
case mtype.FissionCampaignTaskTypeRegister:
|
|
log.Source = mtype.FissionLogSourceRegister
|
|
case mtype.FissionCampaignTaskTypeInstall:
|
|
log.Source = mtype.FissionLogSourceInstall
|
|
case mtype.FissionCampaignTaskTypeCondAll:
|
|
log.Source = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionLogSourceManualCondAll, mtype.FissionLogSourceCondAll)
|
|
case mtype.FissionCampaignTaskTypeCondOne:
|
|
log.Source = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionLogSourceManualCondOne, mtype.FissionLogSourceCondOne)
|
|
}
|
|
|
|
logs = append(logs, log)
|
|
|
|
}
|
|
|
|
if lotteryChance > 0 || threeNum > 0 || fiveNum > 0 || fixNum > 0 {
|
|
m := s.GetDao().FissionUno
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(
|
|
m.Chance.Add(lotteryChance),
|
|
m.ThreeNum.Add(threeNum),
|
|
m.FiveNum.Add(fiveNum),
|
|
m.FixNum.Add(fixNum),
|
|
)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if lotteryChance > 0 {
|
|
s.addChanceNotify(int64(lotteryChance))
|
|
}
|
|
}
|
|
|
|
err = s._addLog(logs...)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.trackGetProp(threeNum, fiveNum, fixNum)
|
|
|
|
return
|
|
}
|
|
|
|
func (s *Uno) trackGetProp(threeNum, fiveNum, fixNum int32) {
|
|
props := []struct {
|
|
name string
|
|
num int32
|
|
}{
|
|
{name: consts.PropNameUnoThree, num: threeNum},
|
|
{name: consts.PropNameUnoFive, num: fiveNum},
|
|
{name: consts.PropNameUnoFix, num: fixNum},
|
|
}
|
|
|
|
now := time.Now().Unix()
|
|
for _, prop := range props {
|
|
if prop.num > 0 {
|
|
s.appTrack().GetProp(now, prop.name, prop.num)
|
|
}
|
|
}
|
|
}
|
|
|
|
// SetInit 获得初始次数
|
|
func (s *Uno) 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().FissionUno
|
|
_, 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
|
|
}
|
|
|
|
log := withdefault.FissionUnoLog(&model.FissionUnoLog{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Type: mtype.FissionUnoLogTypeAdd,
|
|
Source: mtype.FissionLogSourceInit,
|
|
}, mtype.UnoLogVal{
|
|
Chance: conf.InitChance,
|
|
})
|
|
|
|
err = s._addLog(log)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
s.player.Chance += conf.InitChance
|
|
|
|
return
|
|
}
|
|
|
|
// GetConf 获取玩法配置
|
|
func (s *Uno) GetConf() *model.FissionCampaignUno {
|
|
if s.conf == nil {
|
|
s.conf, _ = cache.NewCampaignUno(s.Ctx).FindByCampaignId(s.user.CampaignID)
|
|
}
|
|
|
|
return s.conf
|
|
}
|
|
|
|
// GetPlayer 获取玩家基础数据
|
|
func (s *Uno) GetPlayer() *model.FissionUno {
|
|
return s.player
|
|
}
|
|
|
|
// 玩家
|
|
func (s *Uno) 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.fissionUserUnoClaimOnceKey = ckey.FissionUserUnoClaimOnce(player.UserID)
|
|
s.fissionUserUnoCollectOnceKey = ckey.FissionUserUnoCollectOnce(player.UserID)
|
|
|
|
s.collectMap = make(map[string]*model.FissionUnoCollect, 4)
|
|
s.collectUp = make(map[string]bool, 4)
|
|
}()
|
|
|
|
if player != nil {
|
|
return
|
|
}
|
|
|
|
player, err = s.firstOrCreate()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 创建玩家基础数据
|
|
func (s *Uno) firstOrCreate() (player *model.FissionUno, 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 *Uno) _dbFirst() (*model.FissionUno, error) {
|
|
playerM := dao.FissionUno
|
|
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 *Uno) createPlayer() (player *model.FissionUno, err error) {
|
|
playerM := dao.FissionUno
|
|
player = withdefault.FissionUno(&model.FissionUno{
|
|
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 *Uno) _addLog(logs ...*model.FissionUnoLog) (err error) {
|
|
err = s.GetDao().FissionUnoLog.WithContext(s.Ctx).Create(logs...)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Uno) _userCollect() (data map[string]*model.FissionUnoCollect, err error) {
|
|
if len(s.collectMap) > 0 {
|
|
return s.collectMap, nil
|
|
}
|
|
|
|
player := s.GetPlayer()
|
|
m := s.GetDao().FissionUnoCollect
|
|
list, err := m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
key := s.fissionUserUnoCollectOnceKey
|
|
|
|
lc := app.NewFollower(s.Ctx, key).Lock()
|
|
defer lc.Release()
|
|
if lc.Error() != nil {
|
|
err = lc.Error()
|
|
return
|
|
}
|
|
|
|
list, err = m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).Find()
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
|
|
if len(list) == 0 {
|
|
cardInfo := make([]int32, 9)
|
|
list = append(
|
|
list,
|
|
withdefault.FissionUnoCollect(&model.FissionUnoCollect{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Mark: mtype.FissionCampaignUnoGroupRed,
|
|
}, cardInfo),
|
|
withdefault.FissionUnoCollect(&model.FissionUnoCollect{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Mark: mtype.FissionCampaignUnoGroupBlue,
|
|
}, cardInfo),
|
|
withdefault.FissionUnoCollect(&model.FissionUnoCollect{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Mark: mtype.FissionCampaignUnoGroupYellow,
|
|
}, cardInfo),
|
|
withdefault.FissionUnoCollect(&model.FissionUnoCollect{
|
|
UserID: player.UserID,
|
|
CampaignID: player.CampaignID,
|
|
UnoID: player.ID,
|
|
Mark: mtype.FissionCampaignUnoGroupGreen,
|
|
}, cardInfo),
|
|
)
|
|
|
|
if err = m.WithContext(s.Ctx).Create(list...); err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, v := range list {
|
|
s.collectMap[v.Mark] = v
|
|
}
|
|
|
|
return s.collectMap, nil
|
|
}
|
|
|
|
// 增加抽奖次数通知
|
|
func (s *Uno) addChanceNotify(chance int64) {
|
|
provider.NewFissionClue(s.Ctx, s.user.ID).AddChance(chance)
|
|
}
|
|
|
|
func (s *Uno) _upCollect() (err error) {
|
|
for _, collect := range s.collectMap {
|
|
if up, ok := s.collectUp[collect.Mark]; ok && up {
|
|
err = s.GetDao().FissionUnoCollect.WithContext(s.Ctx).Save(collect)
|
|
if err != nil {
|
|
err = s.BE().MysqlError(err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|