Class WorldBackupService
- Namespace
- McServerLauncher.Services
- Assembly
- McServerLauncher.dll
Creates and restores zip backups of a server's world folder — the "level-name" directory from server.properties ("world" by default) — together with the Nether and the End when the server keeps them beside it. Backups live in "<server folder>/backups/"; old ones beyond the configured retention are pruned after each new one.
public class WorldBackupService
- Inheritance
-
WorldBackupService
- Inherited Members
Remarks
Vanilla and the modded loaders keep every dimension inside the world folder (under
DIM-1, DIM1 or dimensions/), so that folder alone is the whole world. Paper
and Purpur, like every Bukkit server, keep them in sibling folders, world_nether and
world_the_end. Those used to be left out: every backup of a Paper server lacked them,
and restoring one put an old overworld beside today's Nether and End. See
McServerLauncher.Services.WorldBackupService.DimensionSuffixes.
Methods
CreateBackupAsync(ServerConfig, string, IProgress<string>?, string?, CancellationToken)
Zips the world folder into backups/. No-op (returns null) if the world doesn't exist yet — a
server that has never been started has nothing to back up. Prunes old backups beyond
BackupRetention afterward; protectFromPruning (if
given) is never deleted by that pruning, even if it would otherwise have aged out — used by
RestoreBackupAsync(ServerConfig, string, IProgress<string>?, CancellationToken) so its own safety-net backup can never delete the very backup
being restored from.
public virtual Task<string?> CreateBackupAsync(ServerConfig config, string trigger, IProgress<string>? log = null, string? protectFromPruning = null, CancellationToken ct = default)
Parameters
configServerConfigtriggerstringlogIProgress<string>protectFromPruningstringctCancellationToken
Returns
GetLevelName(ServerConfig)
The world folder name (server.properties' level-name, "world" if unset).
public string GetLevelName(ServerConfig config)
Parameters
configServerConfig
Returns
IsUpToDate(ServerConfig)
Whether the world on disk is still the one the last backup copied — so a start or a stop can skip making another copy of it.
public virtual bool IsUpToDate(ServerConfig config)
Parameters
configServerConfig
Returns
Remarks
A server that sleeps when empty and wakes when somebody presses Join used to leave two backups per cycle — one on the way down, one on the way up — even when nobody came in. Enough of those and the retention deleted every copy somebody had actually played in.
False whenever there is any doubt: no record, a record naming a zip that is no longer there
(somebody cleared the folder), a world that is missing, or one whose files differ in any way
from what was recorded — including a level-name that now points somewhere else.
ListBackups(ServerConfig)
All backups for this server, newest first.
public IReadOnlyList<WorldBackupService.BackupInfo> ListBackups(ServerConfig config)
Parameters
configServerConfig
Returns
Remarks
Only names ending exactly in .zip: a copy still being written is a .zip.tmp
(see McServerLauncher.Services.WorldBackupService.PartialSuffix), and Windows' *.zip pattern also matches longer
extensions that merely start with it.
MarkUnchanged(ServerConfig)
Records that the world as it is now counts as the last backup, without copying it again.
public virtual void MarkUnchanged(ServerConfig config)
Parameters
configServerConfig
Remarks
For a server that ran with nobody playing and nothing typed that changes the world. Minecraft
still writes on the way out — level.dat keeps the time it was last saved — so its files
no longer match the backup, but nothing anybody would want back is in the difference. Does
nothing when there is no backup to point at, so it can never stand in for a missing one.
Nor when the server takes commands over RCON (enable-rcon=true): a /fill sent
that way changes the world with nobody joining and nothing typed here, and only the copy can
tell. Other changes nobody joins to make — a farm in the spawn chunks, which tick with nobody
near, or a plugin on a timer — are small enough to wait for the next time somebody plays.
RestoreBackupAsync(ServerConfig, string, IProgress<string>?, CancellationToken)
Restores a backup, replacing the current world folder entirely. Makes a safety backup of the
CURRENT state first (trigger "before-restore") so the restore itself can be undone. That
safety backup's own retention pruning is not allowed to delete zipPath —
otherwise a tight retention could prune the very backup being restored from before it's read.
public Task RestoreBackupAsync(ServerConfig config, string zipPath, IProgress<string>? log = null, CancellationToken ct = default)
Parameters
configServerConfigzipPathstringlogIProgress<string>ctCancellationToken