mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-09-27 22:47:28 +02:00
fix build
This commit is contained in:
parent
f79484690d
commit
fbd564def5
21
build.gradle
21
build.gradle
@ -2,10 +2,11 @@ buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven { url = "https://plugins.gradle.org/m2/" }
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
|
||||
classpath 'org.ajoberstar:grgit:1.7.0'
|
||||
}
|
||||
configurations.all {
|
||||
@ -113,21 +114,3 @@ subprojects {
|
||||
maven {url "https://store.ttyh.ru/libraries/"}
|
||||
}
|
||||
}
|
||||
task aggregatedJavadocs(type: Javadoc, description: 'Generate javadocs from all child projects as if it was a single project', group: 'Documentation') {
|
||||
destinationDir = file("./docs/javadoc")
|
||||
title = "$project.name $version API"
|
||||
options.author true
|
||||
options.links 'http://docs.spring.io/spring/docs/4.3.x/javadoc-api/', 'http://docs.oracle.com/javase/8/docs/api/', 'http://docs.spring.io/spring-ws/docs/2.3.0.RELEASE/api/', 'http://docs.spring.io/spring-security/site/docs/4.0.4.RELEASE/apidocs/'
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
|
||||
delete "./docs"
|
||||
|
||||
subprojects.each { proj ->
|
||||
proj.tasks.withType(Javadoc).each { javadocTask ->
|
||||
source += javadocTask.source
|
||||
classpath += javadocTask.classpath
|
||||
excludes += javadocTask.excludes
|
||||
includes += javadocTask.includes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.github.jengelman.gradle.plugins:shadow:5.1.0"
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
flatDir {dirs 'lib'}
|
||||
}
|
||||
@ -7,9 +17,6 @@ dependencies {
|
||||
compile('com.destroystokyo.paper:paper-api:1.12-R0.1-SNAPSHOT') {
|
||||
exclude group: 'net.md-5'
|
||||
}
|
||||
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
|
||||
compile 'org.bukkit.craftbukkitv1_11:Craftbukkit:1.11'
|
||||
// compile 'org.bukkit.craftbukkitv1_12:Craftbukkit:1.12'
|
||||
compile 'org.bukkit.craftbukkitv1_12_R1:Craftbukkit:1.12.1'
|
||||
compile 'net.milkbowl.vault:VaultAPI:1.5.6'
|
||||
compile 'com.massivecraft:factions:2.8.0'
|
||||
@ -26,9 +33,6 @@ dependencies {
|
||||
compile 'com.sk89q.worldedit:worldedit-bukkit:6.1.4-SNAPSHOT'
|
||||
compile 'com.sk89q.worldedit:worldedit-core:6.1.4-SNAPSHOT'
|
||||
compile 'com.thevoxelbox.voxelsniper:voxelsniper:5.171.0'
|
||||
compile 'org.bukkit.craftbukkit.v1_9R2:craftbukkitv1_9R2:1.9.4'
|
||||
compile 'org.bukkit.craftbukkit:Craftbukkit:1.7.10'
|
||||
compile 'org.bukkit.craftbukkit:CraftBukkit:1.8.8'
|
||||
compile 'com.comphenix.protocol:ProtocolLib-API:4.4.0-SNAPSHOT'
|
||||
compile 'com.wasteofplastic:askyblock:3.0.8.2'
|
||||
compile('org.inventivetalent:mapmanager:1.7.2-SNAPSHOT') {
|
||||
@ -62,7 +66,7 @@ task copyFiles {
|
||||
}
|
||||
}
|
||||
|
||||
/*apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
// We only want the shadow jar produced
|
||||
shadowJar {
|
||||
dependencies {
|
||||
@ -79,6 +83,4 @@ shadowJar.doLast {
|
||||
ant.checksum file: task.archivePath
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar);
|
||||
|
||||
*/
|
||||
build.dependsOn(shadowJar);
|
@ -7,7 +7,17 @@ import com.boydti.fawe.bukkit.listener.BrushListener;
|
||||
import com.boydti.fawe.bukkit.listener.BukkitImageListener;
|
||||
import com.boydti.fawe.bukkit.listener.CFIPacketListener;
|
||||
import com.boydti.fawe.bukkit.listener.RenderListener;
|
||||
import com.boydti.fawe.bukkit.regions.*;
|
||||
import com.boydti.fawe.bukkit.regions.ASkyBlockHook;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsFeature;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsOneFeature;
|
||||
import com.boydti.fawe.bukkit.regions.FactionsUUIDFeature;
|
||||
import com.boydti.fawe.bukkit.regions.FreeBuildRegion;
|
||||
import com.boydti.fawe.bukkit.regions.GriefPreventionFeature;
|
||||
import com.boydti.fawe.bukkit.regions.PlotMeFeature;
|
||||
import com.boydti.fawe.bukkit.regions.PreciousStonesFeature;
|
||||
import com.boydti.fawe.bukkit.regions.ResidenceFeature;
|
||||
import com.boydti.fawe.bukkit.regions.TownyFeature;
|
||||
import com.boydti.fawe.bukkit.regions.Worldguard;
|
||||
import com.boydti.fawe.bukkit.util.BukkitReflectionUtils;
|
||||
import com.boydti.fawe.bukkit.util.BukkitTaskMan;
|
||||
import com.boydti.fawe.bukkit.util.ItemUtil;
|
||||
@ -19,20 +29,18 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_All;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener_8;
|
||||
import com.boydti.fawe.bukkit.v0.ChunkListener_9;
|
||||
import com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10;
|
||||
import com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11;
|
||||
import com.boydti.fawe.bukkit.v1_12.BukkitQueue_1_12;
|
||||
import com.boydti.fawe.bukkit.v1_12.NMSRegistryDumper;
|
||||
import com.boydti.fawe.bukkit.v1_7.BukkitQueue17;
|
||||
import com.boydti.fawe.bukkit.v1_8.BukkitQueue18R3;
|
||||
import com.boydti.fawe.bukkit.v1_9.BukkitQueue_1_9_R1;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweCommand;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.*;
|
||||
import com.boydti.fawe.util.Jars;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.image.ImageViewer;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
@ -61,7 +69,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.primesoft.blockshub.BlocksHubBukkit;
|
||||
|
||||
public class FaweBukkit implements IFawe, Listener {
|
||||
|
||||
@ -623,19 +630,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
|
||||
private boolean enabledBlocksHub = true;
|
||||
|
||||
@Override
|
||||
public Object getBlocksHubApi() {
|
||||
if (!enabledBlocksHub) {
|
||||
return null;
|
||||
}
|
||||
Plugin blocksHubPlugin = Bukkit.getPluginManager().getPlugin("BlocksHub");
|
||||
if (blocksHubPlugin == null) {
|
||||
enabledBlocksHub = false;
|
||||
return null;
|
||||
}
|
||||
return ((BlocksHubBukkit) blocksHubPlugin).getApi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMainThread() {
|
||||
return Bukkit.isPrimaryThread();
|
||||
@ -681,16 +675,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
|
||||
private FaweQueue getQueue(World world) {
|
||||
switch (getVersion()) {
|
||||
case v1_7_R4:
|
||||
return new BukkitQueue17(world);
|
||||
case v1_8_R3:
|
||||
return new BukkitQueue18R3(world);
|
||||
case v1_9_R2:
|
||||
return new BukkitQueue_1_9_R1(world);
|
||||
case v1_10_R1:
|
||||
return new BukkitQueue_1_10(world);
|
||||
case v1_11_R1:
|
||||
return new BukkitQueue_1_11(world);
|
||||
case v1_12_R1:
|
||||
return new BukkitQueue_1_12(world);
|
||||
default:
|
||||
@ -701,16 +685,6 @@ public class FaweBukkit implements IFawe, Listener {
|
||||
|
||||
private FaweQueue getQueue(String world) {
|
||||
switch (getVersion()) {
|
||||
case v1_7_R4:
|
||||
return new BukkitQueue17(world);
|
||||
case v1_8_R3:
|
||||
return new BukkitQueue18R3(world);
|
||||
case v1_9_R2:
|
||||
return new BukkitQueue_1_9_R1(world);
|
||||
case v1_10_R1:
|
||||
return new BukkitQueue_1_10(world);
|
||||
case v1_11_R1:
|
||||
return new BukkitQueue_1_11(world);
|
||||
case v1_12_R1:
|
||||
return new BukkitQueue_1_12(world);
|
||||
default:
|
||||
|
@ -1,477 +0,0 @@
|
||||
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
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.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_10_R1.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
|
||||
public DataPaletteBlock[] sectionPalettes;
|
||||
|
||||
/**
|
||||
* 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_10(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_10(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_10 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
copy.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);
|
||||
copy.sectionPalettes[i] = paletteBlock;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return ((com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10) getParent()).getWorld().getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void removeEntity(Entity entity) {
|
||||
entity.b(false);
|
||||
entity.die();
|
||||
entity.valid = false;
|
||||
}
|
||||
|
||||
public void storeBiomes(byte[] biomes) {
|
||||
this.biomes = Arrays.copyOf(biomes, biomes.length);
|
||||
}
|
||||
|
||||
public boolean storeEntity(Entity ent) throws InvocationTargetException, IllegalAccessException {
|
||||
if (ent instanceof EntityPlayer) {
|
||||
return false;
|
||||
}
|
||||
int x = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
ent.e(tag); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) getParent().toNative(tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
setEntity(nativeTag);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean storeTile(TileEntity tile, BlockPosition pos) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
CompoundTag nativeTag = getParent().getTag(tile);
|
||||
setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
try {
|
||||
BukkitChunk_1_10_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_10_Copy(getParent(), getX(), getZ()) : null;
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftChunk) chunk).getHandle();
|
||||
nmsChunk.f(true); // Set Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world;
|
||||
net.minecraft.server.v1_10_R1.ChunkSection[] sections = nmsChunk.getSections();
|
||||
final Collection<net.minecraft.server.v1_10_R1.Entity>[] entities = (Collection<net.minecraft.server.v1_10_R1.Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||
Map<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
Iterator<net.minecraft.server.v1_10_R1.Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_10_R1.Entity entity = iter.next();
|
||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null) continue;
|
||||
Iterator<net.minecraft.server.v1_10_R1.Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_10_R1.Entity entity = iter.next();
|
||||
if (entity instanceof net.minecraft.server.v1_10_R1.EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = (MathMan.roundInt(entity.locX) & 15);
|
||||
int z = (MathMan.roundInt(entity.locZ) & 15);
|
||||
int y = MathMan.roundInt(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
iter.remove();
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set entities
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
Set<UUID> createdEntities = new HashSet<>();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
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();
|
||||
Entity entity = EntityTypes.createEntityByName(id, 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_10.fromNative(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
int countAir = this.getAir(j);
|
||||
final char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
net.minecraft.server.v1_10_R1.ChunkSection section = sections[j];
|
||||
if (copy != null) {
|
||||
copy.storeSection(section, j);
|
||||
}
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
}
|
||||
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 (countAir >= 4096) {
|
||||
sections[j] = null;
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
int by = j << 4;
|
||||
net.minecraft.server.v1_10_R1.DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
net.minecraft.server.v1_10_R1.IBlockData existing;
|
||||
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:
|
||||
continue;
|
||||
case 1:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_10.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_10.air);
|
||||
continue;
|
||||
default:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_10.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tile = iterator.next();
|
||||
net.minecraft.server.v1_10_R1.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<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
for (Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> entry : toRemove.entrySet()) {
|
||||
net.minecraft.server.v1_10_R1.BlockPosition bp = entry.getKey();
|
||||
net.minecraft.server.v1_10_R1.TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.s(bp);
|
||||
tile.y();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
copy.storeBiomes(nmsChunk.getBiomeIndex());
|
||||
}
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
net.minecraft.server.v1_10_R1.BlockPosition pos = new net.minecraft.server.v1_10_R1.BlockPosition(x, y, z); // Set pos
|
||||
net.minecraft.server.v1_10_R1.TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
net.minecraft.server.v1_10_R1.NBTTagCompound tag = (net.minecraft.server.v1_10_R1.NBTTagCompound) com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
// Change task
|
||||
if (copy != null) {
|
||||
getParent().getChangeTask().run(copy, this);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import net.minecraft.server.v1_10_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_10_R1.NibbleArray;
|
||||
|
||||
public class BukkitChunk_1_10_Copy extends BukkitChunk_1_10 {
|
||||
public final byte[][] idsBytes;
|
||||
public final byte[][] datasBytes;
|
||||
|
||||
public BukkitChunk_1_10_Copy(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
idsBytes = new byte[16][];
|
||||
datasBytes = new byte[16][];
|
||||
}
|
||||
|
||||
public void set(int i, byte[] ids, byte[] data) {
|
||||
this.idsBytes[i] = ids;
|
||||
this.datasBytes[i] = data;
|
||||
}
|
||||
|
||||
public boolean storeSection(ChunkSection section, int layer) throws IllegalAccessException {
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
set(layer, ids, data.asBytes());
|
||||
short solid = (short) getParent().fieldNonEmptyBlockCount.getInt(section);
|
||||
count[layer] = solid;
|
||||
air[layer] = (short) (4096 - solid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getCombinedIdArrays() {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
getIdArray(i);
|
||||
}
|
||||
return super.getCombinedIdArrays();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getIdArray(int i) {
|
||||
char[] combined = this.ids[i];
|
||||
if (combined != null) {
|
||||
return combined;
|
||||
}
|
||||
byte[] idsBytesArray = idsBytes[i];
|
||||
if (idsBytesArray == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] datasBytesArray = datasBytes[i];
|
||||
|
||||
idsBytes[i] = null;
|
||||
datasBytes[i] = null;
|
||||
|
||||
this.ids[i] = combined = new char[4096];
|
||||
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + (datasBytesArray[j] & 15));
|
||||
}
|
||||
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + ((datasBytesArray[j] >> 4) & 15));
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
}
|
@ -1,850 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||
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.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
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 com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import net.minecraft.server.v1_10_R1.BiomeBase;
|
||||
import net.minecraft.server.v1_10_R1.BiomeCache;
|
||||
import net.minecraft.server.v1_10_R1.Block;
|
||||
import net.minecraft.server.v1_10_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_10_R1.ChunkProviderGenerate;
|
||||
import net.minecraft.server.v1_10_R1.ChunkProviderServer;
|
||||
import net.minecraft.server.v1_10_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_10_R1.Entity;
|
||||
import net.minecraft.server.v1_10_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_10_R1.EntityTracker;
|
||||
import net.minecraft.server.v1_10_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_10_R1.EnumDifficulty;
|
||||
import net.minecraft.server.v1_10_R1.EnumGamemode;
|
||||
import net.minecraft.server.v1_10_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_10_R1.IBlockData;
|
||||
import net.minecraft.server.v1_10_R1.IDataManager;
|
||||
import net.minecraft.server.v1_10_R1.MinecraftServer;
|
||||
import net.minecraft.server.v1_10_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_10_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_10_R1.PacketDataSerializer;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutMultiBlockChange;
|
||||
import net.minecraft.server.v1_10_R1.PlayerChunk;
|
||||
import net.minecraft.server.v1_10_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_10_R1.ServerNBTManager;
|
||||
import net.minecraft.server.v1_10_R1.TileEntity;
|
||||
import net.minecraft.server.v1_10_R1.WorldChunkManager;
|
||||
import net.minecraft.server.v1_10_R1.WorldData;
|
||||
import net.minecraft.server.v1_10_R1.WorldManager;
|
||||
import net.minecraft.server.v1_10_R1.WorldServer;
|
||||
import net.minecraft.server.v1_10_R1.WorldSettings;
|
||||
import net.minecraft.server.v1_10_R1.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R1.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Field fieldPalette;
|
||||
protected static Field fieldSize;
|
||||
protected static Method getEntitySlices;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
protected static Field fieldBiomes;
|
||||
protected static Field fieldChunkGenerator;
|
||||
protected static Field fieldSeed;
|
||||
protected static Field fieldBiomeCache;
|
||||
protected static Field fieldBiomes2;
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static MutableGenLayer genLayer;
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE + 1];
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = ChunkProviderGenerate.class.getDeclaredField("C");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldChunkGenerator = ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||
fieldChunkGenerator.setAccessible(true);
|
||||
fieldSeed = WorldData.class.getDeclaredField("e");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = WorldChunkManager.class.getDeclaredField("c");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = WorldChunkManager.class.getDeclaredField("a") ;
|
||||
fieldGenLayer2 = WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
|
||||
fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
|
||||
fieldPalette.setAccessible(true);
|
||||
fieldSize = DataPaletteBlock.class.getDeclaredField("e");
|
||||
fieldSize.setAccessible(true);
|
||||
|
||||
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_10_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_10(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_10(final String world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(net.minecraft.server.v1_10_R1.Chunk chunk) {
|
||||
chunk.f(true); // Set Modified
|
||||
chunk.mustSave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getSections(net.minecraft.server.v1_10_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
try {
|
||||
if (seed == null) {
|
||||
seed = world.getSeed();
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
ChunkProviderGenerate generator = new ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
Biome bukkitBiome = getAdapter().getBiome(biome.getId());
|
||||
BiomeBase base = BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new BiomeBase[]{base});
|
||||
boolean cold = base.getTemperature() <= 1;
|
||||
net.minecraft.server.v1_10_R1.ChunkGenerator existingGenerator = nmsWorld.getChunkProviderServer().chunkGenerator;
|
||||
long existingSeed = world.getSeed();
|
||||
{
|
||||
if (genLayer == null) genLayer = new MutableGenLayer(seed);
|
||||
genLayer.set(biome.getId());
|
||||
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||
}
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return super.regenerateChunk(world, x, z, biome, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
int newHeight = heightMap[i] & 0xFF;
|
||||
int currentHeight = otherMap[i];
|
||||
if (newHeight > currentHeight) {
|
||||
otherMap[i] = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, long time) {
|
||||
return super.next(amount, 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);
|
||||
}
|
||||
|
||||
@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 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 getBiome(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@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 boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
long last = start;
|
||||
synchronized (net.minecraft.server.v1_10_R1.RegionFileCache.class) {
|
||||
World world = getWorld();
|
||||
if (world.getKeepSpawnInMemory()) world.setKeepSpawnInMemory(false);
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderServer provider = nmsWorld.getChunkProviderServer();
|
||||
|
||||
boolean mustSave = false;
|
||||
boolean[][] chunksUnloaded = null;
|
||||
{ // Unload chunks
|
||||
Iterator<net.minecraft.server.v1_10_R1.Chunk> iter = provider.a().iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = iter.next();
|
||||
if (chunk.locX >> 5 == mcaX && chunk.locZ >> 5 == mcaZ) {
|
||||
boolean isIn = allowed.isInChunk(chunk.locX, chunk.locZ);
|
||||
if (isIn) {
|
||||
if (!load) {
|
||||
if (saveChunks && chunk.a(false)) {
|
||||
mustSave = true;
|
||||
provider.saveChunk(chunk);
|
||||
provider.saveChunkNOP(chunk);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
boolean save = saveChunks && chunk.a(false);
|
||||
mustSave |= save;
|
||||
if (save) {
|
||||
provider.unload(chunk);
|
||||
} else {
|
||||
chunk.bukkitChunk.unload(false, false);
|
||||
}
|
||||
if (chunksUnloaded == null) {
|
||||
chunksUnloaded = new boolean[32][];
|
||||
}
|
||||
int relX = chunk.locX & 31;
|
||||
boolean[] arr = chunksUnloaded[relX];
|
||||
if (arr == null) {
|
||||
arr = chunksUnloaded[relX] = new boolean[32];
|
||||
}
|
||||
arr[chunk.locZ & 31] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustSave) provider.c(); // TODO only the necessary chunks
|
||||
|
||||
File unloadedRegion = null;
|
||||
if (load && !net.minecraft.server.v1_10_R1.RegionFileCache.a.isEmpty()) {
|
||||
Map<File, net.minecraft.server.v1_10_R1.RegionFile> map = net.minecraft.server.v1_10_R1.RegionFileCache.a;
|
||||
Iterator<Map.Entry<File, net.minecraft.server.v1_10_R1.RegionFile>> iter = map.entrySet().iterator();
|
||||
String requiredPath = world.getName() + File.separator + "region";
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<File, net.minecraft.server.v1_10_R1.RegionFile> entry = iter.next();
|
||||
File file = entry.getKey();
|
||||
int[] regPos = MainUtil.regionNameToCoords(file.getPath());
|
||||
if (regPos[0] == mcaX && regPos[1] == mcaZ && file.getPath().contains(requiredPath)) {
|
||||
if (file.exists()) {
|
||||
unloadedRegion = file;
|
||||
net.minecraft.server.v1_10_R1.RegionFile regionFile = entry.getValue();
|
||||
iter.remove();
|
||||
try {
|
||||
regionFile.c();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (whileLocked != null) whileLocked.run();
|
||||
if (!load) return;
|
||||
|
||||
{ // Load the region again
|
||||
if (unloadedRegion != null && chunksUnloaded != null && unloadedRegion.exists()) {
|
||||
final boolean[][] finalChunksUnloaded = chunksUnloaded;
|
||||
TaskManager.IMP.async(() -> {
|
||||
int bx = mcaX << 5;
|
||||
int bz = mcaZ << 5;
|
||||
for (int x = 0; x < finalChunksUnloaded.length; x++) {
|
||||
boolean[] arr = finalChunksUnloaded[x];
|
||||
if (arr != null) {
|
||||
for (int z = 0; z < arr.length; z++) {
|
||||
if (arr[z]) {
|
||||
int cx = bx + x;
|
||||
int cz = bz + z;
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value1) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = provider.getChunkAt(cx, cz, null, false);
|
||||
if (chunk != null) {
|
||||
PlayerChunk pc = nmsWorld.getPlayerChunkMap().getChunk(cx, cz);
|
||||
if (pc != null && !pc.c.isEmpty()) {
|
||||
sendChunk(chunk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((CraftWorld) getWorld()).getHandle().getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
boolean[] watchingArr = new boolean[players.length];
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayer player = ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle();
|
||||
if (playerManager.a(player, chunk.getX(), chunk.getZ())) {
|
||||
watchingArr[i] = true;
|
||||
watching = true;
|
||||
}
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
PacketPlayOutMultiBlockChange packet = new PacketPlayOutMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketDataSerializer buffer = new PacketDataSerializer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.d(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
if (combined < 16) combined = 0;
|
||||
buffer.writeShort(index);
|
||||
buffer.d(combined);
|
||||
}
|
||||
});
|
||||
packet.a(buffer);
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
if (watchingArr[i]) ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(net.minecraft.server.v1_10_R1.Chunk nmsChunk, int mask) {
|
||||
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;
|
||||
}
|
||||
if (mask == 0) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65535);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Send chunks
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == null) {
|
||||
sections[i] = emptySection;
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
if (mask == 0 || 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);
|
||||
}
|
||||
if (empty) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == emptySection) {
|
||||
sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_10_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 removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
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_10 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;
|
||||
// Copy blocks
|
||||
BukkitChunk_1_10_Copy previous = new BukkitChunk_1_10_Copy(this, fs.getX(), fs.getZ());
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
previous.set(layer, ids, data.asBytes());
|
||||
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
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) toNative(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(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.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) toNative(tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
c.mustSave = false;
|
||||
if (chunk.isLoaded()) {
|
||||
chunk.unload(false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitChunk_1_10 getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_1_10(this, x, z);
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
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.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_10_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_10_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public final class FaweAdapter_1_10 implements BukkitImplAdapter
|
||||
{
|
||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||
private final Field nbtListTagListField;
|
||||
private final Method nbtCreateTagMethod;
|
||||
|
||||
public FaweAdapter_1_10()
|
||||
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_10_R1.Entity entity)
|
||||
{
|
||||
return EntityTypes.b(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static net.minecraft.server.v1_10_R1.Entity createEntityFromId(String id, World world)
|
||||
{
|
||||
return EntityTypes.createEntityByName(id, world);
|
||||
}
|
||||
|
||||
private static void readTagIntoEntity(NBTTagCompound tag, net.minecraft.server.v1_10_R1.Entity entity)
|
||||
{
|
||||
entity.f(tag);
|
||||
}
|
||||
|
||||
private static void readEntityIntoTag(net.minecraft.server.v1_10_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_10_R1.Entity mcEntity = craftEntity.getHandle();
|
||||
|
||||
String id = getEntityId(mcEntity);
|
||||
if (id != null)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
readEntityIntoTag(mcEntity, tag);
|
||||
return new BaseEntity(id, (CompoundTag)toNative(tag));
|
||||
}
|
||||
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_10_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;
|
||||
}
|
||||
|
||||
public Tag toNative(NBTBase foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof NBTTagCompound) {
|
||||
Map<String, Tag> values = new HashMap<String, Tag>();
|
||||
Set<String> foreignKeys = ((NBTTagCompound) foreign).c(); // map.keySet
|
||||
|
||||
for (String str : foreignKeys) {
|
||||
NBTBase base = ((NBTTagCompound) foreign).get(str);
|
||||
values.put(str, toNative(base));
|
||||
}
|
||||
return new CompoundTag(values);
|
||||
} else if (foreign instanceof NBTTagByte) {
|
||||
return new ByteTag(((NBTTagByte) foreign).g()); // getByte
|
||||
} else if (foreign instanceof NBTTagByteArray) {
|
||||
return new ByteArrayTag(((NBTTagByteArray) foreign).c()); // data
|
||||
} else if (foreign instanceof NBTTagDouble) {
|
||||
return new DoubleTag(((NBTTagDouble) foreign).h()); // getDouble
|
||||
} else if (foreign instanceof NBTTagFloat) {
|
||||
return new FloatTag(((NBTTagFloat) foreign).i()); // getFloat
|
||||
} else if (foreign instanceof NBTTagInt) {
|
||||
return new IntTag(((NBTTagInt) foreign).e()); // getInt
|
||||
} else if (foreign instanceof NBTTagIntArray) {
|
||||
return new IntArrayTag(((NBTTagIntArray) foreign).d()); // data
|
||||
} else if (foreign instanceof NBTTagList) {
|
||||
try {
|
||||
return toNativeList((NBTTagList) foreign);
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.WARNING, "Failed to convert NBTTagList", e);
|
||||
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
|
||||
}
|
||||
} else if (foreign instanceof NBTTagLong) {
|
||||
return new LongTag(((NBTTagLong) foreign).d()); // getLong
|
||||
} else if (foreign instanceof NBTTagShort) {
|
||||
return new ShortTag(((NBTTagShort) foreign).f()); // getShort
|
||||
} else if (foreign instanceof NBTTagString) {
|
||||
return new StringTag(((NBTTagString) foreign).c_()); // data
|
||||
} else if (foreign instanceof NBTTagEnd) {
|
||||
return new EndTag();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public ListTag toNativeList(NBTTagList foreign) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
List<Tag> values = new ArrayList<Tag>();
|
||||
int type = foreign.g();
|
||||
|
||||
List foreignList;
|
||||
foreignList = (List) nbtListTagListField.get(foreign);
|
||||
for (int i = 0; i < foreign.size(); i++) {
|
||||
NBTBase element = (NBTBase) foreignList.get(i);
|
||||
values.add(toNative(element)); // List elements shouldn't have names
|
||||
}
|
||||
|
||||
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
|
||||
return new ListTag(cls, values);
|
||||
}
|
||||
|
||||
public NBTBase fromNative(Tag foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof CompoundTag) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
for (Map.Entry<String, Tag> entry : ((CompoundTag) foreign)
|
||||
.getValue().entrySet()) {
|
||||
tag.set(entry.getKey(), fromNative(entry.getValue()));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof ByteTag) {
|
||||
return new NBTTagByte(((ByteTag) foreign).getValue());
|
||||
} else if (foreign instanceof ByteArrayTag) {
|
||||
return new NBTTagByteArray(((ByteArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof DoubleTag) {
|
||||
return new NBTTagDouble(((DoubleTag) foreign).getValue());
|
||||
} else if (foreign instanceof FloatTag) {
|
||||
return new NBTTagFloat(((FloatTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntTag) {
|
||||
return new NBTTagInt(((IntTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntArrayTag) {
|
||||
return new NBTTagIntArray(((IntArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof ListTag) {
|
||||
NBTTagList tag = new NBTTagList();
|
||||
ListTag<Tag> foreignList = (ListTag) foreign;
|
||||
for (Tag t : foreignList.getValue()) {
|
||||
tag.add(fromNative(t));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof LongTag) {
|
||||
return new NBTTagLong(((LongTag) foreign).getValue());
|
||||
} else if (foreign instanceof ShortTag) {
|
||||
return new NBTTagShort(((ShortTag) foreign).getValue());
|
||||
} else if (foreign instanceof StringTag) {
|
||||
return new NBTTagString(((StringTag) foreign).getValue());
|
||||
} else if (foreign instanceof EndTag) {
|
||||
try {
|
||||
return (NBTBase) nbtCreateTagMethod.invoke(null, (byte) 0);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_10;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.server.v1_10_R1.GenLayer;
|
||||
import net.minecraft.server.v1_10_R1.IntCache;
|
||||
|
||||
public class MutableGenLayer extends GenLayer {
|
||||
|
||||
private int biome;
|
||||
|
||||
public MutableGenLayer(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public MutableGenLayer set(int biome) {
|
||||
this.biome = biome;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||
Arrays.fill(biomes, biome);
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -1,513 +0,0 @@
|
||||
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.config.Settings;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
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.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
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.NBTTagInt;
|
||||
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);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_11(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
public void storeBiomes(byte[] biomes) {
|
||||
this.biomes = Arrays.copyOf(biomes, biomes.length);
|
||||
}
|
||||
|
||||
public boolean storeTile(TileEntity tile, BlockPosition pos) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
CompoundTag nativeTag = getParent().getTag(tile);
|
||||
setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean storeEntity(Entity ent) throws InvocationTargetException, IllegalAccessException {
|
||||
if (ent instanceof EntityPlayer) {
|
||||
return false;
|
||||
}
|
||||
int x = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
ent.e(tag); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) getParent().toNative(tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
setEntity(nativeTag);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_11 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
copy.sectionPalettes = new DataPaletteBlock[16];
|
||||
try {
|
||||
for (int i = 0; i < sectionPalettes.length; i++) {
|
||||
DataPaletteBlock current = sectionPalettes[i];
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
// Clone palette
|
||||
DataPalette currentPalette = (DataPalette) BukkitQueue_1_11.fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
current.a(128, null);
|
||||
}
|
||||
DataPaletteBlock paletteBlock = newDataPaletteBlock();
|
||||
currentPalette = (DataPalette) BukkitQueue_1_11.fieldPalette.get(current);
|
||||
if (!(currentPalette instanceof DataPaletteGlobal)) {
|
||||
throw new RuntimeException("Palette must be global!");
|
||||
}
|
||||
BukkitQueue_1_11.fieldPalette.set(paletteBlock, currentPalette);
|
||||
// Clone size
|
||||
BukkitQueue_1_11.fieldSize.set(paletteBlock, BukkitQueue_1_11.fieldSize.get(current));
|
||||
// Clone palette
|
||||
DataBits currentBits = (DataBits) BukkitQueue_1_11.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);
|
||||
}
|
||||
BukkitQueue_1_11.fieldBits.set(paletteBlock, newBits);
|
||||
copy.sectionPalettes[i] = paletteBlock;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return ((com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11) getParent()).getWorld().getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private void removeEntity(Entity entity) {
|
||||
entity.b(false);
|
||||
entity.die();
|
||||
entity.valid = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
try {
|
||||
BukkitChunk_1_11_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_11_Copy(getParent(), getX(), getZ()) : null;
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
Settings settings = getParent().getSettings();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
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();
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0 || settings.EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null) continue;
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = (MathMan.roundInt(entity.locX) & 15);
|
||||
int z = (MathMan.roundInt(entity.locZ) & 15);
|
||||
int y = MathMan.roundInt(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
iter.remove();
|
||||
removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set entities
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
Set<UUID> createdEntities = new HashSet<>();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
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);
|
||||
entityKeys.put(key.a(), 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.fromNative(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
int countAir = this.getAir(j);
|
||||
final char[] array = this.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
ChunkSection section = sections[j];
|
||||
if (copy != null) {
|
||||
copy.storeSection(section, j);
|
||||
}
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
}
|
||||
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 (countAir >= 4096) {
|
||||
sections[j] = null;
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
int by = j << 4;
|
||||
DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
IBlockData existing;
|
||||
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:
|
||||
continue;
|
||||
case 1:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_11.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_11.air);
|
||||
continue;
|
||||
default:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_11.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// 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<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
copy.storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
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);
|
||||
nmsWorld.s(bp);
|
||||
tile.z();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
copy.storeBiomes(nmsChunk.getBiomeIndex());
|
||||
}
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
// Change task
|
||||
if (copy != null) {
|
||||
getParent().getChangeTask().run(copy, this);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import net.minecraft.server.v1_11_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_11_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_11_R1.NibbleArray;
|
||||
|
||||
public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
|
||||
public final byte[][] idsBytes;
|
||||
public final byte[][] datasBytes;
|
||||
|
||||
public BukkitChunk_1_11_Copy(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
idsBytes = new byte[16][];
|
||||
datasBytes = new byte[16][];
|
||||
}
|
||||
|
||||
public void set(int i, byte[] ids, byte[] data) {
|
||||
this.idsBytes[i] = ids;
|
||||
this.datasBytes[i] = data;
|
||||
}
|
||||
|
||||
public boolean storeSection(ChunkSection section, int layer) throws IllegalAccessException {
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
set(layer, ids, data.asBytes());
|
||||
short solid = (short) getParent().fieldNonEmptyBlockCount.getInt(section);
|
||||
count[layer] = solid;
|
||||
air[layer] = (short) (4096 - solid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getCombinedIdArrays() {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
getIdArray(i);
|
||||
}
|
||||
return super.getCombinedIdArrays();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getIdArray(int i) {
|
||||
char[] combined = this.ids[i];
|
||||
if (combined != null) {
|
||||
return combined;
|
||||
}
|
||||
byte[] idsBytesArray = idsBytes[i];
|
||||
if (idsBytesArray == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] datasBytesArray = datasBytes[i];
|
||||
|
||||
idsBytes[i] = null;
|
||||
datasBytes[i] = null;
|
||||
|
||||
this.ids[i] = combined = new char[4096];
|
||||
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + (datasBytesArray[j] & 15));
|
||||
}
|
||||
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
||||
combined[k] = (char) (((idsBytesArray[k] & 0xFF) << 4) + ((datasBytesArray[j] >> 4) & 15));
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
throw new UnsupportedOperationException("This chunk is an immutable copy");
|
||||
}
|
||||
}
|
@ -1,852 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||
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.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
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 com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import net.minecraft.server.v1_11_R1.BiomeBase;
|
||||
import net.minecraft.server.v1_11_R1.BiomeCache;
|
||||
import net.minecraft.server.v1_11_R1.Block;
|
||||
import net.minecraft.server.v1_11_R1.BlockPosition;
|
||||
import net.minecraft.server.v1_11_R1.ChunkProviderGenerate;
|
||||
import net.minecraft.server.v1_11_R1.ChunkProviderServer;
|
||||
import net.minecraft.server.v1_11_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_11_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_11_R1.Entity;
|
||||
import net.minecraft.server.v1_11_R1.EntityPlayer;
|
||||
import net.minecraft.server.v1_11_R1.EntityTracker;
|
||||
import net.minecraft.server.v1_11_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_11_R1.EnumDifficulty;
|
||||
import net.minecraft.server.v1_11_R1.EnumGamemode;
|
||||
import net.minecraft.server.v1_11_R1.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_11_R1.IBlockData;
|
||||
import net.minecraft.server.v1_11_R1.IDataManager;
|
||||
import net.minecraft.server.v1_11_R1.MinecraftServer;
|
||||
import net.minecraft.server.v1_11_R1.NBTTagCompound;
|
||||
import net.minecraft.server.v1_11_R1.NibbleArray;
|
||||
import net.minecraft.server.v1_11_R1.PacketDataSerializer;
|
||||
import net.minecraft.server.v1_11_R1.PacketPlayOutMultiBlockChange;
|
||||
import net.minecraft.server.v1_11_R1.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_11_R1.ServerNBTManager;
|
||||
import net.minecraft.server.v1_11_R1.TileEntity;
|
||||
import net.minecraft.server.v1_11_R1.WorldChunkManager;
|
||||
import net.minecraft.server.v1_11_R1.WorldData;
|
||||
import net.minecraft.server.v1_11_R1.WorldManager;
|
||||
import net.minecraft.server.v1_11_R1.WorldServer;
|
||||
import net.minecraft.server.v1_11_R1.WorldSettings;
|
||||
import net.minecraft.server.v1_11_R1.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
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.craftbukkit.v1_11_R1.entity.CraftPlayer;
|
||||
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<net.minecraft.server.v1_11_R1.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Field fieldPalette;
|
||||
protected static Field fieldSize;
|
||||
protected static Method getEntitySlices;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
protected static Field fieldBiomes;
|
||||
protected static Field fieldChunkGenerator;
|
||||
protected static Field fieldSeed;
|
||||
protected static Field fieldBiomeCache;
|
||||
protected static Field fieldBiomes2;
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static MutableGenLayer genLayer;
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE + 1];
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = ChunkProviderGenerate.class.getDeclaredField("D");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldChunkGenerator = ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||
fieldChunkGenerator.setAccessible(true);
|
||||
fieldSeed = WorldData.class.getDeclaredField("e");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = WorldChunkManager.class.getDeclaredField("e");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer2 = WorldChunkManager.class.getDeclaredField("c") ;
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
|
||||
fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
|
||||
fieldPalette.setAccessible(true);
|
||||
fieldSize = DataPaletteBlock.class.getDeclaredField("e");
|
||||
fieldSize.setAccessible(true);
|
||||
|
||||
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);
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_11.FaweAdapter_1_11());
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
for (int i = 0; i < IBD_CACHE.length; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_11(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_11(final String world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getSections(net.minecraft.server.v1_11_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_11_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_11_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getChunkAt(x, z, null, true);
|
||||
} else {
|
||||
return provider.getChunkAt(x, z, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_11_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(net.minecraft.server.v1_11_R1.Chunk chunk) {
|
||||
chunk.f(true); // Set Modified
|
||||
chunk.mustSave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
try {
|
||||
if (seed == null) {
|
||||
seed = world.getSeed();
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
ChunkProviderGenerate generator = new ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
Biome bukkitBiome = getAdapter().getBiome(biome.getId());
|
||||
BiomeBase base = BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new BiomeBase[]{base});
|
||||
boolean cold = base.getTemperature() <= 1;
|
||||
net.minecraft.server.v1_11_R1.ChunkGenerator existingGenerator = nmsWorld.getChunkProviderServer().chunkGenerator;
|
||||
long existingSeed = world.getSeed();
|
||||
{
|
||||
if (genLayer == null) genLayer = new MutableGenLayer(seed);
|
||||
genLayer.set(biome.getId());
|
||||
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||
}
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return super.regenerateChunk(world, x, z, biome, seed);
|
||||
}
|
||||
|
||||
private net.minecraft.server.v1_11_R1.PlayerChunk getPlayerChunk(net.minecraft.server.v1_11_R1.WorldServer w, int cx, int cz) {
|
||||
net.minecraft.server.v1_11_R1.PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
net.minecraft.server.v1_11_R1.PlayerChunk playerChunk = chunkMap.getChunk(cx, cz);
|
||||
if (playerChunk == null) {
|
||||
return null;
|
||||
}
|
||||
if (playerChunk.c.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return playerChunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
long last = start;
|
||||
synchronized (net.minecraft.server.v1_11_R1.RegionFileCache.class) {
|
||||
World world = getWorld();
|
||||
if (world.getKeepSpawnInMemory()) world.setKeepSpawnInMemory(false);
|
||||
net.minecraft.server.v1_11_R1.ChunkProviderServer provider = nmsWorld.getChunkProviderServer();
|
||||
|
||||
boolean mustSave = false;
|
||||
boolean[][] chunksUnloaded = null;
|
||||
{ // Unload chunks
|
||||
Iterator<net.minecraft.server.v1_11_R1.Chunk> iter = provider.a().iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = iter.next();
|
||||
if (chunk.locX >> 5 == mcaX && chunk.locZ >> 5 == mcaZ) {
|
||||
boolean isIn = allowed.isInChunk(chunk.locX, chunk.locZ);
|
||||
if (isIn) {
|
||||
if (!load) {
|
||||
if (saveChunks && chunk.a(false)) {
|
||||
mustSave = true;
|
||||
provider.saveChunk(chunk);
|
||||
provider.saveChunkNOP(chunk);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
boolean save = saveChunks && chunk.a(false);
|
||||
mustSave |= save;
|
||||
provider.unloadChunk(chunk, save);
|
||||
if (chunksUnloaded == null) {
|
||||
chunksUnloaded = new boolean[32][];
|
||||
}
|
||||
int relX = chunk.locX & 31;
|
||||
boolean[] arr = chunksUnloaded[relX];
|
||||
if (arr == null) {
|
||||
arr = chunksUnloaded[relX] = new boolean[32];
|
||||
}
|
||||
arr[chunk.locZ & 31] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustSave) provider.c(); // TODO only the necessary chunks
|
||||
|
||||
File unloadedRegion = null;
|
||||
if (load && !net.minecraft.server.v1_11_R1.RegionFileCache.a.isEmpty()) {
|
||||
Map<File, net.minecraft.server.v1_11_R1.RegionFile> map = net.minecraft.server.v1_11_R1.RegionFileCache.a;
|
||||
Iterator<Map.Entry<File, net.minecraft.server.v1_11_R1.RegionFile>> iter = map.entrySet().iterator();
|
||||
String requiredPath = world.getName() + File.separator + "region";
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<File, net.minecraft.server.v1_11_R1.RegionFile> entry = iter.next();
|
||||
File file = entry.getKey();
|
||||
int[] regPos = MainUtil.regionNameToCoords(file.getPath());
|
||||
if (regPos[0] == mcaX && regPos[1] == mcaZ && file.getPath().contains(requiredPath)) {
|
||||
if (file.exists()) {
|
||||
unloadedRegion = file;
|
||||
net.minecraft.server.v1_11_R1.RegionFile regionFile = entry.getValue();
|
||||
iter.remove();
|
||||
try {
|
||||
regionFile.c();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (whileLocked != null) whileLocked.run();
|
||||
if (!load) return;
|
||||
|
||||
{ // Load the region again
|
||||
if (unloadedRegion != null && chunksUnloaded != null && unloadedRegion.exists()) {
|
||||
final boolean[][] finalChunksUnloaded = chunksUnloaded;
|
||||
TaskManager.IMP.async(() -> {
|
||||
int bx = mcaX << 5;
|
||||
int bz = mcaZ << 5;
|
||||
for (int x = 0; x < finalChunksUnloaded.length; x++) {
|
||||
boolean[] arr = finalChunksUnloaded[x];
|
||||
if (arr != null) {
|
||||
for (int z = 0; z < arr.length; z++) {
|
||||
if (arr[z]) {
|
||||
int cx = bx + x;
|
||||
int cz = bz + z;
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value1) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = provider.getChunkAt(cx, cz, null, false);
|
||||
if (chunk != null) {
|
||||
net.minecraft.server.v1_11_R1.PlayerChunk pc = getPlayerChunk(nmsWorld, cx, cz);
|
||||
if (pc != null) {
|
||||
sendChunk(pc, chunk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
int newHeight = heightMap[i] & 0xFF;
|
||||
int currentHeight = otherMap[i];
|
||||
if (newHeight > currentHeight) {
|
||||
otherMap[i] = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, long time) {
|
||||
return super.next(amount, 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);
|
||||
}
|
||||
|
||||
@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 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 getBiome(net.minecraft.server.v1_11_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@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 sendChunk(int x, int z, int bitMask) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(getPlayerChunk((net.minecraft.server.v1_11_R1.WorldServer) chunk.getWorld(), chunk.locX, chunk.locZ), chunk, bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((CraftWorld) getWorld()).getHandle().getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
boolean[] watchingArr = new boolean[players.length];
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayer player = ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle();
|
||||
if (playerManager.a(player, chunk.getX(), chunk.getZ())) {
|
||||
watchingArr[i] = true;
|
||||
watching = true;
|
||||
}
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
PacketPlayOutMultiBlockChange packet = new PacketPlayOutMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketDataSerializer buffer = new PacketDataSerializer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.d(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
if (combined < 16) combined = 0;
|
||||
buffer.writeShort(index);
|
||||
buffer.d(combined);
|
||||
}
|
||||
});
|
||||
packet.a(buffer);
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
if (watchingArr[i]) ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(fc.getX(), fc.getZ(), fc.getBitMask());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendChunk(net.minecraft.server.v1_11_R1.PlayerChunk playerChunk, net.minecraft.server.v1_11_R1.Chunk nmsChunk, int mask) {
|
||||
net.minecraft.server.v1_11_R1.WorldServer w = (net.minecraft.server.v1_11_R1.WorldServer) nmsChunk.getWorld();
|
||||
if (playerChunk == null) {
|
||||
return false;
|
||||
}
|
||||
if (mask == 0) {
|
||||
net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk packet = new net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk(nmsChunk, 65535);
|
||||
for (net.minecraft.server.v1_11_R1.EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Send chunks
|
||||
boolean empty = false;
|
||||
net.minecraft.server.v1_11_R1.ChunkSection[] sections = nmsChunk.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == null) {
|
||||
sections[i] = emptySection;
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk packet = new net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||
for (net.minecraft.server.v1_11_R1.EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
mask = 255;
|
||||
}
|
||||
net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk packet = new net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk(nmsChunk, mask);
|
||||
for (net.minecraft.server.v1_11_R1.EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
if (empty) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == emptySection) {
|
||||
sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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 removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
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;
|
||||
// Copy blocks
|
||||
BukkitChunk_1_11_Copy previous = new BukkitChunk_1_11_Copy(this, fs.getX(), fs.getZ());
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
previous.set(layer, ids, data.asBytes());
|
||||
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
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) toNative(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(net.minecraft.server.v1_11_R1.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.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) toNative(tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
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.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.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
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 {
|
||||
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(Entity entity)
|
||||
{
|
||||
return EntityTypes.b(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Entity createEntityFromId(String id, World world)
|
||||
{
|
||||
return EntityTypes.a(new MinecraftKey(id), world);
|
||||
}
|
||||
|
||||
private static void readTagIntoEntity(NBTTagCompound tag, Entity entity)
|
||||
{
|
||||
entity.f(tag);
|
||||
}
|
||||
|
||||
private static void readEntityIntoTag(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;
|
||||
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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Tag toNative(NBTBase foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof NBTTagCompound) {
|
||||
Map<String, Tag> values = new HashMap<String, Tag>();
|
||||
Set<String> foreignKeys = ((NBTTagCompound) foreign).c(); // map.keySet
|
||||
|
||||
for (String str : foreignKeys) {
|
||||
NBTBase base = ((NBTTagCompound) foreign).get(str);
|
||||
values.put(str, toNative(base));
|
||||
}
|
||||
return new CompoundTag(values);
|
||||
} else if (foreign instanceof NBTTagByte) {
|
||||
return new ByteTag(((NBTTagByte) foreign).g()); // getByte
|
||||
} else if (foreign instanceof NBTTagByteArray) {
|
||||
return new ByteArrayTag(((NBTTagByteArray) foreign).c()); // data
|
||||
} else if (foreign instanceof NBTTagDouble) {
|
||||
return new DoubleTag(((NBTTagDouble) foreign).asDouble()); // getDouble
|
||||
} else if (foreign instanceof NBTTagFloat) {
|
||||
return new FloatTag(((NBTTagFloat) foreign).i()); // getFloat
|
||||
} else if (foreign instanceof NBTTagInt) {
|
||||
return new IntTag(((NBTTagInt) foreign).e()); // getInt
|
||||
} else if (foreign instanceof NBTTagIntArray) {
|
||||
return new IntArrayTag(((NBTTagIntArray) foreign).d()); // data
|
||||
} else if (foreign instanceof NBTTagList) {
|
||||
try {
|
||||
return toNativeList((NBTTagList) foreign);
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.WARNING, "Failed to convert NBTTagList", e);
|
||||
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
|
||||
}
|
||||
} else if (foreign instanceof NBTTagLong) {
|
||||
return new LongTag(((NBTTagLong) foreign).d()); // getLong
|
||||
} else if (foreign instanceof NBTTagShort) {
|
||||
return new ShortTag(((NBTTagShort) foreign).f()); // getShort
|
||||
} else if (foreign instanceof NBTTagString) {
|
||||
return new StringTag(((NBTTagString) foreign).c_()); // data
|
||||
} else if (foreign instanceof NBTTagEnd) {
|
||||
return new EndTag();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public ListTag toNativeList(NBTTagList foreign) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
List<Tag> values = new ArrayList<Tag>();
|
||||
int type = foreign.g();
|
||||
|
||||
List foreignList;
|
||||
foreignList = (List) nbtListTagListField.get(foreign);
|
||||
for (int i = 0; i < foreign.size(); i++) {
|
||||
NBTBase element = (NBTBase) foreignList.get(i);
|
||||
values.add(toNative(element)); // List elements shouldn't have names
|
||||
}
|
||||
|
||||
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
|
||||
return new ListTag(cls, values);
|
||||
}
|
||||
|
||||
public NBTBase fromNative(Tag foreign) {
|
||||
if (foreign == null) {
|
||||
return null;
|
||||
}
|
||||
if (foreign instanceof CompoundTag) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
for (Map.Entry<String, Tag> entry : ((CompoundTag) foreign)
|
||||
.getValue().entrySet()) {
|
||||
tag.set(entry.getKey(), fromNative(entry.getValue()));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof ByteTag) {
|
||||
return new NBTTagByte(((ByteTag) foreign).getValue());
|
||||
} else if (foreign instanceof ByteArrayTag) {
|
||||
return new NBTTagByteArray(((ByteArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof DoubleTag) {
|
||||
return new NBTTagDouble(((DoubleTag) foreign).getValue());
|
||||
} else if (foreign instanceof FloatTag) {
|
||||
return new NBTTagFloat(((FloatTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntTag) {
|
||||
return new NBTTagInt(((IntTag) foreign).getValue());
|
||||
} else if (foreign instanceof IntArrayTag) {
|
||||
return new NBTTagIntArray(((IntArrayTag) foreign).getValue());
|
||||
} else if (foreign instanceof ListTag) {
|
||||
NBTTagList tag = new NBTTagList();
|
||||
ListTag<Tag> foreignList = (ListTag) foreign;
|
||||
for (Tag t : foreignList.getValue()) {
|
||||
tag.add(fromNative(t));
|
||||
}
|
||||
return tag;
|
||||
} else if (foreign instanceof LongTag) {
|
||||
return new NBTTagLong(((LongTag) foreign).getValue());
|
||||
} else if (foreign instanceof ShortTag) {
|
||||
return new NBTTagShort(((ShortTag) foreign).getValue());
|
||||
} else if (foreign instanceof StringTag) {
|
||||
return new NBTTagString(((StringTag) foreign).getValue());
|
||||
} else if (foreign instanceof EndTag) {
|
||||
try {
|
||||
return (NBTBase) nbtCreateTagMethod.invoke(null, (byte) 0);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.server.v1_11_R1.GenLayer;
|
||||
import net.minecraft.server.v1_11_R1.IntCache;
|
||||
|
||||
public class MutableGenLayer extends GenLayer {
|
||||
|
||||
private int biome;
|
||||
|
||||
public MutableGenLayer(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public MutableGenLayer set(int biome) {
|
||||
this.biome = biome;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||
Arrays.fill(biomes, biome);
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -1,452 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_7;
|
||||
|
||||
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.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_7_R4.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_7_R4.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return Bukkit.getWorld(getParent().getWorldName()).getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
public final byte[][] byteIds;
|
||||
public final NibbleArray[] datas;
|
||||
|
||||
public BukkitChunk_1_7(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
this.byteIds = new byte[16][];
|
||||
this.datas = new NibbleArray[16];
|
||||
}
|
||||
|
||||
public BukkitChunk_1_7(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap, byte[][] byteIds, NibbleArray[] datas) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
this.byteIds = byteIds;
|
||||
this.datas = datas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_7 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), ids, count, air, heightMap, byteIds, datas);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone(), (byte[][]) MainUtil.copyNd(byteIds), datas.clone());
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
public byte[] getByteIdArray(int i) {
|
||||
return this.byteIds[i];
|
||||
}
|
||||
|
||||
public NibbleArray getDataArray(int i) {
|
||||
return datas[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id) {
|
||||
this.setBlock(x, y, z, id, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
byte[] vs = this.byteIds[i];
|
||||
char[] vs2 = this.ids[i];
|
||||
if (vs2 == null) {
|
||||
vs2 = this.ids[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else {
|
||||
switch (vs2[j]) {
|
||||
case 0:
|
||||
this.count[i]++;
|
||||
break;
|
||||
case 1:
|
||||
this.air[i]--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vs == null) {
|
||||
vs = this.byteIds[i] = new byte[4096];
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = 0;
|
||||
vs2[j] = (char) 1;
|
||||
return;
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 51:
|
||||
case 74:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 138:
|
||||
case 169:
|
||||
case 213:
|
||||
case 130:
|
||||
case 76:
|
||||
case 62:
|
||||
case 50:
|
||||
case 10:
|
||||
default:
|
||||
vs2[j] = (char) ((id << 4) + data);
|
||||
vs[j] = (byte) id;
|
||||
if (data != 0) {
|
||||
NibbleArray dataArray = datas[i];
|
||||
if (dataArray == null) {
|
||||
datas[i] = dataArray = new NibbleArray(new byte[2048], 4);
|
||||
}
|
||||
dataArray.a(x, y & 15, z, data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
getChunk().load(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
CraftChunk chunk = (CraftChunk) this.getChunk();
|
||||
net.minecraft.server.v1_7_R4.Chunk nmsChunk = chunk.getHandle();
|
||||
nmsChunk.e(); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_7_R4.World nmsWorld = nmsChunk.world;
|
||||
try {
|
||||
final boolean flag = getParent().getWorld().getEnvironment() == World.Environment.NORMAL;
|
||||
// Sections
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
Map<ChunkPosition, TileEntity> tiles = nmsChunk.tileEntities;
|
||||
Collection<Entity>[] entities = nmsChunk.entitySlices;
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null || entities[i] == null || entities[i].isEmpty()) continue;
|
||||
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (Entity entity : entsArr) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = (MathMan.roundInt(entity.locX) & 15);
|
||||
int z = (MathMan.roundInt(entity.locZ) & 15);
|
||||
int y = MathMan.roundInt(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
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<UUID> createdEntities = new HashSet<>();
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (CompoundTag nativeTag : entitiesToSpawn) {
|
||||
Map<String, Tag> entityTagMap = 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();
|
||||
Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
|
||||
if (entity != null) {
|
||||
if (nativeTag != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue17.fromNative(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run change task if applicable
|
||||
if (getParent().getChangeTask() != null) {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
byte[] newIdArray = this.getByteIdArray(j);
|
||||
if (newIdArray == null) {
|
||||
continue;
|
||||
}
|
||||
int countAir = this.getAir(j);
|
||||
NibbleArray newDataArray = this.getDataArray(j);
|
||||
ChunkSection section = sections[j];
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
}
|
||||
sections[j] = section = new ChunkSection(j << 4, flag);
|
||||
BukkitQueue17.fieldCompactId.set(section, 0);
|
||||
BukkitQueue17.fieldIds.set(section, newIdArray);
|
||||
getParent().setCount(0, count - this.getAir(j), section);
|
||||
BukkitQueue17.fieldCompactData.set(section, (byte) 0);
|
||||
BukkitQueue17.fieldData.set(section, newDataArray);
|
||||
continue;
|
||||
}
|
||||
if (count >= 4096) {
|
||||
if (countAir >= 4096) {
|
||||
sections[j] = null;
|
||||
continue;
|
||||
}
|
||||
BukkitQueue17.fieldCompactId.set(section, 0);
|
||||
BukkitQueue17.fieldIds.set(section, newIdArray);
|
||||
getParent().setCount(0, count - this.getAir(j), section);
|
||||
BukkitQueue17.fieldCompactData.set(section, (byte) 0);
|
||||
BukkitQueue17.fieldData.set(section, newDataArray);
|
||||
continue;
|
||||
}
|
||||
char[] charArray = this.getIdArray(j);
|
||||
byte[] currentIdArray = (byte[]) BukkitQueue17.fieldIds.get(section);
|
||||
NibbleArray currentDataArray = (NibbleArray) BukkitQueue17.fieldData.get(section);
|
||||
boolean data = currentDataArray != null && newDataArray != null;
|
||||
if (currentDataArray == null) {
|
||||
int compactData = ((byte) BukkitQueue17.fieldCompactData.get(section)) & 0xFF;
|
||||
if (compactData != 0 && newDataArray == null) {
|
||||
newDataArray = new NibbleArray(new byte[2048], 4);
|
||||
byte full = (byte) ((compactData << 4) + compactData);
|
||||
Arrays.fill(newDataArray.a, full);
|
||||
for (int i = 0; i < newDataArray.a.length; i++) {
|
||||
int i2 = i << 1;
|
||||
int i3 = i2 + 1;
|
||||
byte val = newDataArray.a[i];
|
||||
if (FaweCache.hasData(charArray[i3] >> 4)) {
|
||||
newDataArray.a[i] = (byte) (val & 15);
|
||||
}
|
||||
if (FaweCache.hasData(charArray[i2] >> 4)) {
|
||||
newDataArray.a[i] = (byte) (val & 240);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (newDataArray != null) {
|
||||
if (compactData != 0) {
|
||||
byte full = (byte) ((compactData << 4) + compactData);
|
||||
for (int i = 0; i < newDataArray.a.length; i++) {
|
||||
int i2 = i << 1;
|
||||
int i3 = i2 + 1;
|
||||
byte val = newDataArray.a[i];
|
||||
if (charArray[i3] != 0) {
|
||||
if (charArray[i2] != 0) continue;
|
||||
newDataArray.a[i] = (byte) (val & 240 | compactData);
|
||||
continue;
|
||||
}
|
||||
if (charArray[i2] != 0) {
|
||||
if (charArray[i3] != 0) continue;
|
||||
newDataArray.a[i] = (byte) (val & 15 | (compactData) << 4);
|
||||
continue;
|
||||
}
|
||||
newDataArray.a[i] = full;
|
||||
}
|
||||
}
|
||||
BukkitQueue17.fieldCompactData.set(section, (byte) 0);
|
||||
BukkitQueue17.fieldData.set(section, newDataArray);
|
||||
}
|
||||
} else if (newDataArray == null) {
|
||||
for (int i = 0; i < currentDataArray.a.length; i++) {
|
||||
int i2 = i << 1;
|
||||
int i3 = i2 + 1;
|
||||
byte val = currentDataArray.a[i];
|
||||
if (newIdArray[i3] == 0) {
|
||||
if (newIdArray[i2] != 0) currentDataArray.a[i] = (byte) (val & 240);
|
||||
continue;
|
||||
}
|
||||
if (newIdArray[i2] == 0) {
|
||||
if (newIdArray[i3] != 0) currentDataArray.a[i] = (byte) (val & 15);
|
||||
continue;
|
||||
}
|
||||
currentDataArray.a[i] = 0;
|
||||
}
|
||||
}
|
||||
int solid = 0;
|
||||
if (currentIdArray == null) {
|
||||
byte id = (byte) ((int) BukkitQueue17.fieldCompactId.get(section));
|
||||
if (id != 0) {
|
||||
solid = 4096;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (charArray[i] == 0) newIdArray[i] = id;
|
||||
else if (newIdArray[i] == 0) solid--;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4096; i++) if (newIdArray[i] != 0) solid++;
|
||||
}
|
||||
BukkitQueue17.fieldCompactId.set(section, 0);
|
||||
BukkitQueue17.fieldIds.set(section, newIdArray);
|
||||
} else {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
if (charArray[i] != 0) currentIdArray[i] = newIdArray[i];
|
||||
}
|
||||
for (int i = 0; i < 4096; i++) if (currentIdArray[i] != 0) solid++;
|
||||
}
|
||||
if (data) {
|
||||
for (int k = 0; k < 4096; k++) {
|
||||
int value = charArray[k];
|
||||
if (value != 0) {
|
||||
int dataByte = FaweCache.getData(value);
|
||||
int kShift = k >> 1;
|
||||
if ((k & 1) == 0) {
|
||||
currentDataArray.a[kShift] = (byte) (currentDataArray.a[kShift] & 240 | dataByte);
|
||||
} else {
|
||||
currentDataArray.a[kShift] = (byte) (currentDataArray.a[kShift] & 15 | (dataByte) << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, solid, section);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<ChunkPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<ChunkPosition, TileEntity> toRemove = null;
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<ChunkPosition, TileEntity> tile = iterator.next();
|
||||
ChunkPosition pos = tile.getKey();
|
||||
int lx = pos.x & 15;
|
||||
int ly = pos.y;
|
||||
int lz = pos.z & 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<ChunkPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
ChunkPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
tiles.remove(bp);
|
||||
nmsWorld.p(bp.x, bp.y, bp.z);
|
||||
tile.s();
|
||||
tile.u();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.m();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(x, y, z);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue17.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,711 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_7;
|
||||
|
||||
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.RegionWrapper;
|
||||
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 com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_7_R4.Block;
|
||||
import net.minecraft.server.v1_7_R4.Chunk;
|
||||
import net.minecraft.server.v1_7_R4.ChunkCoordIntPair;
|
||||
import net.minecraft.server.v1_7_R4.ChunkPosition;
|
||||
import net.minecraft.server.v1_7_R4.ChunkSection;
|
||||
import net.minecraft.server.v1_7_R4.Entity;
|
||||
import net.minecraft.server.v1_7_R4.EntityPlayer;
|
||||
import net.minecraft.server.v1_7_R4.EntityTracker;
|
||||
import net.minecraft.server.v1_7_R4.EntityTypes;
|
||||
import net.minecraft.server.v1_7_R4.EnumDifficulty;
|
||||
import net.minecraft.server.v1_7_R4.EnumGamemode;
|
||||
import net.minecraft.server.v1_7_R4.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_7_R4.LongHashMap;
|
||||
import net.minecraft.server.v1_7_R4.MinecraftServer;
|
||||
import net.minecraft.server.v1_7_R4.NBTTagCompound;
|
||||
import net.minecraft.server.v1_7_R4.NibbleArray;
|
||||
import net.minecraft.server.v1_7_R4.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_7_R4.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_7_R4.ServerNBTManager;
|
||||
import net.minecraft.server.v1_7_R4.TileEntity;
|
||||
import net.minecraft.server.v1_7_R4.WorldManager;
|
||||
import net.minecraft.server.v1_7_R4.WorldServer;
|
||||
import net.minecraft.server.v1_7_R4.WorldSettings;
|
||||
import net.minecraft.server.v1_7_R4.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_7_R4.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_7_R4.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_7_R4.CraftWorld;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static Field fieldData;
|
||||
protected static Field fieldIds;
|
||||
protected static Field fieldCompactId;
|
||||
protected static Field fieldCompactData;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldBiomes;
|
||||
protected static Field fieldSeed;
|
||||
protected static Field fieldBiomeCache;
|
||||
protected static Field fieldBiomes2;
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static com.boydti.fawe.bukkit.v1_7.MutableGenLayer genLayer;
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
fieldData = ChunkSection.class.getDeclaredField("blockData");
|
||||
fieldData.setAccessible(true);
|
||||
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldIds.setAccessible(true);
|
||||
fieldCompactId = ChunkSection.class.getDeclaredField("compactId");
|
||||
fieldCompactId.setAccessible(true);
|
||||
fieldCompactData = ChunkSection.class.getDeclaredField("compactData");
|
||||
fieldCompactData.setAccessible(true);
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = net.minecraft.server.v1_7_R4.ChunkProviderGenerate.class.getDeclaredField("z");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldSeed = net.minecraft.server.v1_7_R4.WorldData.class.getDeclaredField("seed");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = net.minecraft.server.v1_7_R4.WorldChunkManager.class.getDeclaredField("e");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = net.minecraft.server.v1_7_R4.WorldChunkManager.class.getDeclaredField("f");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = net.minecraft.server.v1_7_R4.WorldChunkManager.class.getDeclaredField("c");
|
||||
fieldGenLayer2 = net.minecraft.server.v1_7_R4.WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue17(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue17(final String world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(Chunk nmsChunk) {
|
||||
nmsChunk.e(); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
long last = start;
|
||||
synchronized (net.minecraft.server.v1_7_R4.RegionFileCache.class) {
|
||||
World world = getWorld();
|
||||
if (world.getKeepSpawnInMemory()) world.setKeepSpawnInMemory(false);
|
||||
net.minecraft.server.v1_7_R4.ChunkProviderServer provider = nmsWorld.chunkProviderServer;
|
||||
|
||||
boolean mustSave = false;
|
||||
boolean[][] chunksUnloaded = null;
|
||||
{ // Unload chunks
|
||||
Iterator<net.minecraft.server.v1_7_R4.Chunk> iter = provider.a().iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = iter.next();
|
||||
if (chunk.locX >> 5 == mcaX && chunk.locZ >> 5 == mcaZ) {
|
||||
boolean isIn = allowed.isInChunk(chunk.locX, chunk.locZ);
|
||||
if (isIn) {
|
||||
if (!load) {
|
||||
if (saveChunks && chunk.a(false)) {
|
||||
mustSave = true;
|
||||
provider.saveChunk(chunk);
|
||||
provider.saveChunkNOP(chunk);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
boolean save = saveChunks && chunk.a(false);
|
||||
mustSave |= save;
|
||||
chunk.bukkitChunk.unload(save, false);
|
||||
if (chunksUnloaded == null) {
|
||||
chunksUnloaded = new boolean[32][];
|
||||
}
|
||||
int relX = chunk.locX & 31;
|
||||
boolean[] arr = chunksUnloaded[relX];
|
||||
if (arr == null) {
|
||||
arr = chunksUnloaded[relX] = new boolean[32];
|
||||
}
|
||||
arr[chunk.locZ & 31] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustSave) provider.c(); // TODO only the necessary chunks
|
||||
|
||||
File unloadedRegion = null;
|
||||
if (load && !net.minecraft.server.v1_7_R4.RegionFileCache.a.isEmpty()) {
|
||||
Map<File, net.minecraft.server.v1_7_R4.RegionFile> map = net.minecraft.server.v1_7_R4.RegionFileCache.a;
|
||||
Iterator<Map.Entry<File, net.minecraft.server.v1_7_R4.RegionFile>> iter = map.entrySet().iterator();
|
||||
String requiredPath = world.getName() + File.separator + "region";
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<File, net.minecraft.server.v1_7_R4.RegionFile> entry = iter.next();
|
||||
File file = entry.getKey();
|
||||
int[] regPos = MainUtil.regionNameToCoords(file.getPath());
|
||||
if (regPos[0] == mcaX && regPos[1] == mcaZ && file.getPath().contains(requiredPath)) {
|
||||
if (file.exists()) {
|
||||
unloadedRegion = file;
|
||||
net.minecraft.server.v1_7_R4.RegionFile regionFile = entry.getValue();
|
||||
iter.remove();
|
||||
try {
|
||||
regionFile.c();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (whileLocked != null) whileLocked.run();
|
||||
if (!load) return;
|
||||
|
||||
{ // Load the region again
|
||||
if (unloadedRegion != null && chunksUnloaded != null && unloadedRegion.exists()) {
|
||||
final boolean[][] finalChunksUnloaded = chunksUnloaded;
|
||||
TaskManager.IMP.async(() -> {
|
||||
int bx = mcaX << 5;
|
||||
int bz = mcaZ << 5;
|
||||
for (int x = 0; x < finalChunksUnloaded.length; x++) {
|
||||
boolean[] arr = finalChunksUnloaded[x];
|
||||
if (arr != null) {
|
||||
for (int z = 0; z < arr.length; z++) {
|
||||
if (arr[z]) {
|
||||
int cx = bx + x;
|
||||
int cz = bz + z;
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value1) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = provider.getChunkAt(cx, cz, null);
|
||||
if (chunk != null) {
|
||||
if (nmsWorld.getPlayerChunkMap().isChunkInUse(cx, cz)) {
|
||||
sendChunk(chunk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
try {
|
||||
if (seed == null) {
|
||||
seed = world.getSeed();
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
net.minecraft.server.v1_7_R4.ChunkProviderGenerate generator = new net.minecraft.server.v1_7_R4.ChunkProviderGenerate(nmsWorld, seed, false);
|
||||
Biome bukkitBiome = getAdapter().getBiome(biome.getId());
|
||||
net.minecraft.server.v1_7_R4.BiomeBase base = net.minecraft.server.v1_7_R4.BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new net.minecraft.server.v1_7_R4.BiomeBase[]{base});
|
||||
net.minecraft.server.v1_7_R4.IChunkProvider existingGenerator = nmsWorld.chunkProviderServer.chunkProvider;
|
||||
long existingSeed = world.getSeed();
|
||||
{
|
||||
if (genLayer == null) genLayer = new com.boydti.fawe.bukkit.v1_7.MutableGenLayer(seed);
|
||||
genLayer.set(biome.getId());
|
||||
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new net.minecraft.server.v1_7_R4.BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = generator;
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = existingGenerator;
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||
}
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return super.regenerateChunk(world, x, z, biome, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
int newHeight = heightMap[i] & 0xFF;
|
||||
int currentHeight = otherMap[i];
|
||||
if (newHeight > currentHeight) {
|
||||
otherMap[i] = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld(String world) {
|
||||
return Bukkit.getWorld(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_7_R4.Chunk chunk, int x, int z) {
|
||||
return chunk.m()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection[] getSections(net.minecraft.server.v1_7_R4.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk;
|
||||
net.minecraft.server.v1_7_R4.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer;
|
||||
if (generate) {
|
||||
return provider.originalGetChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection getCachedSection(net.minecraft.server.v1_7_R4.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@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().a;
|
||||
Arrays.fill(bytes, Byte.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection ls, int x, int y, int z) {
|
||||
byte[] ids = ls.getIdArray();
|
||||
NibbleArray datasNibble = ls.getDataArray();
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
int combined = ((ids[i] & 0xFF) << 4) + (datasNibble == null ? 0 : datasNibble.a(x & 15, y & 15, z & 15));
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<ChunkPosition, TileEntity> tiles = (Map<ChunkPosition, TileEntity>) tilesGeneric;
|
||||
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||
CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ());
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
byte[] currentIdArray = section.getIdArray();
|
||||
NibbleArray currentDataArray = section.getDataArray();
|
||||
char[] array = new char[4096];
|
||||
for (int j = 0; j < currentIdArray.length; j++) {
|
||||
int x = FaweCache.CACHE_X[layer][j];
|
||||
int y = FaweCache.CACHE_Y[layer][j];
|
||||
int z = FaweCache.CACHE_Z[layer][j];
|
||||
int id = currentIdArray[j] & 0xFF;
|
||||
byte data = (byte) currentDataArray.a(x, y & 15, z);
|
||||
previous.setBlock(x, y, z, id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tiles != null) {
|
||||
for (Map.Entry<ChunkPosition, TileEntity> entry : tiles.entrySet()) {
|
||||
TileEntity tile = entry.getValue();
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
ChunkPosition pos = entry.getKey();
|
||||
CompoundTag nativeTag = getTag(tile);
|
||||
previous.setTile(pos.x & 15, pos.y, pos.z & 15, nativeTag);
|
||||
}
|
||||
}
|
||||
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 = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
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) toNative(tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
previous.setEntity(nativeTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
public CompoundTag getTag(TileEntity tile) {
|
||||
try {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tile.b(tag); // readTagIntoEntity
|
||||
return (CompoundTag) toNative(tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_7_R4.Chunk chunk, int x, int y, int z) {
|
||||
Map<ChunkPosition, TileEntity> tiles = chunk.tileEntities;
|
||||
ChunkPosition pos = new ChunkPosition(x & 15, y, z & 15);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
}
|
||||
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(net.minecraft.server.v1_7_R4.Chunk nmsChunk, final int finalMask) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
try {
|
||||
int mask = finalMask;
|
||||
ChunkCoordIntPair pos = nmsChunk.l(); // getPosition()
|
||||
WorldServer w = (WorldServer) nmsChunk.world;
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
int x = pos.x;
|
||||
int z = pos.z;
|
||||
if (!chunkMap.isChunkInUse(x, z)) {
|
||||
return;
|
||||
}
|
||||
HashSet<EntityPlayer> set = new HashSet<EntityPlayer>();
|
||||
EntityTracker tracker = w.getTracker();
|
||||
// Get players
|
||||
|
||||
Field fieldChunkMap = chunkMap.getClass().getDeclaredField("d");
|
||||
fieldChunkMap.setAccessible(true);
|
||||
LongHashMap map = (LongHashMap) fieldChunkMap.get(chunkMap);
|
||||
long pair = (long) x + 2147483647L | (long) z + 2147483647L << 32;
|
||||
Object playerChunk = map.getEntry(pair);
|
||||
Field fieldPlayers = playerChunk.getClass().getDeclaredField("b");
|
||||
fieldPlayers.setAccessible(true);
|
||||
final HashSet<EntityPlayer> players = new HashSet<>((Collection<EntityPlayer>)fieldPlayers.get(playerChunk));
|
||||
if (players.size() == 0) {
|
||||
return;
|
||||
}
|
||||
// Send chunks
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == null) {
|
||||
sections[i] = emptySection;
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
for (EntityPlayer player : players) {
|
||||
int currentVersion = player.playerConnection.networkManager.getVersion();
|
||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280, currentVersion);
|
||||
player.playerConnection.sendPacket(packet);
|
||||
mask = 255;
|
||||
}
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask, currentVersion);
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
if (empty) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == emptySection) {
|
||||
sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_7_R4.Chunk nmsChunk) {
|
||||
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
||||
List<Entity> slice = nmsChunk.entitySlices[i];
|
||||
if (slice != null && !slice.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.setEmittedLightArray(null);
|
||||
if (sky) {
|
||||
section.setSkyLightArray(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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;
|
||||
ServerNBTManager sdm = new ServerNBTManager(server.getWorldContainer(), name, true);
|
||||
final WorldSettings worldSettings = new WorldSettings(creator.seed(), EnumGamemode.getById(server.getDefaultGameMode().getValue()), generateStructures, hardcore, type);
|
||||
startSet(true);
|
||||
disableChunkLoad = true;
|
||||
final WorldServer internal = new WorldServer(console, sdm, name, dimension, worldSettings, console.methodProfiler, creator.environment(), generator);
|
||||
disableChunkLoad = false;
|
||||
endSet(true);
|
||||
internal.scoreboard = server.getScoreboardManager().getMainScoreboard().getHandle();
|
||||
internal.tracker = new EntityTracker(internal);
|
||||
internal.addIWorldAccess(new WorldManager(console, internal));
|
||||
internal.difficulty = 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 void relight(int x, int y, int z) {
|
||||
nmsWorld.t(x, y, z);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_1_7(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.setSkyLight(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.setEmittedLight(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.getSkyLight(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.getEmittedLight(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||
return section.getTypeId(x & 15, y & 15, z & 15).k();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(ChunkSection section, int x, int y, int z) {
|
||||
return section.getTypeId(x & 15, y & 15, z & 15).m();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getIdArray()[i] != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
|
||||
Block block = section.getTypeId(x & 15, y & 15, z & 15);
|
||||
return MathMan.pair16(block.k(), block.m());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightBlock(int x, int y, int z) {
|
||||
nmsWorld.c(EnumSkyBlock.BLOCK, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relightSky(int x, int y, int z) {
|
||||
nmsWorld.c(EnumSkyBlock.SKY, x, y, z);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_7;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.server.v1_7_R4.GenLayer;
|
||||
import net.minecraft.server.v1_7_R4.IntCache;
|
||||
|
||||
public class MutableGenLayer extends GenLayer {
|
||||
|
||||
private int biome;
|
||||
|
||||
public MutableGenLayer(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public MutableGenLayer set(int biome) {
|
||||
this.biome = biome;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||
Arrays.fill(biomes, biome);
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -1,317 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_8;
|
||||
|
||||
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.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
/**
|
||||
* 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_8(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_8(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_8 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return Bukkit.getWorld(getParent().getWorldName()).getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
getChunk().load(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
CraftChunk chunk = (CraftChunk) this.getChunk();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
|
||||
nmsChunk.f(true); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_8_R3.World nmsWorld = nmsChunk.getWorld();
|
||||
try {
|
||||
final boolean flag = getParent().getWorld().getEnvironment() == World.Environment.NORMAL;
|
||||
// Sections
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
Collection<Entity>[] entities = nmsChunk.getEntitySlices();
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null || entities[i] == null || entities[i].isEmpty()) continue;
|
||||
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (Entity entity : entsArr) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = (MathMan.roundInt(entity.locX) & 15);
|
||||
int z = (MathMan.roundInt(entity.locZ) & 15);
|
||||
int y = MathMan.roundInt(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (ents.isEmpty()) {
|
||||
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
|
||||
for (Entity entity : entsArr) {
|
||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set entities
|
||||
Set<UUID> createdEntities = new HashSet<>();
|
||||
Set<CompoundTag> entitiesToSpawn = this.getEntities();
|
||||
if (!entitiesToSpawn.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (CompoundTag nativeTag : entitiesToSpawn) {
|
||||
Map<String, Tag> entityTagMap = 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();
|
||||
Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
|
||||
if (entity != null) {
|
||||
if (nativeTag != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue18R3.fromNative(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Run change task if applicable
|
||||
if (getParent().getChangeTask() != null) {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Set blocks
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
int count = this.getCount(j);
|
||||
if (count == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] newArray = this.getIdArray(j);
|
||||
if (newArray == null) {
|
||||
continue;
|
||||
}
|
||||
int countAir = this.getAir(j);
|
||||
ChunkSection section = sections[j];
|
||||
if (section != null && BukkitQueue18R3.isDirty != null) {
|
||||
BukkitQueue18R3.isDirty.set(section, true);
|
||||
}
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
}
|
||||
sections[j] = section = new ChunkSection(j << 4, flag, newArray);
|
||||
continue;
|
||||
}
|
||||
if (count >= 4096) {
|
||||
if (count == countAir) {
|
||||
sections[j] = null;
|
||||
continue;
|
||||
}
|
||||
sections[j] = section = new ChunkSection(j << 4, flag, newArray);
|
||||
continue;
|
||||
}
|
||||
int by = j << 4;
|
||||
char[] currentArray = section.getIdArray();
|
||||
int solid = 0;
|
||||
int existingId;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
case 0:
|
||||
continue;
|
||||
case 1:
|
||||
existingId = currentArray[k];
|
||||
if (existingId > 1) {
|
||||
if (FaweCache.hasLight(existingId)) {
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
getParent().getRelighter().addLightUpdate(bx + x, y, bz + z);
|
||||
}
|
||||
solid--;
|
||||
currentArray[k] = 0;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
existingId = currentArray[k];
|
||||
if (existingId <= 1) {
|
||||
solid++;
|
||||
} else if (FaweCache.hasLight(existingId)) {
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
getParent().getRelighter().addLightUpdate(bx + x, y, bz + z);
|
||||
}
|
||||
currentArray[k] = n;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + solid, section);
|
||||
}
|
||||
// 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);
|
||||
nmsWorld.t(bp);
|
||||
tile.y();
|
||||
tile.E();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
byte biome = this.biomes[i];
|
||||
if (biome != 0) {
|
||||
if (biome == -1) biome = 0;
|
||||
currentBiomes[i] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue18R3.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,731 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_8;
|
||||
|
||||
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.RegionWrapper;
|
||||
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.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_8_R3.Block;
|
||||
import net.minecraft.server.v1_8_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_8_R3.Chunk;
|
||||
import net.minecraft.server.v1_8_R3.ChunkSection;
|
||||
import net.minecraft.server.v1_8_R3.Entity;
|
||||
import net.minecraft.server.v1_8_R3.EntityPlayer;
|
||||
import net.minecraft.server.v1_8_R3.EntityTracker;
|
||||
import net.minecraft.server.v1_8_R3.EntityTypes;
|
||||
import net.minecraft.server.v1_8_R3.EnumDifficulty;
|
||||
import net.minecraft.server.v1_8_R3.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_8_R3.IChunkProvider;
|
||||
import net.minecraft.server.v1_8_R3.LongHashMap;
|
||||
import net.minecraft.server.v1_8_R3.MinecraftServer;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_8_R3.NibbleArray;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_8_R3.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_8_R3.ServerNBTManager;
|
||||
import net.minecraft.server.v1_8_R3.TileEntity;
|
||||
import net.minecraft.server.v1_8_R3.WorldData;
|
||||
import net.minecraft.server.v1_8_R3.WorldManager;
|
||||
import net.minecraft.server.v1_8_R3.WorldServer;
|
||||
import net.minecraft.server.v1_8_R3.WorldSettings;
|
||||
import net.minecraft.server.v1_8_R3.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
public static Field isDirty;
|
||||
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
protected static Field fieldChunkMap;
|
||||
protected static Field fieldBiomes;
|
||||
protected static Field fieldSeed;
|
||||
protected static Field fieldBiomeCache;
|
||||
protected static Field fieldBiomes2;
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static com.boydti.fawe.bukkit.v1_8.MutableGenLayer genLayer;
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldChunkMap = PlayerChunkMap.class.getDeclaredField("d");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldChunkMap.setAccessible(true);
|
||||
|
||||
fieldBiomes = net.minecraft.server.v1_8_R3.ChunkProviderGenerate.class.getDeclaredField("B");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldSeed = net.minecraft.server.v1_8_R3.WorldData.class.getDeclaredField("b");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = net.minecraft.server.v1_8_R3.WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = net.minecraft.server.v1_8_R3.WorldChunkManager.class.getDeclaredField("e");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = net.minecraft.server.v1_8_R3.WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer2 = net.minecraft.server.v1_8_R3.WorldChunkManager.class.getDeclaredField("c") ;
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
isDirty = ChunkSection.class.getDeclaredField("isDirty");
|
||||
isDirty.setAccessible(true);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
|
||||
public BukkitQueue18R3(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue18R3(final String world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(Chunk nmsChunk) {
|
||||
nmsChunk.f(true); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, final boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
long last = start;
|
||||
synchronized (net.minecraft.server.v1_8_R3.RegionFileCache.class) {
|
||||
World world = getWorld();
|
||||
if (world.getKeepSpawnInMemory()) world.setKeepSpawnInMemory(false);
|
||||
net.minecraft.server.v1_8_R3.ChunkProviderServer provider = nmsWorld.chunkProviderServer;
|
||||
|
||||
boolean mustSave = false;
|
||||
boolean[][] chunksUnloaded = null;
|
||||
{ // Unload chunks
|
||||
Iterator<net.minecraft.server.v1_8_R3.Chunk> iter = provider.a().iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = iter.next();
|
||||
if (chunk.locX >> 5 == mcaX && chunk.locZ >> 5 == mcaZ) {
|
||||
boolean isIn = allowed.isInChunk(chunk.locX, chunk.locZ);
|
||||
if (isIn) {
|
||||
if (!load) {
|
||||
if (saveChunks && chunk.a(false)) {
|
||||
mustSave = true;
|
||||
provider.saveChunk(chunk);
|
||||
provider.saveChunkNOP(chunk);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
boolean save = saveChunks && chunk.a(false);
|
||||
mustSave |= save;
|
||||
chunk.bukkitChunk.unload(save, false);
|
||||
if (chunksUnloaded == null) {
|
||||
chunksUnloaded = new boolean[32][];
|
||||
}
|
||||
int relX = chunk.locX & 31;
|
||||
boolean[] arr = chunksUnloaded[relX];
|
||||
if (arr == null) {
|
||||
arr = chunksUnloaded[relX] = new boolean[32];
|
||||
}
|
||||
arr[chunk.locZ & 31] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustSave) provider.c(); // TODO only the necessary chunks
|
||||
|
||||
File unloadedRegion = null;
|
||||
if (load && !net.minecraft.server.v1_8_R3.RegionFileCache.a.isEmpty()) {
|
||||
Map<File, net.minecraft.server.v1_8_R3.RegionFile> map = net.minecraft.server.v1_8_R3.RegionFileCache.a;
|
||||
Iterator<Map.Entry<File, net.minecraft.server.v1_8_R3.RegionFile>> iter = map.entrySet().iterator();
|
||||
String requiredPath = world.getName() + File.separator + "region";
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<File, net.minecraft.server.v1_8_R3.RegionFile> entry = iter.next();
|
||||
File file = entry.getKey();
|
||||
int[] regPos = MainUtil.regionNameToCoords(file.getPath());
|
||||
if (regPos[0] == mcaX && regPos[1] == mcaZ && file.getPath().contains(requiredPath)) {
|
||||
if (file.exists()) {
|
||||
unloadedRegion = file;
|
||||
net.minecraft.server.v1_8_R3.RegionFile regionFile = entry.getValue();
|
||||
iter.remove();
|
||||
try {
|
||||
regionFile.c();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (whileLocked != null) whileLocked.run();
|
||||
if (!load) return;
|
||||
|
||||
{ // Load the region again
|
||||
if (unloadedRegion != null && chunksUnloaded != null && unloadedRegion.exists()) {
|
||||
final boolean[][] finalChunksUnloaded = chunksUnloaded;
|
||||
TaskManager.IMP.async(() -> {
|
||||
int bx = mcaX << 5;
|
||||
int bz = mcaZ << 5;
|
||||
for (int x = 0; x < finalChunksUnloaded.length; x++) {
|
||||
boolean[] arr = finalChunksUnloaded[x];
|
||||
if (arr != null) {
|
||||
for (int z = 0; z < arr.length; z++) {
|
||||
if (arr[z]) {
|
||||
int cx = bx + x;
|
||||
int cz = bz + z;
|
||||
SetQueue.IMP.addTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = provider.getChunkAt(cx, cz, null);
|
||||
if (chunk != null) {
|
||||
if (nmsWorld.getPlayerChunkMap().isChunkInUse(cx, cz)) {
|
||||
sendChunk(chunk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
try {
|
||||
if (seed == null) {
|
||||
seed = world.getSeed();
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
net.minecraft.server.v1_8_R3.ChunkProviderGenerate generator = new net.minecraft.server.v1_8_R3.ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
Biome bukkitBiome = getAdapter().getBiome(biome.getId());
|
||||
net.minecraft.server.v1_8_R3.BiomeBase base = net.minecraft.server.v1_8_R3.BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new net.minecraft.server.v1_8_R3.BiomeBase[]{base});
|
||||
IChunkProvider existingGenerator = nmsWorld.chunkProviderServer.chunkProvider;
|
||||
long existingSeed = world.getSeed();
|
||||
{
|
||||
if (genLayer == null) genLayer = new MutableGenLayer(seed);
|
||||
genLayer.set(biome.getId());
|
||||
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new net.minecraft.server.v1_8_R3.BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = generator;
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
nmsWorld.chunkProviderServer.chunkProvider = existingGenerator;
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||
}
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return super.regenerateChunk(world, x, z, biome, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
int newHeight = heightMap[i] & 0xFF;
|
||||
int currentHeight = otherMap[i];
|
||||
if (newHeight > currentHeight) {
|
||||
otherMap[i] = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_8_R3.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection[] getSections(net.minecraft.server.v1_8_R3.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk;
|
||||
net.minecraft.server.v1_8_R3.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_8_R3.CraftWorld) world).getHandle().chunkProviderServer;
|
||||
if (generate) {
|
||||
return provider.originalGetChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = ((CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_8_R3.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection getCachedSection(net.minecraft.server.v1_8_R3.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@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().a();
|
||||
Arrays.fill(bytes, Byte.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection section, int x, int y, int z) {
|
||||
char[] ls = section.getIdArray();
|
||||
return ls[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk 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;
|
||||
CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ());
|
||||
char[][] idPrevious = previous.getCombinedIdArrays();
|
||||
for (int layer = 0; layer < sections.length; layer++) {
|
||||
if (fs.getCount(layer) != 0 || all) {
|
||||
ChunkSection section = sections[layer];
|
||||
if (section != null) {
|
||||
idPrevious[layer] = section.getIdArray().clone();
|
||||
short solid = 0;
|
||||
for (int combined : idPrevious[layer]) {
|
||||
if (combined > 1) {
|
||||
solid++;
|
||||
}
|
||||
}
|
||||
previous.count[layer] = solid;
|
||||
previous.air[layer] = (short) (4096 - solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
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) toNative(tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
previous.setEntity(nativeTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
public CompoundTag getTag(TileEntity tile) {
|
||||
try {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tile.b(tag); // readTagIntoEntity
|
||||
return (CompoundTag) toNative(tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_8_R3.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
}
|
||||
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(net.minecraft.server.v1_8_R3.Chunk nmsChunk, int mask) {
|
||||
try {
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
int x = nmsChunk.locX;
|
||||
int z = nmsChunk.locZ;
|
||||
if (!chunkMap.isChunkInUse(x, z)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LongHashMap<Object> map = (LongHashMap<Object>) fieldChunkMap.get(chunkMap);
|
||||
long pair = (long) x + 2147483647L | (long) z + 2147483647L << 32;
|
||||
Object playerChunk = map.getEntry(pair);
|
||||
Field fieldPlayers = playerChunk.getClass().getDeclaredField("b");
|
||||
fieldPlayers.setAccessible(true);
|
||||
Collection<EntityPlayer> players = (Collection<EntityPlayer>) fieldPlayers.get(playerChunk);
|
||||
if (players.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == null) {
|
||||
sections[i] = emptySection;
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
// Send chunks
|
||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
|
||||
for (EntityPlayer player : players) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
mask = 255;
|
||||
}
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, mask);
|
||||
for (EntityPlayer player : players) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
// Send tiles
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : nmsChunk.getTileEntities().entrySet()) {
|
||||
TileEntity tile = entry.getValue();
|
||||
Packet tilePacket = tile.getUpdatePacket();
|
||||
for (EntityPlayer player : players) {
|
||||
player.playerConnection.sendPacket(tilePacket);
|
||||
}
|
||||
}
|
||||
if (empty) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == emptySection) {
|
||||
sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_8_R3.Chunk nmsChunk) {
|
||||
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
||||
List<Entity> slice = nmsChunk.entitySlices[i];
|
||||
if (slice != null && !slice.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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;
|
||||
ServerNBTManager sdm = new ServerNBTManager(server.getWorldContainer(), name, true);
|
||||
WorldData worlddata = sdm.getWorldData();
|
||||
final WorldSettings worldSettings;
|
||||
if (worlddata == null) {
|
||||
worldSettings = new WorldSettings(creator.seed(), WorldSettings.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 void relight(int x, int y, int z) {
|
||||
pos.c(x, y, z);
|
||||
nmsWorld.x(pos);
|
||||
}
|
||||
|
||||
private WorldServer nmsWorld;
|
||||
|
||||
@Override
|
||||
public World getImpWorld() {
|
||||
World world = super.getImpWorld();
|
||||
if (world != null) {
|
||||
this.nmsWorld = ((CraftWorld) world).getHandle();
|
||||
return super.getImpWorld();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_1_8(this, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.a(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
|
||||
section.b(x & 15, y & 15, z & 15, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.d(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
|
||||
return section.e(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||
int combined = getCombinedId4Data(section, x, y, z);
|
||||
if (combined == 0) {
|
||||
return 0;
|
||||
}
|
||||
Block block = Block.getById(FaweCache.getId(combined));
|
||||
return block.p();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(ChunkSection section, int x, int y, int z) {
|
||||
int combined = getCombinedId4Data(section, x, y, z);
|
||||
if (combined == 0) {
|
||||
return 0;
|
||||
}
|
||||
Block block = Block.getById(FaweCache.getId(combined));
|
||||
return block.r();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
|
||||
int i = FaweCache.CACHE_J[y & 15][z & 15][x & 15];
|
||||
return section.getIdArray()[i] != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
|
||||
int combined = getCombinedId4Data(section, x, y, z);
|
||||
if (combined == 0) {
|
||||
return 0;
|
||||
}
|
||||
Block block = Block.getById(FaweCache.getId(combined));
|
||||
return MathMan.pair16(block.p(), block.r());
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_8;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.server.v1_8_R3.GenLayer;
|
||||
import net.minecraft.server.v1_8_R3.IntCache;
|
||||
|
||||
public class MutableGenLayer extends GenLayer {
|
||||
|
||||
private int biome;
|
||||
|
||||
public MutableGenLayer(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public MutableGenLayer set(int biome) {
|
||||
this.biome = biome;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||
Arrays.fill(biomes, biome);
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -1,425 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_9;
|
||||
|
||||
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.FaweQueue;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import net.minecraft.server.v1_9_R2.*;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
|
||||
public DataPaletteBlock[] sectionPalettes;
|
||||
|
||||
/**
|
||||
* 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_9(FaweQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_9(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_9 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes != null ? biomes.clone() : null;
|
||||
copy.chunk = chunk;
|
||||
}
|
||||
if (sectionPalettes != null) {
|
||||
copy.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);
|
||||
copy.sectionPalettes[i] = paletteBlock;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getNewChunk() {
|
||||
return ((BukkitQueue_1_9_R1) getParent()).getWorld().getChunkAt(getX(), getZ());
|
||||
}
|
||||
|
||||
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() {
|
||||
final Chunk chunk = (Chunk) this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
try {
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_9_R2.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
nmsChunk.f(true); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_9_R2.World nmsWorld = nmsChunk.world;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
Class<? extends net.minecraft.server.v1_9_R2.Chunk> clazzChunk = nmsChunk.getClass();
|
||||
final Field ef = clazzChunk.getDeclaredField("entitySlices");
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) ef.get(nmsChunk);
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
int count = this.getCount(i);
|
||||
if (count == 0 || getParent().getSettings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) {
|
||||
continue;
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
Iterator<Entity> iter = ents.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Entity entity = iter.next();
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null || entities[i] == null || entities[i].isEmpty()) continue;
|
||||
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (Entity entity : entsArr) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
continue;
|
||||
}
|
||||
int x = (MathMan.roundInt(entity.locX) & 15);
|
||||
int z = (MathMan.roundInt(entity.locZ) & 15);
|
||||
int y = MathMan.roundInt(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (BukkitQueue_0.class) {
|
||||
for (int i = 0; i < entities.length; i++) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (ents.isEmpty()) {
|
||||
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
|
||||
for (Entity entity : entsArr) {
|
||||
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.class) {
|
||||
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();
|
||||
Entity entity = EntityTypes.createEntityByName(id, 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_9_R1.fromNative(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) {
|
||||
CharFaweChunk previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
int countAir = this.getAir(j);
|
||||
ChunkSection section = sections[j];
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
}
|
||||
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 (countAir >= 4096) {
|
||||
sections[j] = null;
|
||||
continue;
|
||||
}
|
||||
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();
|
||||
Field fieldBits = nibble.getClass().getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
DataBits bits = (DataBits) fieldBits.get(nibble);
|
||||
|
||||
Field fieldPalette = nibble.getClass().getDeclaredField("c");
|
||||
fieldPalette.setAccessible(true);
|
||||
DataPalette palette = (DataPalette) fieldPalette.get(nibble);
|
||||
int nonEmptyBlockCount = 0;
|
||||
IBlockData existing;
|
||||
int by = j << 4;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
continue;
|
||||
case 1:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_9_R1.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_9_R1.air);
|
||||
continue;
|
||||
default:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_9_R1.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// 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);
|
||||
nmsWorld.s(bp);
|
||||
tile.y();
|
||||
tile.invalidateBlockCache();
|
||||
}
|
||||
|
||||
}
|
||||
// Set biomes
|
||||
byte[] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0; i < currentBiomes.length; i++) {
|
||||
byte newBiome = biomes[i];
|
||||
if (newBiome != 0) {
|
||||
currentBiomes[i] = newBiome;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set tiles
|
||||
Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
short blockHash = entry.getKey();
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
BlockPosition pos = new BlockPosition(x, y, z); // Set pos
|
||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||
if (tileEntity != null) {
|
||||
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_9_R1.fromNative(nativeTag);
|
||||
tag.set("x", new NBTTagInt(x));
|
||||
tag.set("y", new NBTTagInt(y));
|
||||
tag.set("z", new NBTTagInt(z));
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,861 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_9;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.BukkitPlayer;
|
||||
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.FawePlayer;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualChunk;
|
||||
import com.boydti.fawe.object.visitor.FaweChunkVisitor;
|
||||
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 com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import net.minecraft.server.v1_9_R2.Block;
|
||||
import net.minecraft.server.v1_9_R2.BlockPosition;
|
||||
import net.minecraft.server.v1_9_R2.ChunkSection;
|
||||
import net.minecraft.server.v1_9_R2.DataBits;
|
||||
import net.minecraft.server.v1_9_R2.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_9_R2.Entity;
|
||||
import net.minecraft.server.v1_9_R2.EntityPlayer;
|
||||
import net.minecraft.server.v1_9_R2.EntityTracker;
|
||||
import net.minecraft.server.v1_9_R2.EntityTypes;
|
||||
import net.minecraft.server.v1_9_R2.EnumDifficulty;
|
||||
import net.minecraft.server.v1_9_R2.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_9_R2.IBlockData;
|
||||
import net.minecraft.server.v1_9_R2.IDataManager;
|
||||
import net.minecraft.server.v1_9_R2.MinecraftServer;
|
||||
import net.minecraft.server.v1_9_R2.NBTTagCompound;
|
||||
import net.minecraft.server.v1_9_R2.NibbleArray;
|
||||
import net.minecraft.server.v1_9_R2.PacketDataSerializer;
|
||||
import net.minecraft.server.v1_9_R2.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_9_R2.PacketPlayOutMultiBlockChange;
|
||||
import net.minecraft.server.v1_9_R2.PlayerChunk;
|
||||
import net.minecraft.server.v1_9_R2.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_9_R2.ServerNBTManager;
|
||||
import net.minecraft.server.v1_9_R2.TileEntity;
|
||||
import net.minecraft.server.v1_9_R2.WorldData;
|
||||
import net.minecraft.server.v1_9_R2.WorldManager;
|
||||
import net.minecraft.server.v1_9_R2.WorldServer;
|
||||
import net.minecraft.server.v1_9_R2.WorldSettings;
|
||||
import net.minecraft.server.v1_9_R2.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_9_R1 extends BukkitQueue_0<net.minecraft.server.v1_9_R2.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
protected static Field fieldBiomes;
|
||||
protected static Field fieldChunkGenerator;
|
||||
protected static Field fieldSeed;
|
||||
protected static Field fieldBiomeCache;
|
||||
protected static Field fieldBiomes2;
|
||||
protected static Field fieldGenLayer1;
|
||||
protected static Field fieldGenLayer2;
|
||||
protected static com.boydti.fawe.bukkit.v1_9.MutableGenLayer genLayer;
|
||||
protected static ChunkSection emptySection;
|
||||
|
||||
static {
|
||||
try {
|
||||
emptySection = new ChunkSection(0, true);
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
fieldBiomes = net.minecraft.server.v1_9_R2.ChunkProviderGenerate.class.getDeclaredField("C");
|
||||
fieldBiomes.setAccessible(true);
|
||||
fieldChunkGenerator = net.minecraft.server.v1_9_R2.ChunkProviderServer.class.getDeclaredField("chunkGenerator");
|
||||
fieldChunkGenerator.setAccessible(true);
|
||||
fieldSeed = net.minecraft.server.v1_9_R2.WorldData.class.getDeclaredField("e");
|
||||
fieldSeed.setAccessible(true);
|
||||
fieldBiomeCache = net.minecraft.server.v1_9_R2.WorldChunkManager.class.getDeclaredField("c");
|
||||
fieldBiomeCache.setAccessible(true);
|
||||
fieldBiomes2 = net.minecraft.server.v1_9_R2.WorldChunkManager.class.getDeclaredField("d");
|
||||
fieldBiomes2.setAccessible(true);
|
||||
fieldGenLayer1 = net.minecraft.server.v1_9_R2.WorldChunkManager.class.getDeclaredField("a") ;
|
||||
fieldGenLayer2 = net.minecraft.server.v1_9_R2.WorldChunkManager.class.getDeclaredField("b") ;
|
||||
fieldGenLayer1.setAccessible(true);
|
||||
fieldGenLayer2.setAccessible(true);
|
||||
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
if (getAdapter() == null) {
|
||||
setupAdapter(new FaweAdapter_1_9());
|
||||
System.out.println("Using adapter: " + getAdapter());
|
||||
System.out.println("=========================================");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_9_R1(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_9_R1(final String world) {
|
||||
super(world);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunk(net.minecraft.server.v1_9_R2.Chunk chunk) {
|
||||
chunk.f(true); // Set Modified
|
||||
chunk.mustSave = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
try {
|
||||
if (seed == null) {
|
||||
seed = world.getSeed();
|
||||
}
|
||||
nmsWorld.worldData.getSeed();
|
||||
boolean result;
|
||||
net.minecraft.server.v1_9_R2.ChunkProviderGenerate generator = new net.minecraft.server.v1_9_R2.ChunkProviderGenerate(nmsWorld, seed, false, "");
|
||||
Biome bukkitBiome = getAdapter().getBiome(biome.getId());
|
||||
net.minecraft.server.v1_9_R2.BiomeBase base = net.minecraft.server.v1_9_R2.BiomeBase.getBiome(biome.getId());
|
||||
fieldBiomes.set(generator, new net.minecraft.server.v1_9_R2.BiomeBase[]{base});
|
||||
net.minecraft.server.v1_9_R2.ChunkGenerator existingGenerator = nmsWorld.getChunkProviderServer().chunkGenerator;
|
||||
long existingSeed = world.getSeed();
|
||||
{
|
||||
if (genLayer == null) genLayer = new MutableGenLayer(seed);
|
||||
genLayer.set(biome.getId());
|
||||
Object existingGenLayer1 = fieldGenLayer1.get(nmsWorld.getWorldChunkManager());
|
||||
Object existingGenLayer2 = fieldGenLayer2.get(nmsWorld.getWorldChunkManager());
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), genLayer);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, seed);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldBiomeCache, this.nmsWorld.getWorldChunkManager(), new net.minecraft.server.v1_9_R2.BiomeCache(this.nmsWorld.getWorldChunkManager()));
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), generator);
|
||||
|
||||
keepLoaded.remove(MathMan.pairInt(x, z));
|
||||
result = getWorld().regenerateChunk(x, z);
|
||||
|
||||
ReflectionUtils.setFailsafeFieldValue(fieldChunkGenerator, this.nmsWorld.getChunkProviderServer(), existingGenerator);
|
||||
|
||||
fieldSeed.set(nmsWorld.worldData, existingSeed);
|
||||
|
||||
fieldGenLayer1.set(nmsWorld.getWorldChunkManager(), existingGenLayer1);
|
||||
fieldGenLayer2.set(nmsWorld.getWorldChunkManager(), existingGenLayer2);
|
||||
}
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return super.regenerateChunk(world, x, z, biome, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk.getChunk();
|
||||
if (craftChunk != null) {
|
||||
int[] otherMap = craftChunk.getHandle().heightMap;
|
||||
for (int i = 0; i < heightMap.length; i++) {
|
||||
int newHeight = heightMap[i] & 0xFF;
|
||||
int currentHeight = otherMap[i];
|
||||
if (newHeight > currentHeight) {
|
||||
otherMap[i] = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_9_R2.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection[] getSections(net.minecraft.server.v1_9_R2.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk;
|
||||
net.minecraft.server.v1_9_R2.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer().getLoadedChunkAt(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer().getLoadedChunkAt(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection getCachedSection(net.minecraft.server.v1_9_R2.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 boolean setMCA(final int mcaX, final int mcaZ, final RegionWrapper allowed, final Runnable whileLocked, boolean saveChunks, final boolean load) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Boolean>() {
|
||||
@Override
|
||||
public void run(Boolean value) {
|
||||
long start = System.currentTimeMillis();
|
||||
long last = start;
|
||||
synchronized (net.minecraft.server.v1_9_R2.RegionFileCache.class) {
|
||||
World world = getWorld();
|
||||
if (world.getKeepSpawnInMemory()) world.setKeepSpawnInMemory(false);
|
||||
net.minecraft.server.v1_9_R2.ChunkProviderServer provider = nmsWorld.getChunkProviderServer();
|
||||
|
||||
boolean mustSave = false;
|
||||
boolean[][] chunksUnloaded = null;
|
||||
{ // Unload chunks
|
||||
Iterator<net.minecraft.server.v1_9_R2.Chunk> iter = provider.a().iterator();
|
||||
while (iter.hasNext()) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = iter.next();
|
||||
if (chunk.locX >> 5 == mcaX && chunk.locZ >> 5 == mcaZ) {
|
||||
boolean isIn = allowed.isInChunk(chunk.locX, chunk.locZ);
|
||||
if (isIn) {
|
||||
if (!load) {
|
||||
if (saveChunks && chunk.a(false)) {
|
||||
mustSave = true;
|
||||
provider.saveChunk(chunk);
|
||||
provider.saveChunkNOP(chunk);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
boolean save = saveChunks && chunk.a(false);
|
||||
mustSave |= save;
|
||||
if (save) {
|
||||
provider.unload(chunk);
|
||||
} else {
|
||||
chunk.bukkitChunk.unload(false, false);
|
||||
}
|
||||
if (chunksUnloaded == null) {
|
||||
chunksUnloaded = new boolean[32][];
|
||||
}
|
||||
int relX = chunk.locX & 31;
|
||||
boolean[] arr = chunksUnloaded[relX];
|
||||
if (arr == null) {
|
||||
arr = chunksUnloaded[relX] = new boolean[32];
|
||||
}
|
||||
arr[chunk.locZ & 31] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustSave) provider.c(); // TODO only the necessary chunks
|
||||
|
||||
File unloadedRegion = null;
|
||||
if (load && !net.minecraft.server.v1_9_R2.RegionFileCache.a.isEmpty()) {
|
||||
Map<File, net.minecraft.server.v1_9_R2.RegionFile> map = net.minecraft.server.v1_9_R2.RegionFileCache.a;
|
||||
Iterator<Map.Entry<File, net.minecraft.server.v1_9_R2.RegionFile>> iter = map.entrySet().iterator();
|
||||
String requiredPath = world.getName() + File.separator + "region";
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<File, net.minecraft.server.v1_9_R2.RegionFile> entry = iter.next();
|
||||
File file = entry.getKey();
|
||||
int[] regPos = MainUtil.regionNameToCoords(file.getPath());
|
||||
if (regPos[0] == mcaX && regPos[1] == mcaZ && file.getPath().contains(requiredPath)) {
|
||||
if (file.exists()) {
|
||||
unloadedRegion = file;
|
||||
net.minecraft.server.v1_9_R2.RegionFile regionFile = entry.getValue();
|
||||
iter.remove();
|
||||
try {
|
||||
regionFile.c();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (whileLocked != null) whileLocked.run();
|
||||
if (!load) return;
|
||||
|
||||
{ // Load the region again
|
||||
if (unloadedRegion != null && chunksUnloaded != null && unloadedRegion.exists()) {
|
||||
final boolean[][] finalChunksUnloaded = chunksUnloaded;
|
||||
TaskManager.IMP.async(() -> {
|
||||
int bx = mcaX << 5;
|
||||
int bz = mcaZ << 5;
|
||||
for (int x = 0; x < finalChunksUnloaded.length; x++) {
|
||||
boolean[] arr = finalChunksUnloaded[x];
|
||||
if (arr != null) {
|
||||
for (int z = 0; z < arr.length; z++) {
|
||||
if (arr[z]) {
|
||||
int cx = bx + x;
|
||||
int cz = bz + z;
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value1) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = provider.getChunkAt(cx, cz, null, false);
|
||||
if (chunk != null) {
|
||||
net.minecraft.server.v1_9_R2.PlayerChunk pc = nmsWorld.getPlayerChunkMap().getChunk(cx, cz);
|
||||
if (pc != null && !pc.c.isEmpty()) {
|
||||
sendChunk(chunk, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendBlockUpdate(FaweChunk chunk, FawePlayer... players) {
|
||||
try {
|
||||
PlayerChunkMap playerManager = ((CraftWorld) getWorld()).getHandle().getPlayerChunkMap();
|
||||
boolean watching = false;
|
||||
boolean[] watchingArr = new boolean[players.length];
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
EntityPlayer player = ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle();
|
||||
if (playerManager.a(player, chunk.getX(), chunk.getZ())) {
|
||||
watchingArr[i] = true;
|
||||
watching = true;
|
||||
}
|
||||
}
|
||||
if (!watching) return;
|
||||
final LongAdder size = new LongAdder();
|
||||
if (chunk instanceof VisualChunk) {
|
||||
size.add(((VisualChunk) chunk).size());
|
||||
} else if (chunk instanceof CharFaweChunk) {
|
||||
size.add(((CharFaweChunk) chunk).getTotalCount());
|
||||
} else {
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
size.add(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (size.intValue() == 0) return;
|
||||
PacketPlayOutMultiBlockChange packet = new PacketPlayOutMultiBlockChange();
|
||||
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||
final PacketDataSerializer buffer = new PacketDataSerializer(byteBuf);
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.d(size.intValue());
|
||||
chunk.forEachQueuedBlock(new FaweChunkVisitor() {
|
||||
@Override
|
||||
public void run(int localX, int y, int localZ, int combined) {
|
||||
short index = (short) (localX << 12 | localZ << 8 | y);
|
||||
if (combined < 16) combined = 0;
|
||||
buffer.writeShort(index);
|
||||
buffer.d(combined);
|
||||
}
|
||||
});
|
||||
packet.a(buffer);
|
||||
for (int i = 0; i < players.length; i++) {
|
||||
if (watchingArr[i]) ((CraftPlayer) ((BukkitPlayer) players[i]).parent).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(net.minecraft.server.v1_9_R2.Chunk nmsChunk, int mask) {
|
||||
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
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == null) {
|
||||
sections[i] = emptySection;
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
if (mask == 0 || 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);
|
||||
}
|
||||
if (empty) {
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
if (sections[i] == emptySection) {
|
||||
sections[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasEntities(net.minecraft.server.v1_9_R2.Chunk nmsChunk) {
|
||||
for (int i = 0; i < nmsChunk.entitySlices.length; i++) {
|
||||
List<Entity> slice = nmsChunk.entitySlices[i];
|
||||
if (slice != null && !slice.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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(), WorldSettings.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 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.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSectionLighting(ChunkSection section, int layer, boolean sky) {
|
||||
if (section != null) {
|
||||
section.a(new NibbleArray());
|
||||
if (sky) {
|
||||
section.b(new NibbleArray());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@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 boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) {
|
||||
return this.isSolid(this.getId(sections, x, y + 1, z))
|
||||
&& this.isSolid(this.getId(sections, x + 1, y - 1, z))
|
||||
&& this.isSolid(this.getId(sections, x - 1, y, z))
|
||||
&& this.isSolid(this.getId(sections, x, y, z + 1))
|
||||
&& this.isSolid(this.getId(sections, x, y, z - 1));
|
||||
}
|
||||
|
||||
public boolean isSolid(final int id) {
|
||||
return !FaweCache.isTransparent(id);
|
||||
}
|
||||
|
||||
public int getId(final char[][] sections, final int x, final int y, final int z) {
|
||||
if ((x < 0) || (x > 15) || (z < 0) || (z > 15)) {
|
||||
return 1;
|
||||
}
|
||||
if ((y < 0) || (y > 255)) {
|
||||
return 1;
|
||||
}
|
||||
final int i = FaweCache.CACHE_I[y][z][x];
|
||||
final char[] section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
final int j = FaweCache.CACHE_J[y][z][x];
|
||||
return section[j] >> 4;
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
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 CharFaweChunk 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;
|
||||
CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ());
|
||||
// Copy blocks
|
||||
char[][] idPrevious = previous.getCombinedIdArrays();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 = (MathMan.roundInt(ent.locX) & 15);
|
||||
int z = (MathMan.roundInt(ent.locZ) & 15);
|
||||
int y = (MathMan.roundInt(ent.locY) & 0xFF);
|
||||
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) toNative(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(net.minecraft.server.v1_9_R2.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.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) toNative(tag);
|
||||
} catch (Exception e) {
|
||||
MainUtil.handleError(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_9_R2.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
c.mustSave = false;
|
||||
if (chunk.isLoaded()) {
|
||||
chunk.unload(false, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_1_9(this, x, z);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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 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());
|
||||
}
|
||||
|
||||
protected DataBits lastBits;
|
||||
protected DataPaletteBlock lastBlocks;
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@ -1,355 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_9;
|
||||
|
||||
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_9_R2.*;
|
||||
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_9_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
public final class FaweAdapter_1_9 implements BukkitImplAdapter
|
||||
{
|
||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||
private final Field nbtListTagListField;
|
||||
private final Method nbtCreateTagMethod;
|
||||
|
||||
public FaweAdapter_1_9()
|
||||
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_9_R2.Entity entity)
|
||||
{
|
||||
return EntityTypes.b(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static net.minecraft.server.v1_9_R2.Entity createEntityFromId(String id, World world)
|
||||
{
|
||||
return EntityTypes.createEntityByName(id, world);
|
||||
}
|
||||
|
||||
private static void readTagIntoEntity(NBTTagCompound tag, net.minecraft.server.v1_9_R2.Entity entity)
|
||||
{
|
||||
entity.f(tag);
|
||||
}
|
||||
|
||||
private static void readEntityIntoTag(net.minecraft.server.v1_9_R2.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_9_R2.Entity mcEntity = craftEntity.getHandle();
|
||||
|
||||
String id = getEntityId(mcEntity);
|
||||
if (id != null)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
readEntityIntoTag(mcEntity, tag);
|
||||
return new BaseEntity(id, (CompoundTag)toNative(tag));
|
||||
}
|
||||
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_9_R2.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).f());
|
||||
}
|
||||
if ((foreign instanceof NBTTagByteArray)) {
|
||||
return new ByteArrayTag(((NBTTagByteArray)foreign).c());
|
||||
}
|
||||
if ((foreign instanceof NBTTagDouble)) {
|
||||
return new DoubleTag(((NBTTagDouble)foreign).g());
|
||||
}
|
||||
if ((foreign instanceof NBTTagFloat)) {
|
||||
return new FloatTag(((NBTTagFloat)foreign).h());
|
||||
}
|
||||
if ((foreign instanceof NBTTagInt)) {
|
||||
return new IntTag(((NBTTagInt)foreign).d());
|
||||
}
|
||||
if ((foreign instanceof NBTTagIntArray)) {
|
||||
return new IntArrayTag(((NBTTagIntArray)foreign).c());
|
||||
}
|
||||
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).c());
|
||||
}
|
||||
if ((foreign instanceof NBTTagShort)) {
|
||||
return new ShortTag(((NBTTagShort)foreign).e());
|
||||
}
|
||||
if ((foreign instanceof NBTTagString)) {
|
||||
return new StringTag(((NBTTagString)foreign).a_());
|
||||
}
|
||||
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.d();
|
||||
|
||||
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<Tag> 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());
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.v1_9;
|
||||
|
||||
import java.util.Arrays;
|
||||
import net.minecraft.server.v1_9_R2.GenLayer;
|
||||
import net.minecraft.server.v1_9_R2.IntCache;
|
||||
|
||||
public class MutableGenLayer extends GenLayer {
|
||||
|
||||
private int biome;
|
||||
|
||||
public MutableGenLayer(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
public MutableGenLayer set(int biome) {
|
||||
this.biome = biome;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] a(int areaX, int areaY, int areaWidth, int areaHeight) {
|
||||
int[] biomes = IntCache.a(areaWidth * areaHeight);
|
||||
Arrays.fill(biomes, biome);
|
||||
return biomes;
|
||||
}
|
||||
}
|
@ -56,8 +56,6 @@ public interface IFawe {
|
||||
|
||||
public String getName(UUID uuid);
|
||||
|
||||
public Object getBlocksHubApi();
|
||||
|
||||
public default String getDebugInfo() {
|
||||
return "";
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
package com.boydti.fawe.logging;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.changeset.AbstractDelegateChangeSet;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import java.lang.reflect.Constructor;
|
||||
import org.primesoft.blockshub.IBlocksHubApi;
|
||||
import org.primesoft.blockshub.api.IPlayer;
|
||||
import org.primesoft.blockshub.api.IWorld;
|
||||
|
||||
public class LoggingChangeSet extends AbstractDelegateChangeSet {
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
public static FaweChangeSet wrap(FawePlayer player, FaweChangeSet parent) {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
api = (IBlocksHubApi) Fawe.imp().getBlocksHubApi();
|
||||
}
|
||||
if (api == null) {
|
||||
return parent;
|
||||
}
|
||||
return new LoggingChangeSet(player, parent);
|
||||
}
|
||||
|
||||
public static IBlocksHubApi api;
|
||||
|
||||
private final MutableVector loc;
|
||||
private final IPlayer player;
|
||||
private IWorld world;
|
||||
private final MutableBlockData oldBlock;
|
||||
private final MutableBlockData newBlock;
|
||||
|
||||
private LoggingChangeSet(FawePlayer player, FaweChangeSet parent) {
|
||||
super(parent);
|
||||
String world = player.getLocation().world;
|
||||
try {
|
||||
Class<?> classBukkitWorld = Class.forName("org.primesoft.blockshub.platform.bukkit.BukkitWorld");
|
||||
Class<?> classAsyncWorld = Class.forName("com.boydti.fawe.bukkit.wrapper.AsyncWorld");
|
||||
Object asyncWorld = classAsyncWorld.getConstructor(String.class, boolean.class).newInstance(world, false);
|
||||
Constructor<?> constructor = classBukkitWorld.getDeclaredConstructors()[0];
|
||||
constructor.setAccessible(true);
|
||||
this.world = (IWorld) constructor.newInstance(asyncWorld);
|
||||
} catch (Throwable ignore) {
|
||||
this.world = api.getWorld(world);
|
||||
}
|
||||
this.loc = new MutableVector();
|
||||
this.oldBlock = new MutableBlockData();
|
||||
this.newBlock = new MutableBlockData();
|
||||
this.player = api.getPlayer(player.getUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {
|
||||
// Mutable (avoids object creation)
|
||||
loc.x = x;
|
||||
loc.y = y;
|
||||
loc.z = z;
|
||||
oldBlock.id = FaweCache.getId(combinedId4DataFrom);
|
||||
oldBlock.data = FaweCache.getData(combinedId4DataFrom);
|
||||
newBlock.id = FaweCache.getId(combinedId4DataTo);
|
||||
newBlock.data = FaweCache.getData(combinedId4DataTo);
|
||||
// Log to BlocksHub and parent
|
||||
api.logBlock(loc, player, world, oldBlock, newBlock);
|
||||
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.boydti.fawe.logging;
|
||||
|
||||
import org.primesoft.blockshub.api.BlockData;
|
||||
|
||||
public class MutableBlockData extends BlockData {
|
||||
public int data;
|
||||
public int id;
|
||||
|
||||
public MutableBlockData() {
|
||||
super(0, 0);
|
||||
this.id = 0;
|
||||
this.data = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return id == 0;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.boydti.fawe.logging;
|
||||
|
||||
import org.primesoft.blockshub.api.Vector;
|
||||
|
||||
public class MutableVector extends Vector {
|
||||
|
||||
public double x, y, z;
|
||||
|
||||
public MutableVector() {
|
||||
super(0, 0, 0);
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Vector)) {
|
||||
return false;
|
||||
} else {
|
||||
Vector v = (Vector) obj;
|
||||
return this.x == v.getX() && this.z == v.getZ() && this.y == v.getY();
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
byte hash = 3;
|
||||
int hash1 = 59 * hash + (int) (Double.doubleToLongBits(this.x) ^ Double.doubleToLongBits(this.x) >>> 32);
|
||||
hash1 = 59 * hash1 + (int) (Double.doubleToLongBits(this.y) ^ Double.doubleToLongBits(this.y) >>> 32);
|
||||
hash1 = 59 * hash1 + (int) (Double.doubleToLongBits(this.z) ^ Double.doubleToLongBits(this.z) >>> 32);
|
||||
return hash1;
|
||||
}
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
package com.boydti.fawe.logging.rollback;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.database.DBHandler;
|
||||
import com.boydti.fawe.database.RollbackDatabase;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RollbackOptimizedHistory extends DiskStorageHistory {
|
||||
|
@ -27,12 +27,10 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.MappedFaweQueue;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAQueue;
|
||||
import com.boydti.fawe.jnbt.anvil.MCAWorld;
|
||||
import com.boydti.fawe.logging.LoggingChangeSet;
|
||||
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
||||
import com.boydti.fawe.object.*;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.changeset.*;
|
||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||
import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
|
||||
import com.boydti.fawe.object.collection.LocalBlockVectorSet;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
@ -277,13 +275,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
if (this.limit.SPEED_REDUCTION > 0) {
|
||||
this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
|
||||
}
|
||||
if (changeSet instanceof NullChangeSet && Fawe.imp().getBlocksHubApi() != null && player != null) {
|
||||
changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
}
|
||||
if (!(changeSet instanceof NullChangeSet)) {
|
||||
if (!(changeSet instanceof LoggingChangeSet) && player != null && Fawe.imp().getBlocksHubApi() != null) {
|
||||
changeSet = LoggingChangeSet.wrap(player, changeSet);
|
||||
}
|
||||
if (this.blockBag != null) {
|
||||
changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.logging.LoggingChangeSet;
|
||||
import com.boydti.fawe.object.*;
|
||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
@ -199,9 +198,6 @@ public class Sniper {
|
||||
MaskedFaweQueue maskQueue = new MaskedFaweQueue(baseQueue, mask);
|
||||
com.sk89q.worldedit.world.World worldEditWorld = fp.getWorld();
|
||||
FaweChangeSet changeSet = FaweChangeSet.getDefaultChangeSet(worldEditWorld, fp.getUUID());
|
||||
if (Fawe.imp().getBlocksHubApi() != null) {
|
||||
changeSet = LoggingChangeSet.wrap(fp, changeSet);
|
||||
}
|
||||
FaweQueue changeQueue;
|
||||
if (Settings.IMP.HISTORY.COMBINE_STAGES) {
|
||||
changeQueue = maskQueue;
|
||||
|
Loading…
Reference in New Issue
Block a user