mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-21 23:22:34 +01:00
feat(savedata): add tier 2 integrity protections
Strengthen savedata persistence against corruption and race conditions: - SHA-256 checksum: hash the decompressed blob on every save, store in new savedata_hash column, verify on load to detect silent corruption. Pre-existing characters with no hash are silently upgraded on next save. - Atomic transactions: wrap character data + house data + hash + backup into a single DB transaction via SaveCharacterDataAtomic, so a crash mid-save never leaves partial state. - Per-character save mutex: CharacterLocks (sync.Map of charID → Mutex) serializes concurrent saves for the same character, preventing races that could defeat corruption detection. Different characters remain fully independent. Migration 0008 adds the savedata_hash column to the characters table.
This commit is contained in:
@@ -41,6 +41,13 @@ type CharacterRepo interface {
|
||||
LoadSaveData(charID uint32) (uint32, []byte, bool, string, error)
|
||||
SaveBackup(charID uint32, slot int, data []byte) error
|
||||
GetLastBackupTime(charID uint32) (time.Time, error)
|
||||
// SaveCharacterDataAtomic performs all save-related writes in a single
|
||||
// database transaction: character data, house data, checksum, and
|
||||
// optionally a backup snapshot. If any step fails, everything is rolled back.
|
||||
SaveCharacterDataAtomic(params SaveAtomicParams) error
|
||||
// LoadSaveDataWithHash loads savedata along with its stored SHA-256 hash.
|
||||
// The hash may be nil for characters saved before checksums were introduced.
|
||||
LoadSaveDataWithHash(charID uint32) (id uint32, savedata []byte, isNew bool, name string, hash []byte, err error)
|
||||
}
|
||||
|
||||
// GuildRepo defines the contract for guild data access.
|
||||
|
||||
Reference in New Issue
Block a user