Migrate accessories to user data

- Add user_accessory as the per-user accessory inventory table.
- Migrate old accessory wear records to user-owned accessory ids, including legacy common_accessory_m lookups for old installs.
- Allocate default accessories for newly created users and update accessory reads to use user_accessory at runtime.
- Validate accessory ownership when wearing accessories and keep existing accessory-based responses working.

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-13 07:36:21 +08:00
parent 17336de1b7
commit cb0200ff29
11 changed files with 436 additions and 72 deletions
+34 -6
View File
@@ -47,6 +47,7 @@ type memberTagMatchKey struct {
type accessoryBonusRow struct {
AccessoryOwningUserID int `xorm:"accessory_owning_user_id"`
AccessoryID int `xorm:"accessory_id"`
Smile float64 `xorm:"smile_max"`
Pure float64 `xorm:"pure_max"`
Cool float64 `xorm:"cool_max"`
@@ -219,24 +220,51 @@ func loadAccessoryBonusMap(ss *session.Session, userID int, unitOwningUserIDs []
}
rows := []accessoryBonusRow{}
err = ss.MainEng.Table("common_accessory_m").
Join("LEFT", "accessory_m", "common_accessory_m.accessory_id = accessory_m.accessory_id").
In("common_accessory_m.accessory_owning_user_id", accessoryIDs).
Cols("common_accessory_m.accessory_owning_user_id,smile_max,pure_max,cool_max").
err = ss.UserEng.Table("user_accessory").
In("accessory_owning_user_id", accessoryIDs).
Cols("accessory_owning_user_id,accessory_id").
Find(&rows)
if err != nil {
return nil, err
}
accessoryMap := make(map[int]accessoryBonus, len(rows))
accessoryIDSet := make(map[int]struct{}, len(rows))
for _, row := range rows {
accessoryMap[row.AccessoryOwningUserID] = accessoryBonus{
accessoryIDSet[row.AccessoryID] = struct{}{}
}
accessoryIDList := make([]int, 0, len(accessoryIDSet))
for accessoryID := range accessoryIDSet {
accessoryIDList = append(accessoryIDList, accessoryID)
}
staticRows := []accessoryBonusRow{}
err = ss.MainEng.Table("accessory_m").
In("accessory_id", accessoryIDList).
Cols("accessory_id,smile_max,pure_max,cool_max").
Find(&staticRows)
if err != nil {
return nil, err
}
staticBonusMap := make(map[int]accessoryBonus, len(staticRows))
for _, row := range staticRows {
staticBonusMap[row.AccessoryID] = accessoryBonus{
Smile: row.Smile,
Pure: row.Pure,
Cool: row.Cool,
}
}
accessoryMap := make(map[int]accessoryBonus, len(rows))
for _, row := range rows {
bonus, ok := staticBonusMap[row.AccessoryID]
if !ok {
continue
}
accessoryMap[row.AccessoryOwningUserID] = bonus
}
result := make(map[int]accessoryBonus, len(unitToAccessoryID))
for unitOwningUserID, accessoryOwningUserID := range unitToAccessoryID {
if bonus, ok := accessoryMap[accessoryOwningUserID]; ok {