Update to 1.11
This commit is contained in:
parent
21de2096a9
commit
7df6f2d54f
@ -1,6 +1,7 @@
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
||||
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
||||
compile 'net.milkbowl.vault:VaultAPI:1.5'
|
||||
compile 'com.massivecraft:factions:2.8.0'
|
||||
compile 'com.drtshock:factions:1.6.9.5'
|
||||
|
31
bukkit111/build.gradle
Normal file
31
bukkit111/build.gradle
Normal file
@ -0,0 +1,31 @@
|
||||
dependencies {
|
||||
compile project(':bukkit0')
|
||||
}
|
||||
|
||||
processResources {
|
||||
from('src/main/resources') {
|
||||
include 'plugin.yml'
|
||||
expand(
|
||||
name: project.parent.name,
|
||||
version: project.parent.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
// We only want the shadow jar produced
|
||||
jar.enabled = false
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency(':bukkit0'))
|
||||
include(dependency(':core'))
|
||||
}
|
||||
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
|
||||
destinationDir = file '../target'
|
||||
}
|
||||
shadowJar.doLast {
|
||||
task ->
|
||||
ant.checksum file: task.archivePath
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar);
|
@ -0,0 +1,413 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.object.BytePair;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_11_R1.Block;
|
||||
import net.minecraft.server.v1_11_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_11_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_11_R1.DataBits;
|
||||
import net.minecraft.server.v1_11_R1.DataPalette;
|
||||
import net.minecraft.server.v1_11_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_11_R1.DataPaletteGlobal;
|
||||
import net.minecraft.server.v1_11_R1.Entity;
|
||||
import net.minecraft.server.v1_11_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_11_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_11_R1.IBlockData;
|
||||
import net.minecraft.server.v1_11_R1.MinecraftKey;
|
||||
import net.minecraft.server.v1_11_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_11_R1.TileEntity;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11> {
|
||||
|
||||
public DataPaletteBlock[] sectionPalettes;
|
||||
|
||||
public static Map<String, Class<? extends Entity>> entityKeys;
|
||||
|
||||
/**
|
||||
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
||||
*
|
||||
* @param parent
|
||||
* @param x
|
||||
* @param z
|
||||
*/
|
||||
public BukkitChunk_1_11(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return ((com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11) getParent()).getWorld().getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk<Chunk, com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11> copy(boolean shallow) {
|
||||
BukkitChunk_1_11 value = (BukkitChunk_1_11) super.copy(shallow);
|
||||
if (sectionPalettes != null) {
|
||||
value.sectionPalettes = new DataPaletteBlock[16];
|
||||
try {
|
||||
Field fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
Field fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
|
||||
fieldPalette.setAccessible(true);
|
||||
Field fieldSize = DataPaletteBlock.class.getDeclaredField("e");
|
||||
fieldSize.setAccessible(true);
|
||||
for (int i = 0; i < sectionPalettes.length; i++) {
|
||||
DataPaletteBlock current = sectionPalettes[i];
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
// Clone palette
|
||||
DataPalette currentPalette = (DataPalette) fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
current.a(128, null);
|
||||
}
|
||||
DataPaletteBlock paletteBlock = newDataPaletteBlock();
|
||||
currentPalette = (DataPalette) fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
throw new RuntimeException("Palette must be global!");
|
||||
}
|
||||
fieldPalette.set(paletteBlock, currentPalette);
|
||||
// Clone size
|
||||
fieldSize.set(paletteBlock, fieldSize.get(current));
|
||||
// Clone palette
|
||||
DataBits currentBits = (DataBits) fieldBits.get(current);
|
||||
DataBits newBits = new DataBits(1, 0);
|
||||
for (Field field : DataBits.class.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
Object currentValue = field.get(currentBits);
|
||||
if (currentValue instanceof long[]) {
|
||||
currentValue = ((long[]) currentValue).clone();
|
||||
}
|
||||
field.set(newBits, currentValue);
|
||||
}
|
||||
fieldBits.set(paletteBlock, newBits);
|
||||
value.sectionPalettes[i] = paletteBlock;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public DataPaletteBlock newDataPaletteBlock() {
|
||||
try {
|
||||
return new DataPaletteBlock();
|
||||
} catch (Throwable e) {
|
||||
try {
|
||||
Constructor<DataPaletteBlock> constructor = DataPaletteBlock.class.getDeclaredConstructor(IBlockData[].class);
|
||||
return constructor.newInstance((Object) null);
|
||||
} catch (Throwable e2) {
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void optimize() {
|
||||
if (sectionPalettes != null) {
|
||||
return;
|
||||
}
|
||||
char[][] arrays = getCombinedIdArrays();
|
||||
IBlockData lastBlock = null;
|
||||
char lastChar = Character.MAX_VALUE;
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
if (getCount(layer) > 0) {
|
||||
if (sectionPalettes == null) {
|
||||
sectionPalettes = new DataPaletteBlock[16];
|
||||
}
|
||||
DataPaletteBlock palette = newDataPaletteBlock();
|
||||
char[] blocks = getIdArray(layer);
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = blocks[FaweCache.CACHE_J[y][z][x]];
|
||||
if (combinedId > 1) {
|
||||
palette.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
getChunk().load(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
try {
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_11_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
nmsChunk.f(true); // Set Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_11_R1.World nmsWorld = nmsChunk.world;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
Class<? extends net.minecraft.server.v1_11_R1.Chunk> clazzChunk = nmsChunk.getClass();
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// Remove entities
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
ents.clear();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
ents = new ArrayList<>(entities[i]);
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
for (Entity entity : ents) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = ((int) Math.round(entity.locX) & 15);
|
||||
int z = ((int) Math.round(entity.locZ) & 15);
|
||||
int y = (int) Math.round(entity.locY);
|
||||
if (array == null || y < 0 || y > 255) {
|
||||
continue;
|
||||
}
|
||||
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<Entity> ents = new ArrayList<>(entities[i]);
|
||||
for (Entity entity : ents) {
|
||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set entities
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
Set<UUID> createdEntities = new HashSet<>();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
for (CompoundTag nativeTag : entitiesToSpawn) {
|
||||
Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
StringTag idTag = (StringTag) entityTagMap.get("Id");
|
||||
ListTag posTag = (ListTag) entityTagMap.get("Pos");
|
||||
ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
|
||||
if (idTag == null || posTag == null || rotTag == null) {
|
||||
Fawe.debug("Unknown entity tag: " + nativeTag);
|
||||
continue;
|
||||
}
|
||||
double x = posTag.getDouble(0);
|
||||
double y = posTag.getDouble(1);
|
||||
double z = posTag.getDouble(2);
|
||||
float yaw = rotTag.getFloat(0);
|
||||
float pitch = rotTag.getFloat(1);
|
||||
String id = idTag.getValue();
|
||||
if (entityKeys == null) {
|
||||
entityKeys = new HashMap<>();
|
||||
for (MinecraftKey key : EntityTypes.a()) {
|
||||
String currentId = EntityTypes.a(key);
|
||||
Class<? extends Entity> clazz = EntityTypes.b.get(key);
|
||||
entityKeys.put(currentId, clazz);
|
||||
}
|
||||
}
|
||||
Class<? extends Entity> clazz = entityKeys.get(id);
|
||||
if (clazz != null) {
|
||||
Entity entity = EntityTypes.a(clazz, nmsWorld);
|
||||
if (entity != null) {
|
||||
UUID uuid = entity.getUniqueID();
|
||||
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
|
||||
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
|
||||
if (nativeTag != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_11.methodFromNative.invoke(BukkitQueue_1_11.adapter, nativeTag);
|
||||
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
tag.remove(name);
|
||||
}
|
||||
entity.f(tag);
|
||||
}
|
||||
entity.setLocation(x, y, z, yaw, pitch);
|
||||
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
createdEntities.add(entity.getUniqueID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Change task?
|
||||
if (getParent().getChangeTask() != null) {
|
||||
BukkitChunk_1_11 previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
|
||||
BlockPosition pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = FaweCache.CACHE_I[ly][lz][lx];
|
||||
char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int k = FaweCache.CACHE_J[ly][lz][lx];
|
||||
if (array[k] != 0) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
tile.y();
|
||||
nmsWorld.s(bp);
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
final char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
ChunkSection section = sections[j];
|
||||
if (section == null) {
|
||||
if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
|
||||
section = sections[j] = getParent().newChunkSection(j << 4, flag, null);
|
||||
getParent().setPalette(section, this.sectionPalettes[j]);
|
||||
getParent().setCount(0, count - this.getAir(j), section);
|
||||
continue;
|
||||
} else {
|
||||
sections[j] = getParent().newChunkSection(j << 4, flag, array);
|
||||
}
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
if (this.sectionPalettes != null && this.sectionPalettes[j] != null) {
|
||||
getParent().setPalette(section, this.sectionPalettes[j]);
|
||||
getParent().setCount(0, count - this.getAir(j), section);
|
||||
continue;
|
||||
} else {
|
||||
sections[j] = getParent().newChunkSection(j << 4, flag, array);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
short[][] i1 = FaweCache.CACHE_J[y];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
short[] i2 = i1[z];
|
||||
for (int x= 0; x < 16; x++) {
|
||||
char combinedId = array[i2[x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
if (existing != com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.air) {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
nibble.setBlock(x, y, z, com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.air);
|
||||
continue;
|
||||
default:
|
||||
nonEmptyBlockCount++;
|
||||
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<BytePair, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
BytePair pair = entry.getKey();
|
||||
BlockPosition pos = new BlockPosition(MathMan.unpair16x((byte) pair.get0()) + bx, pair.get1() & 0xFF, MathMan.unpair16y((byte) pair.get0()) + bz); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.methodFromNative.invoke(com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.adapter, nativeTag);
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.bukkit.ABukkitMain;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
public class BukkitMain_111 extends ABukkitMain {
|
||||
@Override
|
||||
public BukkitQueue_0 getQueue(World world) {
|
||||
return new com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweQueue getQueue(String world) {
|
||||
return new com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
super.onEnable();
|
||||
}
|
||||
}
|
@ -0,0 +1,520 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import net.minecraft.server.v1_11_R1.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftWorld;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Method getEntitySlices;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||
|
||||
public BukkitQueue_1_11(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
init();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_11(final String world) {
|
||||
super(world);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, int[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
if (heightMap[i] > otherMap[i]) {
|
||||
otherMap[i] = heightMap[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
checkVersion("v1_11_R1");
|
||||
if (air == null) {
|
||||
try {
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_11_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_11.FaweAdapter_1_11());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, ExecutorCompletionService pool, long time) {
|
||||
return super.next(amount, pool, time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.getSkyLightArray().a(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
protected DataBits lastBits;
|
||||
protected DataPaletteBlock lastBlocks;
|
||||
|
||||
@Override
|
||||
public World createWorld(final WorldCreator creator) {
|
||||
final String name = creator.name();
|
||||
ChunkGenerator generator = creator.generator();
|
||||
final CraftServer server = (CraftServer) Bukkit.getServer();
|
||||
final MinecraftServer console = server.getServer();
|
||||
final File folder = new File(server.getWorldContainer(), name);
|
||||
final World world = server.getWorld(name);
|
||||
final WorldType type = WorldType.getType(creator.type().getName());
|
||||
final boolean generateStructures = creator.generateStructures();
|
||||
if (world != null) {
|
||||
return world;
|
||||
}
|
||||
if (folder.exists() && !folder.isDirectory()) {
|
||||
throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder");
|
||||
}
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
try {
|
||||
Field field = CraftServer.class.getDeclaredField("worlds");
|
||||
field.setAccessible(true);
|
||||
Map<Object, Object> existing = (Map<Object, Object>) field.get(server);
|
||||
if (!existing.getClass().getName().contains("SynchronizedMap")) {
|
||||
field.set(server, Collections.synchronizedMap(existing));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (generator == null) {
|
||||
generator = server.getGenerator(name);
|
||||
}
|
||||
int dimension = 10 + console.worlds.size();
|
||||
boolean used = false;
|
||||
do {
|
||||
for (final WorldServer ws : console.worlds) {
|
||||
used = (ws.dimension == dimension);
|
||||
if (used) {
|
||||
++dimension;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (used);
|
||||
final boolean hardcore = false;
|
||||
final IDataManager sdm = new ServerNBTManager(server.getWorldContainer(), name, true, server.getHandle().getServer().getDataConverterManager());
|
||||
WorldData worlddata = sdm.getWorldData();
|
||||
final WorldSettings worldSettings;
|
||||
if (worlddata == null) {
|
||||
worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(server.getDefaultGameMode().getValue()), generateStructures, hardcore, type);
|
||||
worldSettings.setGeneratorSettings(creator.generatorSettings());
|
||||
worlddata = new WorldData(worldSettings, name);
|
||||
} else {
|
||||
worldSettings = null;
|
||||
}
|
||||
worlddata.checkName(name);
|
||||
final WorldServer internal = (WorldServer)new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b();
|
||||
startSet(true); // Temporarily allow async chunk load since the world isn't added yet
|
||||
if (worldSettings != null) {
|
||||
internal.a(worldSettings);
|
||||
}
|
||||
endSet(true);
|
||||
internal.scoreboard = server.getScoreboardManager().getMainScoreboard().getHandle();
|
||||
internal.tracker = new EntityTracker(internal);
|
||||
internal.addIWorldAccess(new WorldManager(console, internal));
|
||||
internal.worldData.setDifficulty(EnumDifficulty.EASY);
|
||||
internal.setSpawnFlags(true, true);
|
||||
if (generator != null) {
|
||||
internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld()));
|
||||
}
|
||||
// Add the world
|
||||
return TaskManager.IMP.sync(new RunnableVal<World>() {
|
||||
@Override
|
||||
public void run(World value) {
|
||||
console.worlds.add(internal);
|
||||
server.getPluginManager().callEvent(new WorldInitEvent(internal.getWorld()));
|
||||
server.getPluginManager().callEvent(new WorldLoadEvent(internal.getWorld()));
|
||||
this.value = internal.getWorld();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
CraftChunk chunk = (CraftChunk) world.getChunkAt(cx, cz);
|
||||
return chunk.getHandle().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection lastSection, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = lastSection.getBlocks();
|
||||
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||
Block block = ibd.getBlock();
|
||||
int id = Block.getId(block);
|
||||
if (FaweCache.hasData(id)) {
|
||||
return (id << 4) + block.toLegacyData(ibd);
|
||||
} else {
|
||||
return id << 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = section.getBlocks();
|
||||
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||
return ibd.c();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(ChunkSection section, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = section.getBlocks();
|
||||
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||
return ibd.d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = section.getBlocks();
|
||||
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
|
||||
return MathMan.pair16(ibd.c(), ibd.d());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_11 fs = (BukkitChunk_1_11) fc;
|
||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
||||
Chunk chunk = fs.getChunk();
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
net.minecraft.server.v1_11_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
PlayerChunk playerChunk = chunkMap.getChunk(nmsChunk.locX, nmsChunk.locZ);
|
||||
if (playerChunk == null) {
|
||||
return;
|
||||
}
|
||||
if (playerChunk.c.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Send chunks
|
||||
int mask = fc.getBitMask();
|
||||
if (mask == 65535 && hasEntities(nmsChunk)) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
mask = 255;
|
||||
}
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, mask);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_11_R1.Chunk nmsChunk) {
|
||||
try {
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) getEntitySlices.invoke(nmsChunk);
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<Entity> slice = entities[i];
|
||||
if (slice != null && !slice.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignore) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
|
||||
if (mode != RelightMode.NONE) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray()); // Emitted
|
||||
if (sky) {
|
||||
section.b(new NibbleArray()); // Skylight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullbright(ChunkSection[] sections) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
ChunkSection section = sections[i];
|
||||
if (section != null) {
|
||||
byte[] bytes = section.getSkyLightArray().asBytes();
|
||||
Arrays.fill(bytes, (byte) 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.b(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.c(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightBlock(int x, int y, int z) {
|
||||
pos.c(x, y, z);
|
||||
nmsWorld.c(EnumSkyBlock.BLOCK, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightSky(int x, int y, int z) {
|
||||
pos.c(x, y, z);
|
||||
nmsWorld.c(EnumSkyBlock.SKY, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relight(int x, int y, int z) {
|
||||
pos.c(x, y, z);
|
||||
nmsWorld.w(pos);
|
||||
}
|
||||
|
||||
protected WorldServer nmsWorld;
|
||||
|
||||
@Override
|
||||
public World getImpWorld() {
|
||||
World world = super.getImpWorld();
|
||||
if (world != null) {
|
||||
this.nmsWorld = ((CraftWorld) world).getHandle();
|
||||
return super.getImpWorld();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldSection.set(section, palette);
|
||||
}
|
||||
|
||||
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||
try {
|
||||
if (array == null) {
|
||||
return new ChunkSection(y2, flag);
|
||||
} else {
|
||||
return new ChunkSection(y2, flag, array);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
try {
|
||||
if (array == null) {
|
||||
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, IBlockData[].class);
|
||||
return constructor.newInstance(y2, flag, (IBlockData[]) null);
|
||||
} else {
|
||||
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, char[].class, IBlockData[].class);
|
||||
return constructor.newInstance(y2, flag, array, (IBlockData[]) null);
|
||||
}
|
||||
} catch (Throwable e2) {
|
||||
throw new RuntimeException(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitChunk_1_11 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
||||
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||
BukkitChunk_1_11 previous = getFaweChunk(fs.getX(), fs.getZ());
|
||||
// Copy blocks
|
||||
char[][] idPrevious = new char[16][];
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
short solid = 0;
|
||||
char[] previousLayer = idPrevious[layer] = new char[4096];
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = FaweCache.CACHE_X[0][j];
|
||||
int y = FaweCache.CACHE_Y[0][j];
|
||||
int z = FaweCache.CACHE_Z[0][j];
|
||||
IBlockData ibd = blocks.a(x, y, z);
|
||||
Block block = ibd.getBlock();
|
||||
int combined = Block.getId(block);
|
||||
if (FaweCache.hasData(combined)) {
|
||||
combined = (combined << 4) + block.toLegacyData(ibd);
|
||||
} else {
|
||||
combined = combined << 4;
|
||||
}
|
||||
if (combined > 1) {
|
||||
solid++;
|
||||
}
|
||||
previousLayer[j] = (char) combined;
|
||||
}
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
previous.ids = idPrevious;
|
||||
// Copy tiles
|
||||
if (tiles != null) {
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : tiles.entrySet()) {
|
||||
TileEntity tile = entry.getValue();
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
BlockPosition pos = entry.getKey();
|
||||
CompoundTag nativeTag = getTag(tile);
|
||||
previous.setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||
}
|
||||
}
|
||||
// Copy entities
|
||||
if (entities != null) {
|
||||
for (Collection<Entity> entityList : entities) {
|
||||
for (Entity ent : entityList) {
|
||||
if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && createdEntities.contains(ent.getUniqueID()))) {
|
||||
continue;
|
||||
}
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = (int) Math.round(ent.locY);
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
char[] array = fs.getIdArray(i);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
if (array[j] != 0) {
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
ent.e(tag); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
previous.setEntity(nativeTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
protected BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
}
|
||||
|
||||
public CompoundTag getTag(TileEntity tile) {
|
||||
try {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tile.save(tag); // readTagIntoEntity
|
||||
return (CompoundTag) methodToNative.invoke(adapter, tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_11_R1.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
c.mustSave = false;
|
||||
if (chunk.isLoaded()) {
|
||||
chunk.unload(false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitChunk_1_11 getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_1_11(this, x, z);
|
||||
}
|
||||
}
|
@ -0,0 +1,355 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.EndTag;
|
||||
import com.sk89q.jnbt.FloatTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.LongTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.server.v1_11_R1.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public final class FaweAdapter_1_11 implements BukkitImplAdapter
|
||||
{
|
||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||
private final Field nbtListTagListField;
|
||||
private final Method nbtCreateTagMethod;
|
||||
|
||||
public FaweAdapter_1_11()
|
||||
throws NoSuchFieldException, NoSuchMethodException
|
||||
{
|
||||
CraftServer.class.cast(Bukkit.getServer());
|
||||
|
||||
this.nbtListTagListField = NBTTagList.class.getDeclaredField("list");
|
||||
this.nbtListTagListField.setAccessible(true);
|
||||
|
||||
this.nbtCreateTagMethod = NBTBase.class.getDeclaredMethod("createTag", new Class[] { Byte.TYPE });
|
||||
this.nbtCreateTagMethod.setAccessible(true);
|
||||
}
|
||||
|
||||
private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity)
|
||||
{
|
||||
tileEntity.a(tag);
|
||||
}
|
||||
|
||||
private static void readTileEntityIntoTag(TileEntity tileEntity, NBTTagCompound tag)
|
||||
{
|
||||
tileEntity.save(tag);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getEntityId(net.minecraft.server.v1_11_R1.Entity entity)
|
||||
{
|
||||
return EntityTypes.b(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static net.minecraft.server.v1_11_R1.Entity createEntityFromId(String id, World world)
|
||||
{
|
||||
return EntityTypes.a(new MinecraftKey(id), world);
|
||||
}
|
||||
|
||||
private static void readTagIntoEntity(NBTTagCompound tag, net.minecraft.server.v1_11_R1.Entity entity)
|
||||
{
|
||||
entity.f(tag);
|
||||
}
|
||||
|
||||
private static void readEntityIntoTag(net.minecraft.server.v1_11_R1.Entity entity, NBTTagCompound tag)
|
||||
{
|
||||
entity.e(tag);
|
||||
}
|
||||
|
||||
public int getBlockId(Material material)
|
||||
{
|
||||
return material.getId();
|
||||
}
|
||||
|
||||
public Material getMaterial(int id)
|
||||
{
|
||||
return Material.getMaterial(id);
|
||||
}
|
||||
|
||||
public int getBiomeId(Biome biome)
|
||||
{
|
||||
BiomeBase mcBiome = CraftBlock.biomeToBiomeBase(biome);
|
||||
return mcBiome != null ? BiomeBase.a(mcBiome) : 0;
|
||||
}
|
||||
|
||||
public Biome getBiome(int id)
|
||||
{
|
||||
BiomeBase mcBiome = BiomeBase.getBiome(id);
|
||||
return CraftBlock.biomeBaseToBiome(mcBiome);
|
||||
}
|
||||
|
||||
public BaseBlock getBlock(Location location)
|
||||
{
|
||||
Preconditions.checkNotNull(location);
|
||||
|
||||
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
|
||||
Block bukkitBlock = location.getBlock();
|
||||
BaseBlock block = new BaseBlock(bukkitBlock.getTypeId(), bukkitBlock.getData());
|
||||
|
||||
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
||||
if (te != null)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
readTileEntityIntoTag(te, tag);
|
||||
block.setNbtData((CompoundTag)toNative(tag));
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
public boolean setBlock(Location location, BaseBlock block, boolean notifyAndLight)
|
||||
{
|
||||
Preconditions.checkNotNull(location);
|
||||
Preconditions.checkNotNull(block);
|
||||
|
||||
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||
int x = location.getBlockX();
|
||||
int y = location.getBlockY();
|
||||
int z = location.getBlockZ();
|
||||
|
||||
boolean changed = location.getBlock().setTypeIdAndData(block.getId(), (byte)block.getData(), notifyAndLight);
|
||||
|
||||
CompoundTag nativeTag = block.getNbtData();
|
||||
if (nativeTag != null)
|
||||
{
|
||||
TileEntity tileEntity = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
||||
if (tileEntity != null)
|
||||
{
|
||||
NBTTagCompound tag = (NBTTagCompound)fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
readTagIntoTileEntity(tag, tileEntity);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public BaseEntity getEntity(org.bukkit.entity.Entity entity)
|
||||
{
|
||||
Preconditions.checkNotNull(entity);
|
||||
|
||||
CraftEntity craftEntity = (CraftEntity)entity;
|
||||
net.minecraft.server.v1_11_R1.Entity mcEntity = craftEntity.getHandle();
|
||||
|
||||
String id = getEntityId(mcEntity);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
readEntityIntoTag(mcEntity, tag);
|
||||
CompoundTag weTag = (CompoundTag) toNative(tag);
|
||||
return new BaseEntity(id, weTag);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state)
|
||||
{
|
||||
Preconditions.checkNotNull(location);
|
||||
Preconditions.checkNotNull(state);
|
||||
|
||||
CraftWorld craftWorld = (CraftWorld)location.getWorld();
|
||||
WorldServer worldServer = craftWorld.getHandle();
|
||||
|
||||
net.minecraft.server.v1_11_R1.Entity createdEntity = createEntityFromId(state.getTypeId(), craftWorld.getHandle());
|
||||
if (createdEntity != null)
|
||||
{
|
||||
CompoundTag nativeTag = state.getNbtData();
|
||||
if (nativeTag != null)
|
||||
{
|
||||
NBTTagCompound tag = (NBTTagCompound)fromNative(nativeTag);
|
||||
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||
tag.remove(name);
|
||||
}
|
||||
readTagIntoEntity(tag, createdEntity);
|
||||
}
|
||||
createdEntity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
worldServer.addEntity(createdEntity, CreatureSpawnEvent.SpawnReason.CUSTOM);
|
||||
return createdEntity.getBukkitEntity();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Tag toNative(NBTBase foreign)
|
||||
{
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if ((foreign instanceof NBTTagCompound))
|
||||
{
|
||||
Map<String, Tag> values = new HashMap();
|
||||
Set<String> foreignKeys = ((NBTTagCompound)foreign).c();
|
||||
for (String str : foreignKeys)
|
||||
{
|
||||
NBTBase base = ((NBTTagCompound)foreign).get(str);
|
||||
values.put(str, toNative(base));
|
||||
}
|
||||
return new CompoundTag(values);
|
||||
}
|
||||
if ((foreign instanceof NBTTagByte)) {
|
||||
return new ByteTag(((NBTTagByte)foreign).g());
|
||||
}
|
||||
if ((foreign instanceof NBTTagByteArray)) {
|
||||
return new ByteArrayTag(((NBTTagByteArray)foreign).c());
|
||||
}
|
||||
if ((foreign instanceof NBTTagDouble)) {
|
||||
return new DoubleTag(((NBTTagDouble)foreign).asDouble());
|
||||
}
|
||||
if ((foreign instanceof NBTTagFloat)) {
|
||||
return new FloatTag(((NBTTagFloat)foreign).i());
|
||||
}
|
||||
if ((foreign instanceof NBTTagInt)) {
|
||||
return new IntTag(((NBTTagInt)foreign).e());
|
||||
}
|
||||
if ((foreign instanceof NBTTagIntArray)) {
|
||||
return new IntArrayTag(((NBTTagIntArray)foreign).d());
|
||||
}
|
||||
if ((foreign instanceof NBTTagList)) {
|
||||
try
|
||||
{
|
||||
return toNativeList((NBTTagList)foreign);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
this.logger.log(Level.WARNING, "Failed to convert NBTTagList", e);
|
||||
return new ListTag(ByteTag.class, new ArrayList());
|
||||
}
|
||||
}
|
||||
if ((foreign instanceof NBTTagLong)) {
|
||||
return new LongTag(((NBTTagLong)foreign).d());
|
||||
}
|
||||
if ((foreign instanceof NBTTagShort)) {
|
||||
return new ShortTag(((NBTTagShort)foreign).f());
|
||||
}
|
||||
if ((foreign instanceof NBTTagString)) {
|
||||
return new StringTag(((NBTTagString)foreign).c_());
|
||||
}
|
||||
if ((foreign instanceof NBTTagEnd)) {
|
||||
return new EndTag();
|
||||
}
|
||||
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
private ListTag toNativeList(NBTTagList foreign)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
|
||||
{
|
||||
List<Tag> values = new ArrayList();
|
||||
int type = foreign.getTypeId();
|
||||
|
||||
List foreignList = (List)this.nbtListTagListField.get(foreign);
|
||||
for (int i = 0; i < foreign.size(); i++)
|
||||
{
|
||||
NBTBase element = (NBTBase)foreignList.get(i);
|
||||
values.add(toNative(element));
|
||||
}
|
||||
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
|
||||
return new ListTag(cls, values);
|
||||
}
|
||||
|
||||
private NBTBase fromNative(Tag foreign)
|
||||
{
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
Map.Entry<String, Tag> entry;
|
||||
if ((foreign instanceof CompoundTag))
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
for (Iterator localIterator = ((CompoundTag)foreign)
|
||||
.getValue().entrySet().iterator(); localIterator.hasNext();)
|
||||
{
|
||||
entry = (Map.Entry)localIterator.next();
|
||||
|
||||
tag.set((String)entry.getKey(), fromNative((Tag)entry.getValue()));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
if ((foreign instanceof ByteTag)) {
|
||||
return new NBTTagByte(((ByteTag)foreign).getValue().byteValue());
|
||||
}
|
||||
if ((foreign instanceof ByteArrayTag)) {
|
||||
return new NBTTagByteArray(((ByteArrayTag)foreign).getValue());
|
||||
}
|
||||
if ((foreign instanceof DoubleTag)) {
|
||||
return new NBTTagDouble(((DoubleTag)foreign).getValue().doubleValue());
|
||||
}
|
||||
if ((foreign instanceof FloatTag)) {
|
||||
return new NBTTagFloat(((FloatTag)foreign).getValue().floatValue());
|
||||
}
|
||||
if ((foreign instanceof IntTag)) {
|
||||
return new NBTTagInt(((IntTag)foreign).getValue().intValue());
|
||||
}
|
||||
if ((foreign instanceof IntArrayTag)) {
|
||||
return new NBTTagIntArray(((IntArrayTag)foreign).getValue());
|
||||
}
|
||||
if ((foreign instanceof ListTag))
|
||||
{
|
||||
NBTTagList tag = new NBTTagList();
|
||||
ListTag foreignList = (ListTag)foreign;
|
||||
for (Tag t : foreignList.getValue()) {
|
||||
tag.add(fromNative(t));
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
if ((foreign instanceof LongTag)) {
|
||||
return new NBTTagLong(((LongTag)foreign).getValue().longValue());
|
||||
}
|
||||
if ((foreign instanceof ShortTag)) {
|
||||
return new NBTTagShort(((ShortTag)foreign).getValue().shortValue());
|
||||
}
|
||||
if ((foreign instanceof StringTag)) {
|
||||
return new NBTTagString(((StringTag)foreign).getValue());
|
||||
}
|
||||
if ((foreign instanceof EndTag)) {
|
||||
try
|
||||
{
|
||||
return (NBTBase)this.nbtCreateTagMethod.invoke(null, new Object[] { Byte.valueOf((byte) 0) });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
30
bukkit111/src/main/resources/plugin.yml
Normal file
30
bukkit111/src/main/resources/plugin.yml
Normal file
@ -0,0 +1,30 @@
|
||||
name: ${name}
|
||||
main: com.boydti.fawe.bukkit.v1_11.BukkitMain_111
|
||||
version: ${version}
|
||||
description: Fast Async WorldEdit plugin
|
||||
authors: [Empire92]
|
||||
loadbefore: [WorldEdit,AsyncWorldEdit,AsyncWorldEditInjector]
|
||||
load: STARTUP
|
||||
database: false
|
||||
#softdepend: [WorldGuard, PlotSquared, MCore, Factions, GriefPrevention, Residence, Towny, PlotMe, PreciousStones]
|
||||
commands:
|
||||
wea:
|
||||
description: (FAWE) Bypass WorldEdit processing and area restrictions
|
||||
aliases: [weanywhere,worldeditanywhere,/wea,/weanywhere,/worldeditanywhere]
|
||||
usage: "Vault is required for the toggle. Optionally, you can set the permission fawe.bypass"
|
||||
fawe:
|
||||
description: (FAWE) Reload the plugin
|
||||
aliases: [/fawe,/fawereload]
|
||||
select:
|
||||
description: (FAWE) Select your current WorldEdit Region.
|
||||
aliases: [/select,wer,/wer,worldeditregion,/worldeditregion,/region]
|
||||
fcancel:
|
||||
description: (FAWE) Cancel your edit
|
||||
aliases: [fawecancel,/fcancel,/cancel,/fawecancel]
|
||||
permissions:
|
||||
fawe.bypass:
|
||||
default: false
|
||||
fawe.admin:
|
||||
default: op
|
||||
fawe.reload:
|
||||
default: false
|
@ -441,7 +441,7 @@ public class Fawe {
|
||||
MainUtil.handleError(e, false);
|
||||
debug("=======================================");
|
||||
debug("Things to check: ");
|
||||
debug(" - Using WorldEdit 6.1.1");
|
||||
debug(" - Using the latest version of WorldEdit/FAWE");
|
||||
debug(" - AsyncWorldEdit/WorldEditRegions isn't installed");
|
||||
debug(" - Any other errors in the startup log");
|
||||
debug(" - Contact Empire92 for assistance!");
|
||||
|
@ -1,3 +1,3 @@
|
||||
rootProject.name = 'FastAsyncWorldEdit'
|
||||
|
||||
include 'core', 'bukkit0', 'bukkit1710', 'bukkit18', 'bukkit19', 'bukkit110', 'forge1710', 'forge189', 'forge194', 'forge110', 'favs', 'nukkit'
|
||||
include 'core', 'bukkit0', 'bukkit1710', 'bukkit18', 'bukkit19', 'bukkit110', 'bukkit111', 'forge1710', 'forge189', 'forge194', 'forge110', 'favs', 'nukkit'
|
||||
|
Loading…
Reference in New Issue
Block a user