9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-19 14:59:21 +00:00

Fix locked maps not rendering after server restart (#620)

This commit is contained in:
its.bread
2025-12-04 23:28:06 +08:00
committed by GitHub
parent 404d359f89
commit 8232282d13
5 changed files with 30 additions and 37 deletions

View File

@@ -124,8 +124,8 @@ public interface BukkitMapHandler {
@Nullable @Nullable
@Blocking @Blocking
private Map.Entry<MapData, Boolean> readMapData(@NotNull String serverName, int mapId) { private MapData readMapData(@NotNull String serverName, int mapId) {
final Map.Entry<byte[], Boolean> readData = fetchMapData(serverName, mapId); final byte[] readData = fetchMapData(serverName, mapId);
if (readData == null) { if (readData == null) {
return null; return null;
} }
@@ -134,23 +134,23 @@ public interface BukkitMapHandler {
@Nullable @Nullable
@Blocking @Blocking
private Map.Entry<byte[], Boolean> fetchMapData(@NotNull String serverName, int mapId) { private byte[] fetchMapData(@NotNull String serverName, int mapId) {
return fetchMapData(serverName, mapId, true); return fetchMapData(serverName, mapId, true);
} }
@Nullable @Nullable
@Blocking @Blocking
private Map.Entry<byte[], Boolean> fetchMapData(@NotNull String serverName, int mapId, boolean doReverseLookup) { private byte[] fetchMapData(@NotNull String serverName, int mapId, boolean doReverseLookup) {
// Read from Redis cache // Read from Redis cache
final byte[] redisData = getRedisManager().getMapData(serverName, mapId); final byte[] redisData = getRedisManager().getMapData(serverName, mapId);
if (redisData != null) { if (redisData != null) {
return new AbstractMap.SimpleImmutableEntry<>(redisData, true); return redisData;
} }
// Read from database and set to Redis // Read from database and set to Redis
@Nullable Map.Entry<byte[], Boolean> databaseData = getPlugin().getDatabase().getMapData(serverName, mapId); final byte[] databaseData = getPlugin().getDatabase().getMapData(serverName, mapId);
if (databaseData != null) { if (databaseData != null) {
getRedisManager().setMapData(serverName, mapId, databaseData.getKey()); getRedisManager().setMapData(serverName, mapId, databaseData);
return databaseData; return databaseData;
} }
@@ -162,7 +162,7 @@ public interface BukkitMapHandler {
} }
@Nullable @Nullable
private Map.Entry<byte[], Boolean> fetchReversedMapData(@NotNull String serverName, int mapId) { private byte[] fetchReversedMapData(@NotNull String serverName, int mapId) {
// Lookup binding from Redis cache, then fetch data if found // Lookup binding from Redis cache, then fetch data if found
Map.Entry<String, Integer> binding = getRedisManager().getReversedMapBound(serverName, mapId); Map.Entry<String, Integer> binding = getRedisManager().getReversedMapBound(serverName, mapId);
if (binding != null) { if (binding != null) {
@@ -179,13 +179,10 @@ public interface BukkitMapHandler {
} }
@Nullable @Nullable
private Map.Entry<MapData, Boolean> deserializeMapData(@NotNull Map.Entry<byte[], Boolean> data) { private MapData deserializeMapData(byte @NotNull [] data) {
try { try {
return new AbstractMap.SimpleImmutableEntry<>( return getPlugin().getDataAdapter().fromBytes(data, AdaptableMapData.class)
getPlugin().getDataAdapter().fromBytes(data.getKey(), AdaptableMapData.class) .getData(getPlugin().getDataVersion(getPlugin().getMinecraftVersion()));
.getData(getPlugin().getDataVersion(getPlugin().getMinecraftVersion())),
data.getValue()
);
} catch (IOException e) { } catch (IOException e) {
getPlugin().log(Level.WARNING, "Failed to deserialize map data", e); getPlugin().log(Level.WARNING, "Failed to deserialize map data", e);
return null; return null;
@@ -297,7 +294,7 @@ public interface BukkitMapHandler {
} }
getPlugin().debug("Deserializing map data from NBT and generating view..."); getPlugin().debug("Deserializing map data from NBT and generating view...");
Map.Entry<MapData, Boolean> mapData = readMapData(originServer, originalId); MapData mapData = readMapData(originServer, originalId);
if (mapData == null && nbt.hasTag(MAP_LEGACY_PIXEL_DATA_KEY)) { if (mapData == null && nbt.hasTag(MAP_LEGACY_PIXEL_DATA_KEY)) {
mapData = readLegacyMapItemData(nbt); mapData = readLegacyMapItemData(nbt);
} }
@@ -308,14 +305,14 @@ public interface BukkitMapHandler {
} }
MapView newView = view != null ? view : Bukkit.createMap(getDefaultMapWorld()); MapView newView = view != null ? view : Bukkit.createMap(getDefaultMapWorld());
generateRenderedMap(Objects.requireNonNull(mapData).getKey(), newView); generateRenderedMap(mapData, newView);
meta.setMapView(newView); meta.setMapView(newView);
} }
private void handleUnboundMap(@NotNull MapMeta meta, @NotNull ReadableItemNBT nbt, @NotNull String originServer, private void handleUnboundMap(@NotNull MapMeta meta, @NotNull ReadableItemNBT nbt, @NotNull String originServer,
int originalId, @NotNull String currentServer) { int originalId, @NotNull String currentServer) {
getPlugin().debug("Deserializing map data from NBT and generating view..."); getPlugin().debug("Deserializing map data from NBT and generating view...");
Map.Entry<MapData, Boolean> mapData = readMapData(originServer, originalId); MapData mapData = readMapData(originServer, originalId);
if (mapData == null && nbt.hasTag(MAP_LEGACY_PIXEL_DATA_KEY)) { if (mapData == null && nbt.hasTag(MAP_LEGACY_PIXEL_DATA_KEY)) {
mapData = readLegacyMapItemData(nbt); mapData = readLegacyMapItemData(nbt);
} }
@@ -325,7 +322,7 @@ public interface BukkitMapHandler {
return; return;
} }
final MapView view = generateRenderedMap(Objects.requireNonNull(mapData, "Pixel data null!").getKey()); final MapView view = generateRenderedMap(Objects.requireNonNull(mapData, "Pixel data null!"));
meta.setMapView(view); meta.setMapView(view);
final int id = view.getId(); final int id = view.getId();
@@ -351,7 +348,7 @@ public interface BukkitMapHandler {
return; return;
} }
Map.Entry<MapData, Boolean> data = readMapData(getPlugin().getServerName(), view.getId()); MapData data = readMapData(getPlugin().getServerName(), view.getId());
if (data == null) { if (data == null) {
data = readLegacyMapFileData(view.getId()); data = readLegacyMapFileData(view.getId());
} }
@@ -362,10 +359,7 @@ public interface BukkitMapHandler {
.formatted(world.getName(), view.getId())); .formatted(world.getName(), view.getId()));
return; return;
} }
if (data.getValue()) { renderMapView(view, data);
return;
}
renderMapView(view, data.getKey());
} }
@NotNull @NotNull
@@ -471,11 +465,11 @@ public interface BukkitMapHandler {
// Legacy - read maps from item stacks // Legacy - read maps from item stacks
@Nullable @Nullable
@Blocking @Blocking
private Map.Entry<MapData, Boolean> readLegacyMapItemData(@NotNull ReadableItemNBT nbt) { private MapData readLegacyMapItemData(@NotNull ReadableItemNBT nbt) {
final int dataVer = getPlugin().getDataVersion(getPlugin().getMinecraftVersion()); final int dataVer = getPlugin().getDataVersion(getPlugin().getMinecraftVersion());
try { try {
return new AbstractMap.SimpleImmutableEntry<>(MapData.fromByteArray(dataVer, return MapData.fromByteArray(dataVer,
Objects.requireNonNull(nbt.getByteArray(MAP_LEGACY_PIXEL_DATA_KEY))), false); Objects.requireNonNull(nbt.getByteArray(MAP_LEGACY_PIXEL_DATA_KEY)));
} catch (IOException e) { } catch (IOException e) {
getPlugin().log(Level.WARNING, "Failed to read legacy map data", e); getPlugin().log(Level.WARNING, "Failed to read legacy map data", e);
return null; return null;
@@ -484,14 +478,14 @@ public interface BukkitMapHandler {
// Legacy - read maps from files // Legacy - read maps from files
@Nullable @Nullable
private Map.Entry<MapData, Boolean> readLegacyMapFileData(int mapId) { private MapData readLegacyMapFileData(int mapId) {
final Path path = getPlugin().getDataFolder().toPath().resolve("maps").resolve(mapId + ".dat"); final Path path = getPlugin().getDataFolder().toPath().resolve("maps").resolve(mapId + ".dat");
final File file = path.toFile(); final File file = path.toFile();
if (!file.exists()) { if (!file.exists()) {
return null; return null;
} }
try { try {
return new AbstractMap.SimpleImmutableEntry<>(MapData.fromNbt(file), false); return MapData.fromNbt(file);
} catch (IOException e) { } catch (IOException e) {
getPlugin().log(Level.WARNING, "Failed to read legacy map file", e); getPlugin().log(Level.WARNING, "Failed to read legacy map file", e);
return null; return null;

View File

@@ -274,10 +274,10 @@ public abstract class Database {
* *
* @param serverName Name of the server the map originates from * @param serverName Name of the server the map originates from
* @param mapId Original map ID * @param mapId Original map ID
* @return Map.Entry (key: map data, value: is from current world) * @return the map data bytes, or null if not found
*/ */
@Blocking @Blocking
public abstract @Nullable Map.Entry<byte[], Boolean> getMapData(@NotNull String serverName, int mapId); public abstract byte @Nullable [] getMapData(@NotNull String serverName, int mapId);
/** /**
* Get a map server -> ID binding in the database * Get a map server -> ID binding in the database

View File

@@ -376,14 +376,14 @@ public class MongoDbDatabase extends Database {
@Blocking @Blocking
@Override @Override
public @Nullable Map.Entry<byte[], Boolean> getMapData(@NotNull String serverName, int mapId) { public byte @Nullable [] getMapData(@NotNull String serverName, int mapId) {
try { try {
Document filter = new Document("server_name", serverName).append("map_id", mapId); Document filter = new Document("server_name", serverName).append("map_id", mapId);
FindIterable<Document> iterable = mongoCollectionHelper.getCollection(mapDataTable).find(filter); FindIterable<Document> iterable = mongoCollectionHelper.getCollection(mapDataTable).find(filter);
Document doc = iterable.first(); Document doc = iterable.first();
if (doc != null) { if (doc != null) {
final Binary bin = doc.get("data", Binary.class); final Binary bin = doc.get("data", Binary.class);
return Map.entry(bin.getData(), true); return bin.getData();
} }
} catch (MongoException e) { } catch (MongoException e) {
plugin.log(Level.SEVERE, "Failed to get map data from the database", e); plugin.log(Level.SEVERE, "Failed to get map data from the database", e);

View File

@@ -473,7 +473,7 @@ public class MySqlDatabase extends Database {
@Blocking @Blocking
@Override @Override
public @Nullable Map.Entry<byte[], Boolean> getMapData(@NotNull String serverName, int mapId) { public byte @Nullable [] getMapData(@NotNull String serverName, int mapId) {
try (Connection connection = getConnection()) { try (Connection connection = getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables(""" try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
SELECT `data` SELECT `data`
@@ -488,7 +488,7 @@ public class MySqlDatabase extends Database {
final Blob blob = resultSet.getBlob("data"); final Blob blob = resultSet.getBlob("data");
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length()); final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
blob.free(); blob.free();
return Map.entry(dataByteArray, true); return dataByteArray;
} }
} }
} catch (SQLException | DataAdapter.AdaptionException e) { } catch (SQLException | DataAdapter.AdaptionException e) {

View File

@@ -469,7 +469,7 @@ public class PostgresDatabase extends Database {
@Blocking @Blocking
@Override @Override
public @Nullable Map.Entry<byte[], Boolean> getMapData(@NotNull String serverName, int mapId) { public byte @Nullable [] getMapData(@NotNull String serverName, int mapId) {
try (Connection connection = getConnection()) { try (Connection connection = getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables(""" try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
SELECT data SELECT data
@@ -480,8 +480,7 @@ public class PostgresDatabase extends Database {
statement.setInt(2, mapId); statement.setInt(2, mapId);
final ResultSet resultSet = statement.executeQuery(); final ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) { if (resultSet.next()) {
final byte[] data = resultSet.getBytes("data"); return resultSet.getBytes("data");
return new AbstractMap.SimpleImmutableEntry<>(data, true);
} }
return null; return null;
} }