Implement persistent hardcore death bans (XUID + IP) for dedicated server

On the dedicated server, hardcore death now persists XUID and IP bans to
banned-players.json and banned-ips.json via the Access system, and
disconnects the player. Bans survive server restarts. Client-hosted games
retain the existing in-memory XUID ban with force-save behavior.

- Add hardcore property to server.properties (forces Hard difficulty)
- Add LevelData::setHardcore() so loaded worlds respect the server config
- Add PlayerList::banPlayerForHardcoreDeath() with persistent XUID + IP bans
- Reject respawn requests server-side in hardcore mode
- Ensure server-side player ticks run without move packets (fixes
  environmental damage not applying for some clients)
- Restore 0x8 hardcore bit on LoginPacket/RespawnPacket wire format so
  the client-side death screen detects hardcore mode correctly
This commit is contained in:
Revela
2026-03-16 02:52:16 -05:00
parent c92a5ab31a
commit 8a6934c83c
14 changed files with 115 additions and 22 deletions

View File

@@ -54,6 +54,7 @@ static const ServerPropertyDefault kServerPropertyDefaults[] =
{ "gamemode", "0" },
{ "gamertags", "true" },
{ "generate-structures", "true" },
{ "hardcore", "false" },
{ "host-can-be-invisible", "true" },
{ "host-can-change-hunger", "true" },
{ "host-can-fly", "true" },
@@ -861,6 +862,7 @@ ServerPropertiesConfig LoadServerPropertiesConfig()
config.doTileDrops = ReadNormalizedBoolProperty(&merged, "do-tile-drops", true, &shouldWrite);
config.naturalRegeneration = ReadNormalizedBoolProperty(&merged, "natural-regeneration", true, &shouldWrite);
config.doDaylightCycle = ReadNormalizedBoolProperty(&merged, "do-daylight-cycle", true, &shouldWrite);
config.hardcore = ReadNormalizedBoolProperty(&merged, "hardcore", false, &shouldWrite);
config.maxBuildHeight = ReadNormalizedIntProperty(&merged, "max-build-height", 256, 64, 256, &shouldWrite);
config.motd = ReadNormalizedStringProperty(&merged, "motd", "A Minecraft Server", 255, &shouldWrite);