Some conversion fixes
This commit is contained in:
parent
4150413885
commit
201809aedd
17729
blocks.json
17729
blocks.json
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,11 @@ import javafx.embed.swing.JFXPanel;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
|
||||
public abstract class BrowseButton extends InteractiveButton {
|
||||
public BrowseButton() {
|
||||
private final String id;
|
||||
|
||||
public BrowseButton(String id) {
|
||||
super("Browse");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public abstract void onSelect(File folder);
|
||||
@ -32,7 +35,8 @@ public abstract class BrowseButton extends InteractiveButton {
|
||||
File file = folderChooser.showDialog(null);
|
||||
if (file != null && file.exists()) {
|
||||
File parent = file.getParentFile();
|
||||
Preferences.userRoot().node(Fawe.class.getName()).put("LAST_USED_FOLDER", file.getPath());
|
||||
if (parent == null) parent = file;
|
||||
Preferences.userRoot().node(Fawe.class.getName()).put("LAST_USED_FOLDER" + id, parent.getPath());
|
||||
onSelect(file);
|
||||
}
|
||||
});
|
||||
|
@ -100,7 +100,7 @@ public class InstallerFrame extends JFrame {
|
||||
text.setBackground(DARKER_GRAY);
|
||||
text.setOpaque(true);
|
||||
text.setBorder(new EmptyBorder(4, 4, 4, 4));
|
||||
browse = new BrowseButton() {
|
||||
browse = new BrowseButton("") {
|
||||
@Override
|
||||
public void onSelect(File folder) {
|
||||
text.setText(folder.getPath());
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.number.MutableLong;
|
||||
import com.boydti.fawe.util.ArrayUtil;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -530,7 +531,8 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
streamer.readFully();
|
||||
}
|
||||
|
||||
public void filterBlocks(MutableMCABackedBaseBlock mutableBlock, MCAFilter filter) {
|
||||
public long filterBlocks(MutableMCABackedBaseBlock mutableBlock, MCAFilter filter) {
|
||||
MutableLong result = new MutableLong();
|
||||
mutableBlock.setChunk(this);
|
||||
int bx = getX() << 4;
|
||||
int bz = getZ() << 4;
|
||||
@ -551,12 +553,13 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
int xIndex = zIndex + x0;
|
||||
mutableBlock.setX(x);
|
||||
mutableBlock.setIndex(xIndex);
|
||||
filter.applyBlock(x, y, z, mutableBlock, null);
|
||||
filter.applyBlock(x, y, z, mutableBlock, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.get();
|
||||
}
|
||||
|
||||
public int[] getHeightMapArray() {
|
||||
|
@ -187,7 +187,6 @@ public class MCAQueueMap implements IFaweQueueMap {
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
lastFileX = Integer.MIN_VALUE;
|
||||
lastFileZ = Integer.MIN_VALUE;
|
||||
System.out.println("Files " + mcaFileMap);
|
||||
if (!mcaFileMap.isEmpty()) {
|
||||
Iterator<Map.Entry<Long, MCAFile>> iter = mcaFileMap.entrySet().iterator();
|
||||
boolean result;
|
||||
|
@ -1,32 +1,231 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.intellectualcrafters.plot.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static com.boydti.fawe.FaweCache.getBlock;
|
||||
|
||||
public class ClipboardRemapper {
|
||||
private final RemapPlatform from;
|
||||
|
||||
public enum RemapPlatform {
|
||||
PE,
|
||||
PC
|
||||
;
|
||||
public RemapPlatform opposite() {
|
||||
return this == PE ? PC : PE;
|
||||
}
|
||||
}
|
||||
|
||||
public ClipboardRemapper() {
|
||||
|
||||
this.from = null;
|
||||
}
|
||||
|
||||
public ClipboardRemapper(RemapPlatform fromPlatform, RemapPlatform toPlatform) {
|
||||
if (fromPlatform == toPlatform) {
|
||||
return;
|
||||
private ItemWikiScraper scraper;
|
||||
|
||||
private synchronized ItemWikiScraper loadItemMapping() throws IOException {
|
||||
ItemWikiScraper tmp = scraper;
|
||||
if (tmp == null) {
|
||||
scraper = tmp = new ItemWikiScraper();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public BaseBlock remapItem(String name, int damage) {
|
||||
if (name.isEmpty()) return EditSession.nullBlock;
|
||||
if (from == RemapPlatform.PC) {
|
||||
BundledBlockData.BlockEntry state = BundledBlockData.getInstance().findById(name);
|
||||
if (state != null) {
|
||||
return remap(new BaseBlock(state.legacyId, damage));
|
||||
} else {
|
||||
try {
|
||||
name = name.replace("minecraft:", "");
|
||||
ItemWikiScraper scraper = loadItemMapping();
|
||||
Map<String, Integer> mapFrom = scraper.scapeOrCache(from);
|
||||
Map<String, Integer> mapTo = scraper.scapeOrCache(from.opposite());
|
||||
scraper.expand(mapTo);
|
||||
switch (name) {
|
||||
case "spruce_boat": return new BaseBlock(333, 1);
|
||||
case "birch_boat": return new BaseBlock(333, 2);
|
||||
case "jungle_boat": return new BaseBlock(333, 3);
|
||||
case "acacia_boat": return new BaseBlock(333, 4);
|
||||
case "dark_oak_boat": return new BaseBlock(333, 5);
|
||||
case "water_bucket": return new BaseBlock(325, 8);
|
||||
case "lava_bucket": return new BaseBlock(325, 10);
|
||||
case "milk_bucket": return new BaseBlock(325, 1);
|
||||
case "tipped_arrow":
|
||||
case "spectral_arrow":
|
||||
name = "arrow"; // Unsupported
|
||||
break;
|
||||
case "totem_of_undying":
|
||||
name = "totem";
|
||||
break;
|
||||
case "furnace_minecart":
|
||||
name = "minecart"; // Unsupported
|
||||
break;
|
||||
}
|
||||
Integer itemId = mapTo.get(name);
|
||||
if (itemId == null) itemId = mapTo.get(name.replace("_", ""));
|
||||
if (itemId == null) itemId = mapFrom.get(name);
|
||||
if (itemId != null) return new BaseBlock(itemId, damage);
|
||||
} catch (IOException ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return EditSession.nullBlock;
|
||||
}
|
||||
|
||||
public Map.Entry<String, Integer> remapItem(int id, int data) {
|
||||
throw new UnsupportedOperationException("TODO");
|
||||
}
|
||||
|
||||
public String remapEntityId(String id) {
|
||||
if (from == null) return id;
|
||||
switch (from) {
|
||||
case PE: {
|
||||
switch (id) {
|
||||
case "EnchantTable": return "minecraft:enchanting_table";
|
||||
case "Music": return "minecraft:noteblock";
|
||||
case "Chest": return "minecraft:trapped_chest";
|
||||
case "ChalkboardBlock": return "minecraft:chalk_board_block";
|
||||
case "FallingSand": return "minecraft:falling_block";
|
||||
case "FireworksRocketEntity": return "minecraft:fireworks_rocket";
|
||||
case "LavaSlime": return "minecraft:magma_cube";
|
||||
case "MinecartChest": return "minecraft:chest_minecart";
|
||||
case "MinecartCommandBlock": return "minecraft:commandblock_minecart";
|
||||
case "MinecartFurnace": return "minecraft:furnace_minecart";
|
||||
case "MinecartHopper": return "minecraft:hopper_minecart";
|
||||
case "MinecartRideable": return "minecraft:minecart";
|
||||
case "MinecartSpawner": return "minecraft:spawner_minecart";
|
||||
case "MinecartTNT": return "minecraft:tnt_minecart";
|
||||
case "MushroomCow": return "minecraft:mooshroom";
|
||||
case "Ocelot": return "minecraft:ocelot";
|
||||
case "PigZombie": return "minecraft:zombie_pigman";
|
||||
case "PrimedTnt": return "minecraft:tnt";
|
||||
case "SnowMan": return "minecraft:snowman";
|
||||
case "ThrownEgg": return "minecraft:egg";
|
||||
case "ThrownEnderpearl": return "minecraft:ender_pearl";
|
||||
case "ThrownExpBottle": return "minecraft:xp_bottle";
|
||||
case "ThrownPotion": return "minecraft:potion";
|
||||
case "WitherBoss": return "minecraft:wither";
|
||||
case "XPOrb": return "minecraft:xp_orb";
|
||||
}
|
||||
StringBuilder result = new StringBuilder("minecraft:");
|
||||
for (int i = 0; i < result.length(); i++) {
|
||||
char c = id.charAt(i);
|
||||
if (Character.isUpperCase(c)) {
|
||||
c = Character.toLowerCase(c);
|
||||
if (i != 0) result.append('_');
|
||||
}
|
||||
result.append(c);
|
||||
}
|
||||
id = result.toString();
|
||||
return id;
|
||||
}
|
||||
case PC: {
|
||||
switch (id) {
|
||||
case "minecraft:enchanting_table": return "EnchantTable";
|
||||
case "minecraft:noteblock": return "Music";
|
||||
case "minecraft:trapped_chest": return "Chest";
|
||||
case "minecraft:chalk_board_block": return "ChalkboardBlock";
|
||||
case "minecraft:falling_block": return "FallingSand";
|
||||
case "minecraft:fireworks_rocket": return "FireworksRocketEntity";
|
||||
case "minecraft:magma_cube": return "LavaSlime";
|
||||
case "minecraft:chest_minecart": return "MinecartChest";
|
||||
case "minecraft:commandblock_minecart": return "MinecartCommandBlock";
|
||||
case "minecraft:furnace_minecart": return "MinecartFurnace";
|
||||
case "minecraft:hopper_minecart": return "MinecartHopper";
|
||||
case "minecraft:minecart": return "MinecartRideable";
|
||||
case "minecraft:spawner_minecart": return "MinecartSpawner";
|
||||
case "minecraft:tnt_minecart": return "MinecartTNT";
|
||||
case "minecraft:mooshroom": return "MushroomCow";
|
||||
case "minecraft:ocelot": return "Ocelot";
|
||||
case "minecraft:zombie_pigman": return "PigZombie";
|
||||
case "minecraft:tnt": return "PrimedTnt";
|
||||
case "minecraft:snowman": return "SnowMan";
|
||||
case "minecraft:egg": return "ThrownEgg";
|
||||
case "minecraft:ender_pearl": return "ThrownEnderpearl";
|
||||
case "minecraft:xp_bottle": return "ThrownExpBottle";
|
||||
case "minecraft:potion": return "ThrownPotion";
|
||||
case "minecraft:wither": return "WitherBoss";
|
||||
case "minecraft:xp_orb": return "XPOrb";
|
||||
}
|
||||
id = id.replace("minecraft:", "");
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean toUpper = false;
|
||||
for (int i = 0; i < id.length(); i++) {
|
||||
char c = id.charAt(i);
|
||||
if (i == 0) toUpper = true;
|
||||
if (c == '_') {
|
||||
toUpper = true;
|
||||
} else {
|
||||
result.append(toUpper ? Character.toUpperCase(c) : c);
|
||||
toUpper = false;
|
||||
}
|
||||
}
|
||||
id = result.toString();
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
private Map<String, List<Integer>> parse(File file) throws IOException {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject toParse = (JsonObject) parser.parse(Resources.toString(file.toURL(), Charset.defaultCharset()));
|
||||
Map<String, List<Integer>> map = new HashMap<>();
|
||||
|
||||
outer:
|
||||
for (Map.Entry<String, JsonElement> entry : toParse.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
JsonObject value = entry.getValue().getAsJsonObject();
|
||||
if (MathMan.isInteger(key)) {
|
||||
int id = Integer.parseInt(key);
|
||||
for (Map.Entry<String, JsonElement> dataEntry : value.entrySet()) {
|
||||
String dataKey = dataEntry.getKey();
|
||||
if (MathMan.isInteger(dataKey)) {
|
||||
int data = Integer.parseInt(dataEntry.getKey());
|
||||
int combined = (id << 4) + data;
|
||||
String name = dataEntry.getValue().getAsJsonObject().get("intermediateID").getAsString();
|
||||
map.putIfAbsent(name, new ArrayList<>());
|
||||
map.get(name).add(combined);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String name = entry.getKey();
|
||||
int id = value.get("id").getAsInt();
|
||||
int data = value.get("data").getAsInt();
|
||||
int combined = FaweCache.getCombined(id, data);
|
||||
map.putIfAbsent(name, new ArrayList<>());
|
||||
map.get(name).add(combined);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private HashMap<BaseBlock, BaseBlock> getPEtoPCMappings() {
|
||||
HashMap<BaseBlock, BaseBlock> mapPEtoPC = new HashMap<>();
|
||||
mapPEtoPC.put(new BaseBlock(281, -1), new BaseBlock(25, -1));
|
||||
mapPEtoPC.put(new BaseBlock(95,-1), new BaseBlock(166,-1));
|
||||
mapPEtoPC.put(new BaseBlock(125,-1), new BaseBlock(158,-1));
|
||||
mapPEtoPC.put(new BaseBlock(126,-1), new BaseBlock(157,-1));
|
||||
@ -34,9 +233,19 @@ public class ClipboardRemapper {
|
||||
mapPEtoPC.put(new BaseBlock(158,-1), new BaseBlock(126,-1));
|
||||
mapPEtoPC.put(new BaseBlock(188,-1), new BaseBlock(210,-1));
|
||||
mapPEtoPC.put(new BaseBlock(189,-1), new BaseBlock(211,-1));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(155,4), new BaseBlock(155,10));
|
||||
mapPEtoPC.put(new BaseBlock(155,3), new BaseBlock(155,6));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(198,-1), new BaseBlock(208,-1));
|
||||
mapPEtoPC.put(new BaseBlock(207,-1), new BaseBlock(212,-1));
|
||||
mapPEtoPC.put(new BaseBlock(208,-1), new BaseBlock(198,-1));
|
||||
{ // beetroot
|
||||
mapPEtoPC.put(new BaseBlock(244, 2), new BaseBlock(207, 1));
|
||||
mapPEtoPC.put(new BaseBlock(244, 4), new BaseBlock(207, 2));
|
||||
mapPEtoPC.put(new BaseBlock(244, 7), new BaseBlock(207, 3));
|
||||
for (int data = 3; data < 16; data++) mapPEtoPC.putIfAbsent(new BaseBlock(244, data), new BaseBlock(207, data));
|
||||
}
|
||||
|
||||
for (int data = 0; data < 16; data++) {
|
||||
mapPEtoPC.put(new BaseBlock(218, data), new BaseBlock(219 + data, -1));
|
||||
}
|
||||
@ -67,16 +276,20 @@ public class ClipboardRemapper {
|
||||
}
|
||||
|
||||
for (int id : new int[] {29, 33}) {
|
||||
addBoth(getBlock(id, 3), getBlock(id, 4));
|
||||
addBoth(getBlock(id, 10), getBlock(id, 11));
|
||||
mapPEtoPC.put(new BaseBlock(id,3), new BaseBlock(id,2));
|
||||
mapPEtoPC.put(new BaseBlock(id,2), new BaseBlock(id,3));
|
||||
mapPEtoPC.put(new BaseBlock(id,5), new BaseBlock(id,4));
|
||||
mapPEtoPC.put(new BaseBlock(id,13), new BaseBlock(id,12));
|
||||
mapPEtoPC.put(new BaseBlock(id,4), new BaseBlock(id,5));
|
||||
mapPEtoPC.put(new BaseBlock(id,12), new BaseBlock(id,13));
|
||||
}
|
||||
mapPEtoPC.put(new BaseBlock(250,-1), new BaseBlock(36,-1));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(236,-1), new BaseBlock(251,-1));
|
||||
mapPEtoPC.put(new BaseBlock(237,-1), new BaseBlock(252,-1));
|
||||
mapPEtoPC.put(new BaseBlock(240,-1), new BaseBlock(199,-1));
|
||||
mapPEtoPC.put(new BaseBlock(241,-1), new BaseBlock(95,-1));
|
||||
mapPEtoPC.put(new BaseBlock(243,0), new BaseBlock(3, 2));
|
||||
mapPEtoPC.put(new BaseBlock(244,-1), new BaseBlock(207,-1));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(251,-1), new BaseBlock(218,-1));
|
||||
|
||||
@ -98,14 +311,18 @@ public class ClipboardRemapper {
|
||||
mapPEtoPC.put(new BaseBlock(85,3), new BaseBlock(190,-1));
|
||||
mapPEtoPC.put(new BaseBlock(85,4), new BaseBlock(192,-1));
|
||||
mapPEtoPC.put(new BaseBlock(85, 5), new BaseBlock(191,-1));
|
||||
mapPEtoPC.put(new BaseBlock(202,-1), new BaseBlock(201,2));
|
||||
mapPEtoPC.put(new BaseBlock(182,1), new BaseBlock(205,-1));
|
||||
mapPEtoPC.put(new BaseBlock(202,-1), new BaseBlock(203,2));
|
||||
|
||||
for (int id : new int[] {208}) { // end rod
|
||||
mapPEtoPC.put(new BaseBlock(id,4), new BaseBlock(id,5));
|
||||
mapPEtoPC.put(new BaseBlock(id,2), new BaseBlock(id,3));
|
||||
mapPEtoPC.put(new BaseBlock(id,5), new BaseBlock(id,4));
|
||||
mapPEtoPC.put(new BaseBlock(id,3), new BaseBlock(id,2));
|
||||
mapPEtoPC.put(new BaseBlock(201,2), new BaseBlock(202,0));
|
||||
mapPEtoPC.put(new BaseBlock(201,10), new BaseBlock(202,8));
|
||||
mapPEtoPC.put(new BaseBlock(201,6), new BaseBlock(202,4));
|
||||
mapPEtoPC.put(new BaseBlock(181,1), new BaseBlock(204,-1));
|
||||
{
|
||||
for (int data = 0; data < 16; data++) mapPEtoPC.put(new BaseBlock(208, data), new BaseBlock(198, data));
|
||||
mapPEtoPC.put(new BaseBlock(208,4), new BaseBlock(198,5));
|
||||
mapPEtoPC.put(new BaseBlock(208,2), new BaseBlock(198,3));
|
||||
mapPEtoPC.put(new BaseBlock(208,5), new BaseBlock(198,4));
|
||||
mapPEtoPC.put(new BaseBlock(208,3), new BaseBlock(198,2));
|
||||
}
|
||||
|
||||
for (int id : new int[] {77, 143}) { // button
|
||||
@ -113,6 +330,11 @@ public class ClipboardRemapper {
|
||||
mapPEtoPC.put(new BaseBlock(id,1), new BaseBlock(id,5));
|
||||
mapPEtoPC.put(new BaseBlock(id,2), new BaseBlock(id,4));
|
||||
mapPEtoPC.put(new BaseBlock(id,5), new BaseBlock(id,1));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(id,13), new BaseBlock(id,9));
|
||||
mapPEtoPC.put(new BaseBlock(id,12), new BaseBlock(id,10));
|
||||
mapPEtoPC.put(new BaseBlock(id,10), new BaseBlock(id,12));
|
||||
mapPEtoPC.put(new BaseBlock(id,9), new BaseBlock(id,13));
|
||||
}
|
||||
|
||||
// leaves
|
||||
@ -123,13 +345,41 @@ public class ClipboardRemapper {
|
||||
for (int data = 0; data < 4; data++) mapPEtoPC.put(new BaseBlock(id, data), new BaseBlock(id, 3 - data));
|
||||
for (int data = 4; data < 12; data++) mapPEtoPC.put(new BaseBlock(id, data), new BaseBlock(id, 15 - data));
|
||||
for (int data = 12; data < 15; data++) mapPEtoPC.put(new BaseBlock(id, data), new BaseBlock(id, 27 - data));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(id, 2), new BaseBlock(id, 0));
|
||||
mapPEtoPC.put(new BaseBlock(id, 3), new BaseBlock(id, 1));
|
||||
|
||||
mapPEtoPC.put(new BaseBlock(id, 7), new BaseBlock(id, 9));
|
||||
mapPEtoPC.put(new BaseBlock(id, 6), new BaseBlock(id, 8));
|
||||
}
|
||||
|
||||
return mapPEtoPC;
|
||||
}
|
||||
|
||||
public ClipboardRemapper(RemapPlatform fromPlatform, RemapPlatform toPlatform) {
|
||||
if (fromPlatform == toPlatform) {
|
||||
this.from = null;
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap<BaseBlock, BaseBlock> mapPEtoPC = getPEtoPCMappings();
|
||||
|
||||
|
||||
// TODO any custom ids
|
||||
switch (fromPlatform) {
|
||||
case PE:
|
||||
for (int data = 0; data < 8; data++) add(new BaseBlock(182, 1), new BaseBlock(205, data));
|
||||
for (int data = 8; data < 16; data++) add(new BaseBlock(182, 9), new BaseBlock(205, data));
|
||||
for (int data = 0; data < 8; data++) add(new BaseBlock(182, 0), new BaseBlock(182, data));
|
||||
for (int data = 8; data < 16; data++) add(new BaseBlock(182, 8), new BaseBlock(182, data));
|
||||
break;
|
||||
case PC:
|
||||
add(new BaseBlock(202, -1), new BaseBlock(201, -1));
|
||||
add(new BaseBlock(204, -1), new BaseBlock(201, -1));
|
||||
for (int data = 0; data < 8; data++) add(new BaseBlock(205, data), new BaseBlock(182, 1));
|
||||
for (int data = 8; data < 16; data++) add(new BaseBlock(205, data), new BaseBlock(182, 9));
|
||||
for (int data = 0; data < 8; data++) add(new BaseBlock(182, data), new BaseBlock(182, 0));
|
||||
for (int data = 8; data < 16; data++) add(new BaseBlock(182, data), new BaseBlock(182, 8));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -142,6 +392,8 @@ public class ClipboardRemapper {
|
||||
add(to, from);
|
||||
}
|
||||
}
|
||||
|
||||
this.from = fromPlatform;
|
||||
}
|
||||
|
||||
public void addBoth(BaseBlock from, BaseBlock to) {
|
||||
@ -191,7 +443,6 @@ public class ClipboardRemapper {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public void add(BaseBlock from, BaseBlock to) {
|
||||
if (from.getData() != to.getData()) {
|
||||
if (from.getData() == -1) {
|
||||
@ -237,4 +488,7 @@ public class ClipboardRemapper {
|
||||
return block;
|
||||
}
|
||||
|
||||
public void remap(CompoundTag tag) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ItemWikiScraper {
|
||||
private static String PE = "https://minecraft.gamepedia.com/index.php?title=Bedrock_Edition_data_values&action=edit§ion=1";
|
||||
private static String PC = "https://minecraft.gamepedia.com/index.php?title=Java_Edition_data_values/Item_IDs&action=edit";
|
||||
|
||||
private Map<ClipboardRemapper.RemapPlatform, Map<String, Integer>> cache = new HashMap<>();
|
||||
|
||||
public Map<String, Integer> expand(Map<String, Integer> map) {
|
||||
HashMap<String, Integer> newMap = new HashMap<>(map);
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
newMap.put(entry.getKey().replace("_", ""), entry.getValue());
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
public synchronized Map<String, Integer> scapeOrCache(ClipboardRemapper.RemapPlatform platform) throws IOException {
|
||||
Map<String, Integer> map;
|
||||
try {
|
||||
Map<String, Integer> cached = cache.get(platform);
|
||||
if (cached != null) return cached;
|
||||
|
||||
File file = new File("lib" + File.separator + "items-" + platform.name().toLowerCase() + ".json");
|
||||
Gson gson = new Gson();
|
||||
if (file.exists()) {
|
||||
try {
|
||||
String str = Resources.toString(file.toURL(), Charset.defaultCharset());
|
||||
return gson.fromJson(str, new TypeToken<Map<String, Integer>>() {
|
||||
}.getType());
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
}
|
||||
map = scrape(platform);
|
||||
java.io.File parent = file.getParentFile();
|
||||
parent.mkdirs();
|
||||
file.createNewFile();
|
||||
Files.write(file.toPath(), gson.toJson(map).getBytes(), StandardOpenOption.CREATE);
|
||||
} catch (IOException e) {
|
||||
map = new HashMap<>();
|
||||
}
|
||||
cache.put(platform, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, Integer> scrape(ClipboardRemapper.RemapPlatform platform) throws IOException {
|
||||
Fawe.debug("Downloading item mappings for " + platform + ". Please wait...");
|
||||
String url = (platform == ClipboardRemapper.RemapPlatform.PC) ? PC : PE;
|
||||
String text = MainUtil.getText(url);
|
||||
|
||||
String header = "{{";
|
||||
String footer = "{{-}}";
|
||||
String prefix = "{{id table|";
|
||||
|
||||
HashMap<String, Integer> map = new HashMap<>();
|
||||
|
||||
int headerIndex = text.indexOf(header);
|
||||
if (headerIndex == -1) return map;
|
||||
int endIndex = text.indexOf(footer, headerIndex);
|
||||
String part = text.substring(headerIndex, endIndex == -1 ? text.length() : endIndex);
|
||||
|
||||
int id = 255;
|
||||
for (String line : part.split("\n")) {
|
||||
String lower = line.toLowerCase();
|
||||
if (lower.startsWith(prefix)) {
|
||||
line = line.substring(prefix.length(), line.indexOf("}}"));
|
||||
String[] split = line.split("\\|");
|
||||
String nameId = null;
|
||||
for (String entry : split) {
|
||||
String[] pair = entry.split("=");
|
||||
switch (pair[0].toLowerCase()) {
|
||||
case "dv":
|
||||
id = Integer.parseInt(pair[1]);
|
||||
break;
|
||||
case "nameid":
|
||||
nameId = pair[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nameId == null) nameId = split[0].toLowerCase().replace(' ', '_');
|
||||
map.put(nameId, id);
|
||||
}
|
||||
id++;
|
||||
}
|
||||
Fawe.debug("Download complete.");
|
||||
return map;
|
||||
}
|
||||
}
|
@ -47,13 +47,16 @@ import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -61,6 +64,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.zip.DataFormatException;
|
||||
@ -508,7 +512,28 @@ public class MainUtil {
|
||||
t.printStackTrace();
|
||||
throw new IOException("Error, could not add URL to system classloader");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getText(String url) throws IOException {
|
||||
try (Scanner scanner = new Scanner(new URL(url).openStream(), "UTF-8")) {
|
||||
return scanner.useDelimiter("\\A").next();
|
||||
}
|
||||
}
|
||||
|
||||
public static void download(URL url, File out) throws IOException {
|
||||
File parent = out.getParentFile();
|
||||
if (!out.exists()) {
|
||||
if (parent != null) parent.mkdirs();
|
||||
File tempFile = File.createTempFile(UUID.randomUUID().toString(), ".tmp", parent);
|
||||
tempFile.deleteOnExit();
|
||||
try (InputStream is = url.openStream()) {
|
||||
ReadableByteChannel rbc = Channels.newChannel(is);
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
Files.copy(tempFile.toPath(), out.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
tempFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,6 +73,16 @@ public final class NBTInputStream implements Closeable {
|
||||
return readNamedTag(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an NBT map from the stream.
|
||||
*
|
||||
* @return The map that was read.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public NamedData readNamedData() throws IOException {
|
||||
return readNamedData(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an NBT from the stream.
|
||||
*
|
||||
@ -85,6 +95,11 @@ public final class NBTInputStream implements Closeable {
|
||||
return new NamedTag(readNamedTagName(type), readTagPayload(type, depth));
|
||||
}
|
||||
|
||||
private NamedData readNamedData(int depth) throws IOException {
|
||||
int type = is.readByte();
|
||||
return new NamedData(readNamedTagName(type), readDataPayload(type, depth));
|
||||
}
|
||||
|
||||
public Tag readTag() throws IOException {
|
||||
int type = is.readByte();
|
||||
return readTagPayload(type, 0);
|
||||
@ -363,6 +378,79 @@ public final class NBTInputStream implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public Object readDataPayload(int type, int depth) throws IOException {
|
||||
switch (type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
if (depth == 0) {
|
||||
throw new IOException(
|
||||
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case NBTConstants.TYPE_BYTE:
|
||||
return is.readByte();
|
||||
case NBTConstants.TYPE_SHORT:
|
||||
return is.readShort();
|
||||
case NBTConstants.TYPE_INT:
|
||||
return is.readInt();
|
||||
case NBTConstants.TYPE_LONG:
|
||||
return is.readLong();
|
||||
case NBTConstants.TYPE_FLOAT:
|
||||
return is.readFloat();
|
||||
case NBTConstants.TYPE_DOUBLE:
|
||||
return is.readDouble();
|
||||
case NBTConstants.TYPE_BYTE_ARRAY:
|
||||
int length = is.readInt();
|
||||
byte[] bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return bytes;
|
||||
case NBTConstants.TYPE_STRING:
|
||||
length = is.readShort();
|
||||
bytes = new byte[length];
|
||||
is.readFully(bytes);
|
||||
return new String(bytes, NBTConstants.CHARSET);
|
||||
case NBTConstants.TYPE_LIST:
|
||||
int childType = is.readByte();
|
||||
if (childType == NBTConstants.TYPE_LIST) {
|
||||
childType = NBTConstants.TYPE_COMPOUND;
|
||||
}
|
||||
length = is.readInt();
|
||||
ArrayList<Object> list = new ArrayList<>();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
Object obj = readDataPayload(childType, depth + 1);
|
||||
if (obj == null) {
|
||||
throw new IOException("TAG_End not permitted in a list.");
|
||||
}
|
||||
list.add(obj);
|
||||
}
|
||||
|
||||
return list;
|
||||
case NBTConstants.TYPE_COMPOUND:
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
while (true) {
|
||||
int newType = is.readByte();
|
||||
String name = readNamedTagName(newType);
|
||||
Object data = readDataPayload(newType, depth + 1);
|
||||
if (data == null) {
|
||||
break;
|
||||
} else {
|
||||
map.put(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
case NBTConstants.TYPE_INT_ARRAY:
|
||||
length = is.readInt();
|
||||
int[] data = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
data[i] = is.readInt();
|
||||
}
|
||||
return data;
|
||||
default:
|
||||
throw new IOException("Invalid tag type: " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the payload of a tag given the type.
|
||||
*
|
||||
|
41
core/src/main/java/com/sk89q/jnbt/NamedData.java
Normal file
41
core/src/main/java/com/sk89q/jnbt/NamedData.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.sk89q.jnbt;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Some data with a name
|
||||
*/
|
||||
public class NamedData {
|
||||
private final String name;
|
||||
private final Object data;
|
||||
|
||||
/**
|
||||
* Create a new named tag.
|
||||
*
|
||||
* @param name the name
|
||||
* @param data the data
|
||||
*/
|
||||
public NamedData(String name, Object data) {
|
||||
checkNotNull(name);
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the tag.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tag.
|
||||
*
|
||||
* @return the tag
|
||||
*/
|
||||
public Object getValue() {
|
||||
return data;
|
||||
}
|
||||
}
|
@ -24,14 +24,9 @@ import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
@ -115,13 +110,17 @@ public class ConverterFrame extends JFrame {
|
||||
final JPanel mainContent = new InvisiblePanel(new BorderLayout());
|
||||
{
|
||||
File world = MainUtil.getWorkingDirectory("minecraft");
|
||||
long lastMod = Long.MIN_VALUE;
|
||||
if (world != null && world.exists()) {
|
||||
File saves = new File(world, "saves");
|
||||
if (saves.exists()) {
|
||||
for (File file : saves.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
world = file;
|
||||
break;
|
||||
long modified = file.lastModified();
|
||||
if (modified > lastMod) {
|
||||
world = file;
|
||||
lastMod = modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,7 +129,7 @@ public class ConverterFrame extends JFrame {
|
||||
final InteractiveButton browseLoadText = new InteractiveButton(world.getPath(), DARKER_GRAY) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
browseLoad.browse(new File(getText()));
|
||||
browseLoad.browse(new File(getText()).getParentFile());
|
||||
}
|
||||
};
|
||||
final InteractiveButton browseSaveText = new InteractiveButton(getDefaultOutput().getPath(), DARKER_GRAY) {
|
||||
@ -145,14 +144,14 @@ public class ConverterFrame extends JFrame {
|
||||
button.setOpaque(true);
|
||||
button.setBorder(new EmptyBorder(4, 4, 4, 4));
|
||||
}
|
||||
browseLoad = new BrowseButton() {
|
||||
browseLoad = new BrowseButton("_FROM") {
|
||||
@Override
|
||||
public void onSelect(File folder) {
|
||||
browseLoadText.setText(folder.getPath());
|
||||
movable.repaint();
|
||||
}
|
||||
};
|
||||
browseSave = new BrowseButton() {
|
||||
browseSave = new BrowseButton("_TO") {
|
||||
@Override
|
||||
public void onSelect(File folder) {
|
||||
browseSaveText.setText(folder.getPath());
|
||||
@ -325,21 +324,20 @@ public class ConverterFrame extends JFrame {
|
||||
FakePlayer console = FakePlayer.getConsole();
|
||||
try {
|
||||
debug("Loading leveldb.jar");
|
||||
File leveldb = new File("leveldb.jar");
|
||||
if (!leveldb.exists()) {
|
||||
File tempFile = File.createTempFile("leveldb.jar", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
String download = "https://github.com/boy0001/FastAsyncWorldedit/raw/master/nukkit/lib/leveldb.jar";
|
||||
debug("Downloading: " + download);
|
||||
URL url = new URL(download);
|
||||
try (InputStream is = url.openStream()) {
|
||||
ReadableByteChannel rbc = Channels.newChannel(is);
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
Files.copy(tempFile.toPath(), leveldb.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
tempFile.delete();
|
||||
}
|
||||
|
||||
File lib = new File("lib");
|
||||
File leveldb = new File(lib, "leveldb.jar");
|
||||
// File blocksPE = new File(lib, "blocks-pe.json");
|
||||
// File blocksPC = new File(lib, "blocks-pc.json");
|
||||
|
||||
URL levelDbUrl = new URL("https://git.io/vdZ9e");
|
||||
// URL urlPE = new URL("https://git.io/vdZSj");
|
||||
// URL urlPC = new URL("https://git.io/vdZSx");
|
||||
|
||||
MainUtil.download(levelDbUrl, leveldb);
|
||||
// MainUtil.download(urlPE, blocksPC);
|
||||
// MainUtil.download(urlPC, blocksPE);
|
||||
|
||||
MainUtil.loadURLClasspath(leveldb.toURL());
|
||||
|
||||
File newWorldFile = new File(output, dirMc.getName());
|
||||
|
@ -19,7 +19,7 @@ import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -27,10 +27,12 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -47,7 +49,7 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
public LevelDBToMCAFile(File from, File to) {
|
||||
super(from, to);
|
||||
try {
|
||||
BundledBlockData.getInstance().loadFromResource();
|
||||
// BundledBlockData.getInstance().loadFromResource();
|
||||
this.pool = new ForkJoinPool();
|
||||
this.remapper = new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PE, ClipboardRemapper.RemapPlatform.PC);
|
||||
int bufferSize = (int) Math.min(Integer.MAX_VALUE, Math.max((long) (MemUtil.getFreeBytes() * 0.8), 134217728));
|
||||
@ -98,7 +100,6 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
File levelDat = new File(folderFrom, "level.dat");
|
||||
copyLevelDat(levelDat);
|
||||
|
||||
|
||||
// Chunks
|
||||
MCAQueue queue = new MCAQueue(worldName, new File(worldOut, "region"), true);
|
||||
RemapFilter filter = new RemapFilter(this.remapper);
|
||||
@ -117,7 +118,7 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
MCAChunk chunk = (MCAChunk) queue.getFaweChunk(cx, cz);
|
||||
|
||||
switch (tag) {
|
||||
case Data2D:
|
||||
case Data2D: {
|
||||
// height
|
||||
ByteBuffer buffer = ByteBuffer.wrap(value);
|
||||
int[] heightArray = chunk.getHeightMapArray();
|
||||
@ -130,7 +131,8 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
System.arraycopy(value, biomeOffset, chunk.biomes, 0, chunk.biomes.length);
|
||||
}
|
||||
break;
|
||||
case SubChunkPrefix:
|
||||
}
|
||||
case SubChunkPrefix: {
|
||||
int layer = key[9];
|
||||
byte[] ids = getOrCreate(chunk.ids, layer, 4096);
|
||||
byte[] data = getOrCreate(chunk.data, layer, 2048);
|
||||
@ -144,15 +146,25 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
|
||||
chunk.filterBlocks(new MutableMCABackedBaseBlock(), filter);
|
||||
break;
|
||||
case BlockEntity:
|
||||
}
|
||||
case BlockEntity: {
|
||||
List<NamedTag> tags = read(value);
|
||||
for (NamedTag nt : tags) {
|
||||
com.sk89q.jnbt.Tag tile = nt.getTag();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Entity:
|
||||
List<NamedTag> tags = read(value);
|
||||
for (NamedTag nt : tags) {
|
||||
com.sk89q.jnbt.Tag ent = nt.getTag();
|
||||
// chunk.setEntity((CompoundTag) ent);
|
||||
}
|
||||
break;
|
||||
// Ignore
|
||||
case LegacyTerrain:
|
||||
case BiomeState:
|
||||
case Data2DLegacy:
|
||||
System.out.println("Legacy terrain not supported, please update.");
|
||||
Fawe.debug("Legacy terrain not supported, please update. " + tag);
|
||||
case BiomeState:
|
||||
case FinalizedState:
|
||||
case PendingTicks:
|
||||
case BlockExtraData:
|
||||
@ -167,10 +179,24 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
close();
|
||||
app.prompt("Compaction complete!");
|
||||
app.prompt("Conversion complete!");
|
||||
}
|
||||
}
|
||||
|
||||
private List<NamedTag> read(byte[] data) {
|
||||
ArrayList<NamedTag> list = new ArrayList<>();
|
||||
ByteArrayInputStream baos = new ByteArrayInputStream(data);
|
||||
try (NBTInputStream in = new NBTInputStream((DataInput) new LittleEndianDataInputStream(baos))) {
|
||||
while (baos.available() > 0) {
|
||||
NamedTag nt = in.readNamedTag();
|
||||
list.add(nt);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void copySection(byte[] dest, byte[] src, int srcPos) {
|
||||
if (src.length <= srcPos) return;
|
||||
switch (dest.length) {
|
||||
@ -240,8 +266,14 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
}
|
||||
|
||||
public void copyLevelDat(File in) throws IOException {
|
||||
copyLevelDat(this.folderTo, in);
|
||||
}
|
||||
|
||||
|
||||
public static void copyLevelDat(File folderTo, File in) throws IOException {
|
||||
File levelDat = new File(folderTo, "level.dat");
|
||||
if (!levelDat.exists()) {
|
||||
folderTo.mkdirs();
|
||||
levelDat.createNewFile();
|
||||
}
|
||||
try (LittleEndianDataInputStream ledis = new LittleEndianDataInputStream(new FileInputStream(in))) {
|
||||
@ -274,7 +306,9 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
if (value instanceof ByteTag) {
|
||||
value = new StringTag((Byte) value.getValue() == 1 ? "true" : "false");
|
||||
}
|
||||
ruleTagValue.put(rule.getValue(), value);
|
||||
if (value != null) {
|
||||
ruleTagValue.put(rule.getValue(), value);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<String> allowed = new HashSet<>(Arrays.asList(
|
||||
@ -284,7 +318,6 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, com.sk89q.jnbt.Tag> entry = iterator.next();
|
||||
if (!allowed.contains(entry.getKey())) {
|
||||
System.out.println("TODO (Unsupported): " + entry.getKey() + " | " + entry.getValue());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.FloatTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
@ -25,6 +27,7 @@ import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutput;
|
||||
@ -55,7 +58,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
||||
private final ByteStore keyStore9 = new ByteStore(9);
|
||||
private final ByteStore keyStore10 = new ByteStore(10);
|
||||
private final ByteStore bufData2D = new ByteStore(512 + 256);
|
||||
private final ByteStore bufSubChunkPrefix = new ByteStore(1 + 4096 + 2058 + 2048 + 2048);
|
||||
private final ByteStore bufSubChunkPrefix = new ByteStore(1 + 4096 + 2048 + 2048 + 2048);
|
||||
|
||||
private final byte[] VERSION = new byte[] { 4 };
|
||||
private final byte[] COMPLETE_STATE = new byte[] { 2, 0, 0, 0 };
|
||||
@ -274,7 +277,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
||||
List<com.sk89q.jnbt.Tag> tiles = new ArrayList<>();
|
||||
for (Map.Entry<Short, CompoundTag> entry : chunk.getTiles().entrySet()) {
|
||||
CompoundTag tag = entry.getValue();
|
||||
tiles.add(transform(tag));
|
||||
tiles.add(transform(chunk, tag));
|
||||
}
|
||||
update(getKey(chunk, Tag.BlockEntity), write(tiles));
|
||||
}
|
||||
@ -282,7 +285,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
||||
if (!chunk.entities.isEmpty()) {
|
||||
List<com.sk89q.jnbt.Tag> entities = new ArrayList<>();
|
||||
for (com.sk89q.jnbt.CompoundTag tag : chunk.getEntities()) {
|
||||
entities.add(transform(tag));
|
||||
entities.add(transform(chunk, tag));
|
||||
}
|
||||
update(getKey(chunk, Tag.Entity), write(entities));
|
||||
}
|
||||
@ -399,42 +402,71 @@ public class MCAFile2LevelDB extends MapConverter {
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
private String convertId(String input) {
|
||||
input = input.replace("minecraft:", "");
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean toUpper = false;
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
if (i == 0) toUpper = true;
|
||||
if (c == '_') {
|
||||
toUpper = true;
|
||||
} else {
|
||||
result.append(toUpper ? Character.toUpperCase(c) : c);
|
||||
toUpper = false;
|
||||
private CompoundTag transformItem(CompoundTag item) {
|
||||
String itemId = item.getString("id");
|
||||
short damage = item.getShort("Damage");
|
||||
BaseBlock remapped = remapper.remapItem(itemId, damage);
|
||||
Map<String, com.sk89q.jnbt.Tag> map = ReflectionUtils.getMap(item.getValue());
|
||||
map.put("id", new ShortTag((short) remapped.getId()));
|
||||
map.put("Damage", new ShortTag((short) remapped.getData()));
|
||||
|
||||
CompoundTag tag = (CompoundTag) item.getValue().get("tag");
|
||||
if (tag != null) {
|
||||
List<CompoundTag> enchants = (List) tag.getList("ench");
|
||||
if (enchants != null) {
|
||||
for (CompoundTag ench : enchants) {
|
||||
Map<String, com.sk89q.jnbt.Tag> value = ReflectionUtils.getMap(ench.getValue());
|
||||
String id = ench.getString("id");
|
||||
String lvl = ench.getString("lvl");
|
||||
if (id != null) value.put("id", new ShortTag(Short.parseShort(id)));
|
||||
if (id != null) value.put("lvl", new ShortTag(Short.parseShort(id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
return item;
|
||||
}
|
||||
|
||||
private CompoundTag transform(CompoundTag tag) {
|
||||
private CompoundTag transform(MCAChunk chunk, CompoundTag tag) {
|
||||
try {
|
||||
String id = tag.getString("id");
|
||||
if (id != null) {
|
||||
Map<String, com.sk89q.jnbt.Tag> map = ReflectionUtils.getMap(tag.getValue());
|
||||
id = convertId(id);
|
||||
id = remapper.remapEntityId(id);
|
||||
map.put("id", new StringTag(id));
|
||||
{ // Convert items
|
||||
com.sk89q.jnbt.ListTag items = tag.getListTag("Items");
|
||||
for (CompoundTag item : (List<CompoundTag>) (List) items.getValue()) {
|
||||
String itemId = item.getString("id");
|
||||
BaseBlock state = BundledBlockData.getInstance().findByState(itemId);
|
||||
if (state != null) {
|
||||
int legacy = state.getId();
|
||||
ReflectionUtils.getMap(item.getValue()).put("id", new ShortTag((short) legacy));
|
||||
((List<CompoundTag>) (List) items.getValue()).forEach(this::transformItem);
|
||||
}
|
||||
{ // Convert item
|
||||
String item = tag.getString("Item");
|
||||
if (item != null) {
|
||||
short damage = tag.getShort("Data");
|
||||
BaseBlock remapped = remapper.remapItem(item, damage);
|
||||
map.put("Item", new ShortTag((short) remapped.getId()));
|
||||
map.put("mData", new IntTag(remapped.getData()));
|
||||
}
|
||||
}
|
||||
{ // Health
|
||||
com.sk89q.jnbt.Tag health = map.get("Health");
|
||||
if (health != null && health instanceof FloatTag) {
|
||||
map.put("Health", new ShortTag((short) tag.getFloat("Health")));
|
||||
}
|
||||
}
|
||||
{ // Orientation / Position
|
||||
for (String key : new String[] {"Orientation", "Position"}) {
|
||||
ListTag list = (ListTag) map.get(key);
|
||||
if (list != null) {
|
||||
List<com.sk89q.jnbt.Tag> value = list.getValue();
|
||||
ArrayList<FloatTag> newList = new ArrayList<>();
|
||||
for (com.sk89q.jnbt.Tag coord : value) {
|
||||
newList.add(new FloatTag(((Number) coord.getValue()).floatValue()));
|
||||
}
|
||||
map.put(key, new ListTag(FloatTag.class, newList));
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (id) {
|
||||
case "EndGateway":
|
||||
case "MobSpawner": {
|
||||
map.clear();
|
||||
break;
|
||||
@ -446,8 +478,30 @@ public class MCAFile2LevelDB extends MapConverter {
|
||||
if (text != null && text.startsWith("{")) {
|
||||
map.put(key, new StringTag(BBC.jsonToString(text)));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CommandBlock": {
|
||||
int x = tag.getInt("x");
|
||||
int y = tag.getInt("y");
|
||||
int z = tag.getInt("z");
|
||||
|
||||
map.put("Version", new IntTag(3));
|
||||
BaseBlock block = chunk.getBlock(x & 15, y, z & 15);
|
||||
int LPCommandMode = 0;
|
||||
switch (block.getId()) {
|
||||
case BlockID.CHAIN_COMMAND_BLOCK:
|
||||
LPCommandMode = 2;
|
||||
break;
|
||||
case BlockID.REPEATING_COMMAND_BLOCK:
|
||||
LPCommandMode = 1;
|
||||
break;
|
||||
}
|
||||
map.putIfAbsent("isMovable", new ByteTag((byte) 1));
|
||||
map.put("LPCommandMode", new IntTag(LPCommandMode));
|
||||
map.put("LPCondionalMode", new ByteTag((byte) (block.getData() > 7 ? 1 : 0)));
|
||||
map.put("LPRedstoneMode", new ByteTag(tag.getByte("auto")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user