geforkt von Mirrors/FastAsyncWorldEdit
Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit
Dieser Commit ist enthalten in:
Commit
653d362806
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
6
renovate.json
Normale Datei
6
renovate.json
Normale Datei
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
],
|
||||||
|
"ignoreDeps": ["guava", "rhino-runtime", "mockito-core", "antlr4", "antlr4-runtime", "paranamer"]
|
||||||
|
}
|
@ -23,6 +23,7 @@ repositories {
|
|||||||
name = "ProtocolLib Repo"
|
name = "ProtocolLib Repo"
|
||||||
url = uri("https://repo.dmulloy2.net/nexus/repository/public/")
|
url = uri("https://repo.dmulloy2.net/nexus/repository/public/")
|
||||||
}
|
}
|
||||||
|
maven { url = uri("https://repo.inventivetalent.org/content/groups/public/") }
|
||||||
flatDir {dir(File("src/main/resources"))}
|
flatDir {dir(File("src/main/resources"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ dependencies {
|
|||||||
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
"compileOnly"("org.jetbrains:annotations:20.1.0")
|
||||||
"testCompileOnly"("org.jetbrains:annotations:20.1.0")
|
"testCompileOnly"("org.jetbrains:annotations:20.1.0")
|
||||||
"compileOnly"("org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT")
|
"compileOnly"("org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT")
|
||||||
"implementation"("io.papermc:paperlib:1.0.4")
|
"implementation"("io.papermc:paperlib:1.0.6")
|
||||||
"compileOnly"("com.sk89q:dummypermscompat:1.10") {
|
"compileOnly"("com.sk89q:dummypermscompat:1.10") {
|
||||||
exclude("com.github.MilkBowl", "VaultAPI")
|
exclude("com.github.MilkBowl", "VaultAPI")
|
||||||
}
|
}
|
||||||
@ -68,15 +69,16 @@ dependencies {
|
|||||||
exclude("com.sk89q.worldedit.worldedit-libs", "bukkit")
|
exclude("com.sk89q.worldedit.worldedit-libs", "bukkit")
|
||||||
exclude("com.sk89q.worldedit.worldedit-libs", "core")
|
exclude("com.sk89q.worldedit.worldedit-libs", "core")
|
||||||
}
|
}
|
||||||
"compile"("org.bstats:bstats-bukkit:1.7")
|
"compile"("org.bstats:bstats-bukkit:1.8")
|
||||||
|
"compile"("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT")
|
||||||
// Third party
|
// Third party
|
||||||
"implementation"("com.github.InventivetalentDev:MapManager:1.7.+") { isTransitive = false }
|
compileOnlyApi("org.inventivetalent:mapmanager:1.7.+") { isTransitive = false }
|
||||||
"implementation"("com.github.TechFortress:GriefPrevention:16.+") { isTransitive = false }
|
"implementation"("com.github.TechFortress:GriefPrevention:16.+") { isTransitive = false }
|
||||||
"implementation"("com.massivecraft:mcore:7.0.1") { isTransitive = false }
|
"implementation"("com.massivecraft:mcore:7.0.1") { isTransitive = false }
|
||||||
"implementation"("com.bekvon.bukkit.residence:Residence:4.5._13.1") { isTransitive = false }
|
"implementation"("com.bekvon.bukkit.residence:Residence:4.5._13.1") { isTransitive = false }
|
||||||
"implementation"("com.palmergames.bukkit:towny:0.84.0.9") { isTransitive = false }
|
"implementation"("com.palmergames.bukkit:towny:0.84.0.9") { isTransitive = false }
|
||||||
"implementation"("com.thevoxelbox.voxelsniper:voxelsniper:5.171.0") { isTransitive = false }
|
"implementation"("com.thevoxelbox.voxelsniper:voxelsniper:5.171.0") { isTransitive = false }
|
||||||
"implementation"("com.comphenix.protocol:ProtocolLib:4.5.0") { isTransitive = false }
|
"implementation"("com.comphenix.protocol:ProtocolLib:4.5.1") { isTransitive = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<Copy>("processResources") {
|
tasks.named<Copy>("processResources") {
|
||||||
@ -107,17 +109,17 @@ tasks.named<ShadowJar>("shadowJar") {
|
|||||||
include(dependency("org.slf4j:slf4j-api"))
|
include(dependency("org.slf4j:slf4j-api"))
|
||||||
include(dependency("org.apache.logging.log4j:log4j-slf4j-impl"))
|
include(dependency("org.apache.logging.log4j:log4j-slf4j-impl"))
|
||||||
include(dependency("org.antlr:antlr4-runtime"))
|
include(dependency("org.antlr:antlr4-runtime"))
|
||||||
relocate("org.bstats", "com.sk89q.worldedit.bukkit.bstats") {
|
|
||||||
include(dependency("org.bstats:bstats-bukkit:1.7"))
|
|
||||||
}
|
|
||||||
relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") {
|
relocate("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") {
|
||||||
include(dependency("io.papermc:paperlib:1.0.4"))
|
include(dependency("io.papermc:paperlib:1.0.6"))
|
||||||
}
|
}
|
||||||
relocate("it.unimi.dsi.fastutil", "com.sk89q.worldedit.bukkit.fastutil") {
|
relocate("it.unimi.dsi.fastutil", "com.sk89q.worldedit.bukkit.fastutil") {
|
||||||
include(dependency("it.unimi.dsi:fastutil"))
|
include(dependency("it.unimi.dsi:fastutil"))
|
||||||
}
|
}
|
||||||
relocate("org.bstats", "com.boydti.metrics") {
|
relocate("org.bstats", "com.boydti.metrics") {
|
||||||
include(dependency("org.bstats:bstats-bukkit:1.7"))
|
include(dependency("org.bstats:bstats-bukkit:1.8"))
|
||||||
|
}
|
||||||
|
relocate("com.intellectualsites.paster", "com.boydti.fawe.paster") {
|
||||||
|
include(dependency("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,37 +190,32 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playerChunk.hasBeenLoaded()) {
|
if (playerChunk.hasBeenLoaded()) {
|
||||||
TaskManager.IMP.sync(() -> {
|
try {
|
||||||
try {
|
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
||||||
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
if (dirtyBits == 0) {
|
||||||
if (dirtyBits == 0) {
|
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
||||||
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
|
||||||
}
|
|
||||||
if (mask == 0) {
|
|
||||||
dirtyBits = 65535;
|
|
||||||
} else {
|
|
||||||
dirtyBits |= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
|
||||||
fieldDirtyCount.set(playerChunk, 64);
|
|
||||||
|
|
||||||
if (lighting) {
|
|
||||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
|
||||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine());
|
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
|
||||||
p.playerConnection.sendPacket(packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return null;
|
if (mask == 0) {
|
||||||
});
|
dirtyBits = 65535;
|
||||||
return;
|
} else {
|
||||||
|
dirtyBits |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||||
|
fieldDirtyCount.set(playerChunk, 64);
|
||||||
|
|
||||||
|
if (lighting) {
|
||||||
|
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
||||||
|
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine());
|
||||||
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
|
p.playerConnection.sendPacket(packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
@ -90,6 +89,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_15_2_Copy copy = null;
|
private BukkitGetBlocks_1_15_2_Copy copy = null;
|
||||||
|
private boolean forceLoadSections = true;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_15_2(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_15_2(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -316,7 +316,8 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world, getChunkX(), getChunkZ()) : null;
|
forceLoadSections = false;
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_15_2_Copy(world) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
@ -357,13 +358,14 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)) {
|
if (!set.hasSection(layer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (createCopy) {
|
|
||||||
copy.storeSection(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
char[] setArr = set.load(layer);
|
char[] setArr = set.load(layer).clone();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer, load(layer).clone());
|
||||||
|
}
|
||||||
|
|
||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -392,7 +394,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
this.nmsChunk = nmsChunk;
|
this.nmsChunk = nmsChunk;
|
||||||
this.sections = null;
|
this.sections = null;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (existingSection != getSections()[layer]) {
|
} else if (existingSection != getSections(false)[layer]) {
|
||||||
this.sections[layer] = existingSection;
|
this.sections[layer] = existingSection;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||||
@ -403,7 +405,6 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode);
|
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode);
|
||||||
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
}
|
}
|
||||||
@ -470,9 +471,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
Set<UUID> entityRemoves = set.getEntityRemoves();
|
Set<UUID> entityRemoves = set.getEntityRemoves();
|
||||||
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
||||||
if (syncTasks == null) {
|
syncTasks = new Runnable[3];
|
||||||
syncTasks = new Runnable[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTasks[2] = () -> {
|
syncTasks[2] = () -> {
|
||||||
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
||||||
@ -632,12 +631,14 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
} finally {
|
||||||
|
forceLoadSections = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections()[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
// Section is null, return empty array
|
// Section is null, return empty array
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
@ -752,7 +753,10 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSection[] getSections() {
|
public ChunkSection[] getSections(boolean force) {
|
||||||
|
if (force && forceLoadSections) {
|
||||||
|
return sections = getChunk().getSections().clone();
|
||||||
|
}
|
||||||
ChunkSection[] tmp = sections;
|
ChunkSection[] tmp = sections;
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -804,7 +808,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return getSections()[layer] != null;
|
return getSections(false)[layer] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -817,10 +821,10 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
|||||||
return super.trim(true);
|
return super.trim(true);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
if (!hasSection(i) || !super.sections[i].isFull()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ChunkSection existing = getSections()[i];
|
ChunkSection existing = getSections(true)[i];
|
||||||
try {
|
try {
|
||||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2;
|
|||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -21,22 +25,25 @@ import net.minecraft.server.v1_15_R1.TileEntity;
|
|||||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
import org.bukkit.craftbukkit.v1_15_R1.block.CraftBlock;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 {
|
public class BukkitGetBlocks_1_15_2_Copy implements IChunkGet {
|
||||||
|
|
||||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
private final Set<CompoundTag> entities = new HashSet<>();
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
private BiomeStorage biomeStorage;
|
private BiomeStorage biomeStorage;
|
||||||
private final char[][] blocks = new char[16][4096];
|
private final char[][] blocks = new char[16][];
|
||||||
|
private final WorldServer world;
|
||||||
|
|
||||||
protected BukkitGetBlocks_1_15_2_Copy(WorldServer world, int X, int Z) {
|
protected BukkitGetBlocks_1_15_2_Copy(WorldServer world) {
|
||||||
super(world, X, Z);
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeTile(TileEntity tile) {
|
protected void storeTile(TileEntity tile) {
|
||||||
@ -87,6 +94,16 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_15_2.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -105,8 +122,18 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeSection(int layer) {
|
@Override
|
||||||
blocks[layer] = update(layer, null).clone();
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlocks reset() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer, char[] data) {
|
||||||
|
blocks[layer] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,15 +142,50 @@ public class BukkitGetBlocks_1_15_2_Copy extends BukkitGetBlocks_1_15_2 {
|
|||||||
return state.toBaseBlock(this, x, y, z);
|
return state.toBaseBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
||||||
|
return blocks[layer] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] load(int layer) {
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypesCache.states[get(x, y, z)];
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmmittedLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public char get(int x, int y, int z) {
|
public char get(int x, int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = (y & 15) << 8 | z << 4 | x;
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
return blocks[layer][index];
|
return blocks[layer][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public class FAWEWorldNativeAccess_1_15_2 implements WorldNativeAccess<Chunk, IB
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockData toNative(com.sk89q.worldedit.world.block.BlockState state) {
|
public IBlockData toNative(com.sk89q.worldedit.world.block.BlockState state) {
|
||||||
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
int stateId = adapter.ordinalToIbdID(state.getOrdinalChar());
|
||||||
return BlockStateIdAccess.isValidInternalId(stateId)
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
? Block.getByCombinedId(stateId)
|
? Block.getByCombinedId(stateId)
|
||||||
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
||||||
@ -72,7 +72,8 @@ public class FAWEWorldNativeAccess_1_15_2 implements WorldNativeAccess<Chunk, IB
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
||||||
return chunk.setType(position, state, false);
|
return chunk.setType(position, state,
|
||||||
|
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -166,9 +167,4 @@ public class FAWEWorldNativeAccess_1_15_2 implements WorldNativeAccess<Chunk, IB
|
|||||||
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
||||||
getWorld().a(pos, oldState, newState);
|
getWorld().a(pos, oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
|
||||||
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,18 @@ import net.minecraft.server.v1_15_R1.NBTTagList;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LazyCompoundTag_1_15_2 extends CompoundTag {
|
public class LazyCompoundTag_1_15_2 extends CompoundTag {
|
||||||
|
|
||||||
private final Supplier<NBTTagCompound> nmsTag;
|
private final Supplier<NBTTagCompound> nmsTag;
|
||||||
|
private CompoundTag cachedValue;
|
||||||
|
|
||||||
public LazyCompoundTag_1_15_2(Supplier<NBTTagCompound> tag) {
|
public LazyCompoundTag_1_15_2(Supplier<NBTTagCompound> tag) {
|
||||||
super(null);
|
super(new HashMap<>());
|
||||||
this.nmsTag = tag;
|
this.nmsTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +37,10 @@ public class LazyCompoundTag_1_15_2 extends CompoundTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Tag> getValue() {
|
public Map<String, Tag> getValue() {
|
||||||
Map<String, Tag> value = super.getValue();
|
if (cachedValue == null) {
|
||||||
if (value == null) {
|
cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
||||||
Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
|
||||||
setValue(((CompoundTag) tag).getValue());
|
|
||||||
}
|
}
|
||||||
return super.getValue();
|
return cachedValue.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(String key) {
|
public boolean containsKey(String key) {
|
||||||
|
@ -187,35 +187,32 @@ public final class BukkitAdapter_1_16_1 extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playerChunk.hasBeenLoaded()) {
|
if (playerChunk.hasBeenLoaded()) {
|
||||||
TaskManager.IMP.sync(() -> {
|
try {
|
||||||
try {
|
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
||||||
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
if (dirtyBits == 0) {
|
||||||
if (dirtyBits == 0) {
|
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
||||||
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
|
||||||
}
|
|
||||||
if (mask == 0) {
|
|
||||||
dirtyBits = 65535;
|
|
||||||
} else {
|
|
||||||
dirtyBits |= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
|
||||||
fieldDirtyCount.set(playerChunk, 64);
|
|
||||||
|
|
||||||
if (lighting) {
|
|
||||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
|
||||||
boolean trustEdges = false; //Added in 1.16.1 Not sure what it does.
|
|
||||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
|
||||||
p.playerConnection.sendPacket(packet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return null;
|
if (mask == 0) {
|
||||||
});
|
dirtyBits = 65535;
|
||||||
|
} else {
|
||||||
|
dirtyBits |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||||
|
fieldDirtyCount.set(playerChunk, 64);
|
||||||
|
|
||||||
|
if (lighting) {
|
||||||
|
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
||||||
|
boolean trustEdges = false; //Added in 1.16.1 Not sure what it does.
|
||||||
|
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
||||||
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
|
p.playerConnection.sendPacket(packet);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
@ -90,6 +89,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_1_Copy copy = null;
|
private BukkitGetBlocks_1_16_1_Copy copy = null;
|
||||||
|
private boolean forceLoadSections = true;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_1(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_1(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -316,7 +316,8 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world, getChunkX(), getChunkZ()) : null;
|
forceLoadSections = false;
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_16_1_Copy(world) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
@ -357,13 +358,14 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)) {
|
if (!set.hasSection(layer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (createCopy) {
|
|
||||||
copy.storeSection(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
char[] setArr = set.load(layer);
|
char[] setArr = set.load(layer).clone();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer, load(layer).clone());
|
||||||
|
}
|
||||||
|
|
||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -392,7 +394,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
this.nmsChunk = nmsChunk;
|
this.nmsChunk = nmsChunk;
|
||||||
this.sections = null;
|
this.sections = null;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (existingSection != getSections()[layer]) {
|
} else if (existingSection != getSections(false)[layer]) {
|
||||||
this.sections[layer] = existingSection;
|
this.sections[layer] = existingSection;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||||
@ -405,7 +407,6 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
if (!BukkitAdapter_1_16_1
|
if (!BukkitAdapter_1_16_1
|
||||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
}
|
}
|
||||||
@ -472,9 +473,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
|
|
||||||
Set<UUID> entityRemoves = set.getEntityRemoves();
|
Set<UUID> entityRemoves = set.getEntityRemoves();
|
||||||
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
||||||
if (syncTasks == null) {
|
syncTasks = new Runnable[3];
|
||||||
syncTasks = new Runnable[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTasks[2] = () -> {
|
syncTasks[2] = () -> {
|
||||||
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
||||||
@ -634,12 +633,14 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
} finally {
|
||||||
|
forceLoadSections = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections()[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
// Section is null, return empty array
|
// Section is null, return empty array
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
@ -754,7 +755,10 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSection[] getSections() {
|
public ChunkSection[] getSections(boolean force) {
|
||||||
|
if (force && forceLoadSections) {
|
||||||
|
return sections = getChunk().getSections().clone();
|
||||||
|
}
|
||||||
ChunkSection[] tmp = sections;
|
ChunkSection[] tmp = sections;
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -806,7 +810,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return getSections()[layer] != null;
|
return getSections(false)[layer] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -819,10 +823,10 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks {
|
|||||||
return super.trim(true);
|
return super.trim(true);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
if (!hasSection(i) || !super.sections[i].isFull()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ChunkSection existing = getSections()[i];
|
ChunkSection existing = getSections(true)[i];
|
||||||
try {
|
try {
|
||||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_1;
|
|||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_1.nbt.LazyCompoundTag_1_16_1;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -16,28 +20,30 @@ import com.sk89q.worldedit.world.block.BlockTypesCache;
|
|||||||
import net.minecraft.server.v1_16_R1.BiomeBase;
|
import net.minecraft.server.v1_16_R1.BiomeBase;
|
||||||
import net.minecraft.server.v1_16_R1.BiomeStorage;
|
import net.minecraft.server.v1_16_R1.BiomeStorage;
|
||||||
import net.minecraft.server.v1_16_R1.Entity;
|
import net.minecraft.server.v1_16_R1.Entity;
|
||||||
import net.minecraft.server.v1_16_R1.IRegistry;
|
|
||||||
import net.minecraft.server.v1_16_R1.NBTTagCompound;
|
import net.minecraft.server.v1_16_R1.NBTTagCompound;
|
||||||
import net.minecraft.server.v1_16_R1.TileEntity;
|
import net.minecraft.server.v1_16_R1.TileEntity;
|
||||||
import net.minecraft.server.v1_16_R1.WorldServer;
|
import net.minecraft.server.v1_16_R1.WorldServer;
|
||||||
import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock;
|
import org.bukkit.craftbukkit.v1_16_R1.block.CraftBlock;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 {
|
public class BukkitGetBlocks_1_16_1_Copy implements IChunkGet {
|
||||||
|
|
||||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
private final Set<CompoundTag> entities = new HashSet<>();
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
private BiomeStorage biomeStorage;
|
private BiomeStorage biomeStorage;
|
||||||
private final char[][] blocks = new char[16][4096];
|
private final char[][] blocks = new char[16][];
|
||||||
|
private final WorldServer world;
|
||||||
|
|
||||||
protected BukkitGetBlocks_1_16_1_Copy(WorldServer world, int X, int Z) {
|
protected BukkitGetBlocks_1_16_1_Copy(WorldServer world) {
|
||||||
super(world, X, Z);
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeTile(TileEntity tile) {
|
protected void storeTile(TileEntity tile) {
|
||||||
@ -88,6 +94,16 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(BukkitAdapter_1_16_1.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -106,8 +122,18 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeSection(int layer) {
|
@Override
|
||||||
blocks[layer] = update(layer, null).clone();
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlocks reset() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer, char[] data) {
|
||||||
|
blocks[layer] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,15 +142,50 @@ public class BukkitGetBlocks_1_16_1_Copy extends BukkitGetBlocks_1_16_1 {
|
|||||||
return state.toBaseBlock(this, x, y, z);
|
return state.toBaseBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
||||||
|
return blocks[layer] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] load(int layer) {
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypesCache.states[get(x, y, z)];
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmmittedLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public char get(int x, int y, int z) {
|
public char get(int x, int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = (y & 15) << 8 | z << 4 | x;
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
return blocks[layer][index];
|
return blocks[layer][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockData toNative(BlockState state) {
|
public IBlockData toNative(BlockState state) {
|
||||||
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
int stateId = adapter.ordinalToIbdID(state.getOrdinalChar());
|
||||||
return BlockStateIdAccess.isValidInternalId(stateId)
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
? Block.getByCombinedId(stateId)
|
? Block.getByCombinedId(stateId)
|
||||||
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
||||||
@ -73,7 +73,8 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
||||||
return chunk.setType(position, state, false);
|
return chunk.setType(position, state,
|
||||||
|
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,9 +168,4 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
||||||
getWorld().a(pos, oldState, newState);
|
getWorld().a(pos, oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
|
||||||
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R1.NBTTagList;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LazyCompoundTag_1_16_1 extends CompoundTag {
|
public class LazyCompoundTag_1_16_1 extends CompoundTag {
|
||||||
|
|
||||||
private final Supplier<NBTTagCompound> nmsTag;
|
private final Supplier<NBTTagCompound> nmsTag;
|
||||||
|
private CompoundTag cachedValue;
|
||||||
|
|
||||||
public LazyCompoundTag_1_16_1(Supplier<NBTTagCompound> tag) {
|
public LazyCompoundTag_1_16_1(Supplier<NBTTagCompound> tag) {
|
||||||
super(null);
|
super(new HashMap<>());
|
||||||
this.nmsTag = tag;
|
this.nmsTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_1 extends CompoundTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Tag> getValue() {
|
public Map<String, Tag> getValue() {
|
||||||
Map<String, Tag> value = super.getValue();
|
if (cachedValue == null) {
|
||||||
if (value == null) {
|
cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
||||||
Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
|
||||||
setValue(((CompoundTag) tag).getValue());
|
|
||||||
}
|
}
|
||||||
return super.getValue();
|
return cachedValue.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(String key) {
|
public boolean containsKey(String key) {
|
||||||
|
@ -199,51 +199,49 @@ public final class BukkitAdapter_1_16_2 extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playerChunk.hasBeenLoaded()) {
|
if (playerChunk.hasBeenLoaded()) {
|
||||||
TaskManager.IMP.sync(() -> {
|
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
||||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
Optional<Chunk> optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
||||||
Optional<Chunk> optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
if (optional.isPresent()) {
|
||||||
if (optional.isPresent()) {
|
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535);
|
||||||
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535);
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
|
p.playerConnection.sendPacket(chunkpacket);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (lighting) {
|
||||||
|
//This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
||||||
|
boolean trustEdges = true;
|
||||||
|
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
p.playerConnection.sendPacket(chunkpacket);
|
p.playerConnection.sendPacket(packet);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} else if (PaperLib.isPaper()) {
|
||||||
|
//Require generic here to work with multiple dependencies trying to take control.
|
||||||
|
PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<?> objects =
|
||||||
|
nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ);
|
||||||
|
if (objects == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Object obj : objects.getBackingSet()) {
|
||||||
|
if (obj == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityPlayer p = (EntityPlayer) obj;
|
||||||
|
Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||||
|
if (chunk != null) {
|
||||||
|
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535);
|
||||||
|
p.playerConnection.sendPacket(chunkpacket);
|
||||||
|
|
||||||
if (lighting) {
|
if (lighting) {
|
||||||
boolean trustEdges = true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
//This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
||||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
boolean trustEdges = true;
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
PacketPlayOutLightUpdate packet =
|
||||||
|
new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
||||||
p.playerConnection.sendPacket(packet);
|
p.playerConnection.sendPacket(packet);
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (PaperLib.isPaper()) {
|
|
||||||
//Require generic here to work with multiple dependencies trying to take control.
|
|
||||||
PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<?> objects =
|
|
||||||
nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ);
|
|
||||||
if (objects == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (Object obj : objects.getBackingSet()) {
|
|
||||||
if (obj == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
EntityPlayer p = (EntityPlayer) obj;
|
|
||||||
Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
|
||||||
if (chunk != null) {
|
|
||||||
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535);
|
|
||||||
p.playerConnection.sendPacket(chunkpacket);
|
|
||||||
|
|
||||||
if (lighting) {
|
|
||||||
boolean trustEdges =
|
|
||||||
true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
|
||||||
PacketPlayOutLightUpdate packet =
|
|
||||||
new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
|
||||||
p.playerConnection.sendPacket(packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
@ -91,6 +90,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_2_Copy copy = null;
|
private BukkitGetBlocks_1_16_2_Copy copy = null;
|
||||||
|
private boolean forceLoadSections = true;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_2(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_2(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -319,7 +319,8 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world, getChunkX(), getChunkZ()) : null;
|
forceLoadSections = false;
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_16_2_Copy(world) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
@ -360,13 +361,14 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)) {
|
if (!set.hasSection(layer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (createCopy) {
|
|
||||||
copy.storeSection(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
char[] setArr = set.load(layer);
|
char[] setArr = set.load(layer).clone();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer, load(layer).clone());
|
||||||
|
}
|
||||||
|
|
||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -395,7 +397,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
this.nmsChunk = nmsChunk;
|
this.nmsChunk = nmsChunk;
|
||||||
this.sections = null;
|
this.sections = null;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (existingSection != getSections()[layer]) {
|
} else if (existingSection != getSections(false)[layer]) {
|
||||||
this.sections[layer] = existingSection;
|
this.sections[layer] = existingSection;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||||
@ -408,7 +410,6 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
if (!BukkitAdapter_1_16_2
|
if (!BukkitAdapter_1_16_2
|
||||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
}
|
}
|
||||||
@ -475,9 +476,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
Set<UUID> entityRemoves = set.getEntityRemoves();
|
Set<UUID> entityRemoves = set.getEntityRemoves();
|
||||||
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
||||||
if (syncTasks == null) {
|
syncTasks = new Runnable[3];
|
||||||
syncTasks = new Runnable[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTasks[2] = () -> {
|
syncTasks[2] = () -> {
|
||||||
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
||||||
@ -637,12 +636,14 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
} finally {
|
||||||
|
forceLoadSections = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections()[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
// Section is null, return empty array
|
// Section is null, return empty array
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
@ -757,7 +758,10 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSection[] getSections() {
|
public ChunkSection[] getSections(boolean force) {
|
||||||
|
if (force && forceLoadSections) {
|
||||||
|
return sections = getChunk().getSections().clone();
|
||||||
|
}
|
||||||
ChunkSection[] tmp = sections;
|
ChunkSection[] tmp = sections;
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -809,7 +813,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return getSections()[layer] != null;
|
return getSections(false)[layer] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -822,10 +826,10 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks {
|
|||||||
return super.trim(true);
|
return super.trim(true);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
if (!hasSection(i) || !super.sections[i].isFull()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ChunkSection existing = getSections()[i];
|
ChunkSection existing = getSections(true)[i];
|
||||||
try {
|
try {
|
||||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_2;
|
|||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_2.nbt.LazyCompoundTag_1_16_2;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -22,22 +26,25 @@ import net.minecraft.server.v1_16_R2.TileEntity;
|
|||||||
import net.minecraft.server.v1_16_R2.WorldServer;
|
import net.minecraft.server.v1_16_R2.WorldServer;
|
||||||
import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock;
|
import org.bukkit.craftbukkit.v1_16_R2.block.CraftBlock;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 {
|
public class BukkitGetBlocks_1_16_2_Copy implements IChunkGet {
|
||||||
|
|
||||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
private final Set<CompoundTag> entities = new HashSet<>();
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
private BiomeStorage biomeStorage;
|
private BiomeStorage biomeStorage;
|
||||||
private final char[][] blocks = new char[16][4096];
|
private final char[][] blocks = new char[16][];
|
||||||
|
private final WorldServer world;
|
||||||
|
|
||||||
protected BukkitGetBlocks_1_16_2_Copy(WorldServer world, int X, int Z) {
|
protected BukkitGetBlocks_1_16_2_Copy(WorldServer world) {
|
||||||
super(world, X, Z);
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeTile(TileEntity tile) {
|
protected void storeTile(TileEntity tile) {
|
||||||
@ -88,6 +95,16 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_2.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -106,8 +123,18 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeSection(int layer) {
|
@Override
|
||||||
blocks[layer] = update(layer, null).clone();
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlocks reset() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer, char[] data) {
|
||||||
|
blocks[layer] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,15 +143,50 @@ public class BukkitGetBlocks_1_16_2_Copy extends BukkitGetBlocks_1_16_2 {
|
|||||||
return state.toBaseBlock(this, x, y, z);
|
return state.toBaseBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
||||||
|
return blocks[layer] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] load(int layer) {
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypesCache.states[get(x, y, z)];
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmmittedLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public char get(int x, int y, int z) {
|
public char get(int x, int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = (y & 15) << 8 | z << 4 | x;
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
return blocks[layer][index];
|
return blocks[layer][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockData toNative(BlockState state) {
|
public IBlockData toNative(BlockState state) {
|
||||||
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
int stateId = adapter.ordinalToIbdID(state.getOrdinalChar());
|
||||||
return BlockStateIdAccess.isValidInternalId(stateId)
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
? Block.getByCombinedId(stateId)
|
? Block.getByCombinedId(stateId)
|
||||||
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
||||||
@ -73,7 +73,8 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
||||||
return chunk.setType(position, state, false);
|
return chunk.setType(position, state,
|
||||||
|
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,9 +168,4 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
||||||
getWorld().a(pos, oldState, newState);
|
getWorld().a(pos, oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
|
||||||
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R2.NBTTagList;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LazyCompoundTag_1_16_2 extends CompoundTag {
|
public class LazyCompoundTag_1_16_2 extends CompoundTag {
|
||||||
|
|
||||||
private final Supplier<NBTTagCompound> nmsTag;
|
private final Supplier<NBTTagCompound> nmsTag;
|
||||||
|
private CompoundTag cachedValue;
|
||||||
|
|
||||||
public LazyCompoundTag_1_16_2(Supplier<NBTTagCompound> tag) {
|
public LazyCompoundTag_1_16_2(Supplier<NBTTagCompound> tag) {
|
||||||
super(null);
|
super(new HashMap<>());
|
||||||
this.nmsTag = tag;
|
this.nmsTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_2 extends CompoundTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Tag> getValue() {
|
public Map<String, Tag> getValue() {
|
||||||
Map<String, Tag> value = super.getValue();
|
if (cachedValue == null) {
|
||||||
if (value == null) {
|
cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
||||||
Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
|
||||||
setValue(((CompoundTag) tag).getValue());
|
|
||||||
}
|
}
|
||||||
return super.getValue();
|
return cachedValue.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(String key) {
|
public boolean containsKey(String key) {
|
||||||
|
@ -199,51 +199,52 @@ public final class BukkitAdapter_1_16_4 extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playerChunk.hasBeenLoaded()) {
|
if (playerChunk.hasBeenLoaded()) {
|
||||||
TaskManager.IMP.sync(() -> {
|
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
||||||
ChunkCoordIntPair chunkCoordIntPair = new ChunkCoordIntPair(chunkX, chunkZ);
|
Optional<Chunk> optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
||||||
Optional<Chunk> optional = ((Either) playerChunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
|
if (optional.isPresent()) {
|
||||||
if (optional.isPresent()) {
|
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535);
|
||||||
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(optional.get(), 65535);
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
|
p.playerConnection.sendPacket(chunkpacket);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (lighting) {
|
||||||
|
//This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
||||||
|
boolean trustEdges = true;
|
||||||
|
PacketPlayOutLightUpdate packet =
|
||||||
|
new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(),
|
||||||
|
trustEdges);
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
||||||
p.playerConnection.sendPacket(chunkpacket);
|
p.playerConnection.sendPacket(packet);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} else if (PaperLib.isPaper()) {
|
||||||
|
//Require generic here to work with multiple dependencies trying to take control.
|
||||||
|
PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<?> objects =
|
||||||
|
nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap
|
||||||
|
.getObjectsInRange(chunkX, chunkZ);
|
||||||
|
if (objects == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Object obj : objects.getBackingSet()) {
|
||||||
|
if (obj == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityPlayer p = (EntityPlayer) obj;
|
||||||
|
Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||||
|
if (chunk != null) {
|
||||||
|
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535);
|
||||||
|
p.playerConnection.sendPacket(chunkpacket);
|
||||||
|
|
||||||
if (lighting) {
|
if (lighting) {
|
||||||
boolean trustEdges = true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
//This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
||||||
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
boolean trustEdges = true;
|
||||||
playerChunk.players.a(chunkCoordIntPair, false).forEach(p -> {
|
PacketPlayOutLightUpdate packet = new PacketPlayOutLightUpdate(chunkCoordIntPair,
|
||||||
|
nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
||||||
p.playerConnection.sendPacket(packet);
|
p.playerConnection.sendPacket(packet);
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (PaperLib.isPaper()) {
|
|
||||||
//Require generic here to work with multiple dependencies trying to take control.
|
|
||||||
PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<?> objects =
|
|
||||||
nmsWorld.getChunkProvider().playerChunkMap.playerViewDistanceNoTickMap.getObjectsInRange(chunkX, chunkZ);
|
|
||||||
if (objects == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (Object obj : objects.getBackingSet()) {
|
|
||||||
if (obj == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
EntityPlayer p = (EntityPlayer) obj;
|
|
||||||
Chunk chunk = nmsWorld.getChunkProvider().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
|
||||||
if (chunk != null) {
|
|
||||||
PacketPlayOutMapChunk chunkpacket = new PacketPlayOutMapChunk(chunk, 65535);
|
|
||||||
p.playerConnection.sendPacket(chunkpacket);
|
|
||||||
|
|
||||||
if (lighting) {
|
|
||||||
boolean trustEdges =
|
|
||||||
true; //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad)
|
|
||||||
PacketPlayOutLightUpdate packet =
|
|
||||||
new PacketPlayOutLightUpdate(chunkCoordIntPair, nmsWorld.getChunkProvider().getLightEngine(), trustEdges);
|
|
||||||
p.playerConnection.sendPacket(packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||||
@ -91,6 +90,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
public NibbleArray[] skyLight = new NibbleArray[16];
|
public NibbleArray[] skyLight = new NibbleArray[16];
|
||||||
private boolean createCopy = false;
|
private boolean createCopy = false;
|
||||||
private BukkitGetBlocks_1_16_4_Copy copy = null;
|
private BukkitGetBlocks_1_16_4_Copy copy = null;
|
||||||
|
private boolean forceLoadSections = true;
|
||||||
|
|
||||||
public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) {
|
public BukkitGetBlocks_1_16_4(World world, int chunkX, int chunkZ) {
|
||||||
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
this(((CraftWorld) world).getHandle(), chunkX, chunkZ);
|
||||||
@ -319,7 +319,8 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalizer) {
|
||||||
copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world, getChunkX(), getChunkZ()) : null;
|
forceLoadSections = false;
|
||||||
|
copy = createCopy ? new BukkitGetBlocks_1_16_4_Copy(world) : null;
|
||||||
try {
|
try {
|
||||||
WorldServer nmsWorld = world;
|
WorldServer nmsWorld = world;
|
||||||
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
Chunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
@ -360,13 +361,14 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
if (!set.hasSection(layer)) {
|
if (!set.hasSection(layer)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (createCopy) {
|
|
||||||
copy.storeSection(layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
char[] setArr = set.load(layer);
|
char[] setArr = set.load(layer).clone();
|
||||||
|
if (createCopy) {
|
||||||
|
copy.storeSection(layer, load(layer).clone());
|
||||||
|
}
|
||||||
|
|
||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -395,7 +397,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
this.nmsChunk = nmsChunk;
|
this.nmsChunk = nmsChunk;
|
||||||
this.sections = null;
|
this.sections = null;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (existingSection != getSections()[layer]) {
|
} else if (existingSection != getSections(false)[layer]) {
|
||||||
this.sections[layer] = existingSection;
|
this.sections[layer] = existingSection;
|
||||||
this.reset();
|
this.reset();
|
||||||
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
} else if (!Arrays.equals(update(layer, new char[4096]), load(layer))) {
|
||||||
@ -408,7 +410,6 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
if (!BukkitAdapter_1_16_4
|
if (!BukkitAdapter_1_16_4
|
||||||
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
.setSectionAtomic(sections, existingSection, newSection, layer)) {
|
||||||
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
log.error("Failed to set chunk section:" + chunkX + "," + chunkZ + " layer: " + layer);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
|
||||||
}
|
}
|
||||||
@ -475,9 +476,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
|
|
||||||
Set<UUID> entityRemoves = set.getEntityRemoves();
|
Set<UUID> entityRemoves = set.getEntityRemoves();
|
||||||
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
||||||
if (syncTasks == null) {
|
syncTasks = new Runnable[3];
|
||||||
syncTasks = new Runnable[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTasks[2] = () -> {
|
syncTasks[2] = () -> {
|
||||||
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
final List<Entity>[] entities = nmsChunk.getEntitySlices();
|
||||||
@ -637,12 +636,14 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
|
} finally {
|
||||||
|
forceLoadSections = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized char[] update(int layer, char[] data) {
|
public synchronized char[] update(int layer, char[] data) {
|
||||||
ChunkSection section = getSections()[layer];
|
ChunkSection section = getSections(true)[layer];
|
||||||
// Section is null, return empty array
|
// Section is null, return empty array
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
@ -757,7 +758,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkSection[] getSections() {
|
public ChunkSection[] getSections(boolean force) {
|
||||||
|
if (force && forceLoadSections) {
|
||||||
|
return sections = getChunk().getSections().clone();
|
||||||
|
}
|
||||||
ChunkSection[] tmp = sections;
|
ChunkSection[] tmp = sections;
|
||||||
if (tmp == null) {
|
if (tmp == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
@ -809,7 +813,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(int layer) {
|
public boolean hasSection(int layer) {
|
||||||
return getSections()[layer] != null;
|
return getSections(false)[layer] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -822,10 +826,10 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks {
|
|||||||
return super.trim(true);
|
return super.trim(true);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
if (!hasSection(i) || !super.sections[i].isFull()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ChunkSection existing = getSections()[i];
|
ChunkSection existing = getSections(true)[i];
|
||||||
try {
|
try {
|
||||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ package com.boydti.fawe.bukkit.adapter.mc1_16_4;
|
|||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
|
import com.boydti.fawe.beta.implementation.lighting.HeightMapType;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4;
|
import com.boydti.fawe.bukkit.adapter.mc1_16_4.nbt.LazyCompoundTag_1_16_4;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -22,22 +26,25 @@ import net.minecraft.server.v1_16_R3.TileEntity;
|
|||||||
import net.minecraft.server.v1_16_R3.WorldServer;
|
import net.minecraft.server.v1_16_R3.WorldServer;
|
||||||
import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock;
|
import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 {
|
public class BukkitGetBlocks_1_16_4_Copy implements IChunkGet {
|
||||||
|
|
||||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
private final Set<CompoundTag> entities = new HashSet<>();
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
private BiomeStorage biomeStorage;
|
private BiomeStorage biomeStorage;
|
||||||
private final char[][] blocks = new char[16][4096];
|
private final char[][] blocks = new char[16][];
|
||||||
|
private final WorldServer world;
|
||||||
|
|
||||||
protected BukkitGetBlocks_1_16_4_Copy(WorldServer world, int X, int Z) {
|
protected BukkitGetBlocks_1_16_4_Copy(WorldServer world) {
|
||||||
super(world, X, Z);
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeTile(TileEntity tile) {
|
protected void storeTile(TileEntity tile) {
|
||||||
@ -88,6 +95,16 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void storeBiomes(BiomeStorage biomeStorage) {
|
protected void storeBiomes(BiomeStorage biomeStorage) {
|
||||||
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone());
|
this.biomeStorage = new BiomeStorage(biomeStorage.g, BukkitAdapter_1_16_4.getBiomeArray(biomeStorage).clone());
|
||||||
}
|
}
|
||||||
@ -106,8 +123,18 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 {
|
|||||||
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
return base != null ? BukkitAdapter.adapt(CraftBlock.biomeBaseToBiome(world.r().b(IRegistry.ay), base)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeSection(int layer) {
|
@Override
|
||||||
blocks[layer] = update(layer, null).clone();
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlocks reset() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer, char[] data) {
|
||||||
|
blocks[layer] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,15 +143,50 @@ public class BukkitGetBlocks_1_16_4_Copy extends BukkitGetBlocks_1_16_4 {
|
|||||||
return state.toBaseBlock(this, x, y, z);
|
return state.toBaseBlock(this, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
||||||
|
return blocks[layer] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] load(int layer) {
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
return BlockTypesCache.states[get(x, y, z)];
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmmittedLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public char get(int x, int y, int z) {
|
public char get(int x, int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = (y & 15) << 8 | z << 4 | x;
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
return blocks[layer][index];
|
return blocks[layer][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockData toNative(BlockState state) {
|
public IBlockData toNative(BlockState state) {
|
||||||
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
int stateId = adapter.ordinalToIbdID(state.getOrdinalChar());
|
||||||
return BlockStateIdAccess.isValidInternalId(stateId)
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
? Block.getByCombinedId(stateId)
|
? Block.getByCombinedId(stateId)
|
||||||
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
||||||
@ -74,7 +74,8 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
public IBlockData setBlockState(Chunk chunk, BlockPosition position, IBlockData state) {
|
||||||
return chunk.setType(position, state, false);
|
return chunk.setType(position, state,
|
||||||
|
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -168,9 +169,4 @@ public class FAWEWorldNativeAccess_1_16 implements WorldNativeAccess<Chunk, IBlo
|
|||||||
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
public void onBlockStateChange(BlockPosition pos, IBlockData oldState, IBlockData newState) {
|
||||||
getWorld().a(pos, oldState, newState);
|
getWorld().a(pos, oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
|
||||||
return this.adapter.setBlock(this.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).bukkitChunk, position.getBlockX(), position.getBlockY(), position.getBlockZ(), block, sideEffectSet.shouldApply(SideEffect.LIGHTING));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,18 @@ import net.minecraft.server.v1_16_R3.NBTTagList;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class LazyCompoundTag_1_16_4 extends CompoundTag {
|
public class LazyCompoundTag_1_16_4 extends CompoundTag {
|
||||||
|
|
||||||
private final Supplier<NBTTagCompound> nmsTag;
|
private final Supplier<NBTTagCompound> nmsTag;
|
||||||
|
private CompoundTag cachedValue;
|
||||||
|
|
||||||
public LazyCompoundTag_1_16_4(Supplier<NBTTagCompound> tag) {
|
public LazyCompoundTag_1_16_4(Supplier<NBTTagCompound> tag) {
|
||||||
super(null);
|
super(new HashMap<>());
|
||||||
this.nmsTag = tag;
|
this.nmsTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +37,10 @@ public class LazyCompoundTag_1_16_4 extends CompoundTag {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Tag> getValue() {
|
public Map<String, Tag> getValue() {
|
||||||
Map<String, Tag> value = super.getValue();
|
if (cachedValue == null) {
|
||||||
if (value == null) {
|
cachedValue = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
||||||
Tag tag = WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(nmsTag.get());
|
|
||||||
setValue(((CompoundTag) tag).getValue());
|
|
||||||
}
|
}
|
||||||
return super.getValue();
|
return cachedValue.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(String key) {
|
public boolean containsKey(String key) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.boydti.fawe.bukkit.regions.plotsquared;
|
package com.boydti.fawe.bukkit.regions.plotsquared;
|
||||||
|
|
||||||
import com.boydti.fawe.FaweAPI;
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||||
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
||||||
@ -9,36 +8,46 @@ import com.boydti.fawe.util.IOUtil;
|
|||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.plot.schematic.Schematic;
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||||
import com.plotsquared.core.util.MainUtil;
|
import com.plotsquared.core.util.MainUtil;
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.CompressedCompoundTag;
|
import com.sk89q.jnbt.CompressedCompoundTag;
|
||||||
import com.sk89q.jnbt.CompressedSchematicTag;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.jnbt.fawe.CompressedSchematicTag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.FastSchematicReader;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getWorld;
|
import static org.bukkit.Bukkit.getWorld;
|
||||||
|
|
||||||
@ -114,16 +123,14 @@ public class FaweSchematicHandler extends SchematicHandler {
|
|||||||
com.plotsquared.core.util.task.TaskManager.runTask(whenDone);
|
com.plotsquared.core.util.task.TaskManager.runTask(whenDone);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
|
final CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
|
||||||
if (weTag instanceof CompressedSchematicTag) {
|
|
||||||
Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource();
|
|
||||||
URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC);
|
|
||||||
whenDone.run(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(OutputStream output) {
|
public void run(OutputStream output) {
|
||||||
|
if (weTag instanceof CompressedSchematicTag) {
|
||||||
|
Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource();
|
||||||
|
BuiltInClipboardFormat.SPONGE_SCHEMATIC.write(output, clipboard);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
try (PGZIPOutputStream gzip = new PGZIPOutputStream(output)) {
|
try (PGZIPOutputStream gzip = new PGZIPOutputStream(output)) {
|
||||||
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
|
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
|
||||||
@ -137,4 +144,42 @@ public class FaweSchematicHandler extends SchematicHandler {
|
|||||||
}
|
}
|
||||||
}, whenDone);
|
}, whenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Schematic getSchematic(@NotNull InputStream is) {
|
||||||
|
try {
|
||||||
|
FastSchematicReader schematicReader = new FastSchematicReader(
|
||||||
|
new NBTInputStream(new BufferedInputStream(new GZIPInputStream(new BufferedInputStream(is)))));
|
||||||
|
Clipboard clip = schematicReader.read();
|
||||||
|
return new Schematic(clip);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (e instanceof EOFException) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
SpongeSchematicReader schematicReader =
|
||||||
|
new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
||||||
|
Clipboard clip = schematicReader.read();
|
||||||
|
return new Schematic(clip);
|
||||||
|
} catch (IOException e2) {
|
||||||
|
if (e2 instanceof EOFException) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
MCEditSchematicReader schematicReader =
|
||||||
|
new MCEditSchematicReader(new NBTInputStream(new GZIPInputStream(is)));
|
||||||
|
Clipboard clip = schematicReader.read();
|
||||||
|
return new Schematic(clip);
|
||||||
|
} catch (IOException e3) {
|
||||||
|
e.printStackTrace();
|
||||||
|
PlotSquared.debug(
|
||||||
|
is.toString() + " | " + is.getClass().getCanonicalName() + " is not in GZIP format : " + e
|
||||||
|
.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
|||||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.CompressedCompoundTag;
|
import com.sk89q.jnbt.CompressedCompoundTag;
|
||||||
import com.sk89q.jnbt.CompressedSchematicTag;
|
import com.sk89q.jnbt.fawe.CompressedSchematicTag;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
@ -65,6 +65,7 @@ public class FaweSchematicHandler extends SchematicHandler {
|
|||||||
ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true);
|
ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true);
|
||||||
|
|
||||||
Clipboard holder = new BlockArrayClipboard(region, clipboard);
|
Clipboard holder = new BlockArrayClipboard(region, clipboard);
|
||||||
|
|
||||||
CompressedSchematicTag tag = new CompressedSchematicTag(holder);
|
CompressedSchematicTag tag = new CompressedSchematicTag(holder);
|
||||||
whenDone.run(tag);
|
whenDone.run(tag);
|
||||||
});
|
});
|
||||||
|
@ -26,8 +26,8 @@ import org.bukkit.plugin.Plugin;
|
|||||||
import org.bukkit.util.BoundingBox;
|
import org.bukkit.util.BoundingBox;
|
||||||
import org.bukkit.util.RayTraceResult;
|
import org.bukkit.util.RayTraceResult;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -70,32 +70,32 @@ public class AsyncBlock implements Block {
|
|||||||
return world.getBlock(x, y, z).getBlockType().getInternalId();
|
return world.getBlock(x, y, z).getBlockType().getInternalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncBlock getRelative(int modX, int modY, int modZ) {
|
public AsyncBlock getRelative(int modX, int modY, int modZ) {
|
||||||
return new AsyncBlock(world, x + modX, y + modY, z + modZ);
|
return new AsyncBlock(world, x + modX, y + modY, z + modZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncBlock getRelative(BlockFace face) {
|
public AsyncBlock getRelative(BlockFace face) {
|
||||||
return this.getRelative(face.getModX(), face.getModY(), face.getModZ());
|
return this.getRelative(face.getModX(), face.getModY(), face.getModZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncBlock getRelative(BlockFace face, int distance) {
|
public AsyncBlock getRelative(BlockFace face, int distance) {
|
||||||
return this.getRelative(face.getModX() * distance, face.getModY() * distance,
|
return this.getRelative(face.getModX() * distance, face.getModY() * distance,
|
||||||
face.getModZ() * distance);
|
face.getModZ() * distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Material getType() {
|
public Material getType() {
|
||||||
return getBlockData().getMaterial();
|
return getBlockData().getMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData() {
|
public BlockData getBlockData() {
|
||||||
return BukkitAdapter.adapt(world.getBlock(x, y, z));
|
return BukkitAdapter.adapt(world.getBlock(x, y, z));
|
||||||
@ -141,7 +141,7 @@ public class AsyncBlock implements Block {
|
|||||||
return (byte) 15;
|
return (byte) 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncWorld getWorld() {
|
public AsyncWorld getWorld() {
|
||||||
return world;
|
return world;
|
||||||
@ -162,7 +162,7 @@ public class AsyncBlock implements Block {
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Location getLocation() {
|
public Location getLocation() {
|
||||||
return new Location(world, x, y, z);
|
return new Location(world, x, y, z);
|
||||||
@ -179,14 +179,14 @@ public class AsyncBlock implements Block {
|
|||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncChunk getChunk() {
|
public AsyncChunk getChunk() {
|
||||||
return world.getChunkAt(x >> 4, z >> 4);
|
return world.getChunkAt(x >> 4, z >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlockData(@NotNull BlockData blockData) {
|
public void setBlockData(@Nonnull BlockData blockData) {
|
||||||
try {
|
try {
|
||||||
world.setBlock(x, y, z, BukkitAdapter.adapt(blockData));
|
world.setBlock(x, y, z, BukkitAdapter.adapt(blockData));
|
||||||
} catch (WorldEditException e) {
|
} catch (WorldEditException e) {
|
||||||
@ -195,12 +195,12 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlockData(@NotNull BlockData blockData, boolean b) {
|
public void setBlockData(@Nonnull BlockData blockData, boolean b) {
|
||||||
setBlockData(blockData);
|
setBlockData(blockData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setType(@NotNull Material type) {
|
public void setType(@Nonnull Material type) {
|
||||||
try {
|
try {
|
||||||
world.setBlock(x, y, z, BukkitAdapter.asBlockType(type).getDefaultState());
|
world.setBlock(x, y, z, BukkitAdapter.asBlockType(type).getDefaultState());
|
||||||
} catch (WorldEditException e) {
|
} catch (WorldEditException e) {
|
||||||
@ -209,12 +209,12 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setType(@NotNull Material type, boolean applyPhysics) {
|
public void setType(@Nonnull Material type, boolean applyPhysics) {
|
||||||
setType(type);
|
setType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockFace getFace(@NotNull Block block) {
|
public BlockFace getFace(@Nonnull Block block) {
|
||||||
BlockFace[] directions = BlockFace.values();
|
BlockFace[] directions = BlockFace.values();
|
||||||
for (BlockFace face : directions) {
|
for (BlockFace face : directions) {
|
||||||
if (this.getX() + face.getModX() == block.getX()
|
if (this.getX() + face.getModX() == block.getX()
|
||||||
@ -226,7 +226,7 @@ public class AsyncBlock implements Block {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public AsyncBlockState getState() {
|
public AsyncBlockState getState() {
|
||||||
BaseBlock state = world.getFullBlock(x, y, z);
|
BaseBlock state = world.getFullBlock(x, y, z);
|
||||||
@ -250,19 +250,19 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@Nonnull
|
||||||
public AsyncBlockState getState(boolean useSnapshot) {
|
public AsyncBlockState getState(boolean useSnapshot) {
|
||||||
return getState();
|
return getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Biome getBiome() {
|
public Biome getBiome() {
|
||||||
return world.getAdapter().adapt(world.getBiomeType(x, y, z));
|
return world.getAdapter().adapt(world.getBiomeType(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBiome(@NotNull Biome bio) {
|
public void setBiome(@Nonnull Biome bio) {
|
||||||
BiomeType biome = world.getAdapter().adapt(bio);
|
BiomeType biome = world.getAdapter().adapt(bio);
|
||||||
world.setBiome(x, 0, z, biome);
|
world.setBiome(x, 0, z, biome);
|
||||||
}
|
}
|
||||||
@ -278,17 +278,17 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBlockFacePowered(@NotNull BlockFace face) {
|
public boolean isBlockFacePowered(@Nonnull BlockFace face) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBlockFaceIndirectlyPowered(@NotNull BlockFace face) {
|
public boolean isBlockFaceIndirectlyPowered(@Nonnull BlockFace face) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBlockPower(@NotNull BlockFace face) {
|
public int getBlockPower(@Nonnull BlockFace face) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +314,21 @@ public class AsyncBlock implements Block {
|
|||||||
return world.getBlock(x, y, z).getMaterial().isLiquid();
|
return world.getBlock(x, y, z).getMaterial().isLiquid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuildable() {
|
||||||
|
return this.getUnsafeBlock().isBuildable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBurnable() {
|
||||||
|
return this.getType().isBurnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplaceable() {
|
||||||
|
return this.getUnsafeBlock().isReplaceable();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getTemperature() {
|
public double getTemperature() {
|
||||||
return this.getWorld().getTemperature(this.getX(), this.getZ());
|
return this.getWorld().getTemperature(this.getX(), this.getZ());
|
||||||
@ -324,7 +339,7 @@ public class AsyncBlock implements Block {
|
|||||||
return this.getWorld().getHumidity(this.getX(), this.getZ());
|
return this.getWorld().getHumidity(this.getX(), this.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public PistonMoveReaction getPistonMoveReaction() {
|
public PistonMoveReaction getPistonMoveReaction() {
|
||||||
return PistonMoveReaction.IGNORE;
|
return PistonMoveReaction.IGNORE;
|
||||||
@ -341,23 +356,23 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean breakNaturally(@NotNull ItemStack tool) {
|
public boolean breakNaturally(@Nonnull ItemStack tool) {
|
||||||
return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool));
|
return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean breakNaturally(@NotNull ItemStack tool, boolean value) {
|
public boolean breakNaturally(@Nonnull ItemStack tool, boolean value) {
|
||||||
return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool));
|
return TaskManager.IMP.sync(() -> getUnsafeBlock().breakNaturally(tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Collection<ItemStack> getDrops() {
|
public Collection<ItemStack> getDrops() {
|
||||||
return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops());
|
return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Collection<ItemStack> getDrops(@NotNull ItemStack tool) {
|
public Collection<ItemStack> getDrops(@Nonnull ItemStack tool) {
|
||||||
return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops(tool));
|
return TaskManager.IMP.sync(() -> getUnsafeBlock().getDrops(tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,23 +381,23 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMetadata(@NotNull String metadataKey, @NotNull MetadataValue newMetadataValue) {
|
public void setMetadata(@Nonnull String metadataKey, @Nonnull MetadataValue newMetadataValue) {
|
||||||
this.getUnsafeBlock().setMetadata(metadataKey, newMetadataValue);
|
this.getUnsafeBlock().setMetadata(metadataKey, newMetadataValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<MetadataValue> getMetadata(@NotNull String metadataKey) {
|
public List<MetadataValue> getMetadata(@Nonnull String metadataKey) {
|
||||||
return this.getUnsafeBlock().getMetadata(metadataKey);
|
return this.getUnsafeBlock().getMetadata(metadataKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMetadata(@NotNull String metadataKey) {
|
public boolean hasMetadata(@Nonnull String metadataKey) {
|
||||||
return this.getUnsafeBlock().hasMetadata(metadataKey);
|
return this.getUnsafeBlock().hasMetadata(metadataKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeMetadata(@NotNull String metadataKey, @NotNull Plugin owningPlugin) {
|
public void removeMetadata(@Nonnull String metadataKey, @Nonnull Plugin owningPlugin) {
|
||||||
this.getUnsafeBlock().removeMetadata(metadataKey, owningPlugin);
|
this.getUnsafeBlock().removeMetadata(metadataKey, owningPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,12 +407,12 @@ public class AsyncBlock implements Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RayTraceResult rayTrace(@NotNull Location arg0, @NotNull Vector arg1, double arg2,
|
public RayTraceResult rayTrace(@Nonnull Location arg0, @Nonnull Vector arg1, double arg2,
|
||||||
@NotNull FluidCollisionMode arg3) {
|
@Nonnull FluidCollisionMode arg3) {
|
||||||
return this.getUnsafeBlock().rayTrace(arg0, arg1, arg2, arg3);
|
return this.getUnsafeBlock().rayTrace(arg0, arg1, arg2, arg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean applyBoneMeal(@NotNull BlockFace face) {
|
public boolean applyBoneMeal(@Nonnull BlockFace face) {
|
||||||
throw new UnsupportedOperationException("FAWE does not support this yet");
|
throw new UnsupportedOperationException("FAWE does not support this yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,22 +420,28 @@ public class AsyncBlock implements Block {
|
|||||||
throw new UnsupportedOperationException("FAWE does not support this yet");
|
throw new UnsupportedOperationException("FAWE does not support this yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public float getDestroySpeed(@NotNull ItemStack itemStack) {
|
public float getDestroySpeed(@Nonnull ItemStack itemStack) {
|
||||||
throw new UnsupportedOperationException("FAWE does not support this yet");
|
throw new UnsupportedOperationException("FAWE does not support this yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public BoundingBox getBoundingBox() {
|
public BoundingBox getBoundingBox() {
|
||||||
return this.getUnsafeBlock().getBoundingBox();
|
return this.getUnsafeBlock().getBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@Nonnull
|
||||||
public BlockSoundGroup getSoundGroup() {
|
public BlockSoundGroup getSoundGroup() {
|
||||||
return TaskManager.IMP.sync(() -> getUnsafeBlock().getSoundGroup());
|
return TaskManager.IMP.sync(() -> getUnsafeBlock().getSoundGroup());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public boolean isSolid() {
|
||||||
|
return this.getType().isSolid();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.boydti.fawe.bukkit.wrapper;
|
package com.boydti.fawe.bukkit.wrapper;
|
||||||
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
@ -16,8 +17,12 @@ import org.bukkit.material.MaterialData;
|
|||||||
import org.bukkit.metadata.MetadataValue;
|
import org.bukkit.metadata.MetadataValue;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class AsyncBlockState implements BlockState {
|
public class AsyncBlockState implements BlockState {
|
||||||
|
|
||||||
@ -25,10 +30,6 @@ public class AsyncBlockState implements BlockState {
|
|||||||
private BlockData blockData;
|
private BlockData blockData;
|
||||||
private final AsyncBlock block;
|
private final AsyncBlock block;
|
||||||
|
|
||||||
public AsyncBlockState(AsyncBlock block) {
|
|
||||||
this(block, block.world.getFullBlock(block.x, block.y, block.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncBlockState(AsyncBlock block, BaseBlock state) {
|
public AsyncBlockState(AsyncBlock block, BaseBlock state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.block = block;
|
this.block = block;
|
||||||
@ -112,11 +113,11 @@ public class AsyncBlockState implements BlockState {
|
|||||||
@Override
|
@Override
|
||||||
public void setBlockData(BlockData blockData) {
|
public void setBlockData(BlockData blockData) {
|
||||||
this.blockData = blockData;
|
this.blockData = blockData;
|
||||||
CompoundTag nbt = state.getNbtData();
|
CompoundTag nbt = this.getNbtData();
|
||||||
BlockType oldType = state.getBlockType();
|
BlockType oldType = state.getBlockType();
|
||||||
com.sk89q.worldedit.world.block.BlockState newState = BukkitAdapter.adapt(blockData);
|
com.sk89q.worldedit.world.block.BlockState newState = BukkitAdapter.adapt(blockData);
|
||||||
if (nbt != null && newState.getBlockType() == oldType) {
|
if (nbt != null && newState.getBlockType() == oldType) {
|
||||||
state = newState.toBaseBlock(nbt);
|
this.setNbtData(nbt);
|
||||||
} else {
|
} else {
|
||||||
state = newState.toBaseBlock();
|
state = newState.toBaseBlock();
|
||||||
}
|
}
|
||||||
@ -146,14 +147,47 @@ public class AsyncBlockState implements BlockState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag getNbtData() {
|
/**
|
||||||
|
* Returns the (unmodifiable) tag compound that belongs to this block state.
|
||||||
|
* If the block state is null, this will return null.
|
||||||
|
*
|
||||||
|
* @return NBT data
|
||||||
|
*/
|
||||||
|
public synchronized @Nullable CompoundTag getNbtData() {
|
||||||
|
if (this.state == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return state.getNbtData();
|
return state.getNbtData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNbtData(CompoundTag nbt) {
|
/**
|
||||||
|
* Clone the NBT {@link CompoundTag} into a new {@link Map}.
|
||||||
|
*
|
||||||
|
* @return Modifiable clone of NBT data
|
||||||
|
*/
|
||||||
|
public @NotNull Map<String, Tag> cloneNbtMap() {
|
||||||
|
return Optional.ofNullable(this.getNbtData()).map(CompoundTag::getValue)
|
||||||
|
.map(HashMap::new).orElse(new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the NBT data of the block.
|
||||||
|
*
|
||||||
|
* @param nbt New NBT data
|
||||||
|
*/
|
||||||
|
public synchronized void setNbtData(@Nullable final CompoundTag nbt) {
|
||||||
state = this.state.toBaseBlock(nbt);
|
state = this.state.toBaseBlock(nbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the NBT data of the block.
|
||||||
|
*
|
||||||
|
* @param map New NBT data
|
||||||
|
*/
|
||||||
|
public void setNbtData(@NotNull final Map<String, Tag> map) {
|
||||||
|
this.setNbtData(new CompoundTag(map));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getRawData() {
|
public byte getRawData() {
|
||||||
return (byte) (state.getInternalId() >> BlockTypesCache.BIT_OFFSET);
|
return (byte) (state.getInternalId() >> BlockTypesCache.BIT_OFFSET);
|
||||||
@ -163,7 +197,7 @@ public class AsyncBlockState implements BlockState {
|
|||||||
public void setRawData(byte data) {
|
public void setRawData(byte data) {
|
||||||
int combinedId = getTypeId() + (data << BlockTypesCache.BIT_OFFSET);
|
int combinedId = getTypeId() + (data << BlockTypesCache.BIT_OFFSET);
|
||||||
state = com.sk89q.worldedit.world.block.BlockState.getFromInternalId(combinedId)
|
state = com.sk89q.worldedit.world.block.BlockState.getFromInternalId(combinedId)
|
||||||
.toBaseBlock(state.getNbtData());
|
.toBaseBlock(this.getNbtData());
|
||||||
this.blockData = BukkitAdapter.adapt(state);
|
this.blockData = BukkitAdapter.adapt(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.util.TaskManager;
|
|||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.ChunkSnapshot;
|
import org.bukkit.ChunkSnapshot;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -14,6 +15,8 @@ import org.bukkit.plugin.Plugin;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class AsyncChunk implements Chunk {
|
public class AsyncChunk implements Chunk {
|
||||||
@ -120,6 +123,16 @@ public class AsyncChunk implements Chunk {
|
|||||||
return TaskManager.IMP.sync(() -> world.getChunkAt(x, z).getTileEntities(useSnapshot));
|
return TaskManager.IMP.sync(() -> world.getChunkAt(x, z).getTileEntities(useSnapshot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull @Override
|
||||||
|
public Collection<BlockState> getTileEntities(@NotNull Predicate<Block> blockPredicate,
|
||||||
|
boolean useSnapshot) {
|
||||||
|
if (!isLoaded()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return TaskManager.IMP.sync(() -> world.getChunkAt(x, z)
|
||||||
|
.getTileEntities(blockPredicate, useSnapshot));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return world.isChunkLoaded(x, z);
|
return world.isChunkLoaded(x, z);
|
||||||
|
@ -16,17 +16,24 @@ import java.util.HashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public final class AsyncDataContainer implements PersistentDataContainer {
|
public final class AsyncDataContainer implements PersistentDataContainer {
|
||||||
private final CompoundTag root;
|
|
||||||
|
|
||||||
public AsyncDataContainer(CompoundTag root) {
|
private final Supplier<CompoundTag> supplier;
|
||||||
this.root = root;
|
private final Consumer<CompoundTag> consumer;
|
||||||
|
|
||||||
|
public AsyncDataContainer(
|
||||||
|
final @NotNull Supplier<CompoundTag> supplier,
|
||||||
|
final @NotNull Consumer<CompoundTag> consumer
|
||||||
|
) {
|
||||||
|
this.supplier = supplier;
|
||||||
|
this.consumer = consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag root() {
|
private CompoundTag root() {
|
||||||
CompoundTag value = (CompoundTag) root.getValue().get("PublicBukkitValues");
|
return (CompoundTag) supplier.get().getValue().get("PublicBukkitValues");
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Tag> get() {
|
private Map<String, Tag> get() {
|
||||||
@ -40,8 +47,9 @@ public final class AsyncDataContainer implements PersistentDataContainer {
|
|||||||
if (!create) {
|
if (!create) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
Map<String, Tag> map = root.getValue();
|
final Map<String, Tag> map = new HashMap<>(root().getValue());
|
||||||
map.put("PublicBukkitValues", new CompoundTag(raw = new HashMap<>()));
|
map.put("PublicBukkitValues", new CompoundTag(raw = new HashMap<>()));
|
||||||
|
this.consumer.accept(new CompoundTag(map));
|
||||||
} else {
|
} else {
|
||||||
raw = tag.getValue();
|
raw = tag.getValue();
|
||||||
}
|
}
|
||||||
@ -52,7 +60,14 @@ public final class AsyncDataContainer implements PersistentDataContainer {
|
|||||||
Validate.notNull(key, "The provided key for the custom value was null");
|
Validate.notNull(key, "The provided key for the custom value was null");
|
||||||
Validate.notNull(type, "The provided type for the custom value was null");
|
Validate.notNull(type, "The provided type for the custom value was null");
|
||||||
Validate.notNull(value, "The provided value for the custom value was null");
|
Validate.notNull(value, "The provided value for the custom value was null");
|
||||||
get().put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null)));
|
// Modify public values
|
||||||
|
final Map<String, Tag> publicValues = new HashMap<>(this.get());
|
||||||
|
publicValues.put(key.toString(), FaweCache.IMP.asTag(type.toPrimitive(value, null)));
|
||||||
|
// Modify the root tag
|
||||||
|
final Map<String, Tag> map = new HashMap<>(root().getValue());
|
||||||
|
map.put("PublicBukkitValues", new CompoundTag(publicValues));
|
||||||
|
// Update the owning object
|
||||||
|
this.consumer.accept(new CompoundTag(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T, Z> boolean has(NamespacedKey key, PersistentDataType<T, Z> type) {
|
public <T, Z> boolean has(NamespacedKey key, PersistentDataType<T, Z> type) {
|
||||||
@ -60,7 +75,7 @@ public final class AsyncDataContainer implements PersistentDataContainer {
|
|||||||
Validate.notNull(type, "The provided type for the custom value was null");
|
Validate.notNull(type, "The provided type for the custom value was null");
|
||||||
Tag value = get(false).get(key.toString());
|
Tag value = get(false).get(key.toString());
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return type == null;
|
return false;
|
||||||
}
|
}
|
||||||
return type.getPrimitiveType() == value.getValue().getClass();
|
return type.getPrimitiveType() == value.getValue().getClass();
|
||||||
}
|
}
|
||||||
@ -93,7 +108,14 @@ public final class AsyncDataContainer implements PersistentDataContainer {
|
|||||||
|
|
||||||
public void remove(NamespacedKey key) {
|
public void remove(NamespacedKey key) {
|
||||||
Validate.notNull(key, "The provided key for the custom value was null");
|
Validate.notNull(key, "The provided key for the custom value was null");
|
||||||
get(false).remove(key.toString());
|
// Modify public values
|
||||||
|
final Map<String, Tag> publicValues = new HashMap<>(this.get(false));
|
||||||
|
publicValues.remove(key.toString());
|
||||||
|
// Modify the root tag
|
||||||
|
final Map<String, Tag> map = new HashMap<>(root().getValue());
|
||||||
|
map.put("PublicBukkitValues", new CompoundTag(publicValues));
|
||||||
|
// Update the owning object
|
||||||
|
this.consumer.accept(new CompoundTag(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
|
@ -19,6 +19,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class AsyncSign extends AsyncBlockState implements Sign {
|
public class AsyncSign extends AsyncBlockState implements Sign {
|
||||||
|
|
||||||
public AsyncSign(AsyncBlock block, BaseBlock state) {
|
public AsyncSign(AsyncBlock block, BaseBlock state) {
|
||||||
super(block, state);
|
super(block, state);
|
||||||
}
|
}
|
||||||
@ -59,11 +60,12 @@ public class AsyncSign extends AsyncBlockState implements Sign {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLine(int index, String line) throws IndexOutOfBoundsException {
|
public void setLine(int index, String line) throws IndexOutOfBoundsException {
|
||||||
CompoundTag nbt = getNbtData();
|
final Map<String, Tag> map = this.cloneNbtMap();
|
||||||
if (nbt != null) {
|
if (map.isEmpty()) {
|
||||||
Map<String, Tag> map = nbt.getValue();
|
return;
|
||||||
map.put("Text" + (index + 1), new StringTag(toJson(line)));
|
|
||||||
}
|
}
|
||||||
|
map.put("Text" + (index + 1), new StringTag(toJson(line)));
|
||||||
|
this.setNbtData(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,13 +81,13 @@ public class AsyncSign extends AsyncBlockState implements Sign {
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public PersistentDataContainer getPersistentDataContainer() {
|
public PersistentDataContainer getPersistentDataContainer() {
|
||||||
return new AsyncDataContainer(getNbtData());
|
return new AsyncDataContainer(this::getNbtData, this::setNbtData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public DyeColor getColor() {
|
public DyeColor getColor() {
|
||||||
CompoundTag nbt = getNbtData();
|
CompoundTag nbt = this.getNbtData();
|
||||||
if (nbt != null) {
|
if (nbt != null) {
|
||||||
String color = nbt.getString("Color").toUpperCase(Locale.ROOT);
|
String color = nbt.getString("Color").toUpperCase(Locale.ROOT);
|
||||||
if (!color.isEmpty()) {
|
if (!color.isEmpty()) {
|
||||||
@ -97,10 +99,11 @@ public class AsyncSign extends AsyncBlockState implements Sign {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setColor(DyeColor color) {
|
public void setColor(DyeColor color) {
|
||||||
CompoundTag nbt = getNbtData();
|
final Map<String, Tag> map = this.cloneNbtMap();
|
||||||
if (nbt != null) {
|
if (map.isEmpty()) {
|
||||||
Map<String, Tag> map = nbt.getValue();
|
return;
|
||||||
map.put("Color", new StringTag(color.name().toLowerCase(Locale.ROOT)));
|
|
||||||
}
|
}
|
||||||
|
map.put("Color", new StringTag(color.name().toLowerCase(Locale.ROOT)));
|
||||||
|
this.setNbtData(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
@ -93,19 +92,6 @@ import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAM
|
|||||||
*/
|
*/
|
||||||
public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
||||||
|
|
||||||
// This must be before the Logger is initialized, which fails in 1.8
|
|
||||||
private static final String FAILED_VERSION_CHECK =
|
|
||||||
"\n**********************************************\n"
|
|
||||||
+ "** This Minecraft version (%s) is not supported by this version of WorldEdit.\n"
|
|
||||||
+ "** Please download an OLDER version of WorldEdit which does.\n"
|
|
||||||
+ "**********************************************\n";
|
|
||||||
|
|
||||||
static {
|
|
||||||
if (PaperLib.getMinecraftVersion() < 13) {
|
|
||||||
throw new IllegalStateException(String.format(FAILED_VERSION_CHECK, Bukkit.getVersion()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class);
|
private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class);
|
||||||
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
|
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
|
||||||
private static WorldEditPlugin INSTANCE;
|
private static WorldEditPlugin INSTANCE;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.impl;
|
package com.sk89q.worldedit.bukkit.adapter.impl;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||||
@ -93,20 +92,21 @@ import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|||||||
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
||||||
private final Spigot_v1_15_R2 parent;
|
private final Spigot_v1_15_R2 parent;
|
||||||
private char[] ibdToStateOrdinal;
|
private char[] ibdToStateOrdinal;
|
||||||
|
private int[] ordinalToIbdID;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -124,12 +124,15 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
|
|||||||
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size
|
||||||
|
ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size
|
||||||
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
||||||
BlockState state = BlockTypesCache.states[i];
|
BlockState state = BlockTypesCache.states[i];
|
||||||
BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial();
|
BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial();
|
||||||
int id = Block.REGISTRY_ID.getId(material.getState());
|
int id = Block.REGISTRY_ID.getId(material.getState());
|
||||||
ibdToStateOrdinal[id] = state.getOrdinalChar();
|
char ordinal = state.getOrdinalChar();
|
||||||
|
ibdToStateOrdinal[id] = ordinal;
|
||||||
|
ordinalToIbdID[ordinal] = id;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -267,13 +270,13 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
|
|||||||
if (id != null) {
|
if (id != null) {
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundTag> saveTag = () -> {
|
Supplier<CompoundTag> saveTag = () -> {
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
final NBTTagCompound minecraftTag = new NBTTagCompound();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
|
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
CompoundTag natve = (CompoundTag) toNative(tag);
|
final CompoundTag tag = (CompoundTag) toNative(minecraftTag);
|
||||||
natve.getValue().put("Id", new StringTag(id));
|
final Map<String, Tag> tags = new HashMap<>(tag.getValue());
|
||||||
return natve;
|
tags.put("Id", new StringTag(id));
|
||||||
|
return new CompoundTag(tags);
|
||||||
};
|
};
|
||||||
return new LazyBaseEntity(type, saveTag);
|
return new LazyBaseEntity(type, saveTag);
|
||||||
} else {
|
} else {
|
||||||
@ -347,6 +350,16 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public int ordinalToIbdID(char ordinal) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID(ordinal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
||||||
|
@ -92,20 +92,21 @@ import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
|
|||||||
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
||||||
private final Spigot_v1_16_R1 parent;
|
private final Spigot_v1_16_R1 parent;
|
||||||
private char[] ibdToStateOrdinal;
|
private char[] ibdToStateOrdinal;
|
||||||
|
private int[] ordinalToIbdID;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -123,12 +124,15 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
|
|||||||
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size
|
||||||
|
ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size
|
||||||
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
||||||
BlockState state = BlockTypesCache.states[i];
|
BlockState state = BlockTypesCache.states[i];
|
||||||
BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial();
|
BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial();
|
||||||
int id = Block.REGISTRY_ID.getId(material.getState());
|
int id = Block.REGISTRY_ID.getId(material.getState());
|
||||||
ibdToStateOrdinal[id] = state.getOrdinalChar();
|
char ordinal = state.getOrdinalChar();
|
||||||
|
ibdToStateOrdinal[id] = ordinal;
|
||||||
|
ordinalToIbdID[ordinal] = id;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -266,13 +270,13 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
|
|||||||
if (id != null) {
|
if (id != null) {
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundTag> saveTag = () -> {
|
Supplier<CompoundTag> saveTag = () -> {
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
final NBTTagCompound minecraftTag = new NBTTagCompound();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
|
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
CompoundTag natve = (CompoundTag) toNative(tag);
|
final CompoundTag tag = (CompoundTag) toNative(minecraftTag);
|
||||||
natve.getValue().put("Id", new StringTag(id));
|
final Map<String, Tag> tags = new HashMap<>(tag.getValue());
|
||||||
return natve;
|
tags.put("Id", new StringTag(id));
|
||||||
|
return new CompoundTag(tags);
|
||||||
};
|
};
|
||||||
return new LazyBaseEntity(type, saveTag);
|
return new LazyBaseEntity(type, saveTag);
|
||||||
} else {
|
} else {
|
||||||
@ -347,6 +351,17 @@ public final class FAWE_Spigot_v1_16_R1 extends CachedBukkitAdapter implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int ordinalToIbdID(char ordinal) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID(ordinal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
||||||
BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial();
|
BlockMaterial_1_16_1 material = (BlockMaterial_1_16_1) state.getMaterial();
|
||||||
|
@ -92,20 +92,22 @@ import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
|
|||||||
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
||||||
private final Spigot_v1_16_R2 parent;
|
private final Spigot_v1_16_R2 parent;
|
||||||
private char[] ibdToStateOrdinal;
|
private char[] ibdToStateOrdinal;
|
||||||
|
private int[] ordinalToIbdID;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
@ -124,12 +126,15 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I
|
|||||||
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size
|
||||||
|
ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size
|
||||||
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
||||||
BlockState state = BlockTypesCache.states[i];
|
BlockState state = BlockTypesCache.states[i];
|
||||||
BlockMaterial_1_16_2 material = (BlockMaterial_1_16_2) state.getMaterial();
|
BlockMaterial_1_16_2 material = (BlockMaterial_1_16_2) state.getMaterial();
|
||||||
int id = Block.REGISTRY_ID.getId(material.getState());
|
int id = Block.REGISTRY_ID.getId(material.getState());
|
||||||
ibdToStateOrdinal[id] = state.getOrdinalChar();
|
char ordinal = state.getOrdinalChar();
|
||||||
|
ibdToStateOrdinal[id] = ordinal;
|
||||||
|
ordinalToIbdID[ordinal] = id;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -267,13 +272,13 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I
|
|||||||
if (id != null) {
|
if (id != null) {
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundTag> saveTag = () -> {
|
Supplier<CompoundTag> saveTag = () -> {
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
final NBTTagCompound minecraftTag = new NBTTagCompound();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
|
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
CompoundTag natve = (CompoundTag) toNative(tag);
|
final CompoundTag tag = (CompoundTag) toNative(minecraftTag);
|
||||||
natve.getValue().put("Id", new StringTag(id));
|
final Map<String, Tag> tags = new HashMap<>(tag.getValue());
|
||||||
return natve;
|
tags.put("Id", new StringTag(id));
|
||||||
|
return new CompoundTag(tags);
|
||||||
};
|
};
|
||||||
return new LazyBaseEntity(type, saveTag);
|
return new LazyBaseEntity(type, saveTag);
|
||||||
} else {
|
} else {
|
||||||
@ -347,6 +352,16 @@ public final class FAWE_Spigot_v1_16_R2 extends CachedBukkitAdapter implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public int ordinalToIbdID(char ordinal) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID(ordinal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.impl;
|
package com.sk89q.worldedit.bukkit.adapter.impl;
|
||||||
|
|
||||||
import com.bekvon.bukkit.residence.commands.material;
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkGet;
|
import com.boydti.fawe.beta.IChunkGet;
|
||||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||||
@ -96,6 +95,7 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -107,6 +107,7 @@ import static org.slf4j.LoggerFactory.getLogger;
|
|||||||
public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
||||||
private final Spigot_v1_16_R3 parent;
|
private final Spigot_v1_16_R3 parent;
|
||||||
private char[] ibdToStateOrdinal;
|
private char[] ibdToStateOrdinal;
|
||||||
|
private int[] ordinalToIbdID;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
@ -125,12 +126,15 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I
|
|||||||
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size
|
||||||
|
ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size
|
||||||
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
||||||
BlockState state = BlockTypesCache.states[i];
|
BlockState state = BlockTypesCache.states[i];
|
||||||
BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial();
|
BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial();
|
||||||
int id = Block.REGISTRY_ID.getId(material.getState());
|
int id = Block.REGISTRY_ID.getId(material.getState());
|
||||||
ibdToStateOrdinal[id] = state.getOrdinalChar();
|
char ordinal = state.getOrdinalChar();
|
||||||
|
ibdToStateOrdinal[id] = ordinal;
|
||||||
|
ordinalToIbdID[ordinal] = id;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -268,13 +272,13 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I
|
|||||||
if (id != null) {
|
if (id != null) {
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundTag> saveTag = () -> {
|
Supplier<CompoundTag> saveTag = () -> {
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
final NBTTagCompound minecraftTag = new NBTTagCompound();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
|
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
CompoundTag natve = (CompoundTag) toNative(tag);
|
final CompoundTag tag = (CompoundTag) toNative(minecraftTag);
|
||||||
natve.getValue().put("Id", new StringTag(id));
|
final Map<String, Tag> tags = new HashMap<>(tag.getValue());
|
||||||
return natve;
|
tags.put("Id", new StringTag(id));
|
||||||
|
return new CompoundTag(tags);
|
||||||
};
|
};
|
||||||
return new LazyBaseEntity(type, saveTag);
|
return new LazyBaseEntity(type, saveTag);
|
||||||
} else {
|
} else {
|
||||||
@ -349,6 +353,17 @@ public final class FAWE_Spigot_v1_16_R3 extends CachedBukkitAdapter implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int ordinalToIbdID(char ordinal) {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID(ordinal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
||||||
BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial();
|
BlockMaterial_1_16_4 material = (BlockMaterial_1_16_4) state.getMaterial();
|
||||||
|
@ -28,14 +28,14 @@ configurations.all {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
"api"(project(":worldedit-libs:core"))
|
"api"(project(":worldedit-libs:core"))
|
||||||
"implementation"("de.schlichtherle:truezip:6.8.3")
|
"implementation"("de.schlichtherle:truezip:6.8.4")
|
||||||
"implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.1")
|
"implementation"("net.java.truevfs:truevfs-profile-default_2.13:0.12.2")
|
||||||
"implementation"("org.mozilla:rhino-runtime:1.7.12")
|
"implementation"("org.mozilla:rhino-runtime:1.7.12")
|
||||||
"implementation"("org.yaml:snakeyaml:1.23")
|
"implementation"("org.yaml:snakeyaml:1.27")
|
||||||
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
|
||||||
"implementation"("com.google.code.findbugs:jsr305:3.0.2")
|
"implementation"("com.google.code.findbugs:jsr305:3.0.2")
|
||||||
"implementation"("com.google.code.gson:gson:${Versions.GSON}")
|
"implementation"("com.google.code.gson:gson:${Versions.GSON}")
|
||||||
"implementation"("org.slf4j:slf4j-api:1.7.27")
|
"implementation"("org.slf4j:slf4j-api:1.7.30")
|
||||||
"implementation"("it.unimi.dsi:fastutil:${Versions.FAST_UTIL}")
|
"implementation"("it.unimi.dsi:fastutil:${Versions.FAST_UTIL}")
|
||||||
|
|
||||||
val antlrVersion = "4.7.2"
|
val antlrVersion = "4.7.2"
|
||||||
@ -51,14 +51,15 @@ dependencies {
|
|||||||
"annotationProcessor"("com.google.auto.value:auto-value:${Versions.AUTO_VALUE}")
|
"annotationProcessor"("com.google.auto.value:auto-value:${Versions.AUTO_VALUE}")
|
||||||
"testImplementation"("ch.qos.logback:logback-core:${Versions.LOGBACK}")
|
"testImplementation"("ch.qos.logback:logback-core:${Versions.LOGBACK}")
|
||||||
"testImplementation"("ch.qos.logback:logback-classic:${Versions.LOGBACK}")
|
"testImplementation"("ch.qos.logback:logback-classic:${Versions.LOGBACK}")
|
||||||
"compile"("com.github.luben:zstd-jni:1.4.3-1")
|
"compile"("com.github.luben:zstd-jni:1.4.8-1")
|
||||||
"compileOnly"("net.fabiozumbi12:redprotect:1.9.6")
|
"compileOnly"("net.fabiozumbi12:redprotect:1.9.6")
|
||||||
"compile"("com.github.intellectualsites.plotsquared:PlotSquared-API:latest") {
|
"compile"("com.github.intellectualsites.plotsquared:PlotSquared-API:latest") {
|
||||||
isTransitive = false
|
isTransitive = false
|
||||||
}
|
}
|
||||||
"compile"("com.plotsquared:PlotSquared-Core:5.12.2") {
|
"compile"("com.plotsquared:PlotSquared-Core:5.13.3") {
|
||||||
isTransitive = false
|
isTransitive = false
|
||||||
}
|
}
|
||||||
|
"api"("com.intellectualsites.paster:Paster:1.0.1-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<Test>("test") {
|
tasks.named<Test>("test") {
|
||||||
@ -109,7 +110,7 @@ tasks.named<Copy>("processResources") {
|
|||||||
}
|
}
|
||||||
tasks.named<ShadowJar>("shadowJar") {
|
tasks.named<ShadowJar>("shadowJar") {
|
||||||
dependencies {
|
dependencies {
|
||||||
include(dependency("com.github.luben:zstd-jni:1.4.3-1"))
|
include(dependency("com.github.luben:zstd-jni:1.4.8-1"))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,8 +235,8 @@ public class Fawe {
|
|||||||
// Setting up config.yml
|
// Setting up config.yml
|
||||||
File file = new File(this.implementation.getDirectory(), "config.yml");
|
File file = new File(this.implementation.getDirectory(), "config.yml");
|
||||||
Settings.IMP.PLATFORM = implementation.getPlatform().replace("\"", "");
|
Settings.IMP.PLATFORM = implementation.getPlatform().replace("\"", "");
|
||||||
try (InputStream stream = getClass().getResourceAsStream(File.separator + "fawe.properties");
|
try (InputStream stream = getClass().getResourceAsStream("/fawe.properties");
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
||||||
String versionString = br.readLine();
|
String versionString = br.readLine();
|
||||||
String commitString = br.readLine();
|
String commitString = br.readLine();
|
||||||
String dateString = br.readLine();
|
String dateString = br.readLine();
|
||||||
|
@ -9,39 +9,57 @@ import org.jetbrains.annotations.Range;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public abstract class CharBlocks implements IBlocks {
|
public abstract class CharBlocks implements IBlocks {
|
||||||
|
|
||||||
public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class);
|
public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class);
|
||||||
|
|
||||||
public static final Section FULL = new Section() {
|
protected static final Section FULL = new Section() {
|
||||||
@Override
|
@Override
|
||||||
public final char[] get(CharBlocks blocks, int layer) {
|
public final char[] get(CharBlocks blocks, int layer) {
|
||||||
return blocks.blocks[layer];
|
return blocks.blocks[layer];
|
||||||
}
|
}
|
||||||
};
|
|
||||||
public static final Section EMPTY = new Section() {
|
|
||||||
@Override
|
@Override
|
||||||
public final synchronized char[] get(CharBlocks blocks, int layer) {
|
public final boolean isFull() {
|
||||||
char[] arr = blocks.blocks[layer];
|
return true;
|
||||||
if (arr == null) {
|
}
|
||||||
arr = blocks.blocks[layer] = blocks.update(layer, null);
|
};
|
||||||
|
protected static final Section EMPTY = new Section() {
|
||||||
|
@Override
|
||||||
|
public final char[] get(CharBlocks blocks, int layer) {
|
||||||
|
blocks.loadLock.lock();
|
||||||
|
try {
|
||||||
|
char[] arr = blocks.blocks[layer];
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
throw new IllegalStateException("Array cannot be null: " + blocks.getClass());
|
arr = blocks.blocks[layer] = blocks.update(layer, null);
|
||||||
|
if (arr == null) {
|
||||||
|
throw new IllegalStateException("Array cannot be null: " + blocks.getClass());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blocks.blocks[layer] = blocks.update(layer, arr);
|
||||||
|
if (blocks.blocks[layer] == null) {
|
||||||
|
throw new IllegalStateException("Array cannot be null (update): " + blocks.getClass());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (blocks.blocks[layer] != null) {
|
||||||
blocks.blocks[layer] = blocks.update(layer, arr);
|
blocks.sections[layer] = FULL;
|
||||||
if (blocks.blocks[layer] == null) {
|
|
||||||
throw new IllegalStateException("Array cannot be null (update): " + blocks.getClass());
|
|
||||||
}
|
}
|
||||||
|
return arr;
|
||||||
|
} finally {
|
||||||
|
blocks.loadLock.unlock();
|
||||||
}
|
}
|
||||||
if (blocks.blocks[layer] != null) {
|
}
|
||||||
blocks.sections[layer] = FULL;
|
|
||||||
}
|
@Override
|
||||||
return arr;
|
public final boolean isFull() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public final char[][] blocks;
|
public final char[][] blocks;
|
||||||
public final Section[] sections;
|
public final Section[] sections;
|
||||||
|
private final ReentrantLock loadLock = new ReentrantLock ();
|
||||||
|
|
||||||
public CharBlocks() {
|
public CharBlocks() {
|
||||||
blocks = new char[16][];
|
blocks = new char[16][];
|
||||||
@ -55,7 +73,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
public boolean trim(boolean aggressive) {
|
public boolean trim(boolean aggressive) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < 16; i++) {
|
||||||
if (sections[i] == EMPTY && blocks[i] != null) {
|
if (!sections[i].isFull() && blocks[i] != null) {
|
||||||
blocks[i] = null;
|
blocks[i] = null;
|
||||||
} else {
|
} else {
|
||||||
result = false;
|
result = false;
|
||||||
@ -67,7 +85,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
@Override
|
@Override
|
||||||
public boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
if (sections[layer] == EMPTY && blocks[layer] != null) {
|
if (!sections[layer].isFull() && blocks[layer] != null) {
|
||||||
blocks[layer] = null;
|
blocks[layer] = null;
|
||||||
} else {
|
} else {
|
||||||
result = false;
|
result = false;
|
||||||
@ -99,7 +117,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
public boolean hasSection(@Range(from = 0, to = 15) int layer) {
|
||||||
return sections[layer] == FULL;
|
return sections[layer].isFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -149,6 +167,8 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
|
|
||||||
public abstract char[] get(CharBlocks blocks, @Range(from = 0, to = 15) int layer);
|
public abstract char[] get(CharBlocks blocks, @Range(from = 0, to = 15) int layer);
|
||||||
|
|
||||||
|
public abstract boolean isFull();
|
||||||
|
|
||||||
public final char get(CharBlocks blocks, @Range(from = 0, to = 15) int layer, int index) {
|
public final char get(CharBlocks blocks, @Range(from = 0, to = 15) int layer, int index) {
|
||||||
return get(blocks, layer)[index];
|
return get(blocks, layer)[index];
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
|
|||||||
return
|
return
|
||||||
// Apply a filter over a region
|
// Apply a filter over a region
|
||||||
apply(region, searchMask
|
apply(region, searchMask
|
||||||
.toFilter(new CountFilter()), false) // Adapt the mask to a filter which counts
|
.toFilter(new CountFilter()), searchMask.replacesAir()) // Adapt the mask to a filter which counts
|
||||||
.getParent() // Get the counter of this mask
|
.getParent() // Get the counter of this mask
|
||||||
.getTotal(); // Get the total from the counter
|
.getTotal(); // Get the total from the counter
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ public class StreamDelegate {
|
|||||||
Object raw = is.readTagPayloadRaw(type, depth);
|
Object raw = is.readTagPayloadRaw(type, depth);
|
||||||
valueReader.apply(0, raw);
|
valueReader.apply(0, raw);
|
||||||
} else {
|
} else {
|
||||||
is.readTagPaylodLazy(type, depth + 1, this);
|
is.readTagPayloadLazy(type, depth + 1, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +137,8 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
}
|
}
|
||||||
if (!tilesTo.isEmpty()) {
|
if (!tilesTo.isEmpty()) {
|
||||||
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesTo.entrySet()) {
|
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesTo.entrySet()) {
|
||||||
CompoundTag nbt = entry.getValue();
|
|
||||||
BlockVector3 pos = entry.getKey();
|
BlockVector3 pos = entry.getKey();
|
||||||
MainUtil.setPosition(nbt, pos.getX() + bx, pos.getY(), pos.getZ() + bz);
|
addTileCreate(MainUtil.setPosition(entry.getValue(), pos.getX() + bx, pos.getY(), pos.getZ() + bz));
|
||||||
addTileCreate(nbt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Set<UUID> entRemoves = set.getEntityRemoves();
|
Set<UUID> entRemoves = set.getEntityRemoves();
|
||||||
@ -176,11 +174,12 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
int zz = z + bz;
|
int zz = z + bz;
|
||||||
for (int x = 0; x < 16; x++, index++) {
|
for (int x = 0; x < 16; x++, index++) {
|
||||||
int xx = bx + x;
|
int xx = bx + x;
|
||||||
int combinedFrom = blocksGet[index];
|
int from = blocksGet[index];
|
||||||
if (combinedFrom == 0) {
|
if (from == 0) {
|
||||||
combinedFrom = BlockID.AIR;
|
from = BlockID.AIR;
|
||||||
}
|
}
|
||||||
int combinedTo = blocksSet[index];
|
final int combinedFrom = from;
|
||||||
|
final int combinedTo = blocksSet[index];
|
||||||
if (combinedTo != 0) {
|
if (combinedTo != 0) {
|
||||||
add(xx, yy, zz, combinedFrom, combinedTo);
|
add(xx, yy, zz, combinedFrom, combinedTo);
|
||||||
}
|
}
|
||||||
@ -249,14 +248,12 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
|
|
||||||
public void add(EntityCreate change) {
|
public void add(EntityCreate change) {
|
||||||
CompoundTag tag = change.state.getNbtData();
|
CompoundTag tag = change.state.getNbtData();
|
||||||
MainUtil.setEntityInfo(tag, change.getEntity());
|
addEntityCreate(MainUtil.setEntityInfo(tag, change.getEntity()));
|
||||||
addEntityCreate(tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(EntityRemove change) {
|
public void add(EntityRemove change) {
|
||||||
CompoundTag tag = change.state.getNbtData();
|
CompoundTag tag = change.state.getNbtData();
|
||||||
MainUtil.setEntityInfo(tag, change.getEntity());
|
addEntityRemove(MainUtil.setEntityInfo(tag, change.getEntity()));
|
||||||
addEntityRemove(tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -299,14 +296,12 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
if (from.hasNbtData()) {
|
if (from.hasNbtData()) {
|
||||||
CompoundTag nbt = from.getNbtData();
|
CompoundTag nbt = from.getNbtData();
|
||||||
assert nbt != null;
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
addTileRemove(MainUtil.setPosition(nbt, x, y, z));
|
||||||
addTileRemove(nbt);
|
|
||||||
}
|
}
|
||||||
if (to.hasNbtData()) {
|
if (to.hasNbtData()) {
|
||||||
CompoundTag nbt = to.getNbtData();
|
CompoundTag nbt = to.getNbtData();
|
||||||
assert nbt != null;
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
addTileCreate(MainUtil.setPosition(nbt, x, y, z));
|
||||||
addTileCreate(nbt);
|
|
||||||
}
|
}
|
||||||
int combinedFrom = from.getOrdinal();
|
int combinedFrom = from.getOrdinal();
|
||||||
int combinedTo = to.getOrdinal();
|
int combinedTo = to.getOrdinal();
|
||||||
@ -322,8 +317,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
if (to.hasNbtData()) {
|
if (to.hasNbtData()) {
|
||||||
CompoundTag nbt = to.getNbtData();
|
CompoundTag nbt = to.getNbtData();
|
||||||
assert nbt != null;
|
assert nbt != null;
|
||||||
MainUtil.setPosition(nbt, x, y, z);
|
addTileCreate(MainUtil.setPosition(nbt, x, y, z));
|
||||||
addTileCreate(nbt);
|
|
||||||
}
|
}
|
||||||
int combinedTo = to.getInternalId();
|
int combinedTo = to.getInternalId();
|
||||||
add(x, y, z, combinedFrom, combinedTo);
|
add(x, y, z, combinedFrom, combinedTo);
|
||||||
@ -357,7 +351,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
wrappedTask.run();
|
wrappedTask.run();
|
||||||
return Futures.immediateCancelledFuture();
|
return Futures.immediateCancelledFuture();
|
||||||
} else {
|
} else {
|
||||||
return Fawe.get().getQueueHandler().async(wrappedTask);
|
return Fawe.get().getQueueHandler().submit(wrappedTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,10 +152,8 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
|||||||
@Override
|
@Override
|
||||||
public Collection<CompoundTag> getTileEntities() {
|
public Collection<CompoundTag> getTileEntities() {
|
||||||
convertTilesToIndex();
|
convertTilesToIndex();
|
||||||
for (Map.Entry<Integer, CompoundTag> entry : nbtMapIndex.entrySet()) {
|
nbtMapIndex.replaceAll((index, tag) -> {
|
||||||
int index = entry.getKey();
|
Map<String, Tag> values = new HashMap<>(tag.getValue());
|
||||||
CompoundTag tag = entry.getValue();
|
|
||||||
Map<String, Tag> values = tag.getValue();
|
|
||||||
if (!values.containsKey("x")) {
|
if (!values.containsKey("x")) {
|
||||||
int y = index / getArea();
|
int y = index / getArea();
|
||||||
index -= y * getArea();
|
index -= y * getArea();
|
||||||
@ -164,23 +162,26 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
|||||||
values.put("x", new IntTag(x));
|
values.put("x", new IntTag(x));
|
||||||
values.put("y", new IntTag(y));
|
values.put("y", new IntTag(y));
|
||||||
values.put("z", new IntTag(z));
|
values.put("z", new IntTag(z));
|
||||||
|
return new CompoundTag(values);
|
||||||
|
} else {
|
||||||
|
return tag;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return nbtMapIndex.values();
|
return nbtMapIndex.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||||
nbtMapLoc.put(new IntTriple(x, y, z), tag);
|
nbtMapLoc.put(new IntTriple(x, y, z), new CompoundTag(tag.getValue()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setTile(int index, CompoundTag tag) {
|
public boolean setTile(int index, CompoundTag tag) {
|
||||||
nbtMapIndex.put(index, tag);
|
final Map<String, Tag> values = new HashMap<>(tag.getValue());
|
||||||
Map<String, Tag> values = tag.getValue();
|
|
||||||
values.remove("x");
|
values.remove("x");
|
||||||
values.remove("y");
|
values.remove("y");
|
||||||
values.remove("z");
|
values.remove("z");
|
||||||
|
nbtMapIndex.put(index, new CompoundTag(values));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -44,7 +45,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A clipboard with disk backed storage. (lower memory + loads on crash)
|
* A clipboard with disk backed storage. (lower memory + loads on crash)
|
||||||
@ -390,11 +390,11 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||||
nbtMap.put(new IntTriple(x, y, z), tag);
|
final Map<String, Tag> values = new HashMap<>(tag.getValue());
|
||||||
Map<String, Tag> values = tag.getValue();
|
|
||||||
values.put("x", new IntTag(x));
|
values.put("x", new IntTag(x));
|
||||||
values.put("y", new IntTag(y));
|
values.put("y", new IntTag(y));
|
||||||
values.put("z", new IntTag(z));
|
values.put("z", new IntTag(z));
|
||||||
|
nbtMap.put(new IntTriple(x, y, z), new CompoundTag(values));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,6 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
|
||||||
* Best used when clipboard selections are small, or using legacy formats
|
|
||||||
* (Small being < Integer.MAX_VALUE/BLOCK_SIZE_BYTES blocks)
|
|
||||||
*/
|
|
||||||
public abstract class LinearClipboard extends SimpleClipboard {
|
public abstract class LinearClipboard extends SimpleClipboard {
|
||||||
|
|
||||||
protected final HashSet<ClipboardEntity> entities = new HashSet<>();
|
protected final HashSet<ClipboardEntity> entities = new HashSet<>();
|
||||||
|
@ -257,11 +257,11 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||||
nbtMap.put(new IntTriple(x, y, z), tag);
|
final Map<String, Tag> values = new HashMap<>(tag.getValue());
|
||||||
Map<String, Tag> values = tag.getValue();
|
|
||||||
values.put("x", new IntTag(x));
|
values.put("x", new IntTag(x));
|
||||||
values.put("y", new IntTag(y));
|
values.put("y", new IntTag(y));
|
||||||
values.put("z", new IntTag(z));
|
values.put("z", new IntTag(z));
|
||||||
|
nbtMap.put(new IntTriple(x, y, z), new CompoundTag(values));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ public abstract class SimpleClipboard implements Clipboard {
|
|||||||
SimpleClipboard(BlockVector3 dimensions) {
|
SimpleClipboard(BlockVector3 dimensions) {
|
||||||
this.size = dimensions;
|
this.size = dimensions;
|
||||||
long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength();
|
long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength();
|
||||||
if (longVolume >= Integer.MAX_VALUE >> 2) {
|
if (longVolume >= Integer.MAX_VALUE) {
|
||||||
throw new IllegalArgumentException("Dimensions are too large for this clipboard format.");
|
throw new IllegalArgumentException("Dimensions are too large for this clipboard format.");
|
||||||
}
|
}
|
||||||
this.area = getWidth() * getLength();
|
this.area = getWidth() * getLength();
|
||||||
|
@ -16,4 +16,9 @@ public class AirMask extends BlockMask {
|
|||||||
return new AirMask(getExtent());
|
return new AirMask(getExtent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,4 +37,9 @@ public class IdDataMask extends AbstractExtentMask implements ResettableMask {
|
|||||||
return new IdDataMask(getExtent());
|
return new IdDataMask(getExtent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,4 +38,9 @@ public class IdMask extends AbstractExtentMask implements ResettableMask {
|
|||||||
return new IdMask(getExtent());
|
return new IdMask(getExtent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,298 +0,0 @@
|
|||||||
package com.boydti.fawe.util;
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.sk89q.worldedit.util.paste.Paster;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.RuntimeMXBean;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Single class paster for the Incendo paste service
|
|
||||||
*
|
|
||||||
* @author Sauilitired
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
||||||
public final class IncendoPaster implements Paster {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload service URL
|
|
||||||
*/
|
|
||||||
public static final String UPLOAD_PATH = "https://athion.net/ISPaster/paste/upload";
|
|
||||||
/**
|
|
||||||
* Valid paste applications
|
|
||||||
*/
|
|
||||||
public static final Collection<String>
|
|
||||||
VALID_APPLICATIONS = Arrays
|
|
||||||
.asList("plotsquared", "fastasyncworldedit", "incendopermissions", "kvantum");
|
|
||||||
|
|
||||||
private final Collection<PasteFile> files = new ArrayList<>();
|
|
||||||
private final String pasteApplication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new paster
|
|
||||||
*
|
|
||||||
* @param pasteApplication The application that is sending the paste
|
|
||||||
*/
|
|
||||||
public IncendoPaster(final String pasteApplication) {
|
|
||||||
if (pasteApplication == null || pasteApplication.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("paste application cannot be null, nor empty");
|
|
||||||
}
|
|
||||||
if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ROOT))) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format("Unknown application name: %s", pasteApplication));
|
|
||||||
}
|
|
||||||
this.pasteApplication = pasteApplication;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Callable<URL> paste(String content) {
|
|
||||||
return new PasteTask(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class PasteTask implements Callable<URL> {
|
|
||||||
|
|
||||||
private PasteTask(String content) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public URL call() throws Exception {
|
|
||||||
return new URL(debugPaste());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an immutable collection containing all the files that have been added to this paster
|
|
||||||
*
|
|
||||||
* @return Unmodifiable collection
|
|
||||||
*/
|
|
||||||
public final Collection<PasteFile> getFiles() {
|
|
||||||
return Collections.unmodifiableCollection(this.files);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a file to the paster
|
|
||||||
*
|
|
||||||
* @param file File to paste
|
|
||||||
*/
|
|
||||||
public void addFile(final PasteFile file) {
|
|
||||||
if (file == null) {
|
|
||||||
throw new IllegalArgumentException("File cannot be null");
|
|
||||||
}
|
|
||||||
// Check to see that no duplicate files are submitted
|
|
||||||
for (final PasteFile pasteFile : this.files) {
|
|
||||||
if (pasteFile.fileName.equalsIgnoreCase(file.getFileName())) {
|
|
||||||
throw new IllegalArgumentException(String.format("Found duplicate file with name %s",
|
|
||||||
file.getFileName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.files.add(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a JSON string from the submitted information
|
|
||||||
*
|
|
||||||
* @return compiled JSON string
|
|
||||||
*/
|
|
||||||
private String toJsonString() {
|
|
||||||
final StringBuilder builder = new StringBuilder("{\n");
|
|
||||||
builder.append("\"paste_application\": \"").append(this.pasteApplication).append("\",\n\"files\": \"");
|
|
||||||
Iterator<PasteFile> fileIterator = this.files.iterator();
|
|
||||||
while (fileIterator.hasNext()) {
|
|
||||||
final PasteFile file = fileIterator.next();
|
|
||||||
builder.append(file.getFileName());
|
|
||||||
if (fileIterator.hasNext()) {
|
|
||||||
builder.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.append("\",\n");
|
|
||||||
fileIterator = this.files.iterator();
|
|
||||||
while (fileIterator.hasNext()) {
|
|
||||||
final PasteFile file = fileIterator.next();
|
|
||||||
builder.append("\"file-").append(file.getFileName()).append("\": \"")
|
|
||||||
.append(file.getContent().replaceAll("\"", "\\\\\"")).append("\"");
|
|
||||||
if (fileIterator.hasNext()) {
|
|
||||||
builder.append(",\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.append("\n}");
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload the paste and return the status message
|
|
||||||
*
|
|
||||||
* @return Status message
|
|
||||||
* @throws Throwable any and all exceptions
|
|
||||||
*/
|
|
||||||
public final String upload() throws Throwable {
|
|
||||||
final URL url = new URL(UPLOAD_PATH);
|
|
||||||
final URLConnection connection = url.openConnection();
|
|
||||||
final HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
|
|
||||||
httpURLConnection.setRequestMethod("POST");
|
|
||||||
httpURLConnection.setDoOutput(true);
|
|
||||||
final byte[] content = toJsonString().getBytes(Charsets.UTF_8);
|
|
||||||
httpURLConnection.setFixedLengthStreamingMode(content.length);
|
|
||||||
httpURLConnection.setRequestProperty("Content-Type", "application/json");
|
|
||||||
httpURLConnection.setRequestProperty("Accept", "*/*");
|
|
||||||
httpURLConnection.connect();
|
|
||||||
try (final OutputStream stream = httpURLConnection.getOutputStream()) {
|
|
||||||
stream.write(content);
|
|
||||||
}
|
|
||||||
if (!httpURLConnection.getResponseMessage().contains("OK")) {
|
|
||||||
throw new IllegalStateException(String.format("Server returned status: %d %s",
|
|
||||||
httpURLConnection.getResponseCode(), httpURLConnection.getResponseMessage()));
|
|
||||||
}
|
|
||||||
final StringBuilder input = new StringBuilder();
|
|
||||||
try (final BufferedReader inputStream = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()))) {
|
|
||||||
String line;
|
|
||||||
while ((line = inputStream.readLine()) != null) {
|
|
||||||
input.append(line).append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return input.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple class that represents a paste file
|
|
||||||
*/
|
|
||||||
public static class PasteFile {
|
|
||||||
|
|
||||||
private final String fileName;
|
|
||||||
private final String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new paste file
|
|
||||||
*
|
|
||||||
* @param fileName File name, cannot be empty, nor null
|
|
||||||
* @param content File content, cannot be empty, nor null
|
|
||||||
*/
|
|
||||||
public PasteFile(final String fileName, final String content) {
|
|
||||||
if (fileName == null || fileName.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("file name cannot be null, nor empty");
|
|
||||||
}
|
|
||||||
if (content == null || content.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("content cannot be null, nor empty");
|
|
||||||
}
|
|
||||||
this.fileName = fileName;
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file name
|
|
||||||
*
|
|
||||||
* @return File name
|
|
||||||
*/
|
|
||||||
public String getFileName() {
|
|
||||||
return this.fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file content as a single string
|
|
||||||
*
|
|
||||||
* @return File content
|
|
||||||
*/
|
|
||||||
public String getContent() {
|
|
||||||
return this.content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String debugPaste() throws IOException {
|
|
||||||
final IncendoPaster incendoPaster = new IncendoPaster("fastasyncworldedit");
|
|
||||||
|
|
||||||
StringBuilder b = new StringBuilder();
|
|
||||||
b.append(
|
|
||||||
"# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your "
|
|
||||||
+ "problem\n");
|
|
||||||
b.append("\n# Server Information\n");
|
|
||||||
b.append(Fawe.imp().getDebugInfo());
|
|
||||||
b.append("\n# YAY! Now, let's see what we can find in your JVM\n");
|
|
||||||
Runtime runtime = Runtime.getRuntime();
|
|
||||||
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
|
||||||
b.append("Uptime: ").append(TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS))
|
|
||||||
.append(" minutes").append('\n');
|
|
||||||
b.append("JVM Flags: ").append(rb.getInputArguments()).append('\n');
|
|
||||||
b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024).append(" MB").append('\n');
|
|
||||||
b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024).append(" MB").append('\n');
|
|
||||||
b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024).append(" MB").append('\n');
|
|
||||||
b.append("Available Processors: ").append(runtime.availableProcessors()).append('\n');
|
|
||||||
b.append("Java Name: ").append(rb.getVmName()).append('\n');
|
|
||||||
b.append("Java Version: '").append(System.getProperty("java.version")).append("'\n");
|
|
||||||
b.append("Java Vendor: '").append(System.getProperty("java.vendor")).append("'\n");
|
|
||||||
b.append("Operating System: '").append(System.getProperty("os.name")).append("'\n");
|
|
||||||
b.append("OS Version: ").append(System.getProperty("os.version")).append('\n');
|
|
||||||
b.append("OS Arch: ").append(System.getProperty("os.arch")).append('\n');
|
|
||||||
b.append("# Okay :D Great. You are now ready to create your bug report!");
|
|
||||||
b.append("\n# You can do so at https://github.com/IntellectualSites/FastAsyncWorldEdit/issues");
|
|
||||||
b.append("\n# or via our Discord at https://discord.gg/KxkjDVg");
|
|
||||||
incendoPaster.addFile(new IncendoPaster.PasteFile("information", b.toString()));
|
|
||||||
|
|
||||||
try {
|
|
||||||
final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log");
|
|
||||||
final String file;
|
|
||||||
if (Files.size(logFile.toPath()) > 14_000_000) {
|
|
||||||
file = "too big :(";
|
|
||||||
} else {
|
|
||||||
file = readFile(logFile);
|
|
||||||
}
|
|
||||||
incendoPaster.addFile(new IncendoPaster.PasteFile("latest.log", file));
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
incendoPaster.addFile(new PasteFile("config.yml", readFile(new File(Fawe.imp().getDirectory(), "config.yml"))));
|
|
||||||
incendoPaster.addFile(new PasteFile("config-legacy.yml", readFile(new File(Fawe.imp().getDirectory(), "config-legacy.yml"))));
|
|
||||||
|
|
||||||
final String rawResponse;
|
|
||||||
try {
|
|
||||||
rawResponse = incendoPaster.upload();
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
throw new IOException(String.format("Failed to upload files: %s", throwable.getMessage()), throwable);
|
|
||||||
}
|
|
||||||
final JsonObject jsonObject = new JsonParser().parse(rawResponse).getAsJsonObject();
|
|
||||||
|
|
||||||
if (jsonObject.has("created")) {
|
|
||||||
final String pasteId = jsonObject.get("paste_id").getAsString();
|
|
||||||
return String.format("https://athion.net/ISPaster/paste/view/%s", pasteId);
|
|
||||||
} else {
|
|
||||||
throw new IOException(String.format("Failed to upload files: %s",
|
|
||||||
jsonObject.get("response").getAsString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String readFile(final File file) throws IOException {
|
|
||||||
final StringBuilder content = new StringBuilder();
|
|
||||||
final List<String> lines = new ArrayList<>();
|
|
||||||
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
lines.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = Math.max(0, lines.size() - 1000); i < lines.size(); i++) {
|
|
||||||
content.append(lines.get(i)).append("\n");
|
|
||||||
}
|
|
||||||
return content.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -34,6 +34,9 @@ import net.jpountz.lz4.LZ4InputStream;
|
|||||||
import net.jpountz.lz4.LZ4Utils;
|
import net.jpountz.lz4.LZ4Utils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -66,6 +69,7 @@ import java.nio.file.attribute.BasicFileAttributes;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -83,8 +87,6 @@ import java.util.zip.GZIPInputStream;
|
|||||||
import java.util.zip.Inflater;
|
import java.util.zip.Inflater;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import static java.lang.System.arraycopy;
|
import static java.lang.System.arraycopy;
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
@ -448,24 +450,44 @@ public class MainUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPosition(CompoundTag tag, int x, int y, int z) {
|
/**
|
||||||
Map<String, Tag> value = tag.getValue();
|
* Create a copy of the tag and modify the (x, y, z) coordinates
|
||||||
|
*
|
||||||
|
* @param tag Tag to copy
|
||||||
|
* @param x New X coordinate
|
||||||
|
* @param y New Y coordinate
|
||||||
|
* @param z New Z coordinate
|
||||||
|
* @return New tag
|
||||||
|
*/
|
||||||
|
public static @NotNull CompoundTag setPosition(@Nonnull CompoundTag tag, int x, int y, int z) {
|
||||||
|
Map<String, Tag> value = new HashMap<>(tag.getValue());
|
||||||
value.put("x", new IntTag(x));
|
value.put("x", new IntTag(x));
|
||||||
value.put("y", new IntTag(y));
|
value.put("y", new IntTag(y));
|
||||||
value.put("z", new IntTag(z));
|
value.put("z", new IntTag(z));
|
||||||
|
return new CompoundTag(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setEntityInfo(CompoundTag tag, Entity entity) {
|
/**
|
||||||
Map<String, Tag> map = tag.getValue();
|
* Create a copy of the tag and modify the entity inf
|
||||||
|
*
|
||||||
|
* @param tag Tag to copy
|
||||||
|
* @param entity Entity
|
||||||
|
* @return New tag
|
||||||
|
*/
|
||||||
|
public static @NotNull CompoundTag setEntityInfo(@NotNull CompoundTag tag, @NotNull Entity entity) {
|
||||||
|
Map<String, Tag> map = new HashMap<>(tag.getValue());
|
||||||
map.put("Id", new StringTag(entity.getState().getType().getId()));
|
map.put("Id", new StringTag(entity.getState().getType().getId()));
|
||||||
ListTag pos = (ListTag) map.get("Pos");
|
ListTag pos = (ListTag) map.get("Pos");
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
Location loc = entity.getLocation();
|
Location loc = entity.getLocation();
|
||||||
List<Tag> posList = ReflectionUtils.getList(pos.getValue());
|
// Create a copy, because the list is immutable...
|
||||||
|
List<Tag> posList = new ArrayList<>(pos.getValue());
|
||||||
posList.set(0, new DoubleTag(loc.getX()));
|
posList.set(0, new DoubleTag(loc.getX()));
|
||||||
posList.set(1, new DoubleTag(loc.getY()));
|
posList.set(1, new DoubleTag(loc.getY()));
|
||||||
posList.set(2, new DoubleTag(loc.getZ()));
|
posList.set(2, new DoubleTag(loc.getZ()));
|
||||||
|
map.put("Pos", new ListTag(pos.getType(), posList));
|
||||||
}
|
}
|
||||||
|
return new CompoundTag(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getText(String url) throws IOException {
|
public static String getText(String url) throws IOException {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.util;
|
package com.boydti.fawe.util;
|
||||||
|
|
||||||
|
import com.plotsquared.core.util.PseudoRandom;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
@ -34,6 +35,8 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
|||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
int i1 = -i;
|
int i1 = -i;
|
||||||
return -ThreadLocalRandom.current().nextInt(i1);
|
return -ThreadLocalRandom.current().nextInt(i1);
|
||||||
|
} else if( i == 0) {
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return ThreadLocalRandom.current().nextInt(i);
|
return ThreadLocalRandom.current().nextInt(i);
|
||||||
}
|
}
|
||||||
|
@ -67,22 +67,6 @@ public class ReflectionUtils {
|
|||||||
blankField(enumClass, "enumConstants"); // IBM JDK
|
blankField(enumClass, "enumConstants"); // IBM JDK
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> getList(List<T> list) {
|
|
||||||
try {
|
|
||||||
Class<? extends List<T>> clazz = (Class<? extends List<T>>) Class
|
|
||||||
.forName("java.util.Collections$UnmodifiableList");
|
|
||||||
if (!clazz.isInstance(list)) {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
Field m = clazz.getDeclaredField("list");
|
|
||||||
m.setAccessible(true);
|
|
||||||
return (List<T>) m.get(list);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object getHandle(Object wrapper) {
|
public static Object getHandle(Object wrapper) {
|
||||||
final Method getHandle = makeMethod(wrapper.getClass(), "getHandle");
|
final Method getHandle = makeMethod(wrapper.getClass(), "getHandle");
|
||||||
return callMethod(getHandle, wrapper);
|
return callMethod(getHandle, wrapper);
|
||||||
|
@ -629,7 +629,6 @@ public class TextureUtil implements TextureHolder {
|
|||||||
mods.add(modId);
|
mods.add(modId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
String modelsDir = "assets/%1$s/models/block/%2$s.json";
|
String modelsDir = "assets/%1$s/models/block/%2$s.json";
|
||||||
String texturesDir = "assets/%1$s/textures/%2$s.png";
|
String texturesDir = "assets/%1$s/textures/%2$s.png";
|
||||||
@ -638,14 +637,14 @@ public class TextureUtil implements TextureHolder {
|
|||||||
}.getType();
|
}.getType();
|
||||||
|
|
||||||
for (BlockType blockType : BlockTypesCache.values) {
|
for (BlockType blockType : BlockTypesCache.values) {
|
||||||
if (!blockType.getMaterial().isFullCube()) {
|
if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int combined = blockType.getInternalId();
|
int combined = blockType.getInternalId();
|
||||||
String id = blockType.getId();
|
String id = blockType.getId();
|
||||||
String[] split = id.split(":", 2);
|
String[] split = id.split(":", 2);
|
||||||
String name = split.length == 1 ? id : split[1];
|
String name = split.length == 1 ? id : split[1];
|
||||||
String nameSpace = split.length == 1 ? "minecraft" : split[0];
|
String nameSpace = split.length == 1 ? "" : split[0];
|
||||||
|
|
||||||
Map<String, String> texturesMap = new ConcurrentHashMap<>();
|
Map<String, String> texturesMap = new ConcurrentHashMap<>();
|
||||||
// Read models
|
// Read models
|
||||||
@ -684,8 +683,11 @@ public class TextureUtil implements TextureHolder {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] texSplit = models.iterator().next().split(":");
|
||||||
|
String texture = texSplit[texSplit.length - 1];
|
||||||
|
|
||||||
textureFileName =
|
textureFileName =
|
||||||
String.format(texturesDir, nameSpace, models.iterator().next());
|
String.format(texturesDir, nameSpace, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedImage image = readImage(zipFile, textureFileName);
|
BufferedImage image = readImage(zipFile, textureFileName);
|
||||||
|
@ -26,11 +26,6 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public final class ByteArrayTag extends Tag {
|
public final class ByteArrayTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_BYTE_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final byte[] value;
|
private final byte[] value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,4 +56,11 @@ public final class ByteArrayTag extends Tag {
|
|||||||
return "TAG_Byte_Array(" + hex + ")";
|
return "TAG_Byte_Array(" + hex + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_BYTE_ARRAY;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Byte} tag.
|
* The {@code TAG_Byte} tag.
|
||||||
*/
|
*/
|
||||||
public final class ByteTag extends NumberTag {
|
public final class ByteTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_BYTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final byte value;
|
private final byte value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class ByteTag extends NumberTag {
|
|||||||
return "TAG_Byte(" + value + ")";
|
return "TAG_Byte(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_BYTE;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
@ -34,12 +35,7 @@ import java.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public class CompoundTag extends Tag {
|
public class CompoundTag extends Tag {
|
||||||
|
|
||||||
@Override
|
private final Map<String, Tag> value;
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_COMPOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Tag> value;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the tag with an empty name.
|
* Creates the tag with an empty name.
|
||||||
@ -48,7 +44,7 @@ public class CompoundTag extends Tag {
|
|||||||
*/
|
*/
|
||||||
public CompoundTag(Map<String, Tag> value) {
|
public CompoundTag(Map<String, Tag> value) {
|
||||||
super();
|
super();
|
||||||
this.value = value;
|
this.value = Collections.unmodifiableMap(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +54,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return true if the tag contains the given key
|
* @return true if the tag contains the given key
|
||||||
*/
|
*/
|
||||||
public boolean containsKey(String key) {
|
public boolean containsKey(String key) {
|
||||||
return getValue().containsKey(key);
|
return value.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,17 +62,6 @@ public class CompoundTag extends Tag {
|
|||||||
return value;
|
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) {
|
|
||||||
this.value = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a compound tag builder.
|
* Create a compound tag builder.
|
||||||
*
|
*
|
||||||
@ -96,7 +81,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a byte array
|
* @return a byte array
|
||||||
*/
|
*/
|
||||||
public byte[] getByteArray(String key) {
|
public byte[] getByteArray(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ByteArrayTag) {
|
if (tag instanceof ByteArrayTag) {
|
||||||
return ((ByteArrayTag) tag).getValue();
|
return ((ByteArrayTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -114,7 +99,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a byte
|
* @return a byte
|
||||||
*/
|
*/
|
||||||
public byte getByte(String key) {
|
public byte getByte(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ByteTag) {
|
if (tag instanceof ByteTag) {
|
||||||
return ((ByteTag) tag).getValue();
|
return ((ByteTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -132,7 +117,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a double
|
* @return a double
|
||||||
*/
|
*/
|
||||||
public double getDouble(String key) {
|
public double getDouble(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof DoubleTag) {
|
if (tag instanceof DoubleTag) {
|
||||||
return ((DoubleTag) tag).getValue();
|
return ((DoubleTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -151,9 +136,25 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a double
|
* @return a double
|
||||||
*/
|
*/
|
||||||
public double asDouble(String key) {
|
public double asDouble(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof NumberTag) {
|
if (tag instanceof ByteTag) {
|
||||||
return ((NumberTag) tag).getValue().doubleValue();
|
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 {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -169,7 +170,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a float
|
* @return a float
|
||||||
*/
|
*/
|
||||||
public float getFloat(String key) {
|
public float getFloat(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof FloatTag) {
|
if (tag instanceof FloatTag) {
|
||||||
return ((FloatTag) tag).getValue();
|
return ((FloatTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -187,7 +188,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return an int array
|
* @return an int array
|
||||||
*/
|
*/
|
||||||
public int[] getIntArray(String key) {
|
public int[] getIntArray(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof IntArrayTag) {
|
if (tag instanceof IntArrayTag) {
|
||||||
return ((IntArrayTag) tag).getValue();
|
return ((IntArrayTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -205,7 +206,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return an int
|
* @return an int
|
||||||
*/
|
*/
|
||||||
public int getInt(String key) {
|
public int getInt(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof IntTag) {
|
if (tag instanceof IntTag) {
|
||||||
return ((IntTag) tag).getValue();
|
return ((IntTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -224,9 +225,25 @@ public class CompoundTag extends Tag {
|
|||||||
* @return an int
|
* @return an int
|
||||||
*/
|
*/
|
||||||
public int asInt(String key) {
|
public int asInt(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof NumberTag) {
|
if (tag instanceof ByteTag) {
|
||||||
return ((NumberTag) tag).getValue().intValue();
|
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 {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -242,7 +259,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a list of tags
|
* @return a list of tags
|
||||||
*/
|
*/
|
||||||
public List<Tag> getList(String key) {
|
public List<Tag> getList(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ListTag) {
|
if (tag instanceof ListTag) {
|
||||||
return ((ListTag) tag).getValue();
|
return ((ListTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -260,7 +277,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a tag list instance
|
* @return a tag list instance
|
||||||
*/
|
*/
|
||||||
public ListTag getListTag(String key) {
|
public ListTag getListTag(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ListTag) {
|
if (tag instanceof ListTag) {
|
||||||
return (ListTag) tag;
|
return (ListTag) tag;
|
||||||
} else {
|
} else {
|
||||||
@ -273,7 +290,7 @@ public class CompoundTag extends Tag {
|
|||||||
*
|
*
|
||||||
* <p>If the key does not exist or its value is not a list tag,
|
* <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
|
* then an empty list will be returned. If the given key references
|
||||||
* a list but the list of a different type, then an empty
|
* a list but the list of of a different type, then an empty
|
||||||
* list will also be returned.</p>
|
* list will also be returned.</p>
|
||||||
*
|
*
|
||||||
* @param key the key
|
* @param key the key
|
||||||
@ -283,7 +300,7 @@ public class CompoundTag extends Tag {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
|
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ListTag) {
|
if (tag instanceof ListTag) {
|
||||||
ListTag listTag = (ListTag) tag;
|
ListTag listTag = (ListTag) tag;
|
||||||
if (listTag.getType().equals(listType)) {
|
if (listTag.getType().equals(listType)) {
|
||||||
@ -299,14 +316,14 @@ public class CompoundTag extends Tag {
|
|||||||
/**
|
/**
|
||||||
* Get a {@code long[]} named with the given key.
|
* Get a {@code long[]} named with the given key.
|
||||||
*
|
*
|
||||||
* <p>If the key does not exist or its value is not a long array tag,
|
* <p>If the key does not exist or its value is not an long array tag,
|
||||||
* then an empty array will be returned.</p>
|
* then an empty array will be returned.</p>
|
||||||
*
|
*
|
||||||
* @param key the key
|
* @param key the key
|
||||||
* @return an int array
|
* @return an int array
|
||||||
*/
|
*/
|
||||||
public long[] getLongArray(String key) {
|
public long[] getLongArray(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof LongArrayTag) {
|
if (tag instanceof LongArrayTag) {
|
||||||
return ((LongArrayTag) tag).getValue();
|
return ((LongArrayTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -324,7 +341,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a long
|
* @return a long
|
||||||
*/
|
*/
|
||||||
public long getLong(String key) {
|
public long getLong(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof LongTag) {
|
if (tag instanceof LongTag) {
|
||||||
return ((LongTag) tag).getValue();
|
return ((LongTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -343,9 +360,25 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a long
|
* @return a long
|
||||||
*/
|
*/
|
||||||
public long asLong(String key) {
|
public long asLong(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof NumberTag) {
|
if (tag instanceof ByteTag) {
|
||||||
return ((NumberTag) tag).getValue().longValue();
|
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 {
|
} else {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
@ -361,7 +394,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a short
|
* @return a short
|
||||||
*/
|
*/
|
||||||
public short getShort(String key) {
|
public short getShort(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof ShortTag) {
|
if (tag instanceof ShortTag) {
|
||||||
return ((ShortTag) tag).getValue();
|
return ((ShortTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -379,7 +412,7 @@ public class CompoundTag extends Tag {
|
|||||||
* @return a string
|
* @return a string
|
||||||
*/
|
*/
|
||||||
public String getString(String key) {
|
public String getString(String key) {
|
||||||
Tag tag = getValue().get(key);
|
Tag tag = value.get(key);
|
||||||
if (tag instanceof StringTag) {
|
if (tag instanceof StringTag) {
|
||||||
return ((StringTag) tag).getValue();
|
return ((StringTag) tag).getValue();
|
||||||
} else {
|
} else {
|
||||||
@ -388,17 +421,17 @@ public class CompoundTag extends Tag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> toRaw() {
|
public String toString() {
|
||||||
HashMap<String, Object> raw = new HashMap<>();
|
StringBuilder bldr = new StringBuilder();
|
||||||
if (this.getValue().isEmpty()) {
|
bldr.append("TAG_Compound").append(": ").append(value.size()).append(" entries\r\n{\r\n");
|
||||||
return raw;
|
for (Map.Entry<String, Tag> entry : value.entrySet()) {
|
||||||
|
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
|
||||||
}
|
}
|
||||||
for (Map.Entry<String, Tag> entry : getValue().entrySet()) {
|
bldr.append("}");
|
||||||
raw.put(entry.getKey(), entry.getValue().toRaw());
|
return bldr.toString();
|
||||||
}
|
|
||||||
return raw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
long most = getLong("UUIDMost");
|
long most = getLong("UUIDMost");
|
||||||
long least = getLong("UUIDLeast");
|
long least = getLong("UUIDLeast");
|
||||||
@ -421,15 +454,21 @@ public class CompoundTag extends Tag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public int getTypeCode() {
|
||||||
Map<String, Tag> value = getValue();
|
return NBTConstants.TYPE_COMPOUND;
|
||||||
StringBuilder bldr = new StringBuilder();
|
|
||||||
bldr.append("TAG_Compound").append(": ").append(getValue().size()).append(" entries\r\n{\r\n");
|
|
||||||
for (Map.Entry<String, Tag> entry : getValue().entrySet()) {
|
|
||||||
bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
|
|
||||||
}
|
|
||||||
bldr.append("}");
|
|
||||||
return bldr.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toRaw() {
|
||||||
|
HashMap<String, Object> raw = new HashMap<>();
|
||||||
|
if (this.getValue().isEmpty()) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Tag> entry : getValue().entrySet()) {
|
||||||
|
raw.put(entry.getKey(), entry.getValue().toRaw());
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Double} tag.
|
* The {@code TAG_Double} tag.
|
||||||
*/
|
*/
|
||||||
public final class DoubleTag extends NumberTag {
|
public final class DoubleTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_DOUBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final double value;
|
private final double value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class DoubleTag extends NumberTag {
|
|||||||
return "TAG_Double(" + value + ")";
|
return "TAG_Double(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_DOUBLE;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,6 @@ package com.sk89q.jnbt;
|
|||||||
*/
|
*/
|
||||||
public final class EndTag extends Tag {
|
public final class EndTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
return null;
|
return null;
|
||||||
@ -39,4 +34,11 @@ public final class EndTag extends Tag {
|
|||||||
return "TAG_End";
|
return "TAG_End";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_END;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Float} tag.
|
* The {@code TAG_Float} tag.
|
||||||
*/
|
*/
|
||||||
public final class FloatTag extends NumberTag {
|
public final class FloatTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_FLOAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final float value;
|
private final float value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class FloatTag extends NumberTag {
|
|||||||
return "TAG_Float(" + value + ")";
|
return "TAG_Float(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_FLOAT;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public final class IntArrayTag extends Tag {
|
public final class IntArrayTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_INT_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int[] value;
|
private final int[] value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,4 +59,11 @@ public final class IntArrayTag extends Tag {
|
|||||||
return "TAG_Int_Array(" + hex + ")";
|
return "TAG_Int_Array(" + hex + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_INT_ARRAY;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Int} tag.
|
* The {@code TAG_Int} tag.
|
||||||
*/
|
*/
|
||||||
public final class IntTag extends NumberTag {
|
public final class IntTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class IntTag extends NumberTag {
|
|||||||
return "TAG_Int(" + value + ")";
|
return "TAG_Int(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_INT;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,9 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -31,11 +30,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public final class ListTag extends Tag {
|
public final class ListTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_LIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<? extends Tag> type;
|
private final Class<? extends Tag> type;
|
||||||
private final List<Tag> value;
|
private final List<Tag> value;
|
||||||
|
|
||||||
@ -421,18 +415,6 @@ public final class ListTag extends Tag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayList toRaw() {
|
|
||||||
ArrayList<Object> raw = new ArrayList<>();
|
|
||||||
if (this.value.isEmpty()) {
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
for (Tag elem : this.value) {
|
|
||||||
raw.add(elem.toRaw());
|
|
||||||
}
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder bldr = new StringBuilder();
|
StringBuilder bldr = new StringBuilder();
|
||||||
@ -444,4 +426,11 @@ public final class ListTag extends Tag {
|
|||||||
return bldr.toString();
|
return bldr.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_LIST;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public class LongArrayTag extends Tag {
|
public class LongArrayTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_LONG_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final long[] value;
|
private final long[] value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,4 +59,11 @@ public class LongArrayTag extends Tag {
|
|||||||
return "TAG_Long_Array(" + hex + ")";
|
return "TAG_Long_Array(" + hex + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_LONG_ARRAY;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Long} tag.
|
* The {@code TAG_Long} tag.
|
||||||
*/
|
*/
|
||||||
public final class LongTag extends NumberTag {
|
public final class LongTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final long value;
|
private final long value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class LongTag extends NumberTag {
|
|||||||
return "TAG_Long(" + value + ")";
|
return "TAG_Long(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_LONG;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,13 @@
|
|||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which holds constant values.
|
* A class which holds constant values.
|
||||||
*/
|
*/
|
||||||
public final class NBTConstants {
|
public final class NBTConstants {
|
||||||
|
|
||||||
public static final Charset CHARSET = StandardCharsets.UTF_8;
|
public static final Charset CHARSET = Charset.forName("UTF-8");
|
||||||
|
|
||||||
public static final int TYPE_END = 0;
|
public static final int TYPE_END = 0;
|
||||||
public static final int TYPE_BYTE = 1;
|
public static final int TYPE_BYTE = 1;
|
||||||
|
@ -32,6 +32,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
// THIS CLASS HAS BEEN HEAVILY MODIFIED BY FAWE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
* This class reads <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
||||||
* streams, and produces an object graph of subclasses of the {@code Tag}
|
* streams, and produces an object graph of subclasses of the {@code Tag}
|
||||||
@ -61,6 +63,14 @@ public final class NBTInputStream implements Closeable {
|
|||||||
this.is = dis;
|
this.is = dis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void mark(int mark) {
|
||||||
|
is.mark(mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() throws IOException {
|
||||||
|
is.reset();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an NBT tag from the stream.
|
* Reads an NBT tag from the stream.
|
||||||
*
|
*
|
||||||
@ -99,7 +109,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
if (child != null) {
|
if (child != null) {
|
||||||
child.acceptRoot(this, type, 0);
|
child.acceptRoot(this, type, 0);
|
||||||
} else {
|
} else {
|
||||||
readTagPaylodLazy(type, 0);
|
readTagPayloadLazy(type, 0);
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -119,7 +129,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
|
|
||||||
private byte[] buf;
|
private byte[] buf;
|
||||||
|
|
||||||
public void readTagPaylodLazy(int type, int depth) throws IOException {
|
public void readTagPayloadLazy(int type, int depth) throws IOException {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NBTConstants.TYPE_END:
|
case NBTConstants.TYPE_END:
|
||||||
return;
|
return;
|
||||||
@ -152,7 +162,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
int childType = is.readByte();
|
int childType = is.readByte();
|
||||||
length = is.readInt();
|
length = is.readInt();
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
readTagPaylodLazy(childType, depth + 1);
|
readTagPayloadLazy(childType, depth + 1);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -165,7 +175,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is.skipBytes(is.readShort() & 0xFFFF);
|
is.skipBytes(is.readShort() & 0xFFFF);
|
||||||
readTagPaylodLazy(childType, depth + 1);
|
readTagPayloadLazy(childType, depth + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case NBTConstants.TYPE_INT_ARRAY: {
|
case NBTConstants.TYPE_INT_ARRAY: {
|
||||||
@ -181,7 +191,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readTagPaylodLazy(int type, int depth, StreamDelegate scope) throws IOException {
|
public void readTagPayloadLazy(int type, int depth, StreamDelegate scope) throws IOException {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NBTConstants.TYPE_END:
|
case NBTConstants.TYPE_END:
|
||||||
return;
|
return;
|
||||||
@ -293,11 +303,11 @@ public final class NBTInputStream implements Closeable {
|
|||||||
child = scope.get0();
|
child = scope.get0();
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
readTagPaylodLazy(childType, depth + 1);
|
readTagPayloadLazy(childType, depth + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
readTagPaylodLazy(childType, depth + 1, child);
|
readTagPayloadLazy(childType, depth + 1, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -330,9 +340,9 @@ public final class NBTInputStream implements Closeable {
|
|||||||
}
|
}
|
||||||
StreamDelegate child = scope.get(is);
|
StreamDelegate child = scope.get(is);
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
readTagPaylodLazy(childType, depth + 1);
|
readTagPayloadLazy(childType, depth + 1);
|
||||||
} else {
|
} else {
|
||||||
readTagPaylodLazy(childType, depth + 1, child);
|
readTagPayloadLazy(childType, depth + 1, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -461,7 +471,7 @@ public final class NBTInputStream implements Closeable {
|
|||||||
case NBTConstants.TYPE_END:
|
case NBTConstants.TYPE_END:
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
|
"TAG_End found without a TAG_Compound/TAG_List tag preceding it.");
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
// THIS CLASS HAS BEEN HEAVILY MODIFIED BY FAWE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
* This class writes <strong>NBT</strong>, or <strong>Named Binary Tag</strong>
|
||||||
* {@code Tag} objects to an underlying {@code OutputStream}.
|
* {@code Tag} objects to an underlying {@code OutputStream}.
|
||||||
|
@ -49,7 +49,7 @@ public final class NBTUtils {
|
|||||||
return "TAG_Byte_Array";
|
return "TAG_Byte_Array";
|
||||||
} else if (clazz.equals(ByteTag.class)) {
|
} else if (clazz.equals(ByteTag.class)) {
|
||||||
return "TAG_Byte";
|
return "TAG_Byte";
|
||||||
} else if (CompoundTag.class.isAssignableFrom(clazz)) {
|
} else if (clazz.equals(CompoundTag.class)) {
|
||||||
return "TAG_Compound";
|
return "TAG_Compound";
|
||||||
} else if (clazz.equals(DoubleTag.class)) {
|
} else if (clazz.equals(DoubleTag.class)) {
|
||||||
return "TAG_Double";
|
return "TAG_Double";
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package com.sk89q.jnbt;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some data with a name
|
|
||||||
*/
|
|
||||||
public class NamedData<T> {
|
|
||||||
private final String name;
|
|
||||||
private final T data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new named tag.
|
|
||||||
*
|
|
||||||
* @param name the name
|
|
||||||
* @param data the data
|
|
||||||
*/
|
|
||||||
public NamedData(String name, T 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 T getValue() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.fawe.NumberTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code TAG_Short} tag.
|
* The {@code TAG_Short} tag.
|
||||||
*/
|
*/
|
||||||
public final class ShortTag extends NumberTag {
|
public final class ShortTag extends NumberTag {
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_SHORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final short value;
|
private final short value;
|
||||||
|
|
||||||
@ -50,4 +48,11 @@ public final class ShortTag extends NumberTag {
|
|||||||
return "TAG_Short(" + value + ")";
|
return "TAG_Short(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_SHORT;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
*/
|
*/
|
||||||
public final class StringTag extends Tag {
|
public final class StringTag extends Tag {
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTypeCode() {
|
|
||||||
return NBTConstants.TYPE_STRING;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,4 +49,11 @@ public final class StringTag extends Tag {
|
|||||||
return "TAG_String(" + value + ")";
|
return "TAG_String(" + value + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
|
@Override
|
||||||
|
public int getTypeCode() {
|
||||||
|
return NBTConstants.TYPE_STRING;
|
||||||
|
}
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,12 @@ public abstract class Tag {
|
|||||||
*/
|
*/
|
||||||
public abstract Object getValue();
|
public abstract Object getValue();
|
||||||
|
|
||||||
|
// FAWE Start
|
||||||
public Object toRaw() {
|
public Object toRaw() {
|
||||||
return getValue();
|
return getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int getTypeCode();
|
public abstract int getTypeCode();
|
||||||
|
// FAWE End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class CompressedCompoundTag<T> extends CompoundTag {
|
public abstract class CompressedCompoundTag<T> extends CompoundTag {
|
||||||
|
|
||||||
private T in;
|
private T in;
|
||||||
|
|
||||||
public CompressedCompoundTag(T in) {
|
public CompressedCompoundTag(T in) {
|
||||||
@ -41,4 +42,5 @@ public abstract class CompressedCompoundTag<T> extends CompoundTag {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt.fawe;
|
||||||
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||||
|
import com.sk89q.jnbt.CompressedCompoundTag;
|
||||||
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.FastSchematicWriter;
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
@ -10,6 +12,7 @@ import net.jpountz.lz4.LZ4BlockOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class CompressedSchematicTag extends CompressedCompoundTag<Clipboard> {
|
public class CompressedSchematicTag extends CompressedCompoundTag<Clipboard> {
|
||||||
|
|
||||||
public CompressedSchematicTag(Clipboard holder) {
|
public CompressedSchematicTag(Clipboard holder) {
|
||||||
super(holder);
|
super(holder);
|
||||||
}
|
}
|
||||||
@ -26,4 +29,5 @@ public class CompressedSchematicTag extends CompressedCompoundTag<Clipboard> {
|
|||||||
FastByteArraysInputStream in = new FastByteArraysInputStream(blocksOut.toByteArrays());
|
FastByteArraysInputStream in = new FastByteArraysInputStream(blocksOut.toByteArrays());
|
||||||
return new LZ4BlockInputStream(in);
|
return new LZ4BlockInputStream(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,13 @@
|
|||||||
package com.sk89q.jnbt;
|
package com.sk89q.jnbt.fawe;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A numerical {@link Tag}
|
||||||
|
*/
|
||||||
public abstract class NumberTag extends Tag {
|
public abstract class NumberTag extends Tag {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract Number getValue();
|
public abstract Number getValue();
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* These are classes added by FAWE. They do not exist in WorldEdit
|
||||||
|
*/
|
||||||
|
package com.sk89q.jnbt.fawe;
|
@ -125,8 +125,6 @@ import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
|||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockCategories;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
@ -148,6 +146,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -2046,18 +2045,18 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
|
|
||||||
int yy;
|
int yy;
|
||||||
|
|
||||||
double nextXn = invRadiusX;
|
double nextXn = 0;
|
||||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||||
final double xn = nextXn;
|
final double xn = nextXn;
|
||||||
double dx = xn * xn;
|
double dx = xn * xn;
|
||||||
nextXn = (x + 1) * invRadiusX;
|
nextXn = (x + 1) * invRadiusX;
|
||||||
double nextZn = invRadiusZ;
|
double nextZn = 0;
|
||||||
forZ: for (int z = 0; z <= ceilRadiusZ; ++z) {
|
forZ: for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||||
final double zn = nextZn;
|
final double zn = nextZn;
|
||||||
double dz = zn * zn;
|
double dz = zn * zn;
|
||||||
double dxz = dx + dz;
|
double dxz = dx + dz;
|
||||||
nextZn = (z + 1) * invRadiusZ;
|
nextZn = (z + 1) * invRadiusZ;
|
||||||
double nextYn = invRadiusY;
|
double nextYn = 0;
|
||||||
|
|
||||||
forY: for (int y = 0; y <= ceilRadiusY; ++y) {
|
forY: for (int y = 0; y <= ceilRadiusY; ++y) {
|
||||||
final double yn = nextYn;
|
final double yn = nextYn;
|
||||||
@ -2767,7 +2766,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
newVset = this.getHollowed(newVset);
|
newVset = this.getHollowed(newVset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return setBlocks(newVset, pattern);
|
return this.changes += setBlocks(newVset, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2840,7 +2839,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
if (!filled) {
|
if (!filled) {
|
||||||
vset = getHollowed(vset);
|
vset = getHollowed(vset);
|
||||||
}
|
}
|
||||||
return setBlocks(vset, pattern);
|
return this.changes += setBlocks(vset, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2892,7 +2891,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
if (!filled) {
|
if (!filled) {
|
||||||
newVset = this.getHollowed(newVset);
|
newVset = this.getHollowed(newVset);
|
||||||
}
|
}
|
||||||
return setBlocks(newVset, pattern);
|
return this.changes += setBlocks(newVset, pattern);
|
||||||
}
|
}
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
@ -3008,23 +3007,21 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType,
|
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType,
|
||||||
final String expressionString, final boolean hollow)
|
final String expressionString, final boolean hollow) throws ExpressionException {
|
||||||
throws ExpressionException, MaxChangedBlocksException {
|
|
||||||
return makeBiomeShape(region, zero, unit, biomeType, expressionString, hollow, WorldEdit.getInstance().getConfiguration().calculationTimeout);
|
return makeBiomeShape(region, zero, unit, biomeType, expressionString, hollow, WorldEdit.getInstance().getConfiguration().calculationTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType,
|
public int makeBiomeShape(final Region region, final Vector3 zero, final Vector3 unit, final BiomeType biomeType,
|
||||||
final String expressionString, final boolean hollow, final int timeout)
|
final String expressionString, final boolean hollow, final int timeout) throws ExpressionException {
|
||||||
throws ExpressionException, MaxChangedBlocksException {
|
|
||||||
|
|
||||||
final Expression expression = Expression.compile(expressionString, "x", "z");
|
final Expression expression = Expression.compile(expressionString, "x", "y", "z");
|
||||||
expression.optimize();
|
expression.optimize();
|
||||||
|
|
||||||
final EditSession editSession = this;
|
final EditSession editSession = this;
|
||||||
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(editSession, unit, zero);
|
final WorldEditExpressionEnvironment environment = new WorldEditExpressionEnvironment(editSession, unit, zero);
|
||||||
expression.setEnvironment(environment);
|
expression.setEnvironment(environment);
|
||||||
|
|
||||||
final int[] timedOut = {0};
|
AtomicInteger timedOut = new AtomicInteger();
|
||||||
final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {
|
final ArbitraryBiomeShape shape = new ArbitraryBiomeShape(region) {
|
||||||
@Override
|
@Override
|
||||||
protected BiomeType getBiome(int x, int y, int z, BiomeType defaultBiomeType) {
|
protected BiomeType getBiome(int x, int y, int z, BiomeType defaultBiomeType) {
|
||||||
@ -3041,7 +3038,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
// TODO: Allow biome setting via a script variable (needs BiomeType<->int mapping)
|
// TODO: Allow biome setting via a script variable (needs BiomeType<->int mapping)
|
||||||
return defaultBiomeType;
|
return defaultBiomeType;
|
||||||
} catch (ExpressionTimeoutException e) {
|
} catch (ExpressionTimeoutException e) {
|
||||||
timedOut[0] = timedOut[0] + 1;
|
timedOut.getAndIncrement();
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Failed to create shape", e);
|
log.warn("Failed to create shape", e);
|
||||||
@ -3050,10 +3047,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
int changed = shape.generate(this, biomeType, hollow);
|
int changed = shape.generate(this, biomeType, hollow);
|
||||||
if (timedOut[0] > 0) {
|
if (timedOut.get() > 0) {
|
||||||
throw new ExpressionTimeoutException(
|
throw new ExpressionTimeoutException(
|
||||||
String.format("%d blocks changed. %d blocks took too long to evaluate (increase time with //timeout)",
|
String.format("%d biomes changed. %d biomes took too long to evaluate (increase time with //timeout)",
|
||||||
changed, timedOut[0]));
|
changed, timedOut.get()));
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,6 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
|||||||
import com.sk89q.worldedit.command.util.CreatureButcher;
|
import com.sk89q.worldedit.command.util.CreatureButcher;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extension.platform.binding.ProvideBindings;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||||
import com.sk89q.worldedit.function.Contextual;
|
import com.sk89q.worldedit.function.Contextual;
|
||||||
@ -130,6 +129,7 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -498,22 +498,23 @@ public class BrushCommands {
|
|||||||
set(context, brush).setSize(radius).setFill(fill);
|
set(context, brush).setSize(radius).setFill(fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(name = "image",
|
||||||
name = "image",
|
|
||||||
desc = "Use a height map to paint a surface",
|
desc = "Use a height map to paint a surface",
|
||||||
descFooter = "Use a height map to paint any surface.\n"
|
descFooter = "Use a height map to paint any surface.\n")
|
||||||
)
|
@CommandPermissions("worldedit.brush.image")
|
||||||
@CommandPermissions("worldedit.brush.stencil")
|
public void imageBrush(LocalSession session,
|
||||||
public void imageBrush(LocalSession session, InjectedValueAccess context,
|
InjectedValueAccess context,
|
||||||
@Arg(desc = "The size of the brush", def = "5")
|
@Arg(desc = "Image URL (imgur only)") String imageURL,
|
||||||
Expression radius, ProvideBindings.ImageUri imageUri,
|
@Arg(desc = "The size of the brush", def = "5") Expression radius,
|
||||||
@Arg(def = "1", desc = "scale height")
|
@Arg(def = "1", desc = "scale height") double yscale,
|
||||||
double yscale,
|
@Switch(name = 'a', desc = "Use image Alpha") boolean alpha,
|
||||||
@Switch(name = 'a', desc = "Use image Alpha")
|
@Switch(name = 'f', desc = "Blend the image with existing terrain") boolean fadeOut)
|
||||||
boolean alpha,
|
throws WorldEditException, IOException {
|
||||||
@Switch(name = 'f', desc = "Blend the image with existing terrain")
|
URL url = new URL(imageURL);
|
||||||
boolean fadeOut) throws WorldEditException, IOException {
|
if (!url.getHost().equalsIgnoreCase("i.imgur.com")) {
|
||||||
BufferedImage image = imageUri.load();
|
throw new IOException("Only i.imgur.com links are allowed!");
|
||||||
|
}
|
||||||
|
BufferedImage image = MainUtil.readImage(url);
|
||||||
worldEdit.checkMaxBrushRadius(radius);
|
worldEdit.checkMaxBrushRadius(radius);
|
||||||
if (yscale != 1) {
|
if (yscale != 1) {
|
||||||
ImageUtil.scaleAlpha(image, yscale);
|
ImageUtil.scaleAlpha(image, yscale);
|
||||||
|
@ -277,7 +277,7 @@ public class ClipboardCommands {
|
|||||||
)
|
)
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@CommandPermissions({"worldedit.clipboard.download"})
|
@CommandPermissions({"worldedit.clipboard.download"})
|
||||||
public void download(final Player player, final LocalSession session, @Arg(name = "format", desc = "String", def = "schem") final String formatName) throws WorldEditException {
|
public void download(final Player player, final LocalSession session, @Arg(name = "format", desc = "String", def = "fast") final String formatName) throws WorldEditException {
|
||||||
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format", formatName));
|
player.print(Caption.of("fawe.worldedit.clipboard.clipboard.invalid.format", formatName));
|
||||||
|
@ -58,7 +58,7 @@ import org.enginehub.piston.annotation.param.Arg;
|
|||||||
import org.enginehub.piston.annotation.param.Switch;
|
import org.enginehub.piston.annotation.param.Switch;
|
||||||
import org.jetbrains.annotations.Range;
|
import org.jetbrains.annotations.Range;
|
||||||
|
|
||||||
import java.awt.RenderingHints;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -131,20 +131,26 @@ public class GenerationCommands {
|
|||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.generation.image")
|
@CommandPermissions("worldedit.generation.image")
|
||||||
@Logging(PLACEMENT)
|
@Logging(PLACEMENT)
|
||||||
public void image(Actor actor, LocalSession session, EditSession editSession, String argStr, @Arg(desc = "boolean", def = "true") boolean randomize,
|
public void image(Actor actor,
|
||||||
@Arg(desc = "TODO", def = "100") int threshold, @Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException {
|
LocalSession session,
|
||||||
|
EditSession editSession,
|
||||||
|
@Arg(desc = "Image URL (imgur only)") String imageURL,
|
||||||
|
@Arg(desc = "boolean", def = "true") boolean randomize,
|
||||||
|
@Arg(desc = "TODO", def = "100") int threshold,
|
||||||
|
@Arg(desc = "BlockVector2", def = "") BlockVector2 dimensions) throws WorldEditException, IOException {
|
||||||
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
TextureUtil tu = Fawe.get().getCachedTextureUtil(randomize, 0, threshold);
|
||||||
URL url = new URL(argStr);
|
URL url = new URL(imageURL);
|
||||||
if (!url.getHost().equalsIgnoreCase("i.imgur.com")) {
|
if (!url.getHost().equalsIgnoreCase("i.imgur.com")) {
|
||||||
throw new IOException("Only i.imgur.com links are allowed!");
|
throw new IOException("Only i.imgur.com links are allowed!");
|
||||||
}
|
}
|
||||||
BufferedImage image = MainUtil.readImage(url);
|
BufferedImage image = MainUtil.readImage(url);
|
||||||
if (dimensions != null) {
|
if (dimensions != null) {
|
||||||
image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(), RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(),
|
||||||
|
RenderingHints.VALUE_INTERPOLATION_BILINEAR, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockVector3 pos1 = session.getPlacementPosition(actor);
|
BlockVector3 pos1 = session.getPlacementPosition(actor);
|
||||||
BlockVector3 pos2 = pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1);
|
BlockVector3 pos2 = pos1.add(image.getWidth() - 1, 0, image.getHeight() - 1);
|
||||||
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
CuboidRegion region = new CuboidRegion(pos1, pos2);
|
||||||
int[] count = new int[1];
|
int[] count = new int[1];
|
||||||
final BufferedImage finalImage = image;
|
final BufferedImage finalImage = image;
|
||||||
|
@ -147,7 +147,7 @@ public class SchematicCommands {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"})
|
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"})
|
||||||
public void loadall(Player player, LocalSession session,
|
public void loadall(Player player, LocalSession session,
|
||||||
@Arg(desc = "Format name.", def = "schematic")
|
@Arg(desc = "Format name.", def = "fast")
|
||||||
String formatName,
|
String formatName,
|
||||||
@Arg(desc = "File name.")
|
@Arg(desc = "File name.")
|
||||||
String filename,
|
String filename,
|
||||||
@ -223,7 +223,7 @@ public class SchematicCommands {
|
|||||||
public void load(Actor actor, LocalSession session,
|
public void load(Actor actor, LocalSession session,
|
||||||
@Arg(desc = "File name.")
|
@Arg(desc = "File name.")
|
||||||
String filename,
|
String filename,
|
||||||
@Arg(desc = "Format name.", def = "sponge")
|
@Arg(desc = "Format name.", def = "fast")
|
||||||
String formatName) throws FilenameException {
|
String formatName) throws FilenameException {
|
||||||
LocalConfiguration config = worldEdit.getConfiguration();
|
LocalConfiguration config = worldEdit.getConfiguration();
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ public class SchematicCommands {
|
|||||||
public void save(Actor actor, LocalSession session,
|
public void save(Actor actor, LocalSession session,
|
||||||
@Arg(desc = "File name.")
|
@Arg(desc = "File name.")
|
||||||
String filename,
|
String filename,
|
||||||
@Arg(desc = "Format name.", def = "sponge")
|
@Arg(desc = "Format name.", def = "fast")
|
||||||
String formatName,
|
String formatName,
|
||||||
@Switch(name = 'f', desc = "Overwrite an existing file.")
|
@Switch(name = 'f', desc = "Overwrite an existing file.")
|
||||||
boolean allowOverwrite,
|
boolean allowOverwrite,
|
||||||
|
@ -22,7 +22,7 @@ package com.sk89q.worldedit.command;
|
|||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweVersion;
|
import com.boydti.fawe.FaweVersion;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.util.IncendoPaster;
|
import com.intellectualsites.paster.IncendoPaster;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
@ -47,6 +47,7 @@ import org.enginehub.piston.annotation.param.Arg;
|
|||||||
import org.enginehub.piston.annotation.param.ArgFlag;
|
import org.enginehub.piston.annotation.param.ArgFlag;
|
||||||
import org.enginehub.piston.annotation.param.Switch;
|
import org.enginehub.piston.annotation.param.Switch;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
@ -139,7 +140,10 @@ public class WorldEditCommands {
|
|||||||
public void report(Actor actor) throws WorldEditException {
|
public void report(Actor actor) throws WorldEditException {
|
||||||
String dest;
|
String dest;
|
||||||
try {
|
try {
|
||||||
dest = IncendoPaster.debugPaste();
|
final File logFile = new File(Fawe.imp().getDirectory(), "../../logs/latest.log");
|
||||||
|
final File config = new File(Fawe.imp().getDirectory(), "config.yml");
|
||||||
|
final File legacyConfig = new File(Fawe.imp().getDirectory(), "config-legacy.yml");
|
||||||
|
dest = IncendoPaster.debugPaste(logFile, Fawe.imp().getDebugInfo(), config, legacyConfig);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
actor.printInfo(TextComponent.of(e.getMessage()));
|
actor.printInfo(TextComponent.of(e.getMessage()));
|
||||||
return;
|
return;
|
||||||
|
@ -24,8 +24,11 @@ import com.boydti.fawe.object.io.ResettableFileInputStream;
|
|||||||
import com.boydti.fawe.object.schematic.MinecraftStructure;
|
import com.boydti.fawe.object.schematic.MinecraftStructure;
|
||||||
import com.boydti.fawe.object.schematic.PNGWriter;
|
import com.boydti.fawe.object.schematic.PNGWriter;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
|
import com.sk89q.jnbt.NamedTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@ -35,6 +38,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
@ -44,40 +48,7 @@ import java.util.zip.GZIPOutputStream;
|
|||||||
*/
|
*/
|
||||||
public enum BuiltInClipboardFormat implements ClipboardFormat {
|
public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||||
|
|
||||||
/**
|
FAST("fast", "fawe") {
|
||||||
* The Schematic format used by MCEdit.
|
|
||||||
*/
|
|
||||||
MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPrimaryFileExtension() {
|
|
||||||
return "schematic";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
|
||||||
if (inputStream instanceof FileInputStream) {
|
|
||||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
|
||||||
}
|
|
||||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
|
||||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
|
||||||
SchematicReader input = new SchematicReader(nbtStream);
|
|
||||||
input.setUnderlyingStream(inputStream);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
|
||||||
throw new IOException("This format does not support saving, use `schem` or `sponge` as format"); // Is more helpful
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFormat(File file) {
|
|
||||||
String name = file.getName().toLowerCase(Locale.ROOT);
|
|
||||||
return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
SPONGE_SCHEMATIC("sponge", "schem") {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPrimaryFileExtension() {
|
public String getPrimaryFileExtension() {
|
||||||
@ -115,6 +86,129 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
SPONGE_SCHEMATIC("sponge", "schem") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrimaryFileExtension() {
|
||||||
|
return "schem";
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||||
|
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream));
|
||||||
|
return new SpongeSchematicReader(nbtStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||||
|
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream));
|
||||||
|
return new SpongeSchematicWriter(nbtStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFormat(File file) {
|
||||||
|
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||||
|
NamedTag rootTag = str.readNamedTag();
|
||||||
|
if (!rootTag.getName().equals("Schematic")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||||
|
|
||||||
|
// Check
|
||||||
|
Map<String, Tag> schematic = schematicTag.getValue();
|
||||||
|
if (!schematic.containsKey("Version")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Schematic format used by MCEdit.
|
||||||
|
*/
|
||||||
|
MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrimaryFileExtension() {
|
||||||
|
return "schematic";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||||
|
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream));
|
||||||
|
return new MCEditSchematicReader(nbtStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||||
|
throw new IOException("This format does not support saving");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFormat(File file) {
|
||||||
|
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||||
|
NamedTag rootTag = str.readNamedTag();
|
||||||
|
if (!rootTag.getName().equals("Schematic")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||||
|
|
||||||
|
// Check
|
||||||
|
Map<String, Tag> schematic = schematicTag.getValue();
|
||||||
|
if (!schematic.containsKey("Materials")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrimaryFileExtension() {
|
||||||
|
return "schem";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||||
|
if (inputStream instanceof FileInputStream) {
|
||||||
|
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||||
|
}
|
||||||
|
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||||
|
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||||
|
FastSchematicReader reader = new FastSchematicReader(nbtStream);
|
||||||
|
reader.setBrokenEntities(true);
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||||
|
OutputStream gzip;
|
||||||
|
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||||
|
gzip = outputStream;
|
||||||
|
} else {
|
||||||
|
outputStream = new BufferedOutputStream(outputStream);
|
||||||
|
gzip = new PGZIPOutputStream(outputStream);
|
||||||
|
}
|
||||||
|
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||||
|
FastSchematicWriter writer = new FastSchematicWriter(nbtStream);
|
||||||
|
writer.setBrokenEntities(true);
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFormat(File file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The structure block format:
|
* The structure block format:
|
||||||
* http://minecraft.gamepedia.com/Structure_block_file_format
|
* http://minecraft.gamepedia.com/Structure_block_file_format
|
||||||
|
@ -30,10 +30,12 @@ import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.IntTag;
|
import com.sk89q.jnbt.IntTag;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
|
import com.sk89q.jnbt.NamedTag;
|
||||||
import com.sk89q.jnbt.StringTag;
|
import com.sk89q.jnbt.StringTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
@ -45,6 +47,7 @@ import com.sk89q.worldedit.world.DataFixer;
|
|||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||||
@ -55,9 +58,11 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.OptionalInt;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@ -70,9 +75,10 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(FastSchematicReader.class);
|
private static final Logger log = LoggerFactory.getLogger(FastSchematicReader.class);
|
||||||
private final NBTInputStream inputStream;
|
private final NBTInputStream inputStream;
|
||||||
private DataFixer fixer = null;
|
private DataFixer fixer;
|
||||||
private int dataVersion = -1;
|
private int dataVersion = -1;
|
||||||
private int version = -1;
|
private int version = -1;
|
||||||
|
private int faweWritten = -1;
|
||||||
|
|
||||||
private FastByteArrayOutputStream blocksOut;
|
private FastByteArrayOutputStream blocksOut;
|
||||||
private FaweOutputStream blocks;
|
private FaweOutputStream blocks;
|
||||||
@ -92,6 +98,8 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
private char[] palette;
|
private char[] palette;
|
||||||
private char[] biomePalette;
|
private char[] biomePalette;
|
||||||
private BlockVector3 min = BlockVector3.ZERO;
|
private BlockVector3 min = BlockVector3.ZERO;
|
||||||
|
private boolean brokenEntities = false;
|
||||||
|
private boolean isWorldEdit = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,6 +113,10 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer();
|
this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBrokenEntities(boolean brokenEntities) {
|
||||||
|
this.brokenEntities = brokenEntities;
|
||||||
|
}
|
||||||
|
|
||||||
private String fix(String palettePart) {
|
private String fix(String palettePart) {
|
||||||
if (fixer == null || dataVersion == -1) {
|
if (fixer == null || dataVersion == -1) {
|
||||||
return palettePart;
|
return palettePart;
|
||||||
@ -133,7 +145,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
return fixer.fixUp(DataFixer.FixTypes.BIOME, biomePalettePart, dataVersion);
|
return fixer.fixUp(DataFixer.FixTypes.BIOME, biomePalettePart, dataVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamDelegate createDelegate() {
|
public StreamDelegate createVersionDelegate() {
|
||||||
StreamDelegate root = new StreamDelegate();
|
StreamDelegate root = new StreamDelegate();
|
||||||
StreamDelegate schematic = root.add("Schematic");
|
StreamDelegate schematic = root.add("Schematic");
|
||||||
schematic.add("DataVersion").withInt((i, v) -> dataVersion = v);
|
schematic.add("DataVersion").withInt((i, v) -> dataVersion = v);
|
||||||
@ -143,6 +155,12 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
dataVersion = Constants.DATA_VERSION_MC_1_13_2;
|
dataVersion = Constants.DATA_VERSION_MC_1_13_2;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StreamDelegate createDelegate() {
|
||||||
|
StreamDelegate root = new StreamDelegate();
|
||||||
|
StreamDelegate schematic = root.add("Schematic");
|
||||||
schematic.add("Width").withInt((i, v) -> width = v);
|
schematic.add("Width").withInt((i, v) -> width = v);
|
||||||
schematic.add("Height").withInt((i, v) -> height = v);
|
schematic.add("Height").withInt((i, v) -> height = v);
|
||||||
schematic.add("Length").withInt((i, v) -> length = v);
|
schematic.add("Length").withInt((i, v) -> length = v);
|
||||||
@ -152,17 +170,23 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
||||||
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
||||||
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
||||||
|
metadata.add("FAWEVersion").withInt((i, v) -> faweWritten = v);
|
||||||
|
|
||||||
|
StreamDelegate worldEditSection = metadata.add("WorldEdit");
|
||||||
|
worldEditSection.withValue((ValueReader<String>) (index, v) -> isWorldEdit = true);
|
||||||
|
|
||||||
|
|
||||||
StreamDelegate paletteDelegate = schematic.add("Palette");
|
StreamDelegate paletteDelegate = schematic.add("Palette");
|
||||||
paletteDelegate.withValue((ValueReader<Map<String, Object>>) (ignore, v) -> {
|
paletteDelegate.withValue((ValueReader<Map<String, Object>>) (ignore, v) -> {
|
||||||
palette = new char[v.size()];
|
palette = new char[v.size()];
|
||||||
for (Entry<String, Object> entry : v.entrySet()) {
|
for (Entry<String, Object> entry : v.entrySet()) {
|
||||||
BlockState state = null;
|
BlockState state;
|
||||||
|
String palettePart = fix(entry.getKey());
|
||||||
try {
|
try {
|
||||||
String palettePart = fix(entry.getKey());
|
|
||||||
state = BlockState.get(palettePart);
|
state = BlockState.get(palettePart);
|
||||||
} catch (InputParseException e) {
|
} catch (InputParseException ignored) {
|
||||||
e.printStackTrace();
|
log.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air.");
|
||||||
|
state = BlockTypes.AIR.getDefaultState();
|
||||||
}
|
}
|
||||||
int index = (int) entry.getValue();
|
int index = (int) entry.getValue();
|
||||||
palette[index] = (char) state.getOrdinal();
|
palette[index] = (char) state.getOrdinal();
|
||||||
@ -224,10 +248,14 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
@Override
|
@Override
|
||||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||||
StreamDelegate root = createDelegate();
|
StreamDelegate root = createDelegate();
|
||||||
|
StreamDelegate versions = createVersionDelegate();
|
||||||
|
inputStream.mark(Integer.MAX_VALUE);
|
||||||
|
inputStream.readNamedTagLazy(versions);
|
||||||
|
inputStream.reset();
|
||||||
inputStream.readNamedTagLazy(root);
|
inputStream.readNamedTagLazy(root);
|
||||||
|
|
||||||
if (version != 1 && version != 2) {
|
if (version != 1 && version != 2) {
|
||||||
throw new IOException("This schematic version is currently not supported");
|
throw new IOException("This schematic version is currently not supported (" + version + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocks != null) {
|
if (blocks != null) {
|
||||||
@ -240,9 +268,11 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
biomes = null;
|
biomes = null;
|
||||||
|
|
||||||
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
||||||
BlockVector3 origin = BlockVector3.ZERO;
|
BlockVector3 origin;
|
||||||
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
||||||
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
||||||
|
} else {
|
||||||
|
origin = BlockVector3.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipboard clipboard = createOutput.apply(dimensions);
|
Clipboard clipboard = createOutput.apply(dimensions);
|
||||||
@ -326,7 +356,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
y = pos[1];
|
y = pos[1];
|
||||||
z = pos[2];
|
z = pos[2];
|
||||||
}
|
}
|
||||||
Map<String, Tag> values = tile.getValue();
|
Map<String, Tag> values = new HashMap<>(tile.getValue());
|
||||||
Tag id = values.get("Id");
|
Tag id = values.get("Id");
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
values.put("x", new IntTag(x));
|
values.put("x", new IntTag(x));
|
||||||
@ -337,22 +367,19 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
values.remove("Id");
|
values.remove("Id");
|
||||||
values.remove("Pos");
|
values.remove("Pos");
|
||||||
|
|
||||||
tile = fixBlockEntity(tile);
|
clipboard.setTile(x, y, z, fixBlockEntity(new CompoundTag(values)));
|
||||||
clipboard.setTile(x, y, z, tile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// entities
|
// entities
|
||||||
if (entities != null && !entities.isEmpty()) {
|
if (entities != null && !entities.isEmpty()) {
|
||||||
for (Map<String, Object> entRaw : entities) {
|
for (Map<String, Object> entRaw : entities) {
|
||||||
CompoundTag ent = FaweCache.IMP.asTag(entRaw);
|
Map<String, Tag> value = new HashMap<>(FaweCache.IMP.asTag(entRaw).getValue());
|
||||||
|
|
||||||
Map<String, Tag> value = ent.getValue();
|
|
||||||
StringTag id = (StringTag) value.get("Id");
|
StringTag id = (StringTag) value.get("Id");
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
id = (StringTag) value.get("id");
|
id = (StringTag) value.get("id");
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return null;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value.put("id", id);
|
value.put("id", id);
|
||||||
@ -360,10 +387,29 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
EntityType type = EntityTypes.parse(id.getValue());
|
EntityType type = EntityTypes.parse(id.getValue());
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
ent = fixEntity(ent);
|
final CompoundTag ent = fixEntity(new CompoundTag(value));
|
||||||
BaseEntity state = new BaseEntity(type, ent);
|
BaseEntity state = new BaseEntity(type, ent);
|
||||||
Location loc = ent.getEntityLocation(clipboard);
|
Location loc = ent.getEntityLocation(clipboard);
|
||||||
clipboard.createEntity(loc, state);
|
if (brokenEntities) {
|
||||||
|
clipboard.createEntity(loc, state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isWorldEdit && faweWritten == -1) {
|
||||||
|
int locX = loc.getBlockX();
|
||||||
|
int locY = loc.getBlockY();
|
||||||
|
int locZ = loc.getBlockZ();
|
||||||
|
BlockVector3 max = min.add(dimensions).subtract(BlockVector3.ONE);
|
||||||
|
if (locX < min.getX() || locY < min.getY() || locZ < min.getZ()
|
||||||
|
|| locX > max.getX() || locY > max.getY() || locZ > max.getZ()) {
|
||||||
|
for (Entity e : clipboard.getEntities()) {
|
||||||
|
clipboard.removeEntity(e);
|
||||||
|
}
|
||||||
|
log.error("Detected schematic entity outside clipboard region. FAWE will not load entities. "
|
||||||
|
+ "Please try loading the schematic with the format \"legacyentity\"");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clipboard.createEntity(loc.setPosition(loc.subtract(min.toVector3())), state);
|
||||||
} else {
|
} else {
|
||||||
log.debug("Invalid entity: " + id);
|
log.debug("Invalid entity: " + id);
|
||||||
}
|
}
|
||||||
@ -372,7 +418,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
|||||||
clipboard.setOrigin(origin);
|
clipboard.setOrigin(origin);
|
||||||
|
|
||||||
if (!min.equals(BlockVector3.ZERO)) {
|
if (!min.equals(BlockVector3.ZERO)) {
|
||||||
new BlockArrayClipboard(clipboard, min);
|
clipboard = new BlockArrayClipboard(clipboard, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clipboard;
|
return clipboard;
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extent.clipboard.io;
|
package com.sk89q.worldedit.extent.clipboard.io;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.jnbt.streamer.IntValueReader;
|
import com.boydti.fawe.jnbt.streamer.IntValueReader;
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
import com.boydti.fawe.util.IOUtil;
|
import com.boydti.fawe.util.IOUtil;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.IntArrayTag;
|
import com.sk89q.jnbt.IntArrayTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
@ -39,6 +39,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|||||||
import com.sk89q.worldedit.function.visitor.Order;
|
import com.sk89q.worldedit.function.visitor.Order;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
@ -58,8 +59,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -72,6 +71,7 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
|
|
||||||
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
|
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
|
||||||
private final NBTOutputStream outputStream;
|
private final NBTOutputStream outputStream;
|
||||||
|
private boolean brokenEntities = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new schematic writer.
|
* Create a new schematic writer.
|
||||||
@ -83,6 +83,10 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
this.outputStream = outputStream;
|
this.outputStream = outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBrokenEntities(boolean brokenEntities) {
|
||||||
|
this.brokenEntities = brokenEntities;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(Clipboard clipboard) throws IOException {
|
public void write(Clipboard clipboard) throws IOException {
|
||||||
// For now always write the latest version. Maybe provide support for earlier if more appear.
|
// For now always write the latest version. Maybe provide support for earlier if more appear.
|
||||||
@ -123,15 +127,16 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
|
|
||||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||||
out.writeNamedTag("Offset", new int[]{
|
out.writeNamedTag("Offset", new int[]{
|
||||||
min.getBlockX(),
|
min.getBlockX(),
|
||||||
min.getBlockY(),
|
min.getBlockY(),
|
||||||
min.getBlockZ(),
|
min.getBlockZ(),
|
||||||
});
|
});
|
||||||
|
|
||||||
out.writeLazyCompoundTag("Metadata", out1 -> {
|
out.writeLazyCompoundTag("Metadata", out1 -> {
|
||||||
out1.writeNamedTag("WEOffsetX", offset.getBlockX());
|
out1.writeNamedTag("WEOffsetX", offset.getBlockX());
|
||||||
out1.writeNamedTag("WEOffsetY", offset.getBlockY());
|
out1.writeNamedTag("WEOffsetY", offset.getBlockY());
|
||||||
out1.writeNamedTag("WEOffsetZ", offset.getBlockZ());
|
out1.writeNamedTag("WEOffsetZ", offset.getBlockZ());
|
||||||
|
out1.writeNamedTag("FAWEVersion", Fawe.get().getVersion().build);
|
||||||
});
|
});
|
||||||
|
|
||||||
ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream();
|
ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream();
|
||||||
@ -157,7 +162,7 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
BaseBlock block = pos.getFullBlock(finalClipboard);
|
BaseBlock block = pos.getFullBlock(finalClipboard);
|
||||||
CompoundTag nbt = block.getNbtData();
|
CompoundTag nbt = block.getNbtData();
|
||||||
if (nbt != null) {
|
if (nbt != null) {
|
||||||
Map<String, Tag> values = nbt.getValue();
|
Map<String, Tag> values = new HashMap<>(nbt.getValue());
|
||||||
|
|
||||||
// Positions are kept in NBT, we don't want that.
|
// Positions are kept in NBT, we don't want that.
|
||||||
values.remove("x");
|
values.remove("x");
|
||||||
@ -170,12 +175,13 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
// Dum.
|
// Dum.
|
||||||
values.remove("id");
|
values.remove("id");
|
||||||
values.put("Pos", new IntArrayTag(new int[]{
|
values.put("Pos", new IntArrayTag(new int[]{
|
||||||
pos.getX(),
|
pos.getX(),
|
||||||
pos.getY(),
|
pos.getY(),
|
||||||
pos.getZ()
|
pos.getZ()
|
||||||
}));
|
}));
|
||||||
numTiles++;
|
numTiles++;
|
||||||
tilesOut.writeTagPayload(block.getNbtData());
|
|
||||||
|
tilesOut.writeTagPayload(new CompoundTag(values));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ordinal = block.getOrdinal();
|
int ordinal = block.getOrdinal();
|
||||||
@ -240,8 +246,12 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
|
|
||||||
// Store our location data, overwriting any
|
// Store our location data, overwriting any
|
||||||
values.remove("id");
|
values.remove("id");
|
||||||
|
Location loc = entity.getLocation();
|
||||||
|
if (!brokenEntities) {
|
||||||
|
loc = loc.setPosition(loc.add(min.toVector3()));
|
||||||
|
}
|
||||||
values.put("Id", new StringTag(state.getType().getId()));
|
values.put("Id", new StringTag(state.getType().getId()));
|
||||||
values.put("Pos", writeVector(entity.getLocation()));
|
values.put("Pos", writeVector(loc));
|
||||||
values.put("Rotation", writeRotation(entity.getLocation()));
|
values.put("Rotation", writeRotation(entity.getLocation()));
|
||||||
|
|
||||||
CompoundTag entityTag = new CompoundTag(values);
|
CompoundTag entityTag = new CompoundTag(values);
|
||||||
@ -311,30 +321,6 @@ public class FastSchematicWriter implements ClipboardWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeEntities(Clipboard clipboard, NBTOutputStream schematic) throws IOException {
|
|
||||||
List<CompoundTag> entities = clipboard.getEntities().stream().map(e -> {
|
|
||||||
BaseEntity state = e.getState();
|
|
||||||
if (state == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Map<String, Tag> values = Maps.newHashMap();
|
|
||||||
CompoundTag rawData = state.getNbtData();
|
|
||||||
if (rawData != null) {
|
|
||||||
values.putAll(rawData.getValue());
|
|
||||||
}
|
|
||||||
values.remove("id");
|
|
||||||
values.put("Id", new StringTag(state.getType().getId()));
|
|
||||||
values.put("Pos", writeVector(e.getLocation().toVector()));
|
|
||||||
values.put("Rotation", writeRotation(e.getLocation()));
|
|
||||||
|
|
||||||
return new CompoundTag(values);
|
|
||||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
|
||||||
if (entities.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
schematic.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
package com.sk89q.worldedit.extent.clipboard.io;
|
|
||||||
|
|
||||||
public class FaweFormat {
|
|
||||||
}
|
|
@ -68,26 +68,24 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads schematic files that are compatible with MCEdit and other editors.
|
* Reads schematic files that are compatible with MCEdit and other editors.
|
||||||
* @deprecated Use SchematicStreamer
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public class MCEditSchematicReader extends NBTSchematicReader {
|
public class MCEditSchematicReader extends NBTSchematicReader {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
private static final Logger log = LoggerFactory.getLogger(MCEditSchematicReader.class);
|
||||||
private final NBTInputStream inputStream;
|
private final NBTInputStream inputStream;
|
||||||
private final DataFixer fixer;
|
private final DataFixer fixer;
|
||||||
private static final ImmutableList<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS
|
private static final ImmutableList<NBTCompatibilityHandler> COMPATIBILITY_HANDLERS
|
||||||
= ImmutableList.of(
|
= ImmutableList.of(
|
||||||
new SignCompatibilityHandler(),
|
new SignCompatibilityHandler(),
|
||||||
new FlowerPotCompatibilityHandler(),
|
new FlowerPotCompatibilityHandler(),
|
||||||
new NoteBlockCompatibilityHandler(),
|
new NoteBlockCompatibilityHandler(),
|
||||||
new SkullBlockCompatibilityHandler(),
|
new SkullBlockCompatibilityHandler(),
|
||||||
new BannerBlockCompatibilityHandler(),
|
new BannerBlockCompatibilityHandler(),
|
||||||
new BedBlockCompatibilityHandler()
|
new BedBlockCompatibilityHandler()
|
||||||
);
|
);
|
||||||
private static final ImmutableList<EntityNBTCompatibilityHandler> ENTITY_COMPATIBILITY_HANDLERS
|
private static final ImmutableList<EntityNBTCompatibilityHandler> ENTITY_COMPATIBILITY_HANDLERS
|
||||||
= ImmutableList.of(
|
= ImmutableList.of(
|
||||||
new Pre13HangingCompatibilityHandler()
|
new Pre13HangingCompatibilityHandler()
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,8 +97,8 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
checkNotNull(inputStream);
|
checkNotNull(inputStream);
|
||||||
this.inputStream = inputStream;
|
this.inputStream = inputStream;
|
||||||
this.fixer = null;
|
this.fixer = null;
|
||||||
//com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability(
|
//com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability(
|
||||||
//com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer();
|
//com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -207,7 +205,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
if (newBlock != null) {
|
if (newBlock != null) {
|
||||||
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) {
|
||||||
if (handler.isAffectedBlock(newBlock)) {
|
if (handler.isAffectedBlock(newBlock)) {
|
||||||
newBlock = handler.updateNBT(block, values);
|
newBlock = handler.updateNBT(block, values).toImmutableState();
|
||||||
if (newBlock == null || values.isEmpty()) {
|
if (newBlock == null || values.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -256,7 +254,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
int combined = block << 8 | data;
|
int combined = block << 8 | data;
|
||||||
if (unknownBlocks.add(combined)) {
|
if (unknownBlocks.add(combined)) {
|
||||||
log.warn("Unknown block when loading schematic: "
|
log.warn("Unknown block when loading schematic: "
|
||||||
+ block + ":" + data + ". This is most likely a bad schematic.");
|
+ block + ":" + data + ". This is most likely a bad schematic.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (WorldEditException ignored) { // BlockArrayClipboard won't throw this
|
} catch (WorldEditException ignored) { // BlockArrayClipboard won't throw this
|
||||||
@ -302,7 +300,7 @@ public class MCEditSchematicReader extends NBTSchematicReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String convertEntityId(String id) {
|
private String convertEntityId(String id) {
|
||||||
switch(id) {
|
switch (id) {
|
||||||
case "AreaEffectCloud": return "area_effect_cloud";
|
case "AreaEffectCloud": return "area_effect_cloud";
|
||||||
case "ArmorStand": return "armor_stand";
|
case "ArmorStand": return "armor_stand";
|
||||||
case "CaveSpider": return "cave_spider";
|
case "CaveSpider": return "cave_spider";
|
||||||
|
@ -1,536 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sk89q.worldedit.extent.clipboard.io;
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.jnbt.streamer.StreamDelegate;
|
|
||||||
import com.boydti.fawe.jnbt.streamer.ValueReader;
|
|
||||||
import com.boydti.fawe.object.FaweInputStream;
|
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
|
||||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
|
||||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BannerBlockCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.BedBlockCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.EntityNBTCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.FlowerPotCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NBTCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.NoteBlockCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.Pre13HangingCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SignCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.legacycompat.SkullBlockCompatibilityHandler;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
|
||||||
import com.sk89q.worldedit.util.Direction;
|
|
||||||
import com.sk89q.worldedit.util.Location;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockCategories;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypeSwitch;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypeSwitchBuilder;
|
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
|
||||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
|
||||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
|
||||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
|
||||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads schematic files based that are compatible with MCEdit and other editors.
|
|
||||||
*/
|
|
||||||
public class SchematicReader implements ClipboardReader {
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SchematicReader.class);
|
|
||||||
|
|
||||||
private static final NBTCompatibilityHandler[] COMPATIBILITY_HANDLERS = {
|
|
||||||
new SignCompatibilityHandler(),
|
|
||||||
new FlowerPotCompatibilityHandler(),
|
|
||||||
new NoteBlockCompatibilityHandler(),
|
|
||||||
new SkullBlockCompatibilityHandler(),
|
|
||||||
new BannerBlockCompatibilityHandler(),
|
|
||||||
new BedBlockCompatibilityHandler()
|
|
||||||
};
|
|
||||||
private static final EntityNBTCompatibilityHandler[] ENTITY_COMPATIBILITY_HANDLERS = {
|
|
||||||
new Pre13HangingCompatibilityHandler()
|
|
||||||
};
|
|
||||||
|
|
||||||
private NBTInputStream inputStream;
|
|
||||||
private InputStream rootStream;
|
|
||||||
|
|
||||||
// private final DataFixer fixer; TODO
|
|
||||||
|
|
||||||
private FastByteArrayOutputStream idOut = new FastByteArrayOutputStream();
|
|
||||||
private FastByteArrayOutputStream dataOut = new FastByteArrayOutputStream();
|
|
||||||
private FastByteArrayOutputStream addOut;
|
|
||||||
private FastByteArrayOutputStream biomesOut;
|
|
||||||
|
|
||||||
private FaweOutputStream ids;
|
|
||||||
private FaweOutputStream datas;
|
|
||||||
private FaweOutputStream adds;
|
|
||||||
private FaweOutputStream biomes;
|
|
||||||
|
|
||||||
private List<Map<String, Object>> tiles;
|
|
||||||
private List<Map<String, Object>> entities;
|
|
||||||
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private int length;
|
|
||||||
private int offsetX;
|
|
||||||
private int offsetY;
|
|
||||||
private int offsetZ;
|
|
||||||
private int originX;
|
|
||||||
private int originY;
|
|
||||||
private int originZ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*
|
|
||||||
* @param inputStream the input stream to read from
|
|
||||||
*/
|
|
||||||
public SchematicReader(NBTInputStream inputStream) {
|
|
||||||
checkNotNull(inputStream);
|
|
||||||
this.inputStream = inputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnderlyingStream(InputStream in) {
|
|
||||||
this.rootStream = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamDelegate createDelegate() {
|
|
||||||
StreamDelegate root = new StreamDelegate();
|
|
||||||
StreamDelegate schematic = root.add("Schematic");
|
|
||||||
schematic.add("Width").withInt((i, v) -> width = v);
|
|
||||||
schematic.add("Height").withInt((i, v) -> height = v);
|
|
||||||
schematic.add("Length").withInt((i, v) -> length = v);
|
|
||||||
|
|
||||||
schematic.add("WEOriginX").withInt((i, v) -> originX = v);
|
|
||||||
schematic.add("WEOriginY").withInt((i, v) -> originY = v);
|
|
||||||
schematic.add("WEOriginZ").withInt((i, v) -> originZ = v);
|
|
||||||
|
|
||||||
StreamDelegate metadata = schematic.add("Metadata");
|
|
||||||
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
|
||||||
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
|
||||||
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
|
||||||
|
|
||||||
StreamDelegate blocksDelegate = schematic.add("Blocks");
|
|
||||||
blocksDelegate.withInfo((length, type) -> ids = new FaweOutputStream(new LZ4BlockOutputStream(idOut)));
|
|
||||||
blocksDelegate.withInt((index, value) -> ids.write(value));
|
|
||||||
|
|
||||||
StreamDelegate dataDelegate = schematic.add("Data");
|
|
||||||
dataDelegate.withInfo((length, type) -> datas = new FaweOutputStream(new LZ4BlockOutputStream(dataOut)));
|
|
||||||
dataDelegate.withInt((index, value) -> datas.write(value));
|
|
||||||
|
|
||||||
StreamDelegate addDelegate = schematic.add("AddBlocks");
|
|
||||||
addDelegate.withInfo((length, type) -> {
|
|
||||||
addOut = new FastByteArrayOutputStream();
|
|
||||||
adds = new FaweOutputStream(new LZ4BlockOutputStream(addOut));
|
|
||||||
});
|
|
||||||
addDelegate.withInt((index, value) -> {
|
|
||||||
if (value != 0) {
|
|
||||||
int first = value & 0x0F;
|
|
||||||
int second = (value & 0xF0) >> 4;
|
|
||||||
adds.write(first);
|
|
||||||
adds.write(second);
|
|
||||||
} else {
|
|
||||||
adds.write(0);
|
|
||||||
adds.write(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
StreamDelegate tilesDelegate = schematic.add("TileEntities");
|
|
||||||
tilesDelegate.withInfo((length, type) -> tiles = new ArrayList<>(length));
|
|
||||||
tilesDelegate.withElem((ValueReader<Map<String, Object>>) (index, tile) -> tiles.add(tile));
|
|
||||||
|
|
||||||
StreamDelegate entitiesDelegate = schematic.add("Entities");
|
|
||||||
entitiesDelegate.withInfo((length, type) -> entities = new ArrayList<>(length));
|
|
||||||
entitiesDelegate.withElem(
|
|
||||||
(ValueReader<Map<String, Object>>) (index, entity) -> entities.add(entity));
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int readCombined(InputStream idIn, InputStream dataIn) throws IOException {
|
|
||||||
return ((idIn.read() & 0xFF) << 4) + (dataIn.read() & 0xF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int readCombined(InputStream idIn, InputStream dataIn, InputStream addIn) throws IOException {
|
|
||||||
return ((addIn.read() & 0xFF) << 8) + readCombined(idIn, dataIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockState getBlock(int combined) {
|
|
||||||
BlockState state = LegacyMapper.getInstance().getBlockFromLegacyCombinedId(combined);
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void write(int index, BlockState block, LinearClipboard clipboard) {
|
|
||||||
clipboard.setBlock(index, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void write(int x, int y, int z, BlockState block, Clipboard clipboard) {
|
|
||||||
clipboard.setBlock(x, y, z, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int index, InputStream idIn, InputStream dataIn, LinearClipboard out) throws IOException {
|
|
||||||
readwrite(index, readCombined(idIn, dataIn), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, Clipboard out) throws IOException {
|
|
||||||
readwrite(x, y, z, readCombined(idIn, dataIn), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int index, InputStream idIn, InputStream dataIn, InputStream addIn, LinearClipboard out) throws IOException {
|
|
||||||
readwrite(index, readCombined(idIn, dataIn, addIn), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int x, int y, int z, InputStream idIn, InputStream dataIn, InputStream addIn, Clipboard out) throws IOException {
|
|
||||||
readwrite(x, y, z, readCombined(idIn, dataIn, addIn), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int index, int combined, LinearClipboard out) throws IOException {
|
|
||||||
write(index, getBlock(combined), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readwrite(int x, int y, int z, int combined, Clipboard out) throws IOException {
|
|
||||||
write(x, y, z, getBlock(combined), out);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
|
||||||
try {
|
|
||||||
return readInternal(uuid, createOutput);
|
|
||||||
} catch (EOFException e) {
|
|
||||||
log.error("EOFException read in schematic. Did you give the schematic the wrong extension?");
|
|
||||||
log.error("We will attempt to rectify your mistake for you and load the schematic assuming it is named .schem not .schematic");
|
|
||||||
e.printStackTrace();
|
|
||||||
final InputStream stream;
|
|
||||||
if (rootStream instanceof FileInputStream) {
|
|
||||||
stream = new ResettableFileInputStream((FileInputStream) rootStream);
|
|
||||||
} else {
|
|
||||||
stream = rootStream;
|
|
||||||
}
|
|
||||||
BufferedInputStream buffered = new BufferedInputStream(stream);
|
|
||||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
|
||||||
return (new FastSchematicReader(nbtStream)).read(uuid, createOutput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Clipboard readInternal(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
|
||||||
StreamDelegate root = createDelegate();
|
|
||||||
inputStream.readNamedTagLazy(root);
|
|
||||||
|
|
||||||
if (ids != null) {
|
|
||||||
ids.close();
|
|
||||||
}
|
|
||||||
if (datas != null) {
|
|
||||||
datas.close();
|
|
||||||
}
|
|
||||||
if (adds != null) {
|
|
||||||
adds.close();
|
|
||||||
}
|
|
||||||
if (biomes != null) {
|
|
||||||
biomes.close();
|
|
||||||
}
|
|
||||||
ids = null;
|
|
||||||
datas = null;
|
|
||||||
adds = null;
|
|
||||||
biomes = null;
|
|
||||||
|
|
||||||
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
|
||||||
BlockVector3 origin = BlockVector3.ZERO;
|
|
||||||
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
|
||||||
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
Clipboard clipboard = createOutput.apply(dimensions);
|
|
||||||
try (InputStream dataIn = new LZ4BlockInputStream(new FastByteArraysInputStream(dataOut.toByteArrays())); InputStream idIn = new LZ4BlockInputStream(new FastByteArraysInputStream(idOut.toByteArrays()))) {
|
|
||||||
if (addOut != null) {
|
|
||||||
try (FaweInputStream addIn = new FaweInputStream(new LZ4BlockInputStream(new FastByteArraysInputStream(addOut.toByteArrays())))) {
|
|
||||||
if (clipboard instanceof LinearClipboard) {
|
|
||||||
LinearClipboard linear = (LinearClipboard) clipboard;
|
|
||||||
for (int y = 0, index = 0; y < height; y++) {
|
|
||||||
for (int z = 0; z < length; z++) {
|
|
||||||
for (int x = 0; x < width; x++, index++) {
|
|
||||||
readwrite(index, idIn, dataIn, addIn, linear);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
for (int z = 0; z < length; z++) {
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
readwrite(x, y, z, idIn, dataIn, addIn, clipboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (clipboard instanceof LinearClipboard) {
|
|
||||||
LinearClipboard linear = (LinearClipboard) clipboard;
|
|
||||||
for (int y = 0, index = 0; y < height; y++) {
|
|
||||||
for (int z = 0; z < length; z++) {
|
|
||||||
for (int x = 0; x < width; x++, index++) {
|
|
||||||
readwrite(index, idIn, dataIn, linear);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
for (int z = 0; z < length; z++) {
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
readwrite(x, y, z, idIn, dataIn, clipboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tiles
|
|
||||||
if (tiles != null && !tiles.isEmpty()) {
|
|
||||||
outer:
|
|
||||||
for (Map<String, Object> tileRaw : tiles) {
|
|
||||||
CompoundTag tile = FaweCache.IMP.asTag(tileRaw);
|
|
||||||
int x = (int) tileRaw.get("x");
|
|
||||||
int y = (int) tileRaw.get("y");
|
|
||||||
int z = (int) tileRaw.get("z");
|
|
||||||
|
|
||||||
BlockState block = clipboard.getBlock(x, y, z);
|
|
||||||
for (NBTCompatibilityHandler compat : COMPATIBILITY_HANDLERS) {
|
|
||||||
if (compat.isAffectedBlock(block)) {
|
|
||||||
block = compat.updateNBT(block, tile.getValue());
|
|
||||||
BaseBlock baseBlock = block.toBaseBlock(tile);
|
|
||||||
clipboard.setBlock(x, y, z, baseBlock);
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clipboard.setTile(x, y, z, tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// entities
|
|
||||||
if (entities != null && !entities.isEmpty()) {
|
|
||||||
for (Map<String, Object> entRaw : entities) {
|
|
||||||
String id = (String) entRaw.get("id");
|
|
||||||
if (id == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entRaw.put("Id", id);
|
|
||||||
EntityType type = EntityTypes.parse(id);
|
|
||||||
if (type != null) {
|
|
||||||
CompoundTag ent = FaweCache.IMP.asTag(entRaw);
|
|
||||||
for (EntityNBTCompatibilityHandler compat : ENTITY_COMPATIBILITY_HANDLERS) {
|
|
||||||
if (compat.isAffectedEntity(type, ent)) {
|
|
||||||
ent = compat.updateNBT(type, ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BaseEntity state = new BaseEntity(type, ent);
|
|
||||||
Location loc = ent.getEntityLocation(clipboard);
|
|
||||||
clipboard.createEntity(loc, state);
|
|
||||||
} else {
|
|
||||||
getLogger(SchematicReader.class).debug("Invalid entity: " + id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fixStates(clipboard);
|
|
||||||
clipboard.setOrigin(origin);
|
|
||||||
|
|
||||||
BlockVector3 min = BlockVector3.at(originX, originY, originZ);
|
|
||||||
if (!min.equals(BlockVector3.ZERO)) {
|
|
||||||
new BlockArrayClipboard(clipboard, min);
|
|
||||||
}
|
|
||||||
return clipboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fixStates(Clipboard fc) {
|
|
||||||
for (BlockVector3 pos : fc) {
|
|
||||||
BlockState block = pos.getBlock(fc);
|
|
||||||
if (block.getMaterial().isAir()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = pos.getX();
|
|
||||||
int y = pos.getY();
|
|
||||||
int z = pos.getZ();
|
|
||||||
|
|
||||||
BlockType type = block.getBlockType();
|
|
||||||
if (BlockCategories.STAIRS.contains(type)) {
|
|
||||||
Direction facing = block.getState(PropertyKey.FACING);
|
|
||||||
|
|
||||||
BlockVector3 forward = facing.toBlockVector();
|
|
||||||
Direction left = facing.getLeft();
|
|
||||||
Direction right = facing.getRight();
|
|
||||||
|
|
||||||
BlockState forwardBlock = fc.getBlock(x + forward.getBlockX(), y + forward.getBlockY(), z + forward.getBlockZ());
|
|
||||||
BlockType forwardType = forwardBlock.getBlockType();
|
|
||||||
if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) {
|
|
||||||
Direction forwardFacing = forwardBlock.getState(PropertyKey.FACING);
|
|
||||||
if (forwardFacing == left) {
|
|
||||||
BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
|
|
||||||
BlockType rightType = rightBlock.getBlockType();
|
|
||||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
|
||||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "inner_left"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (forwardFacing == right) {
|
|
||||||
BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
|
|
||||||
BlockType leftType = leftBlock.getBlockType();
|
|
||||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
|
||||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockState backwardsBlock = fc.getBlock(x - forward.getBlockX(), y - forward.getBlockY(), z - forward.getBlockZ());
|
|
||||||
BlockType backwardsType = backwardsBlock.getBlockType();
|
|
||||||
if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) {
|
|
||||||
Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING);
|
|
||||||
if (backwardsFacing == left) {
|
|
||||||
BlockState rightBlock = fc.getBlock(x + right.toBlockVector().getBlockX(), y + right.toBlockVector().getBlockY(), z + right.toBlockVector().getBlockZ());
|
|
||||||
BlockType rightType = rightBlock.getBlockType();
|
|
||||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
|
||||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_left"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (backwardsFacing == right) {
|
|
||||||
BlockState leftBlock = fc.getBlock(x + left.toBlockVector().getBlockX(), y + left.toBlockVector().getBlockY(), z + left.toBlockVector().getBlockZ());
|
|
||||||
BlockType leftType = leftBlock.getBlockType();
|
|
||||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
|
||||||
pos.setBlock(fc, block.with(PropertyKey.SHAPE, "outer_right"));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int group = group(type);
|
|
||||||
if (group == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BlockState set = block;
|
|
||||||
|
|
||||||
if (set.getState(PropertyKey.NORTH) == Boolean.FALSE && merge(fc, group, x, y, z - 1)) {
|
|
||||||
set = set.with(PropertyKey.NORTH, true);
|
|
||||||
}
|
|
||||||
if (set.getState(PropertyKey.EAST) == Boolean.FALSE && merge(fc, group, x + 1, y, z)) {
|
|
||||||
set = set.with(PropertyKey.EAST, true);
|
|
||||||
}
|
|
||||||
if (set.getState(PropertyKey.SOUTH) == Boolean.FALSE && merge(fc, group, x, y, z + 1)) {
|
|
||||||
set = set.with(PropertyKey.SOUTH, true);
|
|
||||||
}
|
|
||||||
if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(fc, group, x - 1, y, z)) {
|
|
||||||
set = set.with(PropertyKey.WEST, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group == 2) {
|
|
||||||
int ns = (set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0);
|
|
||||||
int ew = (set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0);
|
|
||||||
if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) {
|
|
||||||
set = set.with(PropertyKey.UP, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set != block) {
|
|
||||||
pos.setBlock(fc, set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private BlockTypeSwitch<Boolean> fullCube = new BlockTypeSwitchBuilder<>(false).add(type -> {
|
|
||||||
BlockMaterial mat = type.getMaterial();
|
|
||||||
return (mat.isFullCube() && !mat.isFragileWhenPushed() && mat.getLightValue() == 0 && mat.isOpaque() && mat.isSolid() && !mat.isTranslucent());
|
|
||||||
}, true).build();
|
|
||||||
|
|
||||||
private boolean merge(Clipboard fc, int group, int x, int y, int z) {
|
|
||||||
BlockState block = fc.getBlock(x, y, z);
|
|
||||||
BlockType type = block.getBlockType();
|
|
||||||
return group(type) == group || fullCube.apply(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int group(BlockType type) {
|
|
||||||
switch (type.getInternalId()) {
|
|
||||||
case BlockID.ACACIA_FENCE:
|
|
||||||
case BlockID.BIRCH_FENCE:
|
|
||||||
case BlockID.DARK_OAK_FENCE:
|
|
||||||
case BlockID.JUNGLE_FENCE:
|
|
||||||
case BlockID.OAK_FENCE:
|
|
||||||
case BlockID.SPRUCE_FENCE:
|
|
||||||
return 0;
|
|
||||||
case BlockID.NETHER_BRICK_FENCE:
|
|
||||||
return 1;
|
|
||||||
case BlockID.COBBLESTONE_WALL:
|
|
||||||
case BlockID.MOSSY_COBBLESTONE_WALL:
|
|
||||||
return 2;
|
|
||||||
case BlockID.IRON_BARS:
|
|
||||||
case BlockID.BLACK_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.BLUE_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.BROWN_MUSHROOM_BLOCK:
|
|
||||||
case BlockID.BROWN_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.CYAN_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.GLASS_PANE:
|
|
||||||
case BlockID.GRAY_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.GREEN_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.LIGHT_BLUE_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.LIGHT_GRAY_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.LIME_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.MAGENTA_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.ORANGE_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.PINK_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.PURPLE_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.RED_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.WHITE_STAINED_GLASS_PANE:
|
|
||||||
case BlockID.YELLOW_STAINED_GLASS_PANE:
|
|
||||||
return 3;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -68,7 +68,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
/**
|
/**
|
||||||
* Reads schematic files using the Sponge Schematic Specification.
|
* Reads schematic files using the Sponge Schematic Specification.
|
||||||
*/
|
*/
|
||||||
@Deprecated // High mem usage + slow
|
|
||||||
public class SpongeSchematicReader extends NBTSchematicReader {
|
public class SpongeSchematicReader extends NBTSchematicReader {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
|
private static final Logger log = LoggerFactory.getLogger(SpongeSchematicReader.class);
|
||||||
@ -93,7 +92,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
Map<String, Tag> schematic = schematicTag.getValue();
|
Map<String, Tag> schematic = schematicTag.getValue();
|
||||||
|
|
||||||
final Platform platform = WorldEdit.getInstance().getPlatformManager()
|
final Platform platform = WorldEdit.getInstance().getPlatformManager()
|
||||||
.queryCapability(Capability.WORLD_EDITING);
|
.queryCapability(Capability.WORLD_EDITING);
|
||||||
int liveDataVersion = platform.getDataVersion();
|
int liveDataVersion = platform.getDataVersion();
|
||||||
|
|
||||||
if (schematicVersion == 1) {
|
if (schematicVersion == 1) {
|
||||||
@ -102,17 +101,23 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
return readVersion1(schematicTag);
|
return readVersion1(schematicTag);
|
||||||
} else if (schematicVersion == 2) {
|
} else if (schematicVersion == 2) {
|
||||||
dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||||
|
if (dataVersion < 0) {
|
||||||
|
log.warn("Schematic has an unknown data version ({}). Data may be incompatible.",
|
||||||
|
dataVersion);
|
||||||
|
// Do not DFU unknown data
|
||||||
|
dataVersion = liveDataVersion;
|
||||||
|
}
|
||||||
if (dataVersion > liveDataVersion) {
|
if (dataVersion > liveDataVersion) {
|
||||||
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
log.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.",
|
||||||
dataVersion, liveDataVersion);
|
dataVersion, liveDataVersion);
|
||||||
} else if (dataVersion < liveDataVersion) {
|
} else if (dataVersion < liveDataVersion) {
|
||||||
fixer = platform.getDataFixer();
|
fixer = platform.getDataFixer();
|
||||||
if (fixer != null) {
|
if (fixer != null) {
|
||||||
log.debug("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.",
|
log.debug("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.",
|
||||||
dataVersion, liveDataVersion);
|
dataVersion, liveDataVersion);
|
||||||
} else {
|
} else {
|
||||||
log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.",
|
log.info("Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.",
|
||||||
dataVersion, liveDataVersion);
|
dataVersion, liveDataVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +135,11 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
if (schematicVersion == 1) {
|
if (schematicVersion == 1) {
|
||||||
return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2);
|
return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2);
|
||||||
} else if (schematicVersion == 2) {
|
} else if (schematicVersion == 2) {
|
||||||
return OptionalInt.of(requireTag(schematic, "DataVersion", IntTag.class).getValue());
|
int dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue();
|
||||||
|
if (dataVersion < 0) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
return OptionalInt.of(dataVersion);
|
||||||
}
|
}
|
||||||
return OptionalInt.empty();
|
return OptionalInt.empty();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -140,9 +149,6 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
|
|
||||||
private CompoundTag getBaseTag() throws IOException {
|
private CompoundTag getBaseTag() throws IOException {
|
||||||
NamedTag rootTag = inputStream.readNamedTag();
|
NamedTag rootTag = inputStream.readNamedTag();
|
||||||
if (!rootTag.getName().equals("Schematic")) {
|
|
||||||
throw new IOException("Tag 'Schematic' does not exist or is not first");
|
|
||||||
}
|
|
||||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
@ -226,9 +232,9 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
}
|
}
|
||||||
if (tileEntities != null) {
|
if (tileEntities != null) {
|
||||||
List<Map<String, Tag>> tileEntityTags = tileEntities.getValue().stream()
|
List<Map<String, Tag>> tileEntityTags = tileEntities.getValue().stream()
|
||||||
.map(tag -> (CompoundTag) tag)
|
.map(tag -> (CompoundTag) tag)
|
||||||
.map(CompoundTag::getValue)
|
.map(CompoundTag::getValue)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (Map<String, Tag> tileEntity : tileEntityTags) {
|
for (Map<String, Tag> tileEntity : tileEntityTags) {
|
||||||
int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue();
|
int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue();
|
||||||
@ -321,8 +327,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
}
|
}
|
||||||
BiomeType biome = BiomeTypes.get(key);
|
BiomeType biome = BiomeTypes.get(key);
|
||||||
if (biome == null) {
|
if (biome == null) {
|
||||||
log.warn("Unknown biome type :" + key +
|
log.warn("Unknown biome type :" + key
|
||||||
" in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
+ " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?");
|
||||||
}
|
}
|
||||||
Tag idTag = palettePart.getValue();
|
Tag idTag = palettePart.getValue();
|
||||||
if (!(idTag instanceof IntTag)) {
|
if (!(idTag instanceof IntTag)) {
|
||||||
@ -385,8 +391,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
EntityType entityType = EntityTypes.get(id);
|
EntityType entityType = EntityTypes.get(id);
|
||||||
if (entityType != null) {
|
if (entityType != null) {
|
||||||
Location location = NBTConversions.toLocation(clipboard,
|
Location location = NBTConversions.toLocation(clipboard,
|
||||||
requireTag(tags, "Pos", ListTag.class),
|
requireTag(tags, "Pos", ListTag.class),
|
||||||
requireTag(tags, "Rotation", ListTag.class));
|
requireTag(tags, "Rotation", ListTag.class));
|
||||||
BaseEntity state = new BaseEntity(entityType, entityTag);
|
BaseEntity state = new BaseEntity(entityType, entityTag);
|
||||||
clipboard.createEntity(location, state);
|
clipboard.createEntity(location, state);
|
||||||
} else {
|
} else {
|
||||||
|
@ -19,11 +19,10 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extent.clipboard.io;
|
package com.sk89q.worldedit.extent.clipboard.io;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.sk89q.jnbt.ByteArrayTag;
|
import com.sk89q.jnbt.ByteArrayTag;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.DoubleTag;
|
|
||||||
import com.sk89q.jnbt.FloatTag;
|
|
||||||
import com.sk89q.jnbt.IntArrayTag;
|
import com.sk89q.jnbt.IntArrayTag;
|
||||||
import com.sk89q.jnbt.IntTag;
|
import com.sk89q.jnbt.IntTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
@ -36,7 +35,6 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
|||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -56,7 +54,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
/**
|
/**
|
||||||
* Writes schematic files using the Sponge schematic format.
|
* Writes schematic files using the Sponge schematic format.
|
||||||
*/
|
*/
|
||||||
@Deprecated // High mem usage + slow
|
|
||||||
public class SpongeSchematicWriter implements ClipboardWriter {
|
public class SpongeSchematicWriter implements ClipboardWriter {
|
||||||
|
|
||||||
private static final int CURRENT_VERSION = 2;
|
private static final int CURRENT_VERSION = 2;
|
||||||
@ -108,12 +105,13 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
|||||||
Map<String, Tag> schematic = new HashMap<>();
|
Map<String, Tag> schematic = new HashMap<>();
|
||||||
schematic.put("Version", new IntTag(CURRENT_VERSION));
|
schematic.put("Version", new IntTag(CURRENT_VERSION));
|
||||||
schematic.put("DataVersion", new IntTag(
|
schematic.put("DataVersion", new IntTag(
|
||||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
||||||
|
|
||||||
Map<String, Tag> metadata = new HashMap<>();
|
Map<String, Tag> metadata = new HashMap<>();
|
||||||
metadata.put("WEOffsetX", new IntTag(offset.getBlockX()));
|
metadata.put("WEOffsetX", new IntTag(offset.getBlockX()));
|
||||||
metadata.put("WEOffsetY", new IntTag(offset.getBlockY()));
|
metadata.put("WEOffsetY", new IntTag(offset.getBlockY()));
|
||||||
metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ()));
|
metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ()));
|
||||||
|
metadata.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build));
|
||||||
|
|
||||||
schematic.put("Metadata", new CompoundTag(metadata));
|
schematic.put("Metadata", new CompoundTag(metadata));
|
||||||
|
|
||||||
@ -123,9 +121,9 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
|||||||
|
|
||||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||||
schematic.put("Offset", new IntArrayTag(new int[]{
|
schematic.put("Offset", new IntArrayTag(new int[]{
|
||||||
min.getBlockX(),
|
min.getBlockX(),
|
||||||
min.getBlockY(),
|
min.getBlockY(),
|
||||||
min.getBlockZ(),
|
min.getBlockZ(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
int paletteMax = 0;
|
int paletteMax = 0;
|
||||||
@ -268,21 +266,6 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
|||||||
schematic.put("Entities", new ListTag(CompoundTag.class, entities));
|
schematic.put("Entities", new ListTag(CompoundTag.class, entities));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tag writeVector(Vector3 vector) {
|
|
||||||
List<DoubleTag> list = new ArrayList<>();
|
|
||||||
list.add(new DoubleTag(vector.getX()));
|
|
||||||
list.add(new DoubleTag(vector.getY()));
|
|
||||||
list.add(new DoubleTag(vector.getZ()));
|
|
||||||
return new ListTag(DoubleTag.class, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tag writeRotation(Location location) {
|
|
||||||
List<FloatTag> list = new ArrayList<>();
|
|
||||||
list.add(new FloatTag(location.getYaw()));
|
|
||||||
list.add(new FloatTag(location.getPitch()));
|
|
||||||
return new ListTag(FloatTag.class, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
outputStream.close();
|
outputStream.close();
|
||||||
|
@ -24,9 +24,8 @@ import com.sk89q.jnbt.CompoundTagBuilder;
|
|||||||
import com.sk89q.jnbt.IntTag;
|
import com.sk89q.jnbt.IntTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
@ -38,15 +37,15 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||||
|
|
||||||
private static final DirectionalProperty FacingProperty;
|
private static final Property<Direction> FacingProperty;
|
||||||
private static final IntegerProperty RotationProperty;
|
private static final Property<Integer> RotationProperty;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DirectionalProperty tempFacing;
|
Property<Direction> tempFacing;
|
||||||
IntegerProperty tempRotation;
|
Property<Integer> tempRotation;
|
||||||
try {
|
try {
|
||||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.WHITE_WALL_BANNER.getProperty("facing");
|
tempFacing = BlockTypes.WHITE_WALL_BANNER.getProperty("facing");
|
||||||
tempRotation = (IntegerProperty) (Property<?>) BlockTypes.WHITE_BANNER.getProperty("rotation");
|
tempRotation = BlockTypes.WHITE_BANNER.getProperty("rotation");
|
||||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||||
tempFacing = null;
|
tempFacing = null;
|
||||||
tempRotation = null;
|
tempRotation = null;
|
||||||
@ -62,7 +61,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
Tag typeTag = values.get("Base");
|
Tag typeTag = values.get("Base");
|
||||||
if (typeTag instanceof IntTag) {
|
if (typeTag instanceof IntTag) {
|
||||||
boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER;
|
boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER;
|
||||||
@ -73,10 +72,10 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
|||||||
BlockState state = type.getDefaultState();
|
BlockState state = type.getDefaultState();
|
||||||
|
|
||||||
if (isWall) {
|
if (isWall) {
|
||||||
Property facingProp = type.getProperty("facing");
|
Property<Direction> facingProp = type.getProperty("facing");
|
||||||
state = state.with(facingProp, block.getState(FacingProperty));
|
state = state.with(facingProp, block.getState(FacingProperty));
|
||||||
} else {
|
} else {
|
||||||
Property rotationProp = type.getProperty("rotation");
|
Property<Integer> rotationProp = type.getProperty("rotation");
|
||||||
state = state.with(rotationProp, block.getState(RotationProperty));
|
state = state.with(rotationProp, block.getState(RotationProperty));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +101,7 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler
|
|||||||
}
|
}
|
||||||
values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList));
|
values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList));
|
||||||
}
|
}
|
||||||
return (B) state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat;
|
|||||||
|
|
||||||
import com.sk89q.jnbt.IntTag;
|
import com.sk89q.jnbt.IntTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.EnumProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
@ -31,23 +30,24 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings("")
|
||||||
public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||||
|
|
||||||
private static final DirectionalProperty FacingProperty;
|
private static final Property<Direction> FACING_PROPERTY;
|
||||||
private static final EnumProperty PartProperty;
|
private static final Property<String> PART_PROPERTY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DirectionalProperty tempFacing;
|
Property<Direction> tempFacing;
|
||||||
EnumProperty tempPart;
|
Property<String> tempPart;
|
||||||
try {
|
try {
|
||||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.RED_BED.getProperty("facing");
|
tempFacing = BlockTypes.RED_BED.getProperty("facing");
|
||||||
tempPart = (EnumProperty) (Property<?>) BlockTypes.RED_BED.getProperty("part");
|
tempPart = BlockTypes.RED_BED.getProperty("part");
|
||||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||||
tempFacing = null;
|
tempFacing = null;
|
||||||
tempPart = null;
|
tempPart = null;
|
||||||
}
|
}
|
||||||
FacingProperty = tempFacing;
|
FACING_PROPERTY = tempFacing;
|
||||||
PartProperty = tempPart;
|
PART_PROPERTY = tempPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -56,7 +56,7 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
Tag typeTag = values.get("color");
|
Tag typeTag = values.get("color");
|
||||||
if (typeTag instanceof IntTag) {
|
if (typeTag instanceof IntTag) {
|
||||||
String bedType = convertBedType(((IntTag) typeTag).getValue());
|
String bedType = convertBedType(((IntTag) typeTag).getValue());
|
||||||
@ -65,17 +65,17 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
if (type != null) {
|
if (type != null) {
|
||||||
BlockState state = type.getDefaultState();
|
BlockState state = type.getDefaultState();
|
||||||
|
|
||||||
Property facingProp = type.getProperty("facing");
|
Property<Direction> facingProp = type.getProperty("facing");
|
||||||
state = state.with(facingProp, block.getState(FacingProperty));
|
state = state.with(facingProp, block.getState(FACING_PROPERTY));
|
||||||
|
|
||||||
Property occupiedProp = type.getProperty("occupied");
|
Property<Boolean> occupiedProp = type.getProperty("occupied");
|
||||||
state = state.with(occupiedProp, false);
|
state = state.with(occupiedProp, false);
|
||||||
|
|
||||||
Property partProp = type.getProperty("part");
|
Property<String> partProp = type.getProperty("part");
|
||||||
state = state.with(partProp, block.getState(PartProperty));
|
state = state.with(partProp, block.getState(PART_PROPERTY));
|
||||||
|
|
||||||
values.remove("color");
|
values.remove("color");
|
||||||
return (B) state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
Tag item = values.get("Item");
|
Tag item = values.get("Item");
|
||||||
if (item instanceof StringTag) {
|
if (item instanceof StringTag) {
|
||||||
String id = ((StringTag) item).getValue();
|
String id = ((StringTag) item).getValue();
|
||||||
if (id.isEmpty()) {
|
if (id.isEmpty()) {
|
||||||
return (B) BlockTypes.FLOWER_POT.getDefaultState();
|
return BlockTypes.FLOWER_POT.getDefaultState();
|
||||||
}
|
}
|
||||||
int data = 0;
|
int data = 0;
|
||||||
Tag dataTag = values.get("Data");
|
Tag dataTag = values.get("Data");
|
||||||
@ -52,7 +52,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
BlockState newState = convertLegacyBlockType(id, data);
|
BlockState newState = convertLegacyBlockType(id, data);
|
||||||
if (newState != null) {
|
if (newState != null) {
|
||||||
values.clear();
|
values.clear();
|
||||||
return (B) newState; // generics pls :\
|
return newState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
|
@ -26,5 +26,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
public interface NBTCompatibilityHandler {
|
public interface NBTCompatibilityHandler {
|
||||||
<B extends BlockStateHolder<B>> boolean isAffectedBlock(B block);
|
<B extends BlockStateHolder<B>> boolean isAffectedBlock(B block);
|
||||||
<B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values);
|
|
||||||
|
<B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
// note that instrument was not stored (in state or nbt) previously.
|
// note that instrument was not stored (in state or nbt) previously.
|
||||||
// it will be updated to the block below when it gets set into the world for the first time
|
// it will be updated to the block below when it gets set into the world for the first time
|
||||||
Tag noteTag = values.get("note");
|
Tag noteTag = values.get("note");
|
||||||
@ -55,7 +55,7 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
Byte note = ((ByteTag) noteTag).getValue();
|
Byte note = ((ByteTag) noteTag).getValue();
|
||||||
if (note != null) {
|
if (note != null) {
|
||||||
values.clear();
|
values.clear();
|
||||||
return (B) block.with(NoteProperty, (int) note).toImmutableState();
|
return block.with(NoteProperty, (int) note).toImmutableState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
|
@ -26,8 +26,8 @@ import com.google.gson.JsonPrimitive;
|
|||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.sk89q.jnbt.StringTag;
|
import com.sk89q.jnbt.StringTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.internal.util.DeprecationUtil;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -35,11 +35,11 @@ public class SignCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> boolean isAffectedBlock(B block) {
|
public <B extends BlockStateHolder<B>> boolean isAffectedBlock(B block) {
|
||||||
return block.getBlockType() == BlockTypes.SIGN || block.getBlockType() == BlockTypes.WALL_SIGN;
|
return DeprecationUtil.isSign(block.getBlockType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
String key = "Text" + (i + 1);
|
String key = "Text" + (i + 1);
|
||||||
Tag value = values.get(key);
|
Tag value = values.get(key);
|
||||||
|
@ -21,8 +21,8 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat;
|
|||||||
|
|
||||||
import com.sk89q.jnbt.ByteTag;
|
import com.sk89q.jnbt.ByteTag;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
@ -32,12 +32,12 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
||||||
|
|
||||||
private static final DirectionalProperty FacingProperty;
|
private static final Property<Direction> FacingProperty;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DirectionalProperty tempFacing;
|
Property<Direction> tempFacing;
|
||||||
try {
|
try {
|
||||||
tempFacing = (DirectionalProperty) (Property<?>) BlockTypes.SKELETON_WALL_SKULL.getProperty("facing");
|
tempFacing = BlockTypes.SKELETON_WALL_SKULL.getProperty("facing");
|
||||||
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
} catch (NullPointerException | IllegalArgumentException | ClassCastException e) {
|
||||||
tempFacing = null;
|
tempFacing = null;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <B extends BlockStateHolder<B>> B updateNBT(B block, Map<String, Tag> values) {
|
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
|
||||||
boolean isWall = block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL;
|
boolean isWall = block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL;
|
||||||
Tag typeTag = values.get("SkullType");
|
Tag typeTag = values.get("SkullType");
|
||||||
if (typeTag instanceof ByteTag) {
|
if (typeTag instanceof ByteTag) {
|
||||||
@ -61,18 +61,18 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler {
|
|||||||
if (type != null) {
|
if (type != null) {
|
||||||
BlockState state = type.getDefaultState();
|
BlockState state = type.getDefaultState();
|
||||||
if (isWall) {
|
if (isWall) {
|
||||||
Property newProp = type.getProperty("facing");
|
Property<Direction> newProp = type.getProperty("facing");
|
||||||
state = state.with(newProp, block.getState(FacingProperty));
|
state = state.with(newProp, block.getState(FacingProperty));
|
||||||
} else {
|
} else {
|
||||||
Tag rotTag = values.get("Rot");
|
Tag rotTag = values.get("Rot");
|
||||||
if (rotTag instanceof ByteTag) {
|
if (rotTag instanceof ByteTag) {
|
||||||
Property newProp = type.getProperty("rotation");
|
Property<Integer> newProp = type.getProperty("rotation");
|
||||||
state = state.with(newProp, (int) ((ByteTag) rotTag).getValue());
|
state = state.with(newProp, (int) ((ByteTag) rotTag).getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values.remove("SkullType");
|
values.remove("SkullType");
|
||||||
values.remove("Rot");
|
values.remove("Rot");
|
||||||
return (B) state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.function.mask;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
@ -61,4 +62,9 @@ public class BlockCategoryMask extends AbstractExtentMask {
|
|||||||
public Mask copy() {
|
public Mask copy() {
|
||||||
return new BlockCategoryMask(getExtent(), category);
|
return new BlockCategoryMask(getExtent(), category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replacesAir() {
|
||||||
|
return category.contains(BlockTypes.AIR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import com.sk89q.worldedit.world.block.ImmutableBaseBlock;
|
import com.sk89q.worldedit.world.block.ImmutableBaseBlock;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ public class BlockMask extends ABlockMask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(BlockState state) {
|
public boolean test(BlockState state) {
|
||||||
return ordinals[state.getOrdinal()] || replacesAir() && state.getOrdinal() <= 3;
|
return ordinals[state.getOrdinal()] || replacesAir() && state.getOrdinal() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -259,19 +259,16 @@ public class BlockMask extends ABlockMask {
|
|||||||
|
|
||||||
int setTypes = 0;
|
int setTypes = 0;
|
||||||
BlockType setType = null;
|
BlockType setType = null;
|
||||||
BlockType unsetType = null;
|
|
||||||
int totalTypes = 0;
|
int totalTypes = 0;
|
||||||
|
|
||||||
for (BlockType type : BlockTypesCache.values) {
|
for (BlockType type : BlockTypesCache.values) {
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
totalTypes++;
|
totalTypes++;
|
||||||
boolean hasAll = true;
|
boolean hasAll = true;
|
||||||
boolean hasAny = false;
|
|
||||||
List<BlockState> all = type.getAllStates();
|
List<BlockState> all = type.getAllStates();
|
||||||
for (BlockState state : all) {
|
for (BlockState state : all) {
|
||||||
totalStates++;
|
totalStates++;
|
||||||
hasAll &= test(state);
|
hasAll &= test(state);
|
||||||
hasAny = true;
|
|
||||||
}
|
}
|
||||||
if (hasAll) {
|
if (hasAll) {
|
||||||
setTypes++;
|
setTypes++;
|
||||||
@ -326,6 +323,7 @@ public class BlockMask extends ABlockMask {
|
|||||||
cloned[BlockTypes.AIR.getDefaultState().getOrdinal()] = false;
|
cloned[BlockTypes.AIR.getDefaultState().getOrdinal()] = false;
|
||||||
cloned[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] = false;
|
cloned[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] = false;
|
||||||
cloned[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()] = false;
|
cloned[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()] = false;
|
||||||
|
cloned[0] = false;
|
||||||
}
|
}
|
||||||
return new BlockMask(getExtent(), cloned);
|
return new BlockMask(getExtent(), cloned);
|
||||||
}
|
}
|
||||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren