mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Fix login bonus
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
Build and Push Docker images to Docker Hub / build-and-push (push) Has been cancelled
This commit is contained in:
@@ -42,34 +42,30 @@ func main() {
|
|||||||
|
|
||||||
userStore := sqlite.New(db, nil)
|
userStore := sqlite.New(db, nil)
|
||||||
|
|
||||||
authdb, err := database.Open(*authdbPath)
|
authDb, err := database.Open(*authdbPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("open auth database: %v", err)
|
log.Fatalf("open auth database: %v", err)
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer authDb.Close()
|
||||||
|
|
||||||
authStore, err := auth.NewAuthStore(authdb)
|
authStore, err := auth.NewAuthStore(authDb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("init auth store: %v", err)
|
log.Fatalf("init auth store: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auth user check
|
|
||||||
|
|
||||||
userExists := authStore.UserExists(*name)
|
userExists := authStore.UserExists(*name)
|
||||||
if userExists {
|
if userExists {
|
||||||
log.Fatal("Username is already taken")
|
log.Fatal("Username is already taken")
|
||||||
}
|
}
|
||||||
|
|
||||||
// lunar-tear user
|
|
||||||
|
|
||||||
var userPlatform model.ClientPlatform
|
var userPlatform model.ClientPlatform
|
||||||
|
|
||||||
if *platform == "android" {
|
if *platform == "android" {
|
||||||
userPlatform.OsType = 2
|
userPlatform.OsType = model.OsTypeAndroid
|
||||||
userPlatform.PlatformType = 2
|
userPlatform.PlatformType = model.PlatformTypeGooglePlayStore
|
||||||
} else {
|
} else {
|
||||||
userPlatform.OsType = 1
|
userPlatform.OsType = model.OsTypeIOS
|
||||||
userPlatform.PlatformType = 1
|
userPlatform.PlatformType = model.PlatformTypeAppStore
|
||||||
}
|
}
|
||||||
|
|
||||||
userUuid := uuid.New().String()
|
userUuid := uuid.New().String()
|
||||||
@@ -81,8 +77,6 @@ func main() {
|
|||||||
log.Fatalf("Register user in database: %v", err)
|
log.Fatalf("Register user in database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind
|
|
||||||
|
|
||||||
authUser, err := authStore.CreateUser(*name, *password)
|
authUser, err := authStore.CreateUser(*name, *password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Register auth account: %v", err)
|
log.Fatalf("Register auth account: %v", err)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ package masterdata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"lunar-tear/server/internal/utils"
|
"lunar-tear/server/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,28 +21,71 @@ type LoginBonusReward struct {
|
|||||||
|
|
||||||
type LoginBonusCatalog struct {
|
type LoginBonusCatalog struct {
|
||||||
stamps map[loginBonusStampKey]LoginBonusReward
|
stamps map[loginBonusStampKey]LoginBonusReward
|
||||||
|
bonusPages map[int32][]int32
|
||||||
|
totalPages map[int32]int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LoginBonusCatalog) LookupStampReward(loginBonusId, pageNumber, stampNumber int32) (LoginBonusReward, bool) {
|
func (c *LoginBonusCatalog) LookupStampReward(loginBonusId, pageNumber, stampNumber int32) (LoginBonusReward, bool) {
|
||||||
entry, ok := c.stamps[loginBonusStampKey{loginBonusId, pageNumber, stampNumber}]
|
pages := c.bonusPages[loginBonusId]
|
||||||
|
lower := int32(-1)
|
||||||
|
for _, p := range pages {
|
||||||
|
if p <= pageNumber {
|
||||||
|
lower = p
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if lower < 0 {
|
||||||
|
return LoginBonusReward{}, false
|
||||||
|
}
|
||||||
|
entry, ok := c.stamps[loginBonusStampKey{loginBonusId, lower, stampNumber}]
|
||||||
return entry, ok
|
return entry, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *LoginBonusCatalog) TotalPageCount(loginBonusId int32) int32 {
|
||||||
|
return c.totalPages[loginBonusId]
|
||||||
|
}
|
||||||
|
|
||||||
func LoadLoginBonusCatalog() *LoginBonusCatalog {
|
func LoadLoginBonusCatalog() *LoginBonusCatalog {
|
||||||
stamps, err := utils.ReadTable[EntityMLoginBonusStamp]("m_login_bonus_stamp")
|
stamps, err := utils.ReadTable[EntityMLoginBonusStamp]("m_login_bonus_stamp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("load login bonus stamp table: %v", err)
|
log.Fatalf("load login bonus stamp table: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bonuses, err := utils.ReadTable[EntityMLoginBonus]("m_login_bonus")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("load login bonus table: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
cat := &LoginBonusCatalog{
|
cat := &LoginBonusCatalog{
|
||||||
stamps: make(map[loginBonusStampKey]LoginBonusReward, len(stamps)),
|
stamps: make(map[loginBonusStampKey]LoginBonusReward, len(stamps)),
|
||||||
|
bonusPages: make(map[int32][]int32),
|
||||||
|
totalPages: make(map[int32]int32, len(bonuses)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, b := range bonuses {
|
||||||
|
cat.totalPages[b.LoginBonusId] = b.TotalPageCount
|
||||||
|
}
|
||||||
|
|
||||||
|
seenPages := make(map[loginBonusStampKey]struct{})
|
||||||
for _, s := range stamps {
|
for _, s := range stamps {
|
||||||
cat.stamps[loginBonusStampKey{s.LoginBonusId, s.LowerPageNumber, s.StampNumber}] = LoginBonusReward{
|
cat.stamps[loginBonusStampKey{s.LoginBonusId, s.LowerPageNumber, s.StampNumber}] = LoginBonusReward{
|
||||||
PossessionType: s.RewardPossessionType,
|
PossessionType: s.RewardPossessionType,
|
||||||
PossessionId: s.RewardPossessionId,
|
PossessionId: s.RewardPossessionId,
|
||||||
Count: s.RewardCount,
|
Count: s.RewardCount,
|
||||||
}
|
}
|
||||||
|
dedup := loginBonusStampKey{LoginBonusId: s.LoginBonusId, LowerPageNumber: s.LowerPageNumber}
|
||||||
|
if _, exists := seenPages[dedup]; !exists {
|
||||||
|
seenPages[dedup] = struct{}{}
|
||||||
|
cat.bonusPages[s.LoginBonusId] = append(cat.bonusPages[s.LoginBonusId], s.LowerPageNumber)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for id := range cat.bonusPages {
|
||||||
|
sort.Slice(cat.bonusPages[id], func(i, j int) bool {
|
||||||
|
return cat.bonusPages[id][i] < cat.bonusPages[id][j]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return cat
|
return cat
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,17 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
pb "lunar-tear/server/gen/proto"
|
pb "lunar-tear/server/gen/proto"
|
||||||
"lunar-tear/server/internal/gametime"
|
"lunar-tear/server/internal/gametime"
|
||||||
|
"lunar-tear/server/internal/masterdata"
|
||||||
"lunar-tear/server/internal/runtime"
|
"lunar-tear/server/internal/runtime"
|
||||||
"lunar-tear/server/internal/store"
|
"lunar-tear/server/internal/store"
|
||||||
|
|
||||||
@@ -31,24 +35,25 @@ func (s *LoginBonusServiceServer) ReceiveStamp(ctx context.Context, req *emptypb
|
|||||||
userId := CurrentUserId(ctx, s.users, s.sessions)
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
catalog := s.holder.Get().LoginBonus
|
catalog := s.holder.Get().LoginBonus
|
||||||
|
|
||||||
s.users.UpdateUser(userId, func(user *store.UserState) {
|
user, err := s.users.LoadUser(userId)
|
||||||
now := gametime.NowMillis()
|
if err != nil {
|
||||||
nextStamp := user.LoginBonus.CurrentStampNumber + 1
|
return nil, fmt.Errorf("load user: %w", err)
|
||||||
|
|
||||||
reward, ok := catalog.LookupStampReward(
|
|
||||||
user.LoginBonus.LoginBonusId,
|
|
||||||
user.LoginBonus.CurrentPageNumber,
|
|
||||||
nextStamp,
|
|
||||||
)
|
|
||||||
if !ok {
|
|
||||||
log.Fatalf("[LoginBonusService] no reward found for bonusId=%d page=%d stamp=%d",
|
|
||||||
user.LoginBonus.LoginBonusId, user.LoginBonus.CurrentPageNumber, nextStamp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[LoginBonusService] stamp %d -> possType=%d possId=%d count=%d (-> gift box)",
|
nextPage, nextStamp, reward, err := resolveNextStamp(catalog, user.LoginBonus)
|
||||||
nextStamp, reward.PossessionType, reward.PossessionId, reward.Count)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
user.Gifts.NotReceived = append(user.Gifts.NotReceived, store.NotReceivedGiftState{
|
log.Printf("[LoginBonusService] bonusId=%d page %d->%d stamp %d->%d possType=%d possId=%d count=%d (-> gift box)",
|
||||||
|
user.LoginBonus.LoginBonusId,
|
||||||
|
user.LoginBonus.CurrentPageNumber, nextPage,
|
||||||
|
user.LoginBonus.CurrentStampNumber, nextStamp,
|
||||||
|
reward.PossessionType, reward.PossessionId, reward.Count)
|
||||||
|
|
||||||
|
s.users.UpdateUser(userId, func(u *store.UserState) {
|
||||||
|
now := gametime.NowMillis()
|
||||||
|
u.Gifts.NotReceived = append(u.Gifts.NotReceived, store.NotReceivedGiftState{
|
||||||
GiftCommon: store.GiftCommonState{
|
GiftCommon: store.GiftCommonState{
|
||||||
PossessionType: reward.PossessionType,
|
PossessionType: reward.PossessionType,
|
||||||
PossessionId: reward.PossessionId,
|
PossessionId: reward.PossessionId,
|
||||||
@@ -58,11 +63,42 @@ func (s *LoginBonusServiceServer) ReceiveStamp(ctx context.Context, req *emptypb
|
|||||||
ExpirationDatetime: now + int64(30*24*time.Hour/time.Millisecond),
|
ExpirationDatetime: now + int64(30*24*time.Hour/time.Millisecond),
|
||||||
UserGiftUuid: uuid.New().String(),
|
UserGiftUuid: uuid.New().String(),
|
||||||
})
|
})
|
||||||
user.Notifications.GiftNotReceiveCount = int32(len(user.Gifts.NotReceived))
|
u.Notifications.GiftNotReceiveCount = int32(len(u.Gifts.NotReceived))
|
||||||
user.LoginBonus.CurrentStampNumber = nextStamp
|
u.LoginBonus.CurrentPageNumber = nextPage
|
||||||
user.LoginBonus.LatestRewardReceiveDatetime = now
|
u.LoginBonus.CurrentStampNumber = nextStamp
|
||||||
user.LoginBonus.LatestVersion = now
|
u.LoginBonus.LatestRewardReceiveDatetime = now
|
||||||
|
u.LoginBonus.LatestVersion = now
|
||||||
})
|
})
|
||||||
|
|
||||||
return &pb.ReceiveStampResponse{}, nil
|
return &pb.ReceiveStampResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveNextStamp(catalog *masterdata.LoginBonusCatalog, lb store.UserLoginBonusState) (nextPage, nextStamp int32, reward masterdata.LoginBonusReward, err error) {
|
||||||
|
bonusId := lb.LoginBonusId
|
||||||
|
curPage := lb.CurrentPageNumber
|
||||||
|
curStamp := lb.CurrentStampNumber
|
||||||
|
|
||||||
|
nextPage = curPage
|
||||||
|
nextStamp = curStamp + 1
|
||||||
|
var ok bool
|
||||||
|
reward, ok = catalog.LookupStampReward(bonusId, nextPage, nextStamp)
|
||||||
|
if !ok {
|
||||||
|
nextPage = curPage + 1
|
||||||
|
nextStamp = 1
|
||||||
|
total := catalog.TotalPageCount(bonusId)
|
||||||
|
if total > 0 && nextPage > total {
|
||||||
|
err = status.Errorf(codes.FailedPrecondition,
|
||||||
|
"login bonus %d exhausted (page %d stamp %d is the last)",
|
||||||
|
bonusId, curPage, curStamp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reward, ok = catalog.LookupStampReward(bonusId, nextPage, nextStamp)
|
||||||
|
if !ok {
|
||||||
|
err = status.Errorf(codes.FailedPrecondition,
|
||||||
|
"no reward found for login bonus %d page %d stamp %d",
|
||||||
|
bonusId, nextPage, nextStamp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user