mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
feat: refuse stale character saves with a save generation
Every character gets a save generation in charxml. A world bumps it when it loads the character for play, and every save from that world only goes through while the stored generation is still the one it loaded or last saved (and moves it on). Dashboard edits, restores and maintenance writes bump it too. A world that lost the character to another world (a disconnect noticed late, a zone transfer, an instance migration) or to a dashboard edit can no longer overwrite the newer data: the save is refused, logged and audited as stale_save_refused, the world stops saving that character and a player still connected to it is disconnected with the save failure reason so they reload. Fixes #639 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -659,6 +659,15 @@ Everything that changes a character (the editor, restoring an old version, uploa
|
||||
player if they're online, saves a snapshot of the character as it was, then writes the change and notes it in the
|
||||
audit log. Nothing is ever changed under a player who is still in game.
|
||||
|
||||
Every character also has a save generation (`charxml.save_generation`), so an older copy of it can never be saved over
|
||||
a newer one. It goes up when a world loads the character for play, on every save from that world and on every change
|
||||
made here. A world only saves over the generation it loaded or last saved itself; anything else means someone newer
|
||||
(another world, or the dashboard) saved the character since, so the save is refused and the newer data kept. That
|
||||
covers a world that noticed a disconnect late after the player moved on, and a world still holding a character that
|
||||
was edited here. A refused save is logged by the world and written to the audit log as `stale_save_refused` (so it
|
||||
shows under the account's related data); that world saves nothing more for the character, and a player still
|
||||
connected to it is disconnected (the client's save failure message) so they load the newer data.
|
||||
|
||||
- **Edit** (GM 8+, `characters_edit`): coins, U-score, level, and adding or removing items.
|
||||
- **History** (GM 3+, `characters_history`): earlier versions of the character. Each one shows what differs from
|
||||
now, can be downloaded as XML, and (with `characters_edit`) restored. The `character_snapshots` task saves every
|
||||
|
||||
Reference in New Issue
Block a user