Notice: player.dat represents to player data file(<PlayerUUID>.dat) here, you'll find them in world\playerdata
Steps to Reproduce:
1. Run your test server.
2. Enter the server, /give yourself a bedrock or whatever, then quit the server.
3. Delete your player.dat in world\playerdata, it may appear as 3752d12c-3924-4d32-8407-6c19a4bd409f.dat
4. Enter the server again, and you'll find your stuff is gone even if your player.dat_old still stores your inventory. If you quit the server, your player.dat_old will be overwritten and you will never find your stuff back.
Expected Results:
In Step 4, your stuff shouldn't be gone since player.dat_old has stored it.
(Rename it into player.dat when it is not overwritten and return to the server, you'll see your stuff)
The behavior of player.dat_old should be the same as level.dat_old.
If you delete the level.dat of a world, reenter it and you'll see the data is still there since the game will read the data of the level.dat_old if level_dat doesn't exist.
Notes:
You can't reproduce this in single-player mode since your data is stored in another place.
This bug may cause player data lost if player.dat is corrupted somehow but player.dat_old isn't corrupted.
Code analysis:
This is from net.minecraft.world.WorldSaveHandler method, yarn mapping.
You'll see the game won't do anything if player.dat doesn't exist.
public NbtCompound loadPlayerData(PlayerEntity player) {
NbtCompound nbtCompound = null;
try {
File file = new File(this.playerDataDir, player.getUuidAsString() + ".dat");
if (file.exists() && file.isFile()) {
nbtCompound = NbtIo.readCompressed(file);
}
} catch (Exception var4) {
LOGGER.warn("Failed to load player data for {}", player.getName().getString());
}
...
}However, the game does do something in loading level.dat. If it goes wrong, the game will restore the level.dat from level.dat_old.
This is from net.minecraft.world.level.storage.LevelStorage method, yarn mapping.
public CompletableFuture<List<LevelSummary>> loadSummaries(LevelList levels) {
...
while(var3.hasNext()) {
...
try {
LevelSummary levelSummary = (LevelSummary)this.readLevelProperties(levelSave, this.createLevelDataParser(levelSave, bl));
return levelSummary != null ? levelSummary : null;
...
} catch (StackOverflowError var5) {
LOGGER.error(LogUtils.FATAL_MARKER, "Ran out of stack trying to read summary of {}. Assuming corruption; attempting to restore from from level.dat_old.", levelSave.getRootPath());
Util.backupAndReplace(levelSave.getLevelDatPath(), levelSave.getLevelDatOldPath(), levelSave.getCorruptedLevelDatPath(LocalDateTime.now()), true);
throw var5;
}
}...
}Comments 0
No comments.