diff --git a/server/internal/service/gacha.go b/server/internal/service/gacha.go index 95bbee8..98170ae 100644 --- a/server/internal/service/gacha.go +++ b/server/internal/service/gacha.go @@ -291,11 +291,11 @@ func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb bs := updatedUser.Gacha.BannerStates[entry.GachaId] nextGacha := toProtoGacha(*entry, &bs) - diff := userdata.BuildDiffFromTables(userdata.SelectTables( - userdata.FullClientTableMap(updatedUser), - gachaDiffTables, - )) - userdata.AddWeaponStoryDiff(diff, updatedUser, s.handler.Granter.DrainChangedStoryWeaponIds()) + changedStoryIds := s.handler.Granter.DrainChangedStoryWeaponIds() + diffOrder := append(gachaDiffTables, "IUserWeaponStory") + allTables := userdata.FullClientTableMap(updatedUser) + diff := userdata.BuildDiffFromTablesOrdered(userdata.SelectTables(allTables, diffOrder), diffOrder) + userdata.AddWeaponStoryDiff(diff, updatedUser, changedStoryIds) return &pb.DrawResponse{ NextGacha: nextGacha, diff --git a/server/internal/store/helpers.go b/server/internal/store/helpers.go index 8ac780f..7d9e44b 100644 --- a/server/internal/store/helpers.go +++ b/server/internal/store/helpers.go @@ -156,6 +156,15 @@ func (g *PossessionGranter) GrantCostume(user *UserState, costumeId int32, nowMi func (g *PossessionGranter) GrantWeapon(user *UserState, weaponId int32, nowMillis int64) { key := fmt.Sprintf("reward-weapon-%d-%d", weaponId, nowMillis) + if _, exists := user.Weapons[key]; exists { + for i := 2; ; i++ { + candidate := fmt.Sprintf("%s-%d", key, i) + if _, exists := user.Weapons[candidate]; !exists { + key = candidate + break + } + } + } user.Weapons[key] = WeaponState{ UserWeaponUuid: key, WeaponId: weaponId, diff --git a/server/internal/userdata/proj_user.go b/server/internal/userdata/proj_user.go index 0cd54f1..54095f1 100644 --- a/server/internal/userdata/proj_user.go +++ b/server/internal/userdata/proj_user.go @@ -42,9 +42,10 @@ func init() { }) register("IUserGem", func(user store.UserState) string { s, _ := encodeJSONRecords(&EntityIUserGem{ - UserId: user.UserId, - PaidGem: user.Gem.PaidGem, - FreeGem: user.Gem.FreeGem, + UserId: user.UserId, + PaidGem: user.Gem.PaidGem, + FreeGem: user.Gem.FreeGem, + LatestVersion: gametime.NowMillis(), }) return s }) diff --git a/server/internal/userdata/state_projection.go b/server/internal/userdata/state_projection.go index 7a29e2c..c57f643 100644 --- a/server/internal/userdata/state_projection.go +++ b/server/internal/userdata/state_projection.go @@ -115,6 +115,9 @@ func FirstEntranceClientTableMap(user store.UserState) map[string]string { "IUserParts", "IUserWeaponNote", "IUserWeaponStory", + "IUserWeaponSkill", + "IUserWeaponAbility", + "IUserWeaponAwaken", "IUserCostumeActiveSkill", "IUserDeckTypeNote", } { diff --git a/server/internal/userdata/userdata.go b/server/internal/userdata/userdata.go index c129b18..f71b179 100644 --- a/server/internal/userdata/userdata.go +++ b/server/internal/userdata/userdata.go @@ -107,12 +107,13 @@ type EntityIUserStatus struct { LatestVersion int64 // Key(5) } -// EntityIUserGem mirrors EntityIUserGem [Key(0..2)]. +// EntityIUserGem mirrors EntityIUserGem [Key(0..3)]. type EntityIUserGem struct { - _msgpack struct{} `msgpack:",asArray"` - UserId int64 `json:"userId"` // Key(0) - PaidGem int32 `json:"paidGem"` // Key(1) - FreeGem int32 `json:"freeGem"` // Key(2) + _msgpack struct{} `msgpack:",asArray"` + UserId int64 `json:"userId"` // Key(0) + PaidGem int32 `json:"paidGem"` // Key(1) + FreeGem int32 `json:"freeGem"` // Key(2) + LatestVersion int64 `json:"latestVersion"` // Key(3) } // EntityIUserProfile mirrors EntityIUserProfile [Key(0..7)].