From 4905d88ad314ccd2c4a214cda78bd7d76c325cfa Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 31 May 2022 13:17:19 +0200 Subject: [PATCH] Improved 1.12 .schem loader --- .../src/de/steamwar/core/IDConverter8.java | 83 +++++++++++++++---- .../de/steamwar/core/WorldEditWrapper8.java | 27 ++---- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/SpigotCore_8/src/de/steamwar/core/IDConverter8.java b/SpigotCore_8/src/de/steamwar/core/IDConverter8.java index fdbf70b..7026365 100644 --- a/SpigotCore_8/src/de/steamwar/core/IDConverter8.java +++ b/SpigotCore_8/src/de/steamwar/core/IDConverter8.java @@ -22,33 +22,84 @@ package de.steamwar.core; import org.bukkit.configuration.file.YamlConfiguration; import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; -class IDConverter8 { - private IDConverter8(){} +public class IDConverter8 { + + private final Map> availibleAttributes; + private final Map, BlockTypeID>> map; + + public IDConverter8() { + Map, BlockTypeID>> map = new HashMap<>(); - static Map getMap(){ - Map ids = new HashMap<>(); YamlConfiguration legacy = YamlConfiguration.loadConfiguration(new InputStreamReader(Objects.requireNonNull(IDConverter8.class.getClassLoader().getResourceAsStream("legacy.yml")))); for(String blockString : legacy.getKeys(false)){ - String blockNum = legacy.getString(blockString); - String[] block = blockNum.split(":"); - ids.put(blockString, new BlockTypeID(Integer.parseInt(block[0]), Byte.parseByte(block[1]))); - if(blockString.contains("[")) - ids.putIfAbsent(blockString.split("\\[")[0], new BlockTypeID(Integer.parseInt(block[0]), (byte)0)); + String[] legacyBlockId = legacy.getString(blockString).split(":"); + + map.computeIfAbsent(getBlockId(blockString), bId -> { + Map, BlockTypeID> attributeMap = new HashMap<>(); + attributeMap.put(new HashSet<>(), new BlockTypeID(legacyBlockId[0], "0")); + return attributeMap; + }).put(getAttributes(blockString), new BlockTypeID(legacyBlockId[0], legacyBlockId[1])); } - return ids; + this.map = map; + + Map> availableAttributes = new HashMap<>(); + for (Map.Entry, BlockTypeID>> entry : map.entrySet()) { + availableAttributes.put(entry.getKey(), entry.getValue().keySet().stream().flatMap(Collection::stream).collect(Collectors.toSet())); + } + this.availibleAttributes = availableAttributes; + } + + public BlockTypeID getId(String blockString) { + String blockId = getBlockId(blockString); + Map, IDConverter8.BlockTypeID> attributeMap = map.get(blockId); + if(attributeMap == null) { // Block nonexistent pre-flattening + return new BlockTypeID("0", "0"); + } + + Set attributes = getAttributes(blockString); + Set knownAttributes = this.availibleAttributes.get(blockId); + attributes.removeIf(attribute -> !knownAttributes.contains(attribute)); + + long bestMatch = -1; + BlockTypeID blockID = null; + for(Map.Entry, BlockTypeID> entry : attributeMap.entrySet()) { + Set attrs = entry.getKey(); + if(attrs.size() <= bestMatch) + continue; + + long matching = attributes.stream().filter(attrs::contains).count(); + if(matching > bestMatch) { + blockID = entry.getValue(); + bestMatch = matching; + + if(bestMatch == attributes.size()) + break; + } + } + return blockID; + } + + private String getBlockId(String blockString) { + return blockString.split("\\[", 2)[0]; + } + + private Set getAttributes(String blockString) { + Set attributes = new HashSet<>(); + if(blockString.contains("[")) + Collections.addAll(attributes, blockString.split("\\[")[1].replace("]", "").split(",")); + return attributes; } static class BlockTypeID{ private final int blockId; private final byte dataId; - private BlockTypeID(int blockId, byte dataId) { - this.blockId = blockId; - this.dataId = dataId; + private BlockTypeID(String blockId, String dataId) { + this.blockId = Integer.parseInt(blockId); + this.dataId = Byte.parseByte(dataId); } int getBlockId() { diff --git a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java index 2b1cb0e..e5f6ac8 100644 --- a/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java +++ b/SpigotCore_8/src/de/steamwar/core/WorldEditWrapper8.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.sk89q.jnbt.*; import com.sk89q.worldedit.*; +import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.extension.input.ParserContext; @@ -20,10 +21,7 @@ import de.steamwar.sql.NoClipboardException; import org.bukkit.entity.Player; import java.io.*; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.logging.Level; import java.util.stream.Collectors; @@ -123,7 +121,7 @@ public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { } private BlockArrayClipboard readSchematic(CompoundTag schematicTag) throws IOException { - final Map ids = IDConverter8.getMap(); + IDConverter8 ids = new IDConverter8(); Map schematic = schematicTag.getValue(); int width = (requireTag(schematic, "Width", ShortTag.class)).getValue(); @@ -166,22 +164,9 @@ public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { parserContext.setRestricted(false); parserContext.setPreferringWildcard(false); - int id; - BaseBlock state; - for(Iterator iterator = paletteObject.keySet().iterator(); iterator.hasNext(); palette.put(id, state)) { - String palettePart = iterator.next(); - id = requireTag(paletteObject, palettePart, IntTag.class).getValue(); - - IDConverter8.BlockTypeID blockID = ids.get(palettePart); - if(blockID == null){ - blockID = ids.get(palettePart.split("\\[")[0]); - } - - if(blockID == null){ - state = new BaseBlock(0); //AIR - }else{ - state = new BaseBlock(blockID.getBlockId(), blockID.getDataId()); - } + for(String palettePart : paletteObject.keySet()) { + IDConverter8.BlockTypeID blockID = ids.getId(palettePart); + palette.put(requireTag(paletteObject, palettePart, IntTag.class).getValue(), new BaseBlock(blockID.getBlockId(), blockID.getDataId())); } byte[] blocks = requireTag(schematic, "BlockData", ByteArrayTag.class).getValue();