mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-23 09:47:38 +00:00
Use DFUs for some additional data fixing.
Legacy mapper now uses the data fixers to upgrade blocks and item types (e.g. signs, dyes that changed names in 1.14). The sponge schematic reader can now attempt to use the data fixers to upgrade blocks, block entities, biomes and entities. This has been tested with the 1.13 -> 1.14 changes. It is yet to be seen if it will continue to work because... The mc edit schematic reader has code for using data fixers, but it is currently disabled as there seem to be some issues with fixing up older block entities.
This commit is contained in:
parent
8ee484fca8
commit
b0777f6b06
@ -58,6 +58,10 @@ import org.bukkit.command.Command;
|
|||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -102,11 +106,6 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
|||||||
// Setup platform
|
// Setup platform
|
||||||
server = new BukkitServerInterface(this, getServer());
|
server = new BukkitServerInterface(this, getServer());
|
||||||
worldEdit.getPlatformManager().register(server);
|
worldEdit.getPlatformManager().register(server);
|
||||||
loadAdapter(); // Need an adapter to work with special blocks with NBT data
|
|
||||||
setupRegistries();
|
|
||||||
worldEdit.loadMappings();
|
|
||||||
|
|
||||||
loadConfig(); // Load configuration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,8 +113,6 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
setupTags(); // these have to be done post-world since they rely on MC registries. the other ones just use Bukkit enums
|
|
||||||
|
|
||||||
PermissionsResolverManager.initialize(this); // Setup permission resolver
|
PermissionsResolverManager.initialize(this); // Setup permission resolver
|
||||||
|
|
||||||
// Register CUI
|
// Register CUI
|
||||||
@ -125,10 +122,8 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
|||||||
// Now we can register events
|
// Now we can register events
|
||||||
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
|
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
|
||||||
|
|
||||||
// If we are on MCPC+/Cauldron, then Forge will have already loaded
|
// register this so we can load world-dependent data right as the first world is loading
|
||||||
// Forge WorldEdit and there's (probably) not going to be any other
|
getServer().getPluginManager().registerEvents(new WorldInitListener(), this);
|
||||||
// platforms to be worried about... at the current time of writing
|
|
||||||
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
|
|
||||||
|
|
||||||
// Enable metrics
|
// Enable metrics
|
||||||
new Metrics(this);
|
new Metrics(this);
|
||||||
@ -433,4 +428,20 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
|||||||
return bukkitAdapter;
|
return bukkitAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class WorldInitListener implements Listener {
|
||||||
|
private boolean loaded = false;
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
public void onWorldInit(@SuppressWarnings("unused") WorldInitEvent event) {
|
||||||
|
if (loaded) return;
|
||||||
|
loaded = true;
|
||||||
|
|
||||||
|
loadAdapter(); // Need an adapter to work with special blocks with NBT data
|
||||||
|
setupRegistries();
|
||||||
|
WorldEdit.getInstance().loadMappings();
|
||||||
|
loadConfig(); // Load configuration
|
||||||
|
setupTags();
|
||||||
|
|
||||||
|
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
name: WorldEdit
|
name: WorldEdit
|
||||||
main: com.sk89q.worldedit.bukkit.WorldEditPlugin
|
main: com.sk89q.worldedit.bukkit.WorldEditPlugin
|
||||||
version: "${internalVersion}"
|
version: "${internalVersion}"
|
||||||
|
load: STARTUP
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
|
||||||
# Permissions aren't here. Read http://wiki.sk89q.com/wiki/WEPIF/DinnerPerms
|
# Permissions aren't here. Read http://wiki.sk89q.com/wiki/WEPIF/DinnerPerms
|
||||||
|
Binary file not shown.
@ -44,6 +44,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||||
@ -67,22 +68,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public class MCEditSchematicReader extends NBTSchematicReader {
|
public class MCEditSchematicReader extends NBTSchematicReader {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
||||||
|
private final NBTInputStream inputStream;
|
||||||
|
private final DataFixer fixer;
|
||||||
private static final ImmutableList<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS
|
private static final ImmutableList<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS
|
||||||
= ImmutableList.of(
|
= ImmutableList.of(
|
||||||
new SignCompatibilityHandler(),
|
new SignCompatibilityHandler(),
|
||||||
new FlowerPotCompatibilityHandler(),
|
new FlowerPotCompatibilityHandler(),
|
||||||
new NoteBlockCompatibilityHandler(),
|
new NoteBlockCompatibilityHandler(),
|
||||||
new SkullBlockCompatibilityHandler()
|
new SkullBlockCompatibilityHandler()
|
||||||
// TODO - item tags for inventories...? DFUs :>
|
|
||||||
);
|
);
|
||||||
private static final ImmutableList<EntityNBTCompatibilityHandler> ENTITY_COMPATIBILITY_HANDLERS
|
private static final ImmutableList<EntityNBTCompatibilityHandler> ENTITY_COMPATIBILITY_HANDLERS
|
||||||
= ImmutableList.of(
|
= ImmutableList.of(
|
||||||
new Pre13HangingCompatibilityHandler()
|
new Pre13HangingCompatibilityHandler()
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
|
||||||
private final NBTInputStream inputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
*
|
*
|
||||||
@ -91,6 +91,9 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
public MCEditSchematicReader(NBTInputStream inputStream) {
|
public MCEditSchematicReader(NBTInputStream inputStream) {
|
||||||
checkNotNull(inputStream);
|
checkNotNull(inputStream);
|
||||||
this.inputStream = inputStream;
|
this.inputStream = inputStream;
|
||||||
|
this.fixer = null;
|
||||||
|
//com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability(
|
||||||
|
//com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -176,39 +179,44 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
// Need to pull out tile entities
|
// Need to pull out tile entities
|
||||||
List<Tag> tileEntities = requireTag(schematic, "TileEntities", ListTag.class).getValue();
|
List<Tag> tileEntities = requireTag(schematic, "TileEntities", ListTag.class).getValue();
|
||||||
Map<BlockVector3, Map<String, Tag>> tileEntitiesMap = new HashMap<>();
|
Map<BlockVector3, Map<String, Tag>> tileEntitiesMap = new HashMap<>();
|
||||||
Map<BlockVector3, BlockState> blockOverrides = new HashMap<>();
|
Map<BlockVector3, BlockState> blockStates = new HashMap<>();
|
||||||
|
|
||||||
for (Tag tag : tileEntities) {
|
for (Tag tag : tileEntities) {
|
||||||
if (!(tag instanceof CompoundTag)) continue;
|
if (!(tag instanceof CompoundTag)) continue;
|
||||||
CompoundTag t = (CompoundTag) tag;
|
CompoundTag t = (CompoundTag) tag;
|
||||||
|
Map<String, Tag> values = new HashMap<>(t.getValue());
|
||||||
|
String id = t.getString("id");
|
||||||
|
values.put("id", new StringTag(convertBlockEntityId(id)));
|
||||||
int x = t.getInt("x");
|
int x = t.getInt("x");
|
||||||
int y = t.getInt("y");
|
int y = t.getInt("y");
|
||||||
int z = t.getInt("z");
|
int z = t.getInt("z");
|
||||||
String id = t.getString("id");
|
|
||||||
|
|
||||||
Map<String, Tag> values = new HashMap<>(t.getValue());
|
|
||||||
values.put("id", new StringTag(convertBlockEntityId(id)));
|
|
||||||
|
|
||||||
int index = y * width * length + z * width + x;
|
int index = y * width * length + z * width + x;
|
||||||
BlockState block = LegacyMapper.getInstance().getBlockFromLegacy(blocks[index], blockData[index]);
|
|
||||||
|
BlockState block = getBlockState(blocks[index], blockData[index]);
|
||||||
BlockState newBlock = block;
|
BlockState newBlock = block;
|
||||||
if (newBlock != null) {
|
if (newBlock != null) {
|
||||||
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
||||||
if (handler.isAffectedBlock(newBlock)) {
|
if (handler.isAffectedBlock(newBlock)) {
|
||||||
newBlock = handler.updateNBT(block, values);
|
newBlock = handler.updateNBT(block, values);
|
||||||
if (newBlock == null) {
|
if (newBlock == null || values.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
t = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixer != null && t != null) {
|
||||||
|
t = fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, t, -1);
|
||||||
|
}
|
||||||
|
|
||||||
BlockVector3 vec = BlockVector3.at(x, y, z);
|
BlockVector3 vec = BlockVector3.at(x, y, z);
|
||||||
tileEntitiesMap.put(vec, values);
|
if (t != null) {
|
||||||
if (newBlock != block) {
|
tileEntitiesMap.put(vec, t.getValue());
|
||||||
blockOverrides.put(vec, newBlock);
|
|
||||||
}
|
}
|
||||||
|
blockStates.put(vec, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
||||||
@ -221,10 +229,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
for (int z = 0; z < length; ++z) {
|
for (int z = 0; z < length; ++z) {
|
||||||
int index = y * width * length + z * width + x;
|
int index = y * width * length + z * width + x;
|
||||||
BlockVector3 pt = BlockVector3.at(x, y, z);
|
BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||||
boolean useOverride = blockOverrides.containsKey(pt);
|
BlockState state = blockStates.computeIfAbsent(pt, p -> getBlockState(blocks[index], blockData[index]));
|
||||||
BlockState state = useOverride
|
|
||||||
? blockOverrides.get(pt)
|
|
||||||
: LegacyMapper.getInstance().getBlockFromLegacy(blocks[index], blockData[index]);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
@ -233,7 +238,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
} else {
|
} else {
|
||||||
clipboard.setBlock(region.getMinimumPoint().add(pt), state);
|
clipboard.setBlock(region.getMinimumPoint().add(pt), state);
|
||||||
}
|
}
|
||||||
} else if (!useOverride) {
|
} else {
|
||||||
short block = blocks[index];
|
short block = blocks[index];
|
||||||
byte data = blockData[index];
|
byte data = blockData[index];
|
||||||
int combined = block << 8 | data;
|
int combined = block << 8 | data;
|
||||||
@ -258,9 +263,11 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
for (Tag tag : entityTags) {
|
for (Tag tag : entityTags) {
|
||||||
if (tag instanceof CompoundTag) {
|
if (tag instanceof CompoundTag) {
|
||||||
CompoundTag compound = (CompoundTag) tag;
|
CompoundTag compound = (CompoundTag) tag;
|
||||||
|
if (fixer != null) {
|
||||||
|
compound = fixer.fixUp(DataFixer.FixTypes.ENTITY, compound, -1);
|
||||||
|
}
|
||||||
String id = convertEntityId(compound.getString("id"));
|
String id = convertEntityId(compound.getString("id"));
|
||||||
Location location = NBTConversions.toLocation(clipboard, compound.getListTag("Pos"), compound.getListTag("Rotation"));
|
Location location = NBTConversions.toLocation(clipboard, compound.getListTag("Pos"), compound.getListTag("Rotation"));
|
||||||
|
|
||||||
if (!id.isEmpty()) {
|
if (!id.isEmpty()) {
|
||||||
EntityType entityType = EntityTypes.get(id.toLowerCase(Locale.ROOT));
|
EntityType entityType = EntityTypes.get(id.toLowerCase(Locale.ROOT));
|
||||||
if (entityType != null) {
|
if (entityType != null) {
|
||||||
@ -343,26 +350,43 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String convertBlockEntityId(String id) {
|
private String convertBlockEntityId(String id) {
|
||||||
switch(id) {
|
switch (id) {
|
||||||
case "Cauldron": return "brewing_stand";
|
case "Cauldron":
|
||||||
case "Control": return "command_block";
|
return "brewing_stand";
|
||||||
case "DLDetector": return "daylight_detector";
|
case "Control":
|
||||||
case "Trap": return "dispenser";
|
return "command_block";
|
||||||
case "EnchantTable": return "enchanting_table";
|
case "DLDetector":
|
||||||
case "EndGateway": return "end_gateway";
|
return "daylight_detector";
|
||||||
case "AirPortal": return "end_portal";
|
case "Trap":
|
||||||
case "EnderChest": return "ender_chest";
|
return "dispenser";
|
||||||
case "FlowerPot": return "flower_pot";
|
case "EnchantTable":
|
||||||
case "RecordPlayer": return "jukebox";
|
return "enchanting_table";
|
||||||
case "MobSpawner": return "mob_spawner";
|
case "EndGateway":
|
||||||
|
return "end_gateway";
|
||||||
|
case "AirPortal":
|
||||||
|
return "end_portal";
|
||||||
|
case "EnderChest":
|
||||||
|
return "ender_chest";
|
||||||
|
case "FlowerPot":
|
||||||
|
return "flower_pot";
|
||||||
|
case "RecordPlayer":
|
||||||
|
return "jukebox";
|
||||||
|
case "MobSpawner":
|
||||||
|
return "mob_spawner";
|
||||||
case "Music":
|
case "Music":
|
||||||
case "noteblock":
|
case "noteblock":
|
||||||
return "note_block";
|
return "note_block";
|
||||||
case "Structure": return "structure_block";
|
case "Structure":
|
||||||
default: return id;
|
return "structure_block";
|
||||||
|
default:
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BlockState getBlockState(int id, int data) {
|
||||||
|
return LegacyMapper.getInstance().getBlockFromLegacy(id, data);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
|
@ -36,14 +36,15 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
|||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Platform;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NBTCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -54,7 +55,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -68,14 +68,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public class SpongeSchematicReader extends NBTSchematicReader {
|
public class SpongeSchematicReader extends NBTSchematicReader {
|
||||||
|
|
||||||
private static final List<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
// If NBT Compat handlers are needed - add them here.
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
|
private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
|
||||||
private final NBTInputStream inputStream;
|
private final NBTInputStream inputStream;
|
||||||
|
private DataFixer fixer = null;
|
||||||
|
private int dataVersion = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
@ -97,17 +93,32 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
// Check
|
// Check
|
||||||
Map<String, Tag> schematic = schematicTag.getValue();
|
Map<String, Tag> schematic = schematicTag.getValue();
|
||||||
|
|
||||||
int version = requireTag(schematic, "Version", IntTag.class).getValue();
|
int version = requireTag(schematic, "Version", IntTag.class).getValue();
|
||||||
|
final Platform platform = WorldEdit.getInstance().getPlatformManager()
|
||||||
|
.queryCapability(Capability.WORLD_EDITING);
|
||||||
|
int liveDataVersion = platform.getDataVersion();
|
||||||
|
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
|
dataVersion = 1631; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1-
|
||||||
|
fixer = platform.getDataFixer();
|
||||||
return readVersion1(schematicTag);
|
return readVersion1(schematicTag);
|
||||||
} else if (version == 2) {
|
} else if (version == 2) {
|
||||||
int dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||||
int liveDataVersion = WorldEdit.getInstance().getPlatformManager()
|
|
||||||
.queryCapability(Capability.WORLD_EDITING).getDataVersion();
|
|
||||||
if (dataVersion > liveDataVersion) {
|
if (dataVersion > liveDataVersion) {
|
||||||
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
||||||
dataVersion, liveDataVersion);
|
dataVersion, liveDataVersion);
|
||||||
|
} else if (dataVersion < liveDataVersion) {
|
||||||
|
fixer = platform.getDataFixer();
|
||||||
|
if (fixer != null) {
|
||||||
|
log.info("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.",
|
||||||
|
dataVersion, liveDataVersion);
|
||||||
|
} else {
|
||||||
|
log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.",
|
||||||
|
dataVersion, liveDataVersion);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BlockArrayClipboard clip = readVersion1(schematicTag);
|
BlockArrayClipboard clip = readVersion1(schematicTag);
|
||||||
return readVersion2(clip, schematicTag);
|
return readVersion2(clip, schematicTag);
|
||||||
}
|
}
|
||||||
@ -159,6 +170,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
for (String palettePart : paletteObject.keySet()) {
|
for (String palettePart : paletteObject.keySet()) {
|
||||||
int id = requireTag(paletteObject, palettePart, IntTag.class).getValue();
|
int id = requireTag(paletteObject, palettePart, IntTag.class).getValue();
|
||||||
|
if (fixer != null) {
|
||||||
|
palettePart = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart, dataVersion);
|
||||||
|
}
|
||||||
BlockState state;
|
BlockState state;
|
||||||
try {
|
try {
|
||||||
state = WorldEdit.getInstance().getBlockFactory().parseFromInput(palettePart, parserContext).toImmutableState();
|
state = WorldEdit.getInstance().getBlockFactory().parseFromInput(palettePart, parserContext).toImmutableState();
|
||||||
@ -184,7 +198,18 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
for (Map<String, Tag> tileEntity : tileEntityTags) {
|
for (Map<String, Tag> tileEntity : tileEntityTags) {
|
||||||
int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue();
|
int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue();
|
||||||
tileEntitiesMap.put(BlockVector3.at(pos[0], pos[1], pos[2]), tileEntity);
|
final BlockVector3 pt = BlockVector3.at(pos[0], pos[1], pos[2]);
|
||||||
|
if (fixer != null) {
|
||||||
|
Map<String, Tag> values = Maps.newHashMap(tileEntity);
|
||||||
|
values.put("x", new IntTag(pt.getBlockX()));
|
||||||
|
values.put("y", new IntTag(pt.getBlockY()));
|
||||||
|
values.put("z", new IntTag(pt.getBlockZ()));
|
||||||
|
values.put("id", values.get("Id"));
|
||||||
|
values.remove("Id");
|
||||||
|
values.remove("Pos");
|
||||||
|
tileEntity = fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, new CompoundTag(values), dataVersion).getValue();
|
||||||
|
}
|
||||||
|
tileEntitiesMap.put(pt, tileEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,19 +243,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
BlockVector3 pt = BlockVector3.at(x, y, z);
|
BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||||
try {
|
try {
|
||||||
if (tileEntitiesMap.containsKey(pt)) {
|
if (tileEntitiesMap.containsKey(pt)) {
|
||||||
Map<String, Tag> values = Maps.newHashMap(tileEntitiesMap.get(pt));
|
clipboard.setBlock(clipboard.getMinimumPoint().add(pt), state.toBaseBlock(new CompoundTag(tileEntitiesMap.get(pt))));
|
||||||
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
|
||||||
if (handler.isAffectedBlock(state)) {
|
|
||||||
handler.updateNBT(state, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values.put("x", new IntTag(pt.getBlockX()));
|
|
||||||
values.put("y", new IntTag(pt.getBlockY()));
|
|
||||||
values.put("z", new IntTag(pt.getBlockZ()));
|
|
||||||
values.put("id", values.get("Id"));
|
|
||||||
values.remove("Id");
|
|
||||||
values.remove("Pos");
|
|
||||||
clipboard.setBlock(clipboard.getMinimumPoint().add(pt), state.toBaseBlock(new CompoundTag(values)));
|
|
||||||
} else {
|
} else {
|
||||||
clipboard.setBlock(clipboard.getMinimumPoint().add(pt), state);
|
clipboard.setBlock(clipboard.getMinimumPoint().add(pt), state);
|
||||||
}
|
}
|
||||||
@ -267,9 +280,13 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
Map<String, Tag> paletteEntries = paletteTag.getValue();
|
Map<String, Tag> paletteEntries = paletteTag.getValue();
|
||||||
|
|
||||||
for (Entry<String, Tag> palettePart : paletteEntries.entrySet()) {
|
for (Entry<String, Tag> palettePart : paletteEntries.entrySet()) {
|
||||||
BiomeType biome = BiomeTypes.get(palettePart.getKey());
|
String key = palettePart.getKey();
|
||||||
|
if (fixer != null) {
|
||||||
|
key = fixer.fixUp(DataFixer.FixTypes.BIOME, key, dataVersion);
|
||||||
|
}
|
||||||
|
BiomeType biome = BiomeTypes.get(key);
|
||||||
if (biome == null) {
|
if (biome == null) {
|
||||||
log.warn("Unknown biome type :" + palettePart.getKey() +
|
log.warn("Unknown biome type :" + key +
|
||||||
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
||||||
}
|
}
|
||||||
Tag idTag = palettePart.getValue();
|
Tag idTag = palettePart.getValue();
|
||||||
@ -322,14 +339,18 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
CompoundTag entityTag = (CompoundTag) et;
|
CompoundTag entityTag = (CompoundTag) et;
|
||||||
Map<String, Tag> tags = entityTag.getValue();
|
Map<String, Tag> tags = entityTag.getValue();
|
||||||
String id = requireTag(tags, "Id", StringTag.class).getValue();
|
String id = requireTag(tags, "Id", StringTag.class).getValue();
|
||||||
|
entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build();
|
||||||
|
|
||||||
|
if (fixer != null) {
|
||||||
|
entityTag = fixer.fixUp(DataFixer.FixTypes.ENTITY, entityTag, dataVersion);
|
||||||
|
}
|
||||||
|
|
||||||
EntityType entityType = EntityTypes.get(id);
|
EntityType entityType = EntityTypes.get(id);
|
||||||
if (entityType != null) {
|
if (entityType != null) {
|
||||||
Location location = NBTConversions.toLocation(clipboard,
|
Location location = NBTConversions.toLocation(clipboard,
|
||||||
requireTag(tags, "Pos", ListTag.class),
|
requireTag(tags, "Pos", ListTag.class),
|
||||||
requireTag(tags, "Rotation", ListTag.class));
|
requireTag(tags, "Rotation", ListTag.class));
|
||||||
BaseEntity state = new BaseEntity(entityType,
|
BaseEntity state = new BaseEntity(entityType, entityTag);
|
||||||
entityTag.createBuilder().putString("id", id).remove("Id").build());
|
|
||||||
clipboard.createEntity(location, state);
|
clipboard.createEntity(location, state);
|
||||||
} else {
|
} else {
|
||||||
log.warn("Unknown entity when pasting schematic: " + id);
|
log.warn("Unknown entity when pasting schematic: " + id);
|
||||||
|
@ -48,6 +48,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
}
|
}
|
||||||
BlockState newState = convertLegacyBlockType(id, data);
|
BlockState newState = convertLegacyBlockType(id, data);
|
||||||
if (newState != null) {
|
if (newState != null) {
|
||||||
|
values.clear();
|
||||||
return (B) newState; // generics pls :\
|
return (B) newState; // generics pls :\
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,8 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
if (noteTag instanceof ByteTag) {
|
if (noteTag instanceof ByteTag) {
|
||||||
Byte note = ((ByteTag) noteTag).getValue();
|
Byte note = ((ByteTag) noteTag).getValue();
|
||||||
if (note != null) {
|
if (note != null) {
|
||||||
return block.with(NoteProperty, (int) note);
|
values.clear();
|
||||||
|
return (B) block.with(NoteProperty, (int) note).toImmutableState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
|
@ -22,13 +22,32 @@ package com.sk89q.worldedit.world;
|
|||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This entire class is subject to heavy changes. Do not use this as API.
|
||||||
|
*/
|
||||||
@Beta
|
@Beta
|
||||||
public interface DataFixer {
|
public interface DataFixer {
|
||||||
|
|
||||||
/**
|
final class FixType<T> {
|
||||||
* API SUBJECT TO CHANGE. DON'T USE THIS.
|
private FixType() {
|
||||||
*/
|
}
|
||||||
@Beta
|
}
|
||||||
CompoundTag fixChunk(CompoundTag originalChunk);
|
|
||||||
|
|
||||||
|
final class FixTypes {
|
||||||
|
private FixTypes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FixType<CompoundTag> CHUNK = new FixType<>();
|
||||||
|
public static FixType<CompoundTag> BLOCK_ENTITY = new FixType<>();
|
||||||
|
public static FixType<CompoundTag> ENTITY = new FixType<>();
|
||||||
|
public static FixType<String> BLOCK_STATE = new FixType<>();
|
||||||
|
public static FixType<String> BIOME = new FixType<>();
|
||||||
|
public static FixType<String> ITEM_TYPE = new FixType<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
default <T> T fixUp(FixType<T> type, T original) {
|
||||||
|
return fixUp(type, original, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
<T> T fixUp(FixType<T> type, T original, int srcVer);
|
||||||
}
|
}
|
||||||
|
@ -173,33 +173,10 @@ public class AnvilChunk13 implements Chunk {
|
|||||||
|
|
||||||
CompoundTag t = (CompoundTag) tag;
|
CompoundTag t = (CompoundTag) tag;
|
||||||
|
|
||||||
int x = 0;
|
Map<String, Tag> values = new HashMap<>(t.getValue());
|
||||||
int y = 0;
|
int x = ((IntTag) values.get("x")).getValue();
|
||||||
int z = 0;
|
int y = ((IntTag) values.get("y")).getValue();
|
||||||
|
int z = ((IntTag) values.get("z")).getValue();
|
||||||
Map<String, Tag> values = new HashMap<>();
|
|
||||||
|
|
||||||
for (Map.Entry<String, Tag> entry : t.getValue().entrySet()) {
|
|
||||||
switch (entry.getKey()) {
|
|
||||||
case "x":
|
|
||||||
if (entry.getValue() instanceof IntTag) {
|
|
||||||
x = ((IntTag) entry.getValue()).getValue();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "y":
|
|
||||||
if (entry.getValue() instanceof IntTag) {
|
|
||||||
y = ((IntTag) entry.getValue()).getValue();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "z":
|
|
||||||
if (entry.getValue() instanceof IntTag) {
|
|
||||||
z = ((IntTag) entry.getValue()).getValue();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
values.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockVector3 vec = BlockVector3.at(x, y, z);
|
BlockVector3 vec = BlockVector3.at(x, y, z);
|
||||||
tileEntities.put(vec, values);
|
tileEntities.put(vec, values);
|
||||||
|
@ -26,10 +26,13 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
import com.sk89q.worldedit.util.gson.VectorAdapter;
|
import com.sk89q.worldedit.util.gson.VectorAdapter;
|
||||||
import com.sk89q.worldedit.util.io.ResourceLoader;
|
import com.sk89q.worldedit.util.io.ResourceLoader;
|
||||||
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
@ -41,18 +44,18 @@ import java.io.IOException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
public final class LegacyMapper {
|
||||||
|
|
||||||
public class LegacyMapper {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(LegacyMapper.class);
|
private static final Logger log = LoggerFactory.getLogger(LegacyMapper.class);
|
||||||
private static LegacyMapper INSTANCE;
|
private static LegacyMapper INSTANCE;
|
||||||
|
|
||||||
private Multimap<String, BlockState> stringToBlockMap = HashMultimap.create();
|
private Map<String, String> blockEntries = new HashMap<>();
|
||||||
|
private Map<String, BlockState> stringToBlockMap = new HashMap<>();
|
||||||
private Multimap<BlockState, String> blockToStringMap = HashMultimap.create();
|
private Multimap<BlockState, String> blockToStringMap = HashMultimap.create();
|
||||||
private Multimap<String, ItemType> stringToItemMap = HashMultimap.create();
|
private Map<String, ItemType> stringToItemMap = new HashMap<>();
|
||||||
private Multimap<ItemType, String> itemToStringMap = HashMultimap.create();
|
private Multimap<ItemType, String> itemToStringMap = HashMultimap.create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,31 +85,50 @@ public class LegacyMapper {
|
|||||||
String data = Resources.toString(url, Charset.defaultCharset());
|
String data = Resources.toString(url, Charset.defaultCharset());
|
||||||
LegacyDataFile dataFile = gson.fromJson(data, new TypeToken<LegacyDataFile>() {}.getType());
|
LegacyDataFile dataFile = gson.fromJson(data, new TypeToken<LegacyDataFile>() {}.getType());
|
||||||
|
|
||||||
|
DataFixer fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer();
|
||||||
ParserContext parserContext = new ParserContext();
|
ParserContext parserContext = new ParserContext();
|
||||||
parserContext.setPreferringWildcard(false);
|
parserContext.setPreferringWildcard(false);
|
||||||
parserContext.setRestricted(false);
|
parserContext.setRestricted(false);
|
||||||
parserContext.setTryLegacy(false); // This is legacy. Don't match itself.
|
parserContext.setTryLegacy(false); // This is legacy. Don't match itself.
|
||||||
|
|
||||||
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
|
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
|
||||||
try {
|
|
||||||
String id = blockEntry.getKey();
|
String id = blockEntry.getKey();
|
||||||
|
blockEntries.put(id, blockEntry.getValue());
|
||||||
|
try {
|
||||||
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
|
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
|
||||||
blockToStringMap.put(state, id);
|
blockToStringMap.put(state, id);
|
||||||
stringToBlockMap.put(id, state);
|
stringToBlockMap.put(id, state);
|
||||||
} catch (Exception e) {
|
} catch (InputParseException e) {
|
||||||
|
boolean fixed = false;
|
||||||
|
if (fixer != null) {
|
||||||
|
String newEntry = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, blockEntry.getValue(), 1631);
|
||||||
|
try {
|
||||||
|
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(newEntry, parserContext).toImmutableState();
|
||||||
|
blockToStringMap.put(state, id);
|
||||||
|
stringToBlockMap.put(id, state);
|
||||||
|
fixed = true;
|
||||||
|
} catch (InputParseException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!fixed) {
|
||||||
log.warn("Unknown block: " + blockEntry.getValue());
|
log.warn("Unknown block: " + blockEntry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, String> itemEntry : dataFile.items.entrySet()) {
|
for (Map.Entry<String, String> itemEntry : dataFile.items.entrySet()) {
|
||||||
try {
|
|
||||||
String id = itemEntry.getKey();
|
String id = itemEntry.getKey();
|
||||||
ItemType type = ItemTypes.get(itemEntry.getValue());
|
String value = itemEntry.getValue();
|
||||||
checkNotNull(type);
|
ItemType type = ItemTypes.get(value);
|
||||||
|
if (type == null && fixer != null) {
|
||||||
|
value = fixer.fixUp(DataFixer.FixTypes.ITEM_TYPE, value, 1631);
|
||||||
|
type = ItemTypes.get(value);
|
||||||
|
}
|
||||||
|
if (type == null) {
|
||||||
|
log.warn("Unknown item: " + value);
|
||||||
|
} else {
|
||||||
itemToStringMap.put(type, id);
|
itemToStringMap.put(type, id);
|
||||||
stringToItemMap.put(id, type);
|
stringToItemMap.put(id, type);
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("Unknown item: " + itemEntry.getValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,16 +140,16 @@ public class LegacyMapper {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemType getItemFromLegacy(int legacyId, int data) {
|
public ItemType getItemFromLegacy(int legacyId, int data) {
|
||||||
return stringToItemMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
|
return stringToItemMap.get(legacyId + ":" + data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public int[] getLegacyFromItem(ItemType itemType) {
|
public int[] getLegacyFromItem(ItemType itemType) {
|
||||||
if (!itemToStringMap.containsKey(itemType)) {
|
if (itemToStringMap.containsKey(itemType)) {
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
String value = itemToStringMap.get(itemType).stream().findFirst().get();
|
String value = itemToStringMap.get(itemType).stream().findFirst().get();
|
||||||
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,16 +160,16 @@ public class LegacyMapper {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockState getBlockFromLegacy(int legacyId, int data) {
|
public BlockState getBlockFromLegacy(int legacyId, int data) {
|
||||||
return stringToBlockMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
|
return stringToBlockMap.get(legacyId + ":" + data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public int[] getLegacyFromBlock(BlockState blockState) {
|
public int[] getLegacyFromBlock(BlockState blockState) {
|
||||||
if (!blockToStringMap.containsKey(blockState)) {
|
if (blockToStringMap.containsKey(blockState)) {
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
String value = blockToStringMap.get(blockState).stream().findFirst().get();
|
String value = blockToStringMap.get(blockState).stream().findFirst().get();
|
||||||
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ public class PassthroughBlockMaterial implements BlockMaterial {
|
|||||||
if (blockMaterial == null) {
|
if (blockMaterial == null) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return blockMaterial.isOpaque();
|
return blockMaterial.isBurnable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +106,13 @@ public abstract class ChunkStore implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dataVersion = rootTag.getInt("DataVersion");
|
int dataVersion = rootTag.getInt("DataVersion");
|
||||||
|
if (dataVersion == 0) dataVersion = -1;
|
||||||
final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
||||||
final int currentDataVersion = platform.getDataVersion();
|
final int currentDataVersion = platform.getDataVersion();
|
||||||
if (dataVersion < currentDataVersion) {
|
if (dataVersion < currentDataVersion) {
|
||||||
final DataFixer dataFixer = platform.getDataFixer();
|
final DataFixer dataFixer = platform.getDataFixer();
|
||||||
if (dataFixer != null) {
|
if (dataFixer != null) {
|
||||||
return new AnvilChunk13((CompoundTag) dataFixer.fixChunk(rootTag).getValue().get("Level"));
|
return new AnvilChunk13((CompoundTag) dataFixer.fixUp(DataFixer.FixTypes.CHUNK, rootTag, dataVersion).getValue().get("Level"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dataVersion >= DATA_VERSION_MC_1_13) {
|
if (dataVersion >= DATA_VERSION_MC_1_13) {
|
||||||
|
Loading…
Reference in New Issue
Block a user