Implement unique key generation for weapon grants to prevent overwrites

This commit is contained in:
Ilya Groshev
2026-04-16 16:07:56 +03:00
parent cbc052c3ed
commit ef8a241a0a
5 changed files with 27 additions and 13 deletions
+5 -5
View File
@@ -291,11 +291,11 @@ func (s *GachaServiceServer) Draw(ctx context.Context, req *pb.DrawRequest) (*pb
bs := updatedUser.Gacha.BannerStates[entry.GachaId] bs := updatedUser.Gacha.BannerStates[entry.GachaId]
nextGacha := toProtoGacha(*entry, &bs) nextGacha := toProtoGacha(*entry, &bs)
diff := userdata.BuildDiffFromTables(userdata.SelectTables( changedStoryIds := s.handler.Granter.DrainChangedStoryWeaponIds()
userdata.FullClientTableMap(updatedUser), diffOrder := append(gachaDiffTables, "IUserWeaponStory")
gachaDiffTables, allTables := userdata.FullClientTableMap(updatedUser)
)) diff := userdata.BuildDiffFromTablesOrdered(userdata.SelectTables(allTables, diffOrder), diffOrder)
userdata.AddWeaponStoryDiff(diff, updatedUser, s.handler.Granter.DrainChangedStoryWeaponIds()) userdata.AddWeaponStoryDiff(diff, updatedUser, changedStoryIds)
return &pb.DrawResponse{ return &pb.DrawResponse{
NextGacha: nextGacha, NextGacha: nextGacha,
+9
View File
@@ -156,6 +156,15 @@ func (g *PossessionGranter) GrantCostume(user *UserState, costumeId int32, nowMi
func (g *PossessionGranter) GrantWeapon(user *UserState, weaponId int32, nowMillis int64) { func (g *PossessionGranter) GrantWeapon(user *UserState, weaponId int32, nowMillis int64) {
key := fmt.Sprintf("reward-weapon-%d-%d", weaponId, nowMillis) 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{ user.Weapons[key] = WeaponState{
UserWeaponUuid: key, UserWeaponUuid: key,
WeaponId: weaponId, WeaponId: weaponId,
+1
View File
@@ -45,6 +45,7 @@ func init() {
UserId: user.UserId, UserId: user.UserId,
PaidGem: user.Gem.PaidGem, PaidGem: user.Gem.PaidGem,
FreeGem: user.Gem.FreeGem, FreeGem: user.Gem.FreeGem,
LatestVersion: gametime.NowMillis(),
}) })
return s return s
}) })
@@ -115,6 +115,9 @@ func FirstEntranceClientTableMap(user store.UserState) map[string]string {
"IUserParts", "IUserParts",
"IUserWeaponNote", "IUserWeaponNote",
"IUserWeaponStory", "IUserWeaponStory",
"IUserWeaponSkill",
"IUserWeaponAbility",
"IUserWeaponAwaken",
"IUserCostumeActiveSkill", "IUserCostumeActiveSkill",
"IUserDeckTypeNote", "IUserDeckTypeNote",
} { } {
+2 -1
View File
@@ -107,12 +107,13 @@ type EntityIUserStatus struct {
LatestVersion int64 // Key(5) LatestVersion int64 // Key(5)
} }
// EntityIUserGem mirrors EntityIUserGem [Key(0..2)]. // EntityIUserGem mirrors EntityIUserGem [Key(0..3)].
type EntityIUserGem struct { type EntityIUserGem struct {
_msgpack struct{} `msgpack:",asArray"` _msgpack struct{} `msgpack:",asArray"`
UserId int64 `json:"userId"` // Key(0) UserId int64 `json:"userId"` // Key(0)
PaidGem int32 `json:"paidGem"` // Key(1) PaidGem int32 `json:"paidGem"` // Key(1)
FreeGem int32 `json:"freeGem"` // Key(2) FreeGem int32 `json:"freeGem"` // Key(2)
LatestVersion int64 `json:"latestVersion"` // Key(3)
} }
// EntityIUserProfile mirrors EntityIUserProfile [Key(0..7)]. // EntityIUserProfile mirrors EntityIUserProfile [Key(0..7)].