docs & feat: add license & attribution notice (Apache-2.0 / GPL-3.0) and core system enhancements
This commit is contained in:
1 parent
507836d367
commit
ce6aabfc55
47 files changed
+5674
-724
No files matched your search
@@ -40,10 +40,12 @@ func (f *FreesrData) persistentSnapshot() Persistent {
|
||||
ex[id] = avatar.ExRankUnlocked
|
||||
}
|
||||
}
|
||||
wMode := f.WarpUnlockMode
|
||||
return Persistent{Profile: f.Profile, TeamPresets: f.TeamPresets, ActiveTeamPreset: f.ActiveTeamPreset, TierceProgress: f.TierceProgress, TechniqueFoodStock: f.TechniqueFoodStock, AutoTechniqueFood: f.AutoTechniqueFood, Lineups: f.Lineups, Position: f.Position, Scene: f.Scene,
|
||||
MainCharacter: f.MainCharacter, MarchType: f.MarchType,
|
||||
EnableSWGlobal: f.EnableSWGlobal, EnableCastoriceGlobal: f.EnableCastoriceGlobal,
|
||||
EnableAhaGlobal: f.EnableAhaGlobal, DressedSkins: f.DressedSkins, PlayerOutfits: f.PlayerOutfits, SceneGroupProperties: f.SceneGroupProperties, ExRanksUnlocked: ex}
|
||||
EnableAhaGlobal: f.EnableAhaGlobal, DressedSkins: f.DressedSkins, PlayerOutfits: f.PlayerOutfits, SceneGroupProperties: f.SceneGroupProperties, ExRanksUnlocked: ex,
|
||||
WarpUnlockMode: &wMode}
|
||||
}
|
||||
|
||||
// Apply only locally changed fields. A stale game session saving its position
|
||||
@@ -152,6 +154,21 @@ func (f *FreesrData) RefreshExRanks(p *Persistent) []uint32 {
|
||||
// Patch only the selected avatar's rank in the latest import. Unknown FreeSR
|
||||
// fields and all inventory IDs/affixes retain their original JSON values.
|
||||
func SaveAvatarRank(id, rank uint32) error {
|
||||
return SaveAvatarProgress(id, nil, &rank)
|
||||
}
|
||||
|
||||
// SaveAvatarProgress patches only the selected level and/or rank in the latest
|
||||
// import, under the same cross-process lock used by inventory and gacha saves.
|
||||
func SaveAvatarProgress(id uint32, level, rank *uint32) error {
|
||||
if id == 0 || (level == nil && rank == nil) {
|
||||
return fmt.Errorf("avatar ID and a change are required")
|
||||
}
|
||||
if level != nil && (*level < 1 || *level > 80) {
|
||||
return fmt.Errorf("level must be between 1 and 80")
|
||||
}
|
||||
if rank != nil && *rank > 6 {
|
||||
return fmt.Errorf("rank must be between 0 and 6")
|
||||
}
|
||||
persistentWriteMu.Lock()
|
||||
defer persistentWriteMu.Unlock()
|
||||
unlock, err := lockPersistentFile()
|
||||
@@ -173,19 +190,30 @@ func SaveAvatarRank(id, rank uint32) error {
|
||||
}
|
||||
var avatar map[string]json.RawMessage
|
||||
if err := json.Unmarshal(avatars[id], &avatar); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("avatar %d not found or invalid: %w", id, err)
|
||||
}
|
||||
var data map[string]json.RawMessage
|
||||
if err := json.Unmarshal(avatar["data"], &data); err != nil {
|
||||
return err
|
||||
if avatar == nil {
|
||||
return fmt.Errorf("avatar %d is invalid", id)
|
||||
}
|
||||
data["rank"], err = json.Marshal(rank)
|
||||
if err != nil {
|
||||
return err
|
||||
if level != nil {
|
||||
avatar["level"], err = json.Marshal(*level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
avatar["data"], err = json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
if rank != nil {
|
||||
var data map[string]json.RawMessage
|
||||
if err := json.Unmarshal(avatar["data"], &data); err != nil || data == nil {
|
||||
return fmt.Errorf("avatar %d rank data is invalid", id)
|
||||
}
|
||||
data["rank"], err = json.Marshal(*rank)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
avatar["data"], err = json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
avatars[id], err = json.Marshal(avatar)
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user