Progress, lower memory usage
This commit is contained in:
parent
911f613f2f
commit
b2395f7aa9
@ -1,7 +1,6 @@
|
|||||||
package com.boydti.fawe.object.clipboard;
|
package com.boydti.fawe.object.clipboard;
|
||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
import com.google.common.reflect.TypeToken;
|
import com.google.common.reflect.TypeToken;
|
||||||
@ -58,7 +57,6 @@ public class ItemWikiScraper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Integer> scrape(ClipboardRemapper.RemapPlatform platform) throws IOException {
|
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 url = (platform == ClipboardRemapper.RemapPlatform.PC) ? PC : PE;
|
||||||
String text = MainUtil.getText(url);
|
String text = MainUtil.getText(url);
|
||||||
|
|
||||||
@ -96,7 +94,6 @@ public class ItemWikiScraper {
|
|||||||
}
|
}
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
Fawe.debug("Download complete.");
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
409
core/src/main/java/com/sk89q/jnbt/CompoundTag.java
Normal file
409
core/src/main/java/com/sk89q/jnbt/CompoundTag.java
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code TAG_Compound} tag.
|
||||||
|
*/
|
||||||
|
public final class CompoundTag extends Tag {
|
||||||
|
|
||||||
|
private final Map<String, Tag> value;
|
||||||
|
/**
|
||||||
|
* Creates the tag with an empty name.
|
||||||
|
*
|
||||||
|
* @param value the value of the tag
|
||||||
|
*/
|
||||||
|
public CompoundTag(Map<String, Tag> value) {
|
||||||
|
super();
|
||||||
|
this.value = Collections.unmodifiableMap(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getRaw() {
|
||||||
|
HashMap<String, Object> raw = new HashMap<>();
|
||||||
|
for (Map.Entry<String, Tag> entry : value.entrySet()) {
|
||||||
|
raw.put(entry.getKey(), entry.getValue().getRaw());
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this compound tag contains the given key.
|
||||||
|
*
|
||||||
|
* @param key the given key
|
||||||
|
* @return true if the tag contains the given key
|
||||||
|
*/
|
||||||
|
public boolean containsKey(String key) {
|
||||||
|
return value.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Tag> getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new compound tag with the given values.
|
||||||
|
*
|
||||||
|
* @param value the value
|
||||||
|
* @return the new compound tag
|
||||||
|
*/
|
||||||
|
public CompoundTag setValue(Map<String, Tag> value) {
|
||||||
|
return new CompoundTag(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a compound tag builder.
|
||||||
|
*
|
||||||
|
* @return the builder
|
||||||
|
*/
|
||||||
|
public CompoundTagBuilder createBuilder() {
|
||||||
|
return new CompoundTagBuilder(new HashMap<String, Tag>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a byte array named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a byte array tag,
|
||||||
|
* then an empty byte array will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a byte array
|
||||||
|
*/
|
||||||
|
public byte[] getByteArray(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ByteArrayTag) {
|
||||||
|
return ((ByteArrayTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a byte named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a byte tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a byte
|
||||||
|
*/
|
||||||
|
public byte getByte(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return (byte) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a double named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a double tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
public double getDouble(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a double named with the given key, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
public double asDouble(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a float named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a float tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a float
|
||||||
|
*/
|
||||||
|
public float getFloat(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@code int[]} named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not an int array tag,
|
||||||
|
* then an empty array will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return an int array
|
||||||
|
*/
|
||||||
|
public int[] getIntArray(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof IntArrayTag) {
|
||||||
|
return ((IntArrayTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an int named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not an int tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
public int getInt(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an int named with the given key, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
public int asInt(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of tags named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a list tag,
|
||||||
|
* then an empty list will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a list of tags
|
||||||
|
*/
|
||||||
|
public List<Tag> getList(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
return ((ListTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@code TagList} named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a list tag,
|
||||||
|
* then an empty tag list will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a tag list instance
|
||||||
|
*/
|
||||||
|
public ListTag getListTag(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
return (ListTag) tag;
|
||||||
|
} else {
|
||||||
|
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of tags named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a list tag,
|
||||||
|
* then an empty list will be returned. If the given key references
|
||||||
|
* a list but the list of of a different type, then an empty
|
||||||
|
* list will also be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @param listType the class of the contained type
|
||||||
|
* @return a list of tags
|
||||||
|
* @param <T> the type of list
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
ListTag listTag = (ListTag) tag;
|
||||||
|
if (listTag.getType().equals(listType)) {
|
||||||
|
return (List<T>) listTag.getValue();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a long tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
public long getLong(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long named with the given key, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
public long asLong(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue().longValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue().longValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a short named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a short tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a short
|
||||||
|
*/
|
||||||
|
public short getShort(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string named with the given key.
|
||||||
|
*
|
||||||
|
* <p>If the key does not exist or its value is not a string tag,
|
||||||
|
* then {@code ""} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param key the key
|
||||||
|
* @return a string
|
||||||
|
*/
|
||||||
|
public String getString(String key) {
|
||||||
|
Tag tag = value.get(key);
|
||||||
|
if (tag instanceof StringTag) {
|
||||||
|
return ((StringTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder bldr = new StringBuilder();
|
||||||
|
bldr.append("TAG_Compound").append(": ").append(value.size()).append(" entries\r\n{\r\n");
|
||||||
|
for (Map.Entry<String, Tag> entry : value.entrySet()) {
|
||||||
|
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
|
||||||
|
}
|
||||||
|
bldr.append("}");
|
||||||
|
return bldr.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
422
core/src/main/java/com/sk89q/jnbt/ListTag.java
Normal file
422
core/src/main/java/com/sk89q/jnbt/ListTag.java
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code TAG_List} tag.
|
||||||
|
*/
|
||||||
|
public final class ListTag extends Tag {
|
||||||
|
|
||||||
|
private final Class<? extends Tag> type;
|
||||||
|
private final List<Tag> value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the tag with an empty name.
|
||||||
|
*
|
||||||
|
* @param type the type of tag
|
||||||
|
* @param value the value of the tag
|
||||||
|
*/
|
||||||
|
public ListTag(Class<? extends Tag> type, List<? extends Tag> value) {
|
||||||
|
super();
|
||||||
|
checkNotNull(value);
|
||||||
|
this.type = type;
|
||||||
|
this.value = Collections.unmodifiableList(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> getRaw() {
|
||||||
|
ArrayList<Object> raw = new ArrayList<>();
|
||||||
|
for (Tag t : value) {
|
||||||
|
raw.add(t.getRaw());
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of item in this list.
|
||||||
|
*
|
||||||
|
* @return The type of item in this list.
|
||||||
|
*/
|
||||||
|
public Class<? extends Tag> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tag> getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new list tag with this tag's name and type.
|
||||||
|
*
|
||||||
|
* @param list the new list
|
||||||
|
* @return a new list tag
|
||||||
|
*/
|
||||||
|
public ListTag setValue(List<Tag> list) {
|
||||||
|
return new ListTag(getType(), list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tag if it exists at the given index.
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return the tag or null
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Tag getIfExists(int index) {
|
||||||
|
try {
|
||||||
|
return value.get(index);
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a byte array named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a byte array tag,
|
||||||
|
* then an empty byte array will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a byte array
|
||||||
|
*/
|
||||||
|
public byte[] getByteArray(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ByteArrayTag) {
|
||||||
|
return ((ByteArrayTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a byte named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a byte tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a byte
|
||||||
|
*/
|
||||||
|
public byte getByte(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return (byte) 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a double named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a double tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
public double getDouble(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a double named with the given index, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
public double asDouble(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a float named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a float tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a float
|
||||||
|
*/
|
||||||
|
public float getFloat(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@code int[]} named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not an int array tag,
|
||||||
|
* then an empty array will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return an int array
|
||||||
|
*/
|
||||||
|
public int[] getIntArray(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof IntArrayTag) {
|
||||||
|
return ((IntArrayTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an int named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not an int tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
public int getInt(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an int named with the given index, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
public int asInt(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue().intValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of tags named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a list tag,
|
||||||
|
* then an empty list will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a list of tags
|
||||||
|
*/
|
||||||
|
public List<Tag> getList(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
return ((ListTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@code TagList} named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a list tag,
|
||||||
|
* then an empty tag list will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a tag list instance
|
||||||
|
*/
|
||||||
|
public ListTag getListTag(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
return (ListTag) tag;
|
||||||
|
} else {
|
||||||
|
return new ListTag(StringTag.class, Collections.<Tag>emptyList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of tags named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a list tag,
|
||||||
|
* then an empty list will be returned. If the given index references
|
||||||
|
* a list but the list of of a different type, then an empty
|
||||||
|
* list will also be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @param listType the class of the contained type
|
||||||
|
* @return a list of tags
|
||||||
|
* @param <T> the NBT type
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends Tag> List<T> getList(int index, Class<T> listType) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ListTag) {
|
||||||
|
ListTag listTag = (ListTag) tag;
|
||||||
|
if (listTag.getType().equals(listType)) {
|
||||||
|
return (List<T>) listTag.getValue();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a long tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
public long getLong(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a long named with the given index, even if it's another
|
||||||
|
* type of number.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a number,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
public long asLong(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ByteTag) {
|
||||||
|
return ((ByteTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof IntTag) {
|
||||||
|
return ((IntTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof LongTag) {
|
||||||
|
return ((LongTag) tag).getValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof FloatTag) {
|
||||||
|
return ((FloatTag) tag).getValue().longValue();
|
||||||
|
|
||||||
|
} else if (tag instanceof DoubleTag) {
|
||||||
|
return ((DoubleTag) tag).getValue().longValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a short named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a short tag,
|
||||||
|
* then {@code 0} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a short
|
||||||
|
*/
|
||||||
|
public short getShort(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof ShortTag) {
|
||||||
|
return ((ShortTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string named with the given index.
|
||||||
|
*
|
||||||
|
* <p>If the index does not exist or its value is not a string tag,
|
||||||
|
* then {@code ""} will be returned.</p>
|
||||||
|
*
|
||||||
|
* @param index the index
|
||||||
|
* @return a string
|
||||||
|
*/
|
||||||
|
public String getString(int index) {
|
||||||
|
Tag tag = getIfExists(index);
|
||||||
|
if (tag instanceof StringTag) {
|
||||||
|
return ((StringTag) tag).getValue();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder bldr = new StringBuilder();
|
||||||
|
bldr.append("TAG_List").append(": ").append(value.size()).append(" entries of type ").append(NBTUtils.getTypeName(type)).append("\r\n{\r\n");
|
||||||
|
for (Tag t : value) {
|
||||||
|
bldr.append(" ").append(t.toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
|
||||||
|
}
|
||||||
|
bldr.append("}");
|
||||||
|
return bldr.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
core/src/main/java/com/sk89q/jnbt/Tag.java
Normal file
38
core/src/main/java/com/sk89q/jnbt/Tag.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a NBT tag.
|
||||||
|
*/
|
||||||
|
public abstract class Tag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of this tag.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
*/
|
||||||
|
public abstract Object getValue();
|
||||||
|
|
||||||
|
public Object getRaw() {
|
||||||
|
return getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
@ -11,6 +11,8 @@ import com.boydti.fawe.installer.MinimizeButton;
|
|||||||
import com.boydti.fawe.installer.MovablePanel;
|
import com.boydti.fawe.installer.MovablePanel;
|
||||||
import com.boydti.fawe.installer.TextAreaOutputStream;
|
import com.boydti.fawe.installer.TextAreaOutputStream;
|
||||||
import com.boydti.fawe.installer.URLButton;
|
import com.boydti.fawe.installer.URLButton;
|
||||||
|
import com.boydti.fawe.object.clipboard.ClipboardRemapper;
|
||||||
|
import com.boydti.fawe.object.clipboard.ItemWikiScraper;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.wrappers.FakePlayer;
|
import com.boydti.fawe.wrappers.FakePlayer;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
@ -30,6 +32,10 @@ import java.net.URL;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@ -37,13 +43,17 @@ import javax.swing.JFrame;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
public class ConverterFrame extends JFrame {
|
public class ConverterFrame extends JFrame {
|
||||||
private final InvisiblePanel loggerPanel;
|
private final InvisiblePanel loggerPanel;
|
||||||
|
private final JProgressBar progressBar;
|
||||||
private Color LIGHT_GRAY = new Color(0x66, 0x66, 0x66);
|
private Color LIGHT_GRAY = new Color(0x66, 0x66, 0x66);
|
||||||
private Color GRAY = new Color(0x44, 0x44, 0x46);
|
private Color GRAY = new Color(0x44, 0x44, 0x46);
|
||||||
private Color DARK_GRAY = new Color(0x33, 0x33, 0x36);
|
private Color DARK_GRAY = new Color(0x33, 0x33, 0x36);
|
||||||
@ -56,6 +66,8 @@ public class ConverterFrame extends JFrame {
|
|||||||
private BrowseButton browseSave;
|
private BrowseButton browseSave;
|
||||||
|
|
||||||
public ConverterFrame() throws Exception {
|
public ConverterFrame() throws Exception {
|
||||||
|
async(() -> downloadDependencies());
|
||||||
|
|
||||||
final MovablePanel movable = new MovablePanel(this);
|
final MovablePanel movable = new MovablePanel(this);
|
||||||
movable.setBorder(BorderFactory.createLineBorder(new Color(0x28, 0x28, 0x29)));
|
movable.setBorder(BorderFactory.createLineBorder(new Color(0x28, 0x28, 0x29)));
|
||||||
|
|
||||||
@ -69,23 +81,27 @@ public class ConverterFrame extends JFrame {
|
|||||||
int y = (int) ((dimension.getHeight() - this.getHeight()) / 2);
|
int y = (int) ((dimension.getHeight() - this.getHeight()) / 2);
|
||||||
this.setLocation(x, y);
|
this.setLocation(x, y);
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
this.setOpacity(0);
|
|
||||||
|
if (this.transparency(0)) {
|
||||||
|
fadeIn();
|
||||||
|
}
|
||||||
|
|
||||||
movable.setBackground(DARK_GRAY);
|
movable.setBackground(DARK_GRAY);
|
||||||
movable.setLayout(new BorderLayout());
|
movable.setLayout(new BorderLayout());
|
||||||
|
|
||||||
fadeIn();
|
|
||||||
|
|
||||||
JPanel topBar = new InvisiblePanel(new BorderLayout());
|
JPanel topBar = new InvisiblePanel(new BorderLayout());
|
||||||
{
|
{
|
||||||
JPanel topBarLeft = new InvisiblePanel();
|
JPanel topBarLeft = new InvisiblePanel();
|
||||||
JPanel topBarCenter = new InvisiblePanel();
|
JPanel topBarCenter = new InvisiblePanel();
|
||||||
JPanel topBarRight = new InvisiblePanel();
|
JPanel topBarRight = new InvisiblePanel();
|
||||||
|
|
||||||
JLabel title = new JLabel("(FAWE) Anvil and LevelDB converter");
|
JLabel title = new JLabel();
|
||||||
title.setHorizontalAlignment(SwingConstants.CENTER);
|
title.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
title.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
title.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
title.setForeground(Color.LIGHT_GRAY);
|
title.setForeground(Color.LIGHT_GRAY);
|
||||||
|
title.setText("(FAWE) Anvil and LevelDB converter");
|
||||||
title.setFont(new Font("Lucida Sans Unicode", Font.PLAIN, 15));
|
title.setFont(new Font("Lucida Sans Unicode", Font.PLAIN, 15));
|
||||||
|
setTitle(null);
|
||||||
|
|
||||||
MinimizeButton minimize = new MinimizeButton(this);
|
MinimizeButton minimize = new MinimizeButton(this);
|
||||||
CloseButton exit = new CloseButton();
|
CloseButton exit = new CloseButton();
|
||||||
@ -195,8 +211,7 @@ public class ConverterFrame extends JFrame {
|
|||||||
installContent.add(install);
|
installContent.add(install);
|
||||||
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
|
installContent.setBorder(new EmptyBorder(10, 0, 10, 0));
|
||||||
this.loggerPanel = new InvisiblePanel(new BorderLayout());
|
this.loggerPanel = new InvisiblePanel(new BorderLayout());
|
||||||
this.loggerPanel.setBackground(Color.GREEN);
|
loggerPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 380));
|
||||||
loggerPanel.setPreferredSize(new Dimension(416, 442));
|
|
||||||
loggerTextArea = new JTextArea();
|
loggerTextArea = new JTextArea();
|
||||||
loggerTextArea.setBackground(Color.GRAY);
|
loggerTextArea.setBackground(Color.GRAY);
|
||||||
loggerTextArea.setForeground(Color.DARK_GRAY);
|
loggerTextArea.setForeground(Color.DARK_GRAY);
|
||||||
@ -208,10 +223,22 @@ public class ConverterFrame extends JFrame {
|
|||||||
loggerPanel.add(scroll);
|
loggerPanel.add(scroll);
|
||||||
loggerPanel.setVisible(false);
|
loggerPanel.setVisible(false);
|
||||||
|
|
||||||
|
this.progressBar = new JProgressBar();
|
||||||
|
progressBar.setVisible(false);
|
||||||
|
progressBar.setStringPainted(true);
|
||||||
|
progressBar.setBackground(DARK_GRAY);
|
||||||
|
progressBar.setForeground(OFF_WHITE);
|
||||||
|
|
||||||
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
|
mainContent.setBorder(new EmptyBorder(6, 32, 6, 32));
|
||||||
mainContent.add(browseContent, BorderLayout.NORTH);
|
mainContent.add(browseContent, BorderLayout.NORTH);
|
||||||
mainContent.add(installContent, BorderLayout.CENTER);
|
mainContent.add(installContent, BorderLayout.CENTER);
|
||||||
mainContent.add(loggerPanel, BorderLayout.SOUTH);
|
|
||||||
|
final JPanel console = new InvisiblePanel(new BorderLayout());
|
||||||
|
console.setBorder(new EmptyBorder(6, 0, 6, 0));
|
||||||
|
console.add(progressBar, BorderLayout.SOUTH);
|
||||||
|
console.add(loggerPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
mainContent.add(console, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
JPanel bottomBar = new InvisiblePanel();
|
JPanel bottomBar = new InvisiblePanel();
|
||||||
{
|
{
|
||||||
@ -270,6 +297,47 @@ public class ConverterFrame extends JFrame {
|
|||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prompt(String message) {
|
||||||
|
JOptionPane.showMessageDialog(null, message);
|
||||||
|
Fawe.debug(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(String m) {
|
||||||
|
System.out.println(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(String text, int percent) {
|
||||||
|
Border border = BorderFactory.createTitledBorder(new EmptyBorder(0, 0, 0, 0), "Time remaining: " + text, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Lucida Sans Unicode",Font.PLAIN,12), OFF_WHITE);
|
||||||
|
progressBar.setVisible(true);
|
||||||
|
progressBar.setBorder(border);
|
||||||
|
progressBar.setValue(percent);
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fadeIn() {
|
||||||
|
async(() -> {
|
||||||
|
for (float i = 0; i <= 1.015; i += 0.016) {
|
||||||
|
if (!transparency(Math.min(1, i))) return;
|
||||||
|
try {
|
||||||
|
Thread.sleep(16);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (UnsupportedOperationException ignore) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean transparency(float val) {
|
||||||
|
try {
|
||||||
|
super.setOpacity(val);
|
||||||
|
return true;
|
||||||
|
} catch (UnsupportedOperationException ignore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private File getDefaultOutput() {
|
private File getDefaultOutput() {
|
||||||
if (MainUtil.getPlatform() == MainUtil.OS.WINDOWS) {
|
if (MainUtil.getPlatform() == MainUtil.OS.WINDOWS) {
|
||||||
String applicationData = System.getenv("APPDATA");
|
String applicationData = System.getenv("APPDATA");
|
||||||
@ -281,16 +349,61 @@ public class ConverterFrame extends JFrame {
|
|||||||
return new File(".");
|
return new File(".");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prompt(String message) {
|
private void async(Runnable r) {
|
||||||
JOptionPane.showMessageDialog(null, message);
|
new Thread(r).start();
|
||||||
Fawe.debug(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(String m) {
|
private AtomicBoolean dependenciesLoaded = new AtomicBoolean(false);
|
||||||
System.out.println(m);
|
private void downloadDependencies() {
|
||||||
|
synchronized (dependenciesLoaded) {
|
||||||
|
if (dependenciesLoaded.get()) return;
|
||||||
|
try {
|
||||||
|
ExecutorService pool = Executors.newCachedThreadPool();
|
||||||
|
ItemWikiScraper scraper = new ItemWikiScraper();
|
||||||
|
|
||||||
|
File lib = new File("lib");
|
||||||
|
File leveldb = new File(lib, "leveldb_v1.jar");
|
||||||
|
URL levelDbUrl = new URL("https://git.io/vdZ9e");
|
||||||
|
|
||||||
|
pool.submit((Runnable) () -> {
|
||||||
|
try {
|
||||||
|
MainUtil.download(levelDbUrl, leveldb);
|
||||||
|
MainUtil.loadURLClasspath(leveldb.toURL());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pool.submit((Runnable) () -> {
|
||||||
|
try {
|
||||||
|
scraper.scapeOrCache(ClipboardRemapper.RemapPlatform.PE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pool.submit((Runnable) () -> {
|
||||||
|
try {
|
||||||
|
scraper.scapeOrCache(ClipboardRemapper.RemapPlatform.PC);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pool.shutdown();
|
||||||
|
try {
|
||||||
|
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
dependenciesLoaded.set(true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void install(String input, String output) throws Exception {
|
private void install(String input, String output) throws Exception {
|
||||||
if (!loggerPanel.isVisible()) {
|
if (!loggerPanel.isVisible()) {
|
||||||
loggerPanel.setVisible(true);
|
loggerPanel.setVisible(true);
|
||||||
this.repaint();
|
this.repaint();
|
||||||
@ -324,30 +437,10 @@ public class ConverterFrame extends JFrame {
|
|||||||
public void run() {
|
public void run() {
|
||||||
FakePlayer console = FakePlayer.getConsole();
|
FakePlayer console = FakePlayer.getConsole();
|
||||||
try {
|
try {
|
||||||
debug("Loading leveldb.jar");
|
debug("Downloading levedb.jar and mappings (~4MB), please wait...");
|
||||||
|
downloadDependencies();
|
||||||
File lib = new File("lib");
|
|
||||||
|
|
||||||
File leveldb = new File(lib, "leveldb.jar");
|
|
||||||
URL levelDbUrl = new URL("https://git.io/vdZ9e");
|
|
||||||
|
|
||||||
|
|
||||||
// File blocksPE = new File(lib, "blocks-pe.json");
|
|
||||||
// File blocksPC = new File(lib, "blocks-pc.json");
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
|
|
||||||
debug("Starting converter...");
|
debug("Starting converter...");
|
||||||
|
File newWorldFile = new File(output, dirMc.getName());
|
||||||
MapConverter converter = MapConverter.get(dirMc, newWorldFile);
|
MapConverter converter = MapConverter.get(dirMc, newWorldFile);
|
||||||
converter.accept(ConverterFrame.this);
|
converter.accept(ConverterFrame.this);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -355,28 +448,13 @@ public class ConverterFrame extends JFrame {
|
|||||||
prompt("[ERROR] Conversion failed, you will have to do it manually (Nukkit server + anvil2leveldb command)");
|
prompt("[ERROR] Conversion failed, you will have to do it manually (Nukkit server + anvil2leveldb command)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
System.gc();
|
||||||
|
System.gc();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
installThread.start();
|
installThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fadeIn() {
|
|
||||||
Thread thread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (float i = 0; i <= 1.015; i += 0.016) {
|
|
||||||
ConverterFrame.this.setOpacity(Math.min(1, i));
|
|
||||||
try {
|
|
||||||
Thread.sleep(16);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
ConverterFrame window = new ConverterFrame();
|
ConverterFrame window = new ConverterFrame();
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import com.boydti.fawe.object.RunnableVal;
|
|||||||
import com.boydti.fawe.object.clipboard.ClipboardRemapper;
|
import com.boydti.fawe.object.clipboard.ClipboardRemapper;
|
||||||
import com.boydti.fawe.object.io.LittleEndianOutputStream;
|
import com.boydti.fawe.object.io.LittleEndianOutputStream;
|
||||||
import com.boydti.fawe.object.number.MutableLong;
|
import com.boydti.fawe.object.number.MutableLong;
|
||||||
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.boydti.fawe.util.StringMan;
|
import com.boydti.fawe.util.StringMan;
|
||||||
@ -52,6 +53,7 @@ import java.util.concurrent.ForkJoinPool;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import org.iq80.leveldb.CompressionType;
|
||||||
import org.iq80.leveldb.DB;
|
import org.iq80.leveldb.DB;
|
||||||
import org.iq80.leveldb.Options;
|
import org.iq80.leveldb.Options;
|
||||||
import org.iq80.leveldb.WriteBatch;
|
import org.iq80.leveldb.WriteBatch;
|
||||||
@ -61,16 +63,22 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
private final byte[] VERSION = new byte[] { 4 };
|
private final byte[] VERSION = new byte[] { 4 };
|
||||||
private final byte[] COMPLETE_STATE = new byte[] { 2, 0, 0, 0 };
|
private final byte[] COMPLETE_STATE = new byte[] { 2, 0, 0, 0 };
|
||||||
|
|
||||||
private DB db;
|
private final DB db;
|
||||||
private final ClipboardRemapper remapper;
|
private final ClipboardRemapper remapper;
|
||||||
private final ForkJoinPool pool;
|
private final ForkJoinPool pool;
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
private LongAdder submitted = new LongAdder();
|
private LongAdder submittedChunks = new LongAdder();
|
||||||
|
private LongAdder submittedFiles = new LongAdder();
|
||||||
|
|
||||||
|
private LongAdder totalOperations = new LongAdder();
|
||||||
|
private long estimatedOperations;
|
||||||
|
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
private boolean remap;
|
private boolean remap;
|
||||||
|
|
||||||
|
private final long startTime;
|
||||||
|
private ConverterFrame app;
|
||||||
|
|
||||||
private ConcurrentLinkedQueue<CompoundTag> portals = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<CompoundTag> portals = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
private ConcurrentHashMap<Thread, WriteBatch> batches = new ConcurrentHashMap<Thread, WriteBatch>() {
|
private ConcurrentHashMap<Thread, WriteBatch> batches = new ConcurrentHashMap<Thread, WriteBatch>() {
|
||||||
@ -79,7 +87,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
public WriteBatch get(Object key) {
|
public WriteBatch get(Object key) {
|
||||||
WriteBatch value = super.get(key);
|
WriteBatch value = super.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
synchronized (batches) {
|
synchronized (MCAFile2LevelDB.this) {
|
||||||
synchronized (Thread.currentThread()) {
|
synchronized (Thread.currentThread()) {
|
||||||
value = db.createWriteBatch();
|
value = db.createWriteBatch();
|
||||||
put((Thread) key, value);
|
put((Thread) key, value);
|
||||||
@ -92,6 +100,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
|
|
||||||
public MCAFile2LevelDB(File folderFrom, File folderTo) {
|
public MCAFile2LevelDB(File folderFrom, File folderTo) {
|
||||||
super(folderFrom, folderTo);
|
super(folderFrom, folderTo);
|
||||||
|
this.startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
if (!folderTo.exists()) {
|
if (!folderTo.exists()) {
|
||||||
folderTo.mkdirs();
|
folderTo.mkdirs();
|
||||||
@ -104,15 +113,61 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
this.pool = new ForkJoinPool();
|
this.pool = new ForkJoinPool();
|
||||||
this.remapper = new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE);
|
this.remapper = new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE);
|
||||||
BundledBlockData.getInstance().loadFromResource();
|
BundledBlockData.getInstance().loadFromResource();
|
||||||
flush(true);
|
|
||||||
|
int bufferSize = (int) Math.min(Integer.MAX_VALUE, Math.max((long) (MemUtil.getFreeBytes() * 0.8), 134217728));
|
||||||
|
this.db = Iq80DBFactory.factory.open(new File(folderTo, "db"),
|
||||||
|
new Options()
|
||||||
|
.createIfMissing(true)
|
||||||
|
.verifyChecksums(false)
|
||||||
|
.compressionType(CompressionType.ZLIB)
|
||||||
|
.blockSize(262144) // 256K
|
||||||
|
.cacheSize(8388608) // 8MB
|
||||||
|
.writeBufferSize(134217728) // >=512MB
|
||||||
|
);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush(boolean openDB) throws IOException {
|
private double lastPercent;
|
||||||
|
private double lastTimeRatio;
|
||||||
|
|
||||||
|
private void progress(int increment) {
|
||||||
|
if (app == null) return;
|
||||||
|
totalOperations.add(increment);
|
||||||
|
|
||||||
|
long completedOps = totalOperations.longValue();
|
||||||
|
double percent = Math.max(0, Math.min(100, (Math.pow(completedOps, 1.5) * 100 / Math.pow(estimatedOperations, 1.5))));
|
||||||
|
double lastPercent = (this.lastPercent == 0 ? percent : this.lastPercent);
|
||||||
|
percent = (percent + lastPercent * 19) / 20;
|
||||||
|
if (increment != 0) this.lastPercent = percent;
|
||||||
|
|
||||||
|
double remaining = estimatedOperations - completedOps;
|
||||||
|
long timeSpent = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
double totalTime = Math.pow(estimatedOperations, 1.5) * 1000;
|
||||||
|
double estimatedTimeSpent = Math.pow(completedOps, 1.5) * 1000;
|
||||||
|
|
||||||
|
double timeRemaining;
|
||||||
|
if (completedOps > 32) {
|
||||||
|
double timeRatio = (timeSpent * totalTime / estimatedTimeSpent);
|
||||||
|
double lastTimeRatio = this.lastTimeRatio == 0 ? timeRatio : this.lastTimeRatio;
|
||||||
|
timeRatio = (timeRatio + lastTimeRatio * 19) / 20;
|
||||||
|
if (increment != 0) this.lastTimeRatio = timeRatio;
|
||||||
|
timeRemaining = timeRatio - timeSpent;
|
||||||
|
} else {
|
||||||
|
timeRemaining = ((long) totalTime >> 5) - timeSpent;
|
||||||
|
}
|
||||||
|
String msg = MainUtil.secToTime((long) (timeRemaining / 1000));
|
||||||
|
app.setProgress(msg, (int) percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flush() throws IOException {
|
||||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||||
synchronized (batches) {
|
progress(1);
|
||||||
|
synchronized (MCAFile2LevelDB.this) {
|
||||||
|
int count = pool.getParallelism();
|
||||||
Iterator<Map.Entry<Thread, WriteBatch>> iter = batches.entrySet().iterator();
|
Iterator<Map.Entry<Thread, WriteBatch>> iter = batches.entrySet().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry<Thread, WriteBatch> entry = iter.next();
|
Map.Entry<Thread, WriteBatch> entry = iter.next();
|
||||||
@ -121,29 +176,20 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
db.write(batch);
|
db.write(batch);
|
||||||
batch.close();
|
batch.close();
|
||||||
iter.remove();
|
iter.remove();
|
||||||
|
progress(2);
|
||||||
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (openDB) {
|
System.gc();
|
||||||
Fawe.debug("Flushing changes, please wait");
|
System.gc();
|
||||||
if (db != null) db.close();
|
progress(count * 2);
|
||||||
System.gc();
|
|
||||||
System.gc();
|
|
||||||
int bufferSize = (int) Math.min(Integer.MAX_VALUE, Math.max((long) (MemUtil.getFreeBytes() * 0.8), 134217728));
|
|
||||||
this.db = Iq80DBFactory.factory.open(new File(folderTo, "db"),
|
|
||||||
new Options()
|
|
||||||
.createIfMissing(true)
|
|
||||||
.verifyChecksums(false)
|
|
||||||
.blockSize(262144) // 256K
|
|
||||||
.cacheSize(8388608) // 8MB
|
|
||||||
.writeBufferSize(536870912) // >=512MB
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelegateMCAFilter<MutableLong> toFilter(final int dimension) {
|
public DelegateMCAFilter<MutableLong> toFilter(final int dimension) {
|
||||||
RemapFilter filter = new RemapFilter(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE);
|
RemapFilter filter = new RemapFilter(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE);
|
||||||
filter.setDimension(dimension);
|
filter.setDimension(dimension);
|
||||||
|
|
||||||
DelegateMCAFilter<MutableLong> delegate = new DelegateMCAFilter<MutableLong>(filter) {
|
DelegateMCAFilter<MutableLong> delegate = new DelegateMCAFilter<MutableLong>(filter) {
|
||||||
@Override
|
@Override
|
||||||
public void finishFile(MCAFile file, MutableLong cache) {
|
public void finishFile(MCAFile file, MutableLong cache) {
|
||||||
@ -158,6 +204,16 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
file.clear();
|
file.clear();
|
||||||
|
|
||||||
|
progress(1);
|
||||||
|
submittedFiles.increment();
|
||||||
|
if ((submittedFiles.longValue() & 7) == 0) {
|
||||||
|
try {
|
||||||
|
flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return delegate;
|
return delegate;
|
||||||
@ -166,6 +222,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ConverterFrame app) {
|
public void accept(ConverterFrame app) {
|
||||||
|
this.app = app;
|
||||||
File levelDat = new File(folderFrom, "level.dat");
|
File levelDat = new File(folderFrom, "level.dat");
|
||||||
if (levelDat.exists()) {
|
if (levelDat.exists()) {
|
||||||
try {
|
try {
|
||||||
@ -177,12 +234,34 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
|
|
||||||
List<CompoundTag> portals = new ArrayList<>();
|
List<CompoundTag> portals = new ArrayList<>();
|
||||||
String[] dimDirs = {"region", "DIM-1/region", "DIM1/region"};
|
String[] dimDirs = {"region", "DIM-1/region", "DIM1/region"};
|
||||||
|
File[] regionFolders = new File[dimDirs.length];
|
||||||
|
int totalFiles = 0;
|
||||||
for (int dim = 0; dim < 3; dim++) {
|
for (int dim = 0; dim < 3; dim++) {
|
||||||
File source = new File(folderFrom, dimDirs[dim]);
|
File source = new File(folderFrom, dimDirs[dim]);
|
||||||
if (source.exists()) {
|
if (source.exists()) {
|
||||||
|
regionFolders[dim] = source;
|
||||||
|
totalFiles += source.listFiles().length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.estimatedOperations = totalFiles + (totalFiles >> 3) + (totalFiles >> 3) * pool.getParallelism() * 2;
|
||||||
|
|
||||||
|
Thread progressThread = new Thread(() -> {
|
||||||
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
progress(0);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
progressThread.start();
|
||||||
|
|
||||||
|
for (int dim = 0; dim < regionFolders.length; dim++) {
|
||||||
|
File source = regionFolders[dim];
|
||||||
|
if (source != null) {
|
||||||
DelegateMCAFilter filter = toFilter(dim);
|
DelegateMCAFilter filter = toFilter(dim);
|
||||||
MCAQueue queue = new MCAQueue(null, source, true);
|
MCAQueue queue = new MCAQueue(null, source, true);
|
||||||
|
|
||||||
MCAFilter result = queue.filterWorld(filter);
|
MCAFilter result = queue.filterWorld(filter);
|
||||||
portals.addAll(((RemapFilter) filter.getFilter()).getPortals());
|
portals.addAll(((RemapFilter) filter.getFilter()).getPortals());
|
||||||
}
|
}
|
||||||
@ -201,11 +280,13 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
flush(false);
|
flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
progressThread.interrupt();
|
||||||
close();
|
close();
|
||||||
|
app.setProgress("Done", 0);
|
||||||
app.prompt(
|
app.prompt(
|
||||||
"Conversion complete!\n" +
|
"Conversion complete!\n" +
|
||||||
" - The world save is still being compacted, but you can close the program anytime\n" +
|
" - The world save is still being compacted, but you can close the program anytime\n" +
|
||||||
@ -223,7 +304,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public synchronized void close() {
|
||||||
try {
|
try {
|
||||||
if (closed == (closed = true)) return;
|
if (closed == (closed = true)) return;
|
||||||
Fawe.debug("Collecting threads");
|
Fawe.debug("Collecting threads");
|
||||||
@ -238,7 +319,7 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void compact() {
|
public synchronized void compact() {
|
||||||
// Since the library doesn't support it, only way to flush the cache is to loop over everything
|
// Since the library doesn't support it, only way to flush the cache is to loop over everything
|
||||||
try (DB newDb = Iq80DBFactory.factory.open(new File(folderTo, "db"), new Options()
|
try (DB newDb = Iq80DBFactory.factory.open(new File(folderTo, "db"), new Options()
|
||||||
.verifyChecksums(false)
|
.verifyChecksums(false)
|
||||||
@ -315,8 +396,9 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void write(MCAChunk chunk, boolean remap, int dim) throws IOException {
|
public void write(MCAChunk chunk, boolean remap, int dim) throws IOException {
|
||||||
submitted.add(1);
|
submittedChunks.add(1);
|
||||||
if ((submitted.longValue() & 1023) == 0) {
|
long numChunks = submittedChunks.longValue();
|
||||||
|
if ((numChunks & 1023) == 0) {
|
||||||
long queued = pool.getQueuedTaskCount() + pool.getQueuedSubmissionCount();
|
long queued = pool.getQueuedTaskCount() + pool.getQueuedSubmissionCount();
|
||||||
if (queued > 127) {
|
if (queued > 127) {
|
||||||
System.gc();
|
System.gc();
|
||||||
@ -329,110 +411,106 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((submitted.longValue() & 8191) == 0) {
|
}
|
||||||
boolean reopen = (submitted.longValue() & 65535) == 0;
|
synchronized (MCAFile2LevelDB.this) {
|
||||||
flush(reopen);
|
try {
|
||||||
|
update(getKey(chunk, Tag.Version, dim), VERSION);
|
||||||
|
update(getKey(chunk, Tag.FinalizedState, dim), COMPLETE_STATE);
|
||||||
|
|
||||||
|
ByteBuffer data2d = ByteBuffer.wrap(new byte[512 + 256]);
|
||||||
|
int[] heightMap = chunk.getHeightMapArray();
|
||||||
|
for (int i = 0; i < heightMap.length; i++) {
|
||||||
|
data2d.putShort((short) heightMap[i]);
|
||||||
|
}
|
||||||
|
if (chunk.biomes != null) {
|
||||||
|
System.arraycopy(chunk.biomes, 0, data2d.array(), 512, 256);
|
||||||
|
}
|
||||||
|
update(getKey(chunk, Tag.Data2D, dim), data2d.array());
|
||||||
|
|
||||||
|
if (!chunk.tiles.isEmpty()) {
|
||||||
|
List<CompoundTag> tickList = null;
|
||||||
|
List<com.sk89q.jnbt.Tag> tiles = new ArrayList<>();
|
||||||
|
for (Map.Entry<Short, CompoundTag> entry : chunk.getTiles().entrySet()) {
|
||||||
|
CompoundTag tag = entry.getValue();
|
||||||
|
if (transform(chunk, tag) && time != 0l) {
|
||||||
|
// Needs tick
|
||||||
|
if (tickList == null) tickList = new ArrayList<>();
|
||||||
|
|
||||||
|
int x = tag.getInt("x");
|
||||||
|
int y = tag.getInt("y");
|
||||||
|
int z = tag.getInt("z");
|
||||||
|
BaseBlock block = chunk.getBlock(x & 15, y, z & 15);
|
||||||
|
|
||||||
|
Map<String, com.sk89q.jnbt.Tag> tickable = new HashMap<>();
|
||||||
|
tickable.put("tileID", new ByteTag((byte) block.getId()));
|
||||||
|
tickable.put("x", new IntTag(x));
|
||||||
|
tickable.put("y", new IntTag(y));
|
||||||
|
tickable.put("z", new IntTag(z));
|
||||||
|
tickable.put("time", new LongTag(1));
|
||||||
|
tickList.add(new CompoundTag(tickable));
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles.add(tag);
|
||||||
|
}
|
||||||
|
update(getKey(chunk, Tag.BlockEntity, dim), write(tiles));
|
||||||
|
|
||||||
|
if (tickList != null) {
|
||||||
|
HashMap<String, com.sk89q.jnbt.Tag> root = new HashMap<String, com.sk89q.jnbt.Tag>();
|
||||||
|
root.put("tickList", new ListTag(CompoundTag.class, tickList));
|
||||||
|
update(getKey(chunk, Tag.PendingTicks, dim), write(Arrays.asList(new CompoundTag(root))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chunk.entities.isEmpty()) {
|
||||||
|
List<com.sk89q.jnbt.Tag> entities = new ArrayList<>();
|
||||||
|
for (CompoundTag tag : chunk.getEntities()) {
|
||||||
|
transform(chunk, tag);
|
||||||
|
entities.add(tag);
|
||||||
|
}
|
||||||
|
update(getKey(chunk, Tag.Entity, dim), write(entities));
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxLayer = chunk.ids.length - 1;
|
||||||
|
while (maxLayer >= 0 && chunk.ids[maxLayer] == null) maxLayer--;
|
||||||
|
if (maxLayer >= 0) {
|
||||||
|
for (int layer = 0; layer <= maxLayer; layer++) {
|
||||||
|
// Set layer
|
||||||
|
byte[] key = getSectionKey(chunk, layer, dim);
|
||||||
|
byte[] value = new byte[1 + 4096 + 2048 + 2048 + 2048];
|
||||||
|
byte[] ids = chunk.ids[layer];
|
||||||
|
if (ids == null) {
|
||||||
|
Arrays.fill(value, (byte) 0);
|
||||||
|
} else {
|
||||||
|
byte[] data = chunk.data[layer];
|
||||||
|
byte[] skyLight = chunk.skyLight[layer];
|
||||||
|
byte[] blockLight = chunk.blockLight[layer];
|
||||||
|
|
||||||
|
if (remap) {
|
||||||
|
copySection(ids, value, 1);
|
||||||
|
copySection(data, value, 1 + 4096);
|
||||||
|
copySection(skyLight, value, 1 + 4096 + 2048);
|
||||||
|
copySection(blockLight, value, 1 + 4096 + 2048 + 2048);
|
||||||
|
} else {
|
||||||
|
System.arraycopy(ids, 0, value, 1, ids.length);
|
||||||
|
System.arraycopy(data, 0, value, 1 + 4096, data.length);
|
||||||
|
System.arraycopy(skyLight, 0, value, 1 + 4096 + 2048, skyLight.length);
|
||||||
|
System.arraycopy(blockLight, 0, value, 1 + 4096 + 2048 + 2048, blockLight.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pool.submit((Runnable) () -> {
|
|
||||||
synchronized (Thread.currentThread()) {
|
|
||||||
try {
|
|
||||||
update(getKey(chunk, Tag.Version, dim), VERSION);
|
|
||||||
update(getKey(chunk, Tag.FinalizedState, dim), COMPLETE_STATE);
|
|
||||||
|
|
||||||
ByteBuffer data2d = ByteBuffer.wrap(new byte[512 + 256]);
|
|
||||||
int[] heightMap = chunk.getHeightMapArray();
|
|
||||||
for (int i = 0; i < heightMap.length; i++) {
|
|
||||||
data2d.putShort((short) heightMap[i]);
|
|
||||||
}
|
|
||||||
if (chunk.biomes != null) {
|
|
||||||
System.arraycopy(chunk.biomes, 0, data2d.array(), 512, 256);
|
|
||||||
}
|
|
||||||
update(getKey(chunk, Tag.Data2D, dim), data2d.array());
|
|
||||||
|
|
||||||
if (!chunk.tiles.isEmpty()) {
|
|
||||||
List<CompoundTag> tickList = null;
|
|
||||||
List<com.sk89q.jnbt.Tag> tiles = new ArrayList<>();
|
|
||||||
for (Map.Entry<Short, CompoundTag> entry : chunk.getTiles().entrySet()) {
|
|
||||||
CompoundTag tag = entry.getValue();
|
|
||||||
if (transform(chunk, tag) && time != 0l) {
|
|
||||||
// Needs tick
|
|
||||||
if (tickList == null) tickList = new ArrayList<>();
|
|
||||||
|
|
||||||
int x = tag.getInt("x");
|
|
||||||
int y = tag.getInt("y");
|
|
||||||
int z = tag.getInt("z");
|
|
||||||
BaseBlock block = chunk.getBlock(x & 15, y, z & 15);
|
|
||||||
|
|
||||||
Map<String, com.sk89q.jnbt.Tag> tickable = new HashMap<>();
|
|
||||||
tickable.put("tileID", new ByteTag((byte) block.getId()));
|
|
||||||
tickable.put("x", new IntTag(x));
|
|
||||||
tickable.put("y", new IntTag(y));
|
|
||||||
tickable.put("z", new IntTag(z));
|
|
||||||
tickable.put("time", new LongTag(1));
|
|
||||||
tickList.add(new CompoundTag(tickable));
|
|
||||||
}
|
|
||||||
|
|
||||||
tiles.add(tag);
|
|
||||||
}
|
|
||||||
update(getKey(chunk, Tag.BlockEntity, dim), write(tiles));
|
|
||||||
|
|
||||||
if (tickList != null) {
|
|
||||||
HashMap<String, com.sk89q.jnbt.Tag> root = new HashMap<String, com.sk89q.jnbt.Tag>();
|
|
||||||
root.put("tickList", new ListTag(CompoundTag.class, tickList));
|
|
||||||
update(getKey(chunk, Tag.PendingTicks, dim), write(Arrays.asList(new CompoundTag(root))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chunk.entities.isEmpty()) {
|
|
||||||
List<com.sk89q.jnbt.Tag> entities = new ArrayList<>();
|
|
||||||
for (CompoundTag tag : chunk.getEntities()) {
|
|
||||||
transform(chunk, tag);
|
|
||||||
entities.add(tag);
|
|
||||||
}
|
|
||||||
update(getKey(chunk, Tag.Entity, dim), write(entities));
|
|
||||||
}
|
|
||||||
|
|
||||||
int maxLayer = chunk.ids.length - 1;
|
|
||||||
while (maxLayer >= 0 && chunk.ids[maxLayer] == null) maxLayer--;
|
|
||||||
if (maxLayer >= 0) {
|
|
||||||
for (int layer = maxLayer; layer >= 0; layer--) {
|
|
||||||
// Set layer
|
|
||||||
byte[] key = getSectionKey(chunk, layer, dim);
|
|
||||||
byte[] value = new byte[1 + 4096 + 2048 + 2048 + 2048];
|
|
||||||
byte[] ids = chunk.ids[layer];
|
|
||||||
if (ids == null) {
|
|
||||||
Arrays.fill(value, (byte) 0);
|
|
||||||
} else {
|
|
||||||
byte[] data = chunk.data[layer];
|
|
||||||
byte[] skyLight = chunk.skyLight[layer];
|
|
||||||
byte[] blockLight = chunk.blockLight[layer];
|
|
||||||
|
|
||||||
if (remap) {
|
|
||||||
copySection(ids, value, 1);
|
|
||||||
copySection(data, value, 1 + 4096);
|
|
||||||
copySection(skyLight, value, 1 + 4096 + 2048);
|
|
||||||
copySection(blockLight, value, 1 + 4096 + 2048 + 2048);
|
|
||||||
} else {
|
|
||||||
System.arraycopy(ids, 0, value, 1, ids.length);
|
|
||||||
System.arraycopy(data, 0, value, 1 + 4096, data.length);
|
|
||||||
System.arraycopy(skyLight, 0, value, 1 + 4096 + 2048, skyLight.length);
|
|
||||||
System.arraycopy(blockLight, 0, value, 1 + 4096 + 2048 + 2048, blockLight.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(byte[] key, byte[] value) {
|
private void update(byte[] key, byte[] value) {
|
||||||
WriteBatch batch = batches.get(Thread.currentThread());
|
synchronized (Thread.currentThread()) {
|
||||||
batch.put(key, value);
|
WriteBatch batch = batches.get(Thread.currentThread());
|
||||||
|
batch.put(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copySection(byte[] src, byte[] dest, int destPos) {
|
private void copySection(byte[] src, byte[] dest, int destPos) {
|
||||||
@ -541,6 +619,9 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
Map<String, com.sk89q.jnbt.Tag> map = ReflectionUtils.getMap(tag.getValue());
|
Map<String, com.sk89q.jnbt.Tag> map = ReflectionUtils.getMap(tag.getValue());
|
||||||
id = remapper.remapEntityId(id);
|
id = remapper.remapEntityId(id);
|
||||||
map.put("id", new StringTag(id));
|
map.put("id", new StringTag(id));
|
||||||
|
if (map.containsKey("Pos")) {
|
||||||
|
map.put("id", new IntTag(11));
|
||||||
|
}
|
||||||
{ // Convert items
|
{ // Convert items
|
||||||
com.sk89q.jnbt.ListTag items = tag.getListTag("Items");
|
com.sk89q.jnbt.ListTag items = tag.getListTag("Items");
|
||||||
((List<CompoundTag>) (List) items.getValue()).forEach(this::transformItem);
|
((List<CompoundTag>) (List) items.getValue()).forEach(this::transformItem);
|
||||||
@ -555,13 +636,21 @@ public class MCAFile2LevelDB extends MapConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // Health
|
{ // Health
|
||||||
com.sk89q.jnbt.Tag health = map.get("Health");
|
com.sk89q.jnbt.Tag tVal = map.get("Health");
|
||||||
if (health != null && health instanceof FloatTag) {
|
if (tVal != null) {
|
||||||
map.put("Health", new ShortTag((short) tag.getFloat("Health")));
|
short newVal = ((Number) tVal.getValue()).shortValue();
|
||||||
|
map.put("Health", new ShortTag((short) (newVal * 2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String key : new String[] {"Age", "Health"}) {
|
||||||
|
com.sk89q.jnbt.Tag tVal = map.get(key);
|
||||||
|
if (tVal != null) {
|
||||||
|
short newVal = ((Number) tVal.getValue()).shortValue();
|
||||||
|
map.put(key, new ShortTag(newVal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // Orientation / Position
|
{ // Orientation / Position
|
||||||
for (String key : new String[] {"Orientation", "Position"}) {
|
for (String key : new String[] {"Orientation", "Position", "Rotation", "Pos", "Motion"}) {
|
||||||
ListTag list = (ListTag) map.get(key);
|
ListTag list = (ListTag) map.get(key);
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
List<com.sk89q.jnbt.Tag> value = list.getValue();
|
List<com.sk89q.jnbt.Tag> value = list.getValue();
|
||||||
|
Loading…
Reference in New Issue
Block a user