mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Implement remaining Memoirs preset management RPCs
This commit is contained in:
@@ -270,3 +270,102 @@ func (s *PartsServiceServer) ReplacePreset(ctx context.Context, req *pb.PartsRep
|
|||||||
|
|
||||||
return &pb.PartsReplacePresetResponse{}, nil
|
return &pb.PartsReplacePresetResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PartsServiceServer) UpdatePresetName(ctx context.Context, req *pb.PartsUpdatePresetNameRequest) (*pb.PartsUpdatePresetNameResponse, error) {
|
||||||
|
log.Printf("[PartsService] UpdatePresetName: preset=%d name=%q", req.UserPartsPresetNumber, req.Name)
|
||||||
|
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
_, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
preset := user.PartsPresets[req.UserPartsPresetNumber]
|
||||||
|
preset.UserPartsPresetNumber = req.UserPartsPresetNumber
|
||||||
|
preset.Name = req.Name
|
||||||
|
preset.LatestVersion = nowMillis
|
||||||
|
user.PartsPresets[req.UserPartsPresetNumber] = preset
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parts update preset name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PartsUpdatePresetNameResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PartsServiceServer) UpdatePresetTagNumber(ctx context.Context, req *pb.PartsUpdatePresetTagNumberRequest) (*pb.PartsUpdatePresetTagNumberResponse, error) {
|
||||||
|
log.Printf("[PartsService] UpdatePresetTagNumber: preset=%d tag=%d", req.UserPartsPresetNumber, req.UserPartsPresetTagNumber)
|
||||||
|
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
_, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
preset := user.PartsPresets[req.UserPartsPresetNumber]
|
||||||
|
preset.UserPartsPresetNumber = req.UserPartsPresetNumber
|
||||||
|
preset.UserPartsPresetTagNumber = req.UserPartsPresetTagNumber
|
||||||
|
preset.LatestVersion = nowMillis
|
||||||
|
user.PartsPresets[req.UserPartsPresetNumber] = preset
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parts update preset tag number: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PartsUpdatePresetTagNumberResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PartsServiceServer) UpdatePresetTagName(ctx context.Context, req *pb.PartsUpdatePresetTagNameRequest) (*pb.PartsUpdatePresetTagNameResponse, error) {
|
||||||
|
log.Printf("[PartsService] UpdatePresetTagName: tag=%d name=%q", req.UserPartsPresetTagNumber, req.Name)
|
||||||
|
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
_, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
tag := user.PartsPresetTags[req.UserPartsPresetTagNumber]
|
||||||
|
tag.UserPartsPresetTagNumber = req.UserPartsPresetTagNumber
|
||||||
|
tag.Name = req.Name
|
||||||
|
tag.LatestVersion = nowMillis
|
||||||
|
user.PartsPresetTags[req.UserPartsPresetTagNumber] = tag
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parts update preset tag name: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PartsUpdatePresetTagNameResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PartsServiceServer) CopyPreset(ctx context.Context, req *pb.PartsCopyPresetRequest) (*pb.PartsCopyPresetResponse, error) {
|
||||||
|
log.Printf("[PartsService] CopyPreset: from=%d to=%d", req.FromUserPartsPresetNumber, req.ToUserPartsPresetNumber)
|
||||||
|
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
nowMillis := gametime.NowMillis()
|
||||||
|
|
||||||
|
_, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
from, ok := user.PartsPresets[req.FromUserPartsPresetNumber]
|
||||||
|
if !ok {
|
||||||
|
log.Printf("[PartsService] CopyPreset: source preset=%d not found, skipping", req.FromUserPartsPresetNumber)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
to := from
|
||||||
|
to.UserPartsPresetNumber = req.ToUserPartsPresetNumber
|
||||||
|
to.LatestVersion = nowMillis
|
||||||
|
user.PartsPresets[req.ToUserPartsPresetNumber] = to
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parts copy preset: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PartsCopyPresetResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *PartsServiceServer) RemovePreset(ctx context.Context, req *pb.PartsRemovePresetRequest) (*pb.PartsRemovePresetResponse, error) {
|
||||||
|
log.Printf("[PartsService] RemovePreset: preset=%d", req.UserPartsPresetNumber)
|
||||||
|
|
||||||
|
userId := CurrentUserId(ctx, s.users, s.sessions)
|
||||||
|
|
||||||
|
_, err := s.users.UpdateUser(userId, func(user *store.UserState) {
|
||||||
|
delete(user.PartsPresets, req.UserPartsPresetNumber)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parts remove preset: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PartsRemovePresetResponse{}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ func CloneUserState(u UserState) UserState {
|
|||||||
out.Parts = maps.Clone(u.Parts)
|
out.Parts = maps.Clone(u.Parts)
|
||||||
out.PartsGroupNotes = maps.Clone(u.PartsGroupNotes)
|
out.PartsGroupNotes = maps.Clone(u.PartsGroupNotes)
|
||||||
out.PartsPresets = maps.Clone(u.PartsPresets)
|
out.PartsPresets = maps.Clone(u.PartsPresets)
|
||||||
|
out.PartsPresetTags = maps.Clone(u.PartsPresetTags)
|
||||||
out.PartsStatusSubs = maps.Clone(u.PartsStatusSubs)
|
out.PartsStatusSubs = maps.Clone(u.PartsStatusSubs)
|
||||||
out.ImportantItems = maps.Clone(u.ImportantItems)
|
out.ImportantItems = maps.Clone(u.ImportantItems)
|
||||||
out.CostumeActiveSkills = maps.Clone(u.CostumeActiveSkills)
|
out.CostumeActiveSkills = maps.Clone(u.CostumeActiveSkills)
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ func SeedUserState(userId int64, uuid string, nowMillis int64, platform model.Cl
|
|||||||
Parts: make(map[string]PartsState),
|
Parts: make(map[string]PartsState),
|
||||||
PartsGroupNotes: make(map[int32]PartsGroupNoteState),
|
PartsGroupNotes: make(map[int32]PartsGroupNoteState),
|
||||||
PartsPresets: make(map[int32]PartsPresetState),
|
PartsPresets: make(map[int32]PartsPresetState),
|
||||||
|
PartsPresetTags: make(map[int32]PartsPresetTagState),
|
||||||
PartsStatusSubs: make(map[PartsStatusSubKey]PartsStatusSubState),
|
PartsStatusSubs: make(map[PartsStatusSubKey]PartsStatusSubState),
|
||||||
ImportantItems: make(map[int32]int32),
|
ImportantItems: make(map[int32]int32),
|
||||||
CostumeActiveSkills: make(map[string]CostumeActiveSkillState),
|
CostumeActiveSkills: make(map[string]CostumeActiveSkillState),
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ func initMaps(u *store.UserState) {
|
|||||||
u.Parts = make(map[string]store.PartsState)
|
u.Parts = make(map[string]store.PartsState)
|
||||||
u.PartsGroupNotes = make(map[int32]store.PartsGroupNoteState)
|
u.PartsGroupNotes = make(map[int32]store.PartsGroupNoteState)
|
||||||
u.PartsPresets = make(map[int32]store.PartsPresetState)
|
u.PartsPresets = make(map[int32]store.PartsPresetState)
|
||||||
|
u.PartsPresetTags = make(map[int32]store.PartsPresetTagState)
|
||||||
u.PartsStatusSubs = make(map[store.PartsStatusSubKey]store.PartsStatusSubState)
|
u.PartsStatusSubs = make(map[store.PartsStatusSubKey]store.PartsStatusSubState)
|
||||||
u.DeckTypeNotes = make(map[model.DeckType]store.DeckTypeNoteState)
|
u.DeckTypeNotes = make(map[model.DeckType]store.DeckTypeNoteState)
|
||||||
u.ConsumableItems = make(map[int32]int32)
|
u.ConsumableItems = make(map[int32]int32)
|
||||||
@@ -492,6 +493,14 @@ func loadMapTables(db *sql.DB, uid int64, u *store.UserState) {
|
|||||||
u.PartsPresets[v.UserPartsPresetNumber] = v
|
u.PartsPresets[v.UserPartsPresetNumber] = v
|
||||||
})
|
})
|
||||||
|
|
||||||
|
queryRows(db, `SELECT user_parts_preset_tag_number, name, latest_version
|
||||||
|
FROM user_parts_preset_tags WHERE user_id=?`, uid,
|
||||||
|
func(rows *sql.Rows) {
|
||||||
|
var v store.PartsPresetTagState
|
||||||
|
rows.Scan(&v.UserPartsPresetTagNumber, &v.Name, &v.LatestVersion)
|
||||||
|
u.PartsPresetTags[v.UserPartsPresetTagNumber] = v
|
||||||
|
})
|
||||||
|
|
||||||
queryRows(db, `SELECT user_parts_uuid, status_index, parts_status_sub_lottery_id, level,
|
queryRows(db, `SELECT user_parts_uuid, status_index, parts_status_sub_lottery_id, level,
|
||||||
status_kind_type, status_calculation_type, status_change_value, latest_version
|
status_kind_type, status_calculation_type, status_change_value, latest_version
|
||||||
FROM user_parts_status_subs WHERE user_id=?`, uid,
|
FROM user_parts_status_subs WHERE user_id=?`, uid,
|
||||||
|
|||||||
@@ -312,6 +312,12 @@ func writeUserState(tx *sql.Tx, uid int64, u *store.UserState) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, v := range u.PartsPresetTags {
|
||||||
|
if err := exec(`INSERT INTO user_parts_preset_tags (user_id, user_parts_preset_tag_number, name, latest_version) VALUES (?,?,?,?)`,
|
||||||
|
uid, v.UserPartsPresetTagNumber, v.Name, v.LatestVersion); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, v := range u.PartsStatusSubs {
|
for _, v := range u.PartsStatusSubs {
|
||||||
if err := exec(`INSERT INTO user_parts_status_subs (user_id, user_parts_uuid, status_index, parts_status_sub_lottery_id, level, status_kind_type, status_calculation_type, status_change_value, latest_version) VALUES (?,?,?,?,?,?,?,?,?)`,
|
if err := exec(`INSERT INTO user_parts_status_subs (user_id, user_parts_uuid, status_index, parts_status_sub_lottery_id, level, status_kind_type, status_calculation_type, status_change_value, latest_version) VALUES (?,?,?,?,?,?,?,?,?)`,
|
||||||
uid, v.UserPartsUuid, v.StatusIndex, v.PartsStatusSubLotteryId, v.Level, v.StatusKindType, v.StatusCalculationType, v.StatusChangeValue, v.LatestVersion); err != nil {
|
uid, v.UserPartsUuid, v.StatusIndex, v.PartsStatusSubLotteryId, v.Level, v.StatusKindType, v.StatusCalculationType, v.StatusChangeValue, v.LatestVersion); err != nil {
|
||||||
@@ -862,6 +868,10 @@ func diffAndSave(tx *sql.Tx, uid int64, before, after *store.UserState) error {
|
|||||||
func(v store.PartsPresetState) []any {
|
func(v store.PartsPresetState) []any {
|
||||||
return []any{v.UserPartsPresetNumber, v.UserPartsUuid01, v.UserPartsUuid02, v.UserPartsUuid03, v.Name, v.UserPartsPresetTagNumber, v.LatestVersion}
|
return []any{v.UserPartsPresetNumber, v.UserPartsUuid01, v.UserPartsUuid02, v.UserPartsUuid03, v.Name, v.UserPartsPresetTagNumber, v.LatestVersion}
|
||||||
}, "user_parts_preset_number, user_parts_uuid01, user_parts_uuid02, user_parts_uuid03, name, user_parts_preset_tag_number, latest_version")
|
}, "user_parts_preset_number, user_parts_uuid01, user_parts_uuid02, user_parts_uuid03, name, user_parts_preset_tag_number, latest_version")
|
||||||
|
diffMapInt32(tx, uid, before.PartsPresetTags, after.PartsPresetTags, "user_parts_preset_tags", "user_parts_preset_tag_number",
|
||||||
|
func(v store.PartsPresetTagState) []any {
|
||||||
|
return []any{v.UserPartsPresetTagNumber, v.Name, v.LatestVersion}
|
||||||
|
}, "user_parts_preset_tag_number, name, latest_version")
|
||||||
|
|
||||||
for k, v := range after.PartsStatusSubs {
|
for k, v := range after.PartsStatusSubs {
|
||||||
if old, ok := before.PartsStatusSubs[k]; !ok || old != v {
|
if old, ok := before.PartsStatusSubs[k]; !ok || old != v {
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ func (s *SQLiteStore) ImportUser(u *store.UserState) error {
|
|||||||
"user_decks",
|
"user_decks",
|
||||||
"user_deck_characters",
|
"user_deck_characters",
|
||||||
"user_parts_status_subs",
|
"user_parts_status_subs",
|
||||||
|
"user_parts_preset_tags",
|
||||||
"user_parts_presets",
|
"user_parts_presets",
|
||||||
"user_parts_group_notes",
|
"user_parts_group_notes",
|
||||||
"user_parts",
|
"user_parts",
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ type UserState struct {
|
|||||||
Parts map[string]PartsState
|
Parts map[string]PartsState
|
||||||
PartsGroupNotes map[int32]PartsGroupNoteState
|
PartsGroupNotes map[int32]PartsGroupNoteState
|
||||||
PartsPresets map[int32]PartsPresetState
|
PartsPresets map[int32]PartsPresetState
|
||||||
|
PartsPresetTags map[int32]PartsPresetTagState
|
||||||
PartsStatusSubs map[PartsStatusSubKey]PartsStatusSubState
|
PartsStatusSubs map[PartsStatusSubKey]PartsStatusSubState
|
||||||
ImportantItems map[int32]int32
|
ImportantItems map[int32]int32
|
||||||
CostumeActiveSkills map[string]CostumeActiveSkillState
|
CostumeActiveSkills map[string]CostumeActiveSkillState
|
||||||
@@ -206,6 +207,9 @@ func (u *UserState) EnsureMaps() {
|
|||||||
if u.PartsPresets == nil {
|
if u.PartsPresets == nil {
|
||||||
u.PartsPresets = make(map[int32]PartsPresetState)
|
u.PartsPresets = make(map[int32]PartsPresetState)
|
||||||
}
|
}
|
||||||
|
if u.PartsPresetTags == nil {
|
||||||
|
u.PartsPresetTags = make(map[int32]PartsPresetTagState)
|
||||||
|
}
|
||||||
if u.PartsStatusSubs == nil {
|
if u.PartsStatusSubs == nil {
|
||||||
u.PartsStatusSubs = make(map[PartsStatusSubKey]PartsStatusSubState)
|
u.PartsStatusSubs = make(map[PartsStatusSubKey]PartsStatusSubState)
|
||||||
}
|
}
|
||||||
@@ -890,6 +894,12 @@ type PartsPresetState struct {
|
|||||||
LatestVersion int64
|
LatestVersion int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PartsPresetTagState struct {
|
||||||
|
UserPartsPresetTagNumber int32
|
||||||
|
Name string
|
||||||
|
LatestVersion int64
|
||||||
|
}
|
||||||
|
|
||||||
type PartsStatusSubKey struct {
|
type PartsStatusSubKey struct {
|
||||||
UserPartsUuid string
|
UserPartsUuid string
|
||||||
StatusIndex int32
|
StatusIndex int32
|
||||||
|
|||||||
@@ -163,6 +163,9 @@ func ChangedTables(before, after *store.UserState) []string {
|
|||||||
if !mapsEqualStruct(before.PartsPresets, after.PartsPresets) {
|
if !mapsEqualStruct(before.PartsPresets, after.PartsPresets) {
|
||||||
add("IUserPartsPreset")
|
add("IUserPartsPreset")
|
||||||
}
|
}
|
||||||
|
if !mapsEqualStruct(before.PartsPresetTags, after.PartsPresetTags) {
|
||||||
|
add("IUserPartsPresetTag")
|
||||||
|
}
|
||||||
if !mapsEqualStruct(before.PartsStatusSubs, after.PartsStatusSubs) {
|
if !mapsEqualStruct(before.PartsStatusSubs, after.PartsStatusSubs) {
|
||||||
add("IUserPartsStatusSub")
|
add("IUserPartsStatusSub")
|
||||||
}
|
}
|
||||||
@@ -419,6 +422,8 @@ func keyFieldsForTable(table string) []string {
|
|||||||
return []string{"userId", "partsGroupId"}
|
return []string{"userId", "partsGroupId"}
|
||||||
case "IUserPartsPreset":
|
case "IUserPartsPreset":
|
||||||
return []string{"userId", "userPartsPresetNumber"}
|
return []string{"userId", "userPartsPresetNumber"}
|
||||||
|
case "IUserPartsPresetTag":
|
||||||
|
return []string{"userId", "userPartsPresetTagNumber"}
|
||||||
case "IUserCageOrnamentReward":
|
case "IUserCageOrnamentReward":
|
||||||
return []string{"userId", "cageOrnamentId"}
|
return []string{"userId", "cageOrnamentId"}
|
||||||
case "IUserAutoSaleSettingDetail":
|
case "IUserAutoSaleSettingDetail":
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ func init() {
|
|||||||
s, _ := utils.EncodeJSONMaps(sortedPartsPresetRecords(user)...)
|
s, _ := utils.EncodeJSONMaps(sortedPartsPresetRecords(user)...)
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
|
register("IUserPartsPresetTag", func(user store.UserState) string {
|
||||||
|
s, _ := utils.EncodeJSONMaps(sortedPartsPresetTagRecords(user)...)
|
||||||
|
return s
|
||||||
|
})
|
||||||
register("IUserCostumeAwakenStatusUp", func(user store.UserState) string {
|
register("IUserCostumeAwakenStatusUp", func(user store.UserState) string {
|
||||||
s, _ := utils.EncodeJSONMaps(sortedCostumeAwakenStatusUpRecords(user)...)
|
s, _ := utils.EncodeJSONMaps(sortedCostumeAwakenStatusUpRecords(user)...)
|
||||||
return s
|
return s
|
||||||
@@ -122,7 +126,6 @@ func init() {
|
|||||||
"IUserCostumeLevelBonusReleaseStatus",
|
"IUserCostumeLevelBonusReleaseStatus",
|
||||||
"IUserCostumeLotteryEffectAbility",
|
"IUserCostumeLotteryEffectAbility",
|
||||||
"IUserCostumeLotteryEffectStatusUp",
|
"IUserCostumeLotteryEffectStatusUp",
|
||||||
"IUserPartsPresetTag",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,6 +499,25 @@ func sortedPartsPresetRecords(user store.UserState) []map[string]any {
|
|||||||
return records
|
return records
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sortedPartsPresetTagRecords(user store.UserState) []map[string]any {
|
||||||
|
ids := make([]int, 0, len(user.PartsPresetTags))
|
||||||
|
for id := range user.PartsPresetTags {
|
||||||
|
ids = append(ids, int(id))
|
||||||
|
}
|
||||||
|
sort.Ints(ids)
|
||||||
|
records := make([]map[string]any, 0, len(ids))
|
||||||
|
for _, id := range ids {
|
||||||
|
row := user.PartsPresetTags[int32(id)]
|
||||||
|
records = append(records, map[string]any{
|
||||||
|
"userId": user.UserId,
|
||||||
|
"userPartsPresetTagNumber": row.UserPartsPresetTagNumber,
|
||||||
|
"name": row.Name,
|
||||||
|
"latestVersion": row.LatestVersion,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
|
||||||
func sortedPartsStatusSubRecords(user store.UserState) []map[string]any {
|
func sortedPartsStatusSubRecords(user store.UserState) []map[string]any {
|
||||||
keys := make([]store.PartsStatusSubKey, 0, len(user.PartsStatusSubs))
|
keys := make([]store.PartsStatusSubKey, 0, len(user.PartsStatusSubs))
|
||||||
for k := range user.PartsStatusSubs {
|
for k := range user.PartsStatusSubs {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- +goose Up
|
||||||
|
CREATE TABLE user_parts_preset_tags (
|
||||||
|
user_id INTEGER NOT NULL REFERENCES users(user_id),
|
||||||
|
user_parts_preset_tag_number INTEGER NOT NULL,
|
||||||
|
name TEXT NOT NULL DEFAULT '',
|
||||||
|
latest_version INTEGER NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (user_id, user_parts_preset_tag_number)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
DROP TABLE IF EXISTS user_parts_preset_tags;
|
||||||
Reference in New Issue
Block a user