Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 08:02:50 +02:00
some adapter refactoring
Dieser Commit ist enthalten in:
Ursprung
751765cc01
Commit
1b07846746
@ -0,0 +1,53 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.IBlocks;
|
||||||
|
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class MapChunkUtil<T> {
|
||||||
|
protected Field fieldX;
|
||||||
|
protected Field fieldZ;
|
||||||
|
protected Field fieldHeightMap;
|
||||||
|
protected Field fieldBitMask;
|
||||||
|
protected Field fieldChunkData;
|
||||||
|
protected Field fieldBlockEntities;
|
||||||
|
protected Field fieldFull;
|
||||||
|
|
||||||
|
public abstract T createPacket();
|
||||||
|
|
||||||
|
public T create(BukkitImplAdapter adapter, ChunkPacket packet) {
|
||||||
|
try {
|
||||||
|
T nmsPacket;
|
||||||
|
int bitMask = packet.getChunk().getBitMask();
|
||||||
|
nmsPacket = createPacket();
|
||||||
|
fieldX.setInt(nmsPacket, packet.getChunkX());
|
||||||
|
fieldZ.setInt(nmsPacket, packet.getChunkZ());
|
||||||
|
fieldBitMask.set(nmsPacket, packet.getChunk().getBitMask());
|
||||||
|
Object heightMap = adapter.fromNative(packet.getHeightMap());
|
||||||
|
fieldHeightMap.set(nmsPacket, heightMap);
|
||||||
|
|
||||||
|
fieldChunkData.set(nmsPacket, packet.getSectionBytes());
|
||||||
|
|
||||||
|
Map<BlockVector3, CompoundTag> tiles = packet.getChunk().getTiles();
|
||||||
|
ArrayList<Object> nmsTiles = new ArrayList<>(tiles.size());
|
||||||
|
for (Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||||
|
Object nmsTag = adapter.fromNative(entry.getValue());
|
||||||
|
nmsTiles.add(nmsTag);
|
||||||
|
}
|
||||||
|
fieldBlockEntities.set(nmsPacket, nmsTiles);
|
||||||
|
fieldFull.set(nmsPacket, packet.isFull());
|
||||||
|
return nmsPacket;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.boydti.fawe.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.world.block.BlockID;
|
||||||
|
import net.minecraft.server.v1_14_R1.ChunkSection;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class NMSAdapter<T> {
|
||||||
|
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, char[] set) {
|
||||||
|
int air = 0;
|
||||||
|
int num_palette = 0;
|
||||||
|
for (int i = 0; i < 4096; i++) {
|
||||||
|
char ordinal = set[i];
|
||||||
|
switch (ordinal) {
|
||||||
|
case 0:
|
||||||
|
ordinal = BlockID.AIR;
|
||||||
|
case BlockID.AIR:
|
||||||
|
case BlockID.CAVE_AIR:
|
||||||
|
case BlockID.VOID_AIR:
|
||||||
|
air++;
|
||||||
|
}
|
||||||
|
int palette = blockToPalette[ordinal];
|
||||||
|
if (palette == Integer.MAX_VALUE) {
|
||||||
|
blockToPalette[ordinal] = palette = num_palette;
|
||||||
|
paletteToBlock[num_palette] = ordinal;
|
||||||
|
num_palette++;
|
||||||
|
}
|
||||||
|
blocksCopy[i] = palette;
|
||||||
|
}
|
||||||
|
num_palette_buffer[0] = num_palette;
|
||||||
|
return air;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set) {
|
||||||
|
int air = 0;
|
||||||
|
int num_palette = 0;
|
||||||
|
int i = 0;
|
||||||
|
outer:
|
||||||
|
for (; i < 4096; i++) {
|
||||||
|
char ordinal = set[i];
|
||||||
|
switch (ordinal) {
|
||||||
|
case BlockID.__RESERVED__:
|
||||||
|
break outer;
|
||||||
|
case BlockID.AIR:
|
||||||
|
case BlockID.CAVE_AIR:
|
||||||
|
case BlockID.VOID_AIR:
|
||||||
|
air++;
|
||||||
|
}
|
||||||
|
int palette = blockToPalette[ordinal];
|
||||||
|
if (palette == Integer.MAX_VALUE) {
|
||||||
|
blockToPalette[ordinal] = palette = num_palette;
|
||||||
|
paletteToBlock[num_palette] = ordinal;
|
||||||
|
num_palette++;
|
||||||
|
}
|
||||||
|
blocksCopy[i] = palette;
|
||||||
|
}
|
||||||
|
if (i != 4096) {
|
||||||
|
char[] getArr = get.apply(layer);
|
||||||
|
for (; i < 4096; i++) {
|
||||||
|
char ordinal = set[i];
|
||||||
|
switch (ordinal) {
|
||||||
|
case BlockID.__RESERVED__:
|
||||||
|
ordinal = getArr[i];
|
||||||
|
switch (ordinal) {
|
||||||
|
case BlockID.__RESERVED__:
|
||||||
|
ordinal = BlockID.AIR;
|
||||||
|
case BlockID.AIR:
|
||||||
|
case BlockID.CAVE_AIR:
|
||||||
|
case BlockID.VOID_AIR:
|
||||||
|
air++;
|
||||||
|
default:
|
||||||
|
set[i] = ordinal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BlockID.AIR:
|
||||||
|
case BlockID.CAVE_AIR:
|
||||||
|
case BlockID.VOID_AIR:
|
||||||
|
air++;
|
||||||
|
}
|
||||||
|
int palette = blockToPalette[ordinal];
|
||||||
|
if (palette == Integer.MAX_VALUE) {
|
||||||
|
blockToPalette[ordinal] = palette = num_palette;
|
||||||
|
paletteToBlock[num_palette] = ordinal;
|
||||||
|
num_palette++;
|
||||||
|
}
|
||||||
|
blocksCopy[i] = palette;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
num_palette_buffer[0] = num_palette;
|
||||||
|
return air;
|
||||||
|
}
|
||||||
|
}
|
@ -2,15 +2,13 @@ package com.boydti.fawe.bukkit.adapter.mc1_14;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
import com.boydti.fawe.bukkit.adapter.NMSAdapter;
|
||||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.collection.BitArray4096;
|
import com.boydti.fawe.object.collection.BitArray4096;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.world.block.BlockID;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.jpountz.util.UnsafeUtils;
|
import net.jpountz.util.UnsafeUtils;
|
||||||
@ -24,7 +22,6 @@ import net.minecraft.server.v1_14_R1.DataPaletteBlock;
|
|||||||
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
|
||||||
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
|
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
|
||||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
||||||
@ -35,16 +32,13 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public final class BukkitAdapter_1_14 {
|
|
||||||
|
|
||||||
|
public final class BukkitAdapter_1_14 extends NMSAdapter {
|
||||||
/*
|
/*
|
||||||
NMS fields
|
NMS fields
|
||||||
*/
|
*/
|
||||||
public final static Field fieldBits;
|
public final static Field fieldBits;
|
||||||
public final static Field fieldPalette;
|
public final static Field fieldPalette;
|
||||||
public final static Field fieldSize;
|
public final static Field fieldSize;
|
||||||
@ -152,10 +146,6 @@ public final class BukkitAdapter_1_14 {
|
|||||||
try {
|
try {
|
||||||
CraftChunk chunk = (CraftChunk) future.get();
|
CraftChunk chunk = (CraftChunk) future.get();
|
||||||
return chunk.getHandle();
|
return chunk.getHandle();
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -178,34 +168,25 @@ public final class BukkitAdapter_1_14 {
|
|||||||
if (playerChunk == null) {
|
if (playerChunk == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ChunkSection[] sections = nmsChunk.getSections();
|
|
||||||
// for (int layer = 0; layer < 16; layer++) {
|
|
||||||
// if (sections[layer] == null && (mask & (1 << layer)) != 0) {
|
|
||||||
// sections[layer] = new ChunkSection(layer << 4);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (playerChunk.hasBeenLoaded()) {
|
if (playerChunk.hasBeenLoaded()) {
|
||||||
TaskManager.IMP.sync(new Supplier<Object>() {
|
TaskManager.IMP.sync(() -> {
|
||||||
@Override
|
try {
|
||||||
public Object get() {
|
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
||||||
try {
|
if (dirtyBits == 0) {
|
||||||
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
|
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
||||||
if (dirtyBits == 0) {
|
|
||||||
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
|
|
||||||
}
|
|
||||||
if (mask == 0) {
|
|
||||||
dirtyBits = 65535;
|
|
||||||
} else {
|
|
||||||
dirtyBits |= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldDirtyBits.set(playerChunk, dirtyBits);
|
|
||||||
fieldDirtyCount.set(playerChunk, 64);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return null;
|
if (mask == 0) {
|
||||||
|
dirtyBits = 65535;
|
||||||
|
} else {
|
||||||
|
dirtyBits |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldDirtyBits.set(playerChunk, dirtyBits);
|
||||||
|
fieldDirtyCount.set(playerChunk, 64);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -219,90 +200,6 @@ public final class BukkitAdapter_1_14 {
|
|||||||
return newChunkSection(layer, null, blocks);
|
return newChunkSection(layer, null, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set) {
|
|
||||||
int air = 0;
|
|
||||||
int num_palette = 0;
|
|
||||||
int i = 0;
|
|
||||||
outer:
|
|
||||||
for (; i < 4096; i++) {
|
|
||||||
char ordinal = set[i];
|
|
||||||
switch (ordinal) {
|
|
||||||
case BlockID.__RESERVED__:
|
|
||||||
break outer;
|
|
||||||
case BlockID.AIR:
|
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
|
||||||
}
|
|
||||||
int palette = blockToPalette[ordinal];
|
|
||||||
if (palette == Integer.MAX_VALUE) {
|
|
||||||
blockToPalette[ordinal] = palette = num_palette;
|
|
||||||
paletteToBlock[num_palette] = ordinal;
|
|
||||||
num_palette++;
|
|
||||||
}
|
|
||||||
blocksCopy[i] = palette;
|
|
||||||
}
|
|
||||||
if (i != 4096) {
|
|
||||||
char[] getArr = get.apply(layer);
|
|
||||||
for (; i < 4096; i++) {
|
|
||||||
char ordinal = set[i];
|
|
||||||
switch (ordinal) {
|
|
||||||
case BlockID.__RESERVED__:
|
|
||||||
ordinal = getArr[i];
|
|
||||||
switch (ordinal) {
|
|
||||||
case BlockID.__RESERVED__:
|
|
||||||
ordinal = BlockID.AIR;
|
|
||||||
case BlockID.AIR:
|
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
|
||||||
default:
|
|
||||||
set[i] = ordinal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BlockID.AIR:
|
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
|
||||||
}
|
|
||||||
int palette = blockToPalette[ordinal];
|
|
||||||
if (palette == Integer.MAX_VALUE) {
|
|
||||||
blockToPalette[ordinal] = palette = num_palette;
|
|
||||||
paletteToBlock[num_palette] = ordinal;
|
|
||||||
num_palette++;
|
|
||||||
}
|
|
||||||
blocksCopy[i] = palette;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
num_palette_buffer[0] = num_palette;
|
|
||||||
return air;
|
|
||||||
}
|
|
||||||
private static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, char[] set) {
|
|
||||||
int air = 0;
|
|
||||||
int num_palette = 0;
|
|
||||||
for (int i = 0; i < 4096; i++) {
|
|
||||||
char ordinal = set[i];
|
|
||||||
switch (ordinal) {
|
|
||||||
case 0:
|
|
||||||
ordinal = BlockID.AIR;
|
|
||||||
case BlockID.AIR:
|
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
|
||||||
}
|
|
||||||
int palette = blockToPalette[ordinal];
|
|
||||||
if (palette == Integer.MAX_VALUE) {
|
|
||||||
blockToPalette[ordinal] = palette = num_palette;
|
|
||||||
paletteToBlock[num_palette] = ordinal;
|
|
||||||
num_palette++;
|
|
||||||
}
|
|
||||||
blocksCopy[i] = palette;
|
|
||||||
}
|
|
||||||
num_palette_buffer[0] = num_palette;
|
|
||||||
return air;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
|
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
return newChunkSection(layer);
|
return newChunkSection(layer);
|
||||||
|
@ -39,7 +39,6 @@ import java.util.concurrent.Future;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import net.minecraft.server.v1_14_R1.BiomeBase;
|
import net.minecraft.server.v1_14_R1.BiomeBase;
|
||||||
import net.minecraft.server.v1_14_R1.Block;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockPosition;
|
import net.minecraft.server.v1_14_R1.BlockPosition;
|
||||||
import net.minecraft.server.v1_14_R1.Chunk;
|
import net.minecraft.server.v1_14_R1.Chunk;
|
||||||
import net.minecraft.server.v1_14_R1.ChunkSection;
|
import net.minecraft.server.v1_14_R1.ChunkSection;
|
||||||
@ -521,7 +520,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
lock.setModified(false);
|
lock.setModified(false);
|
||||||
// Efficiently convert ChunkSection to raw data
|
// Efficiently convert ChunkSection to raw data
|
||||||
try {
|
try {
|
||||||
Spigot_v1_14_R4 adapter = ((Spigot_v1_14_R4) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
FAWE_Spigot_v1_14_R4 adapter = ((FAWE_Spigot_v1_14_R4) WorldEditPlugin.getInstance().getBukkitImplAdapter());
|
||||||
|
|
||||||
final DataPaletteBlock<IBlockData> blocks = section.getBlocks();
|
final DataPaletteBlock<IBlockData> blocks = section.getBlocks();
|
||||||
final DataBits bits = (DataBits) BukkitAdapter_1_14.fieldBits.get(blocks);
|
final DataBits bits = (DataBits) BukkitAdapter_1_14.fieldBits.get(blocks);
|
||||||
@ -599,7 +598,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final char ordinal(IBlockData ibd, Spigot_v1_14_R4 adapter) {
|
private final char ordinal(IBlockData ibd, FAWE_Spigot_v1_14_R4 adapter) {
|
||||||
if (ibd == null) {
|
if (ibd == null) {
|
||||||
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
||||||
} else {
|
} else {
|
||||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -0,0 +1,346 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
|
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
|
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.Spigot_v1_14_R4;
|
||||||
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.entity.LazyBaseEntity;
|
||||||
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
|
import net.minecraft.server.v1_14_R1.Block;
|
||||||
|
import net.minecraft.server.v1_14_R1.BlockPosition;
|
||||||
|
import net.minecraft.server.v1_14_R1.Chunk;
|
||||||
|
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
|
||||||
|
import net.minecraft.server.v1_14_R1.ChunkSection;
|
||||||
|
import net.minecraft.server.v1_14_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_14_R1.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_14_R1.EntityTypes;
|
||||||
|
import net.minecraft.server.v1_14_R1.IBlockData;
|
||||||
|
import net.minecraft.server.v1_14_R1.IRegistry;
|
||||||
|
import net.minecraft.server.v1_14_R1.ItemStack;
|
||||||
|
import net.minecraft.server.v1_14_R1.MinecraftKey;
|
||||||
|
import net.minecraft.server.v1_14_R1.NBTBase;
|
||||||
|
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_14_R1.NBTTagInt;
|
||||||
|
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
||||||
|
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
||||||
|
import net.minecraft.server.v1_14_R1.TileEntity;
|
||||||
|
import net.minecraft.server.v1_14_R1.World;
|
||||||
|
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
|
||||||
|
private final BukkitImplAdapter<NBTBase> parent;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Code that may break between versions of Minecraft
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public FAWE_Spigot_v1_14_R4() throws NoSuchFieldException, NoSuchMethodException {
|
||||||
|
this.parent = new Spigot_v1_14_R4();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BukkitImplAdapter<NBTBase> getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[] idbToStateOrdinal;
|
||||||
|
|
||||||
|
private synchronized boolean init() {
|
||||||
|
if (idbToStateOrdinal != null) return false;
|
||||||
|
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
||||||
|
for (int i = 0; i < idbToStateOrdinal.length; i++) {
|
||||||
|
BlockState state = BlockTypesCache.states[i];
|
||||||
|
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
||||||
|
int id = Block.REGISTRY_ID.getId(material.getState());
|
||||||
|
idbToStateOrdinal[id] = state.getOrdinalChar();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockMaterial getMaterial(BlockType blockType) {
|
||||||
|
return new BlockMaterial_1_14(getBlock(blockType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockMaterial getMaterial(BlockState state) {
|
||||||
|
IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState();
|
||||||
|
return new BlockMaterial_1_14(bs.getBlock(), bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(BlockType blockType) {
|
||||||
|
return IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public BaseBlock getBlock(Location location) {
|
||||||
|
checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
if (state.getBlockType().getMaterial().hasContainer()) {
|
||||||
|
//Read the NBT data
|
||||||
|
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
||||||
|
if (te != null) {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
te.save(tag); // readTileEntityIntoTag
|
||||||
|
return state.toBaseBlock((CompoundTag) toNative(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.toBaseBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight) {
|
||||||
|
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
||||||
|
CraftChunk craftChunk = (CraftChunk) chunk;
|
||||||
|
Chunk nmsChunk = craftChunk.getHandle();
|
||||||
|
World nmsWorld = nmsChunk.getWorld();
|
||||||
|
|
||||||
|
IBlockData blockData = ((BlockMaterial_1_14) state.getMaterial()).getState();
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
int y4 = y >> 4;
|
||||||
|
ChunkSection section = sections[y4];
|
||||||
|
|
||||||
|
IBlockData existing;
|
||||||
|
if (section == null) {
|
||||||
|
existing = ((BlockMaterial_1_14) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
|
||||||
|
} else {
|
||||||
|
existing = section.getType(x & 15, y & 15, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPosition pos = new BlockPosition(x, y, z);
|
||||||
|
|
||||||
|
nmsChunk.removeTileEntity(pos); // Force delete the old tile entity
|
||||||
|
|
||||||
|
CompoundTag nativeTag = state instanceof BaseBlock ? ((BaseBlock)state).getNbtData() : null;
|
||||||
|
if (nativeTag != null || existing instanceof TileEntityBlock) {
|
||||||
|
nmsWorld.setTypeAndData(pos, blockData, 0);
|
||||||
|
// remove tile
|
||||||
|
if (nativeTag != null) {
|
||||||
|
// We will assume that the tile entity was created for us,
|
||||||
|
// though we do not do this on the Forge version
|
||||||
|
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
||||||
|
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));
|
||||||
|
tileEntity.load(tag); // readTagIntoTileEntity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (existing == blockData) return true;
|
||||||
|
if (section == null) {
|
||||||
|
if (blockData.isAir()) return true;
|
||||||
|
sections[y4] = section = new ChunkSection(y4 << 4);
|
||||||
|
}
|
||||||
|
nmsChunk.setType(pos = new BlockPosition(x, y, z), blockData, false);
|
||||||
|
}
|
||||||
|
if (update) {
|
||||||
|
nmsWorld.getMinecraftWorld().notify(pos, existing, blockData, 0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getEntityId(Entity entity) {
|
||||||
|
MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType());
|
||||||
|
return minecraftkey == null ? null : minecraftkey.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readEntityIntoTag(Entity entity, NBTTagCompound tag) {
|
||||||
|
entity.save(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
|
||||||
|
checkNotNull(entity);
|
||||||
|
|
||||||
|
CraftEntity craftEntity = ((CraftEntity) entity);
|
||||||
|
Entity mcEntity = craftEntity.getHandle();
|
||||||
|
|
||||||
|
String id = getEntityId(mcEntity);
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
|
Supplier<CompoundTag> saveTag = () -> {
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
readEntityIntoTag(mcEntity, tag);
|
||||||
|
return (CompoundTag) toNative(tag);
|
||||||
|
};
|
||||||
|
return new LazyBaseEntity(type, saveTag);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
||||||
|
if (material.isAir()) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
IBlockData mcState = material.getCraftBlockData().getState();
|
||||||
|
return OptionalInt.of(Block.REGISTRY_ID.getId(mcState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState adapt(BlockData blockData) {
|
||||||
|
CraftBlockData cbd = ((CraftBlockData) blockData);
|
||||||
|
IBlockData ibd = cbd.getState();
|
||||||
|
return adapt(ibd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockState adapt(IBlockData ibd) {
|
||||||
|
return BlockTypesCache.states[adaptToInt(ibd)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int adaptToInt(IBlockData ibd) {
|
||||||
|
try {
|
||||||
|
int id = Block.REGISTRY_ID.getId(ibd);
|
||||||
|
return idbToStateOrdinal[id];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return adaptToInt(ibd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public char adaptToChar(IBlockData ibd) {
|
||||||
|
try {
|
||||||
|
int id = Block.REGISTRY_ID.getId(ibd);
|
||||||
|
return idbToStateOrdinal[id];
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
init();
|
||||||
|
return adaptToChar(ibd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData adapt(BlockStateHolder state) {
|
||||||
|
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
||||||
|
return material.getCraftBlockData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||||
|
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapChunkUtil_1_14 mapUtil = new MapChunkUtil_1_14();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
|
||||||
|
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
PlayerChunk map = BukkitAdapter_1_14.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ());
|
||||||
|
if (map != null && map.hasBeenLoaded()) {
|
||||||
|
boolean flag = false;
|
||||||
|
PlayerChunk.d players = map.players;
|
||||||
|
Stream<EntityPlayer> stream = players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag);
|
||||||
|
|
||||||
|
EntityPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle();
|
||||||
|
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
|
||||||
|
.forEach(entityPlayer -> {
|
||||||
|
synchronized (packet) {
|
||||||
|
PacketPlayOutMapChunk nmsPacket = (PacketPlayOutMapChunk) packet.getNativePacket();
|
||||||
|
if (nmsPacket == null) {
|
||||||
|
nmsPacket = mapUtil.create( this, packet);
|
||||||
|
packet.setNativePacket(nmsPacket);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
FaweCache.IMP.CHUNK_FLAG.get().set(true);
|
||||||
|
entityPlayer.playerConnection.sendPacket(nmsPacket);
|
||||||
|
} finally {
|
||||||
|
FaweCache.IMP.CHUNK_FLAG.get().set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||||
|
Map<String, ? extends Property<?>> result = getParent().getProperties(blockType);
|
||||||
|
System.out.println("Result " + result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
|
||||||
|
ItemStack stack = new ItemStack(IRegistry.ITEM.get(MinecraftKey.a(item.getType().getId())), item.getAmount());
|
||||||
|
stack.setTag(((NBTTagCompound) fromNative(item.getNbtData())));
|
||||||
|
return CraftItemStack.asCraftMirror(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||||
|
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
|
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
||||||
|
weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag())));
|
||||||
|
return weStack;
|
||||||
|
}
|
||||||
|
}
|
@ -1,80 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import net.minecraft.server.v1_14_R1.DamageSource;
|
|
||||||
import net.minecraft.server.v1_14_R1.DimensionManager;
|
|
||||||
import net.minecraft.server.v1_14_R1.Entity;
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityPlayer;
|
|
||||||
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
|
|
||||||
import net.minecraft.server.v1_14_R1.ITileInventory;
|
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayInSettings;
|
|
||||||
import net.minecraft.server.v1_14_R1.PlayerInteractManager;
|
|
||||||
import net.minecraft.server.v1_14_R1.Statistic;
|
|
||||||
import net.minecraft.server.v1_14_R1.Vec3D;
|
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
class FakePlayer_v1_14_R4 extends EntityPlayer {
|
|
||||||
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
|
|
||||||
|
|
||||||
FakePlayer_v1_14_R4(WorldServer world) {
|
|
||||||
super(world.getMinecraftServer(), world, FAKE_WORLDEDIT_PROFILE, new PlayerInteractManager(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vec3D bP() {
|
|
||||||
return new Vec3D(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void die(DamageSource damagesource) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Entity a(DimensionManager dimensionmanager, TeleportCause cause) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OptionalInt openContainer(@Nullable ITileInventory itileinventory) {
|
|
||||||
return OptionalInt.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void a(PacketPlayInSettings packetplayinsettings) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void a(IChatBaseComponent ichatbasecomponent, boolean flag) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void a(Statistic<?> statistic, int i) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void a(Statistic<?> statistic) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isInvulnerable(DamageSource damagesource) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean p(boolean flag) { // canEat, search for foodData usage
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,129 +1,28 @@
|
|||||||
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.bukkit.adapter.MapChunkUtil;
|
||||||
import com.boydti.fawe.beta.IBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
|
||||||
import com.boydti.fawe.object.FaweInputStream;
|
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
|
||||||
import com.boydti.fawe.util.TaskManager;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import net.minecraft.server.v1_14_R1.Chunk;
|
|
||||||
import net.minecraft.server.v1_14_R1.ChunkSection;
|
|
||||||
import net.minecraft.server.v1_14_R1.IRegistry;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTBase;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.block.Biome;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
public class MapChunkUtil_1_14 extends MapChunkUtil<PacketPlayOutMapChunk> {
|
||||||
import java.io.ByteArrayOutputStream;
|
public MapChunkUtil_1_14() throws NoSuchFieldException {
|
||||||
import java.io.DataOutputStream;
|
fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a");
|
||||||
import java.io.IOException;
|
fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b");
|
||||||
import java.lang.reflect.Field;
|
fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c");
|
||||||
import java.nio.ByteBuffer;
|
fieldHeightMap = PacketPlayOutMapChunk.class.getDeclaredField("d");
|
||||||
import java.util.ArrayList;
|
fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("e");
|
||||||
import java.util.HashMap;
|
fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("f");
|
||||||
import java.util.Map;
|
fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("g");
|
||||||
import java.util.concurrent.Callable;
|
fieldX.setAccessible(true);
|
||||||
import java.util.function.Supplier;
|
fieldZ.setAccessible(true);
|
||||||
|
fieldBitMask.setAccessible(true);
|
||||||
public class MapChunkUtil_1_14 {
|
fieldHeightMap.setAccessible(true);
|
||||||
private static final Field fieldX;
|
fieldChunkData.setAccessible(true);
|
||||||
|
fieldBlockEntities.setAccessible(true);
|
||||||
private static final Field fieldZ;
|
fieldFull.setAccessible(true);
|
||||||
|
|
||||||
private static final Field fieldHeightMap;
|
|
||||||
|
|
||||||
private static final Field fieldBitMask;
|
|
||||||
|
|
||||||
private static final Field fieldChunkData;
|
|
||||||
|
|
||||||
private static final Field fieldBlockEntities;
|
|
||||||
|
|
||||||
private static final Field fieldFull;
|
|
||||||
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a");
|
|
||||||
fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b");
|
|
||||||
fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c");
|
|
||||||
fieldHeightMap = PacketPlayOutMapChunk.class.getDeclaredField("d");
|
|
||||||
fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("e");
|
|
||||||
fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("f");
|
|
||||||
fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("g");
|
|
||||||
|
|
||||||
fieldX.setAccessible(true);
|
|
||||||
fieldZ.setAccessible(true);
|
|
||||||
fieldBitMask.setAccessible(true);
|
|
||||||
fieldHeightMap.setAccessible(true);
|
|
||||||
fieldChunkData.setAccessible(true);
|
|
||||||
fieldBlockEntities.setAccessible(true);
|
|
||||||
fieldFull.setAccessible(true);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PacketPlayOutMapChunk create(WorldServer world, BukkitImplAdapter<NBTBase> adapter, ChunkPacket packet) {
|
|
||||||
IBlocks chunk = packet.getChunk();
|
|
||||||
try {
|
|
||||||
PacketPlayOutMapChunk nmsPacket;
|
|
||||||
int bitMask = packet.getChunk().getBitMask();
|
|
||||||
if (bitMask == 0) { // TODO remove once sending tiles/entities is fixed
|
|
||||||
nmsPacket = Fawe.get().getQueueHandler().sync((Callable<PacketPlayOutMapChunk>) () -> {
|
|
||||||
Chunk nmsChunk = world.getChunkAt(packet.getChunkX(), packet.getChunkZ());
|
|
||||||
PacketPlayOutMapChunk nmsPacket1 = new PacketPlayOutMapChunk(nmsChunk, 65535);
|
|
||||||
byte[] data = (byte[]) fieldChunkData.get(nmsPacket1);
|
|
||||||
int len = data.length;
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(data, len - 256 * 4, 256 * 4);
|
@Override
|
||||||
for (int z = 0; z < 16; z++) {
|
public PacketPlayOutMapChunk createPacket() {
|
||||||
for (int x = 0; x < 16; x++) {
|
return new PacketPlayOutMapChunk();
|
||||||
BiomeType biome = chunk.getBiomeType(x, z);
|
|
||||||
if (biome != null) {
|
|
||||||
buffer.putInt(biome.getLegacyId());
|
|
||||||
} else {
|
|
||||||
buffer.getInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nmsPacket1;
|
|
||||||
}).get();
|
|
||||||
} else {
|
|
||||||
nmsPacket = new PacketPlayOutMapChunk();
|
|
||||||
fieldX.setInt(nmsPacket, packet.getChunkX());
|
|
||||||
fieldZ.setInt(nmsPacket, packet.getChunkZ());
|
|
||||||
fieldBitMask.set(nmsPacket, packet.getChunk().getBitMask());
|
|
||||||
NBTBase heightMap = adapter.fromNative(/* packet.getHeightMap() */ new CompoundTag(new HashMap<>()));
|
|
||||||
fieldHeightMap.set(nmsPacket, heightMap);
|
|
||||||
|
|
||||||
fieldChunkData.set(nmsPacket, packet.getSectionBytes());
|
|
||||||
|
|
||||||
Map<BlockVector3, CompoundTag> tiles = packet.getChunk().getTiles();
|
|
||||||
ArrayList<NBTTagCompound> nmsTiles = new ArrayList<>(tiles.size());
|
|
||||||
for (Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
|
||||||
NBTBase nmsTag = adapter.fromNative(entry.getValue());
|
|
||||||
nmsTiles.add((NBTTagCompound) nmsTag);
|
|
||||||
}
|
|
||||||
fieldBlockEntities.set(nmsPacket, nmsTiles);
|
|
||||||
fieldFull.set(nmsPacket, packet.isFull());
|
|
||||||
}
|
|
||||||
return nmsPacket;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,757 +0,0 @@
|
|||||||
/*
|
|
||||||
* WorldEdit, a Minecraft world manipulation toolkit
|
|
||||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
|
||||||
* Copyright (C) WorldEdit team and contributors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as published by the
|
|
||||||
* Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.boydti.fawe.bukkit.adapter.mc1_14;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
|
||||||
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
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.LongArrayTag;
|
|
||||||
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.BaseItem;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
|
||||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
|
||||||
import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
|
||||||
import com.sk89q.worldedit.entity.LazyBaseEntity;
|
|
||||||
import com.sk89q.worldedit.internal.Constants;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.registry.state.BooleanProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.EnumProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
|
||||||
import com.sk89q.worldedit.util.Direction;
|
|
||||||
import com.sk89q.worldedit.world.DataFixer;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
|
||||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.server.v1_14_R1.Block;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockPosition;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockStateBoolean;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockStateDirection;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockStateEnum;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockStateInteger;
|
|
||||||
import net.minecraft.server.v1_14_R1.BlockStateList;
|
|
||||||
import net.minecraft.server.v1_14_R1.Chunk;
|
|
||||||
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
|
|
||||||
import net.minecraft.server.v1_14_R1.ChunkSection;
|
|
||||||
import net.minecraft.server.v1_14_R1.Entity;
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityPlayer;
|
|
||||||
import net.minecraft.server.v1_14_R1.EntityTypes;
|
|
||||||
import net.minecraft.server.v1_14_R1.EnumDirection;
|
|
||||||
import net.minecraft.server.v1_14_R1.EnumHand;
|
|
||||||
import net.minecraft.server.v1_14_R1.EnumInteractionResult;
|
|
||||||
import net.minecraft.server.v1_14_R1.IBlockData;
|
|
||||||
import net.minecraft.server.v1_14_R1.IBlockState;
|
|
||||||
import net.minecraft.server.v1_14_R1.INamable;
|
|
||||||
import net.minecraft.server.v1_14_R1.IRegistry;
|
|
||||||
import net.minecraft.server.v1_14_R1.ItemActionContext;
|
|
||||||
import net.minecraft.server.v1_14_R1.ItemStack;
|
|
||||||
import net.minecraft.server.v1_14_R1.MinecraftKey;
|
|
||||||
import net.minecraft.server.v1_14_R1.MovingObjectPositionBlock;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTBase;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagByte;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagByteArray;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagCompound;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagDouble;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagEnd;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagFloat;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagInt;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagIntArray;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagList;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagLong;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagLongArray;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagShort;
|
|
||||||
import net.minecraft.server.v1_14_R1.NBTTagString;
|
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityStatus;
|
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
|
|
||||||
import net.minecraft.server.v1_14_R1.PacketPlayOutTileEntityData;
|
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunk;
|
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
|
|
||||||
import net.minecraft.server.v1_14_R1.TileEntity;
|
|
||||||
import net.minecraft.server.v1_14_R1.Vec3D;
|
|
||||||
import net.minecraft.server.v1_14_R1.World;
|
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.craftbukkit.v1_14_R1.util.CraftMagicNumbers;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public final class Spigot_v1_14_R4 extends CachedBukkitAdapter implements BukkitImplAdapter<NBTBase>{
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
|
||||||
|
|
||||||
private final Field nbtListTagListField;
|
|
||||||
private final Method nbtCreateTagMethod;
|
|
||||||
|
|
||||||
static {
|
|
||||||
// A simple test
|
|
||||||
if (!Bukkit.getServer().getClass().getName().endsWith("DummyServer")) CraftServer.class.cast(Bukkit.getServer());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Code that may break between versions of Minecraft
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public Spigot_v1_14_R4() throws NoSuchFieldException, NoSuchMethodException {
|
|
||||||
// The list of tags on an NBTTagList
|
|
||||||
nbtListTagListField = NBTTagList.class.getDeclaredField("list");
|
|
||||||
nbtListTagListField.setAccessible(true);
|
|
||||||
|
|
||||||
// The method to create an NBTBase tag given its type ID
|
|
||||||
nbtCreateTagMethod = NBTBase.class.getDeclaredMethod("createTag", byte.class);
|
|
||||||
nbtCreateTagMethod.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public char[] idbToStateOrdinal;
|
|
||||||
|
|
||||||
private synchronized boolean init() {
|
|
||||||
if (idbToStateOrdinal != null) return false;
|
|
||||||
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
|
|
||||||
for (int i = 0; i < idbToStateOrdinal.length; i++) {
|
|
||||||
BlockState state = BlockTypesCache.states[i];
|
|
||||||
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
|
||||||
int id = Block.REGISTRY_ID.getId(material.getState());
|
|
||||||
idbToStateOrdinal[id] = state.getOrdinalChar();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the given NBT data into the given tile entity.
|
|
||||||
*
|
|
||||||
* @param tileEntity the tile entity
|
|
||||||
* @param tag the tag
|
|
||||||
*/
|
|
||||||
private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity) {
|
|
||||||
try {
|
|
||||||
tileEntity.load(tag);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
//Fawe.debug("Invalid tag " + tag + " | " + tileEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the tile entity's NBT data to the given tag.
|
|
||||||
*
|
|
||||||
* @param tileEntity the tile entity
|
|
||||||
* @param tag the tag
|
|
||||||
*/
|
|
||||||
private static void readTileEntityIntoTag(TileEntity tileEntity, NBTTagCompound tag) {
|
|
||||||
tileEntity.save(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the ID string of the given entity.
|
|
||||||
*
|
|
||||||
* @param entity the entity
|
|
||||||
* @return the entity ID or null if one is not known
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
private static String getEntityId(Entity entity) {
|
|
||||||
MinecraftKey minecraftkey = EntityTypes.getName(entity.getBukkitEntity().getHandle().getEntityType());
|
|
||||||
return minecraftkey == null ? null : minecraftkey.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an entity using the given entity ID.
|
|
||||||
*
|
|
||||||
* @param id the entity ID
|
|
||||||
* @param world the world
|
|
||||||
* @return an entity or null
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
private static Entity createEntityFromId(String id, World world) {
|
|
||||||
return EntityTypes.a(id).get().a(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the given NBT data into the given entity.
|
|
||||||
*
|
|
||||||
* @param entity the entity
|
|
||||||
* @param tag the tag
|
|
||||||
*/
|
|
||||||
private static void readTagIntoEntity(NBTTagCompound tag, Entity entity) {
|
|
||||||
entity.f(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the entity's NBT data to the given tag.
|
|
||||||
*
|
|
||||||
* @param entity the entity
|
|
||||||
* @param tag the tag
|
|
||||||
*/
|
|
||||||
private static void readEntityIntoTag(Entity entity, NBTTagCompound tag) {
|
|
||||||
entity.save(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockMaterial getMaterial(BlockType blockType) {
|
|
||||||
return new BlockMaterial_1_14(getBlock(blockType));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockMaterial getMaterial(BlockState state) {
|
|
||||||
IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState();
|
|
||||||
return new BlockMaterial_1_14(bs.getBlock(), bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block getBlock(BlockType blockType) {
|
|
||||||
return IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// Code that is less likely to break
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDataVersion() {
|
|
||||||
return CraftMagicNumbers.INSTANCE.getDataVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataFixer getDataFixer() {
|
|
||||||
return DataConverters_1_14_R4.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public BaseBlock getBlock(Location location) {
|
|
||||||
checkNotNull(location);
|
|
||||||
|
|
||||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
|
||||||
int x = location.getBlockX();
|
|
||||||
int y = location.getBlockY();
|
|
||||||
int z = location.getBlockZ();
|
|
||||||
|
|
||||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
|
||||||
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
|
||||||
if (state.getBlockType().getMaterial().hasContainer()) {
|
|
||||||
//Read the NBT data
|
|
||||||
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
|
|
||||||
if (te != null) {
|
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
|
||||||
readTileEntityIntoTag(te, tag); // Load data
|
|
||||||
return state.toBaseBlock((CompoundTag) toNative(tag));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return state.toBaseBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChunkInUse(org.bukkit.Chunk chunk) {
|
|
||||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
|
||||||
PlayerChunkMap chunkMap = ((WorldServer) craftChunk.getHandle().getWorld()).getChunkProvider().playerChunkMap;
|
|
||||||
return chunkMap.visibleChunks.containsKey(ChunkCoordIntPair.pair(chunk.getX(), chunk.getZ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
|
||||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
|
||||||
Chunk nmsChunk = craftChunk.getHandle();
|
|
||||||
World nmsWorld = nmsChunk.getWorld();
|
|
||||||
|
|
||||||
IBlockData blockData = ((BlockMaterial_1_14) state.getMaterial()).getState();
|
|
||||||
ChunkSection[] sections = nmsChunk.getSections();
|
|
||||||
int y4 = y >> 4;
|
|
||||||
ChunkSection section = sections[y4];
|
|
||||||
|
|
||||||
IBlockData existing;
|
|
||||||
if (section == null) {
|
|
||||||
existing = ((BlockMaterial_1_14) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
|
|
||||||
} else {
|
|
||||||
existing = section.getType(x & 15, y & 15, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
|
||||||
|
|
||||||
nmsChunk.removeTileEntity(pos); // Force delete the old tile entity
|
|
||||||
|
|
||||||
CompoundTag nativeTag = state instanceof BaseBlock ? ((BaseBlock)state).getNbtData() : null;
|
|
||||||
if (nativeTag != null || existing instanceof TileEntityBlock) {
|
|
||||||
nmsWorld.setTypeAndData(pos, blockData, 0);
|
|
||||||
// remove tile
|
|
||||||
if (nativeTag != null) {
|
|
||||||
// We will assume that the tile entity was created for us,
|
|
||||||
// though we do not do this on the Forge version
|
|
||||||
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
|
|
||||||
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); // Load data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (existing == blockData) return true;
|
|
||||||
if (section == null) {
|
|
||||||
if (blockData.isAir()) return true;
|
|
||||||
sections[y4] = section = new ChunkSection(y4 << 4);
|
|
||||||
}
|
|
||||||
nmsChunk.setType(pos = new BlockPosition(x, y, z), blockData, false);
|
|
||||||
}
|
|
||||||
if (update) {
|
|
||||||
nmsWorld.getMinecraftWorld().notify(pos, existing, blockData, 0);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
|
|
||||||
checkNotNull(entity);
|
|
||||||
|
|
||||||
CraftEntity craftEntity = ((CraftEntity) entity);
|
|
||||||
Entity mcEntity = craftEntity.getHandle();
|
|
||||||
|
|
||||||
String id = getEntityId(mcEntity);
|
|
||||||
|
|
||||||
if (id != null) {
|
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
|
||||||
Supplier<CompoundTag> saveTag = new Supplier<CompoundTag>() {
|
|
||||||
@Override
|
|
||||||
public CompoundTag get() {
|
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
|
||||||
readEntityIntoTag(mcEntity, tag);
|
|
||||||
return (CompoundTag) toNative(tag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return new LazyBaseEntity(type, saveTag);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) {
|
|
||||||
checkNotNull(location);
|
|
||||||
checkNotNull(state);
|
|
||||||
if (state.getType() == com.sk89q.worldedit.world.entity.EntityTypes.PLAYER) return null;
|
|
||||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
|
||||||
WorldServer worldServer = craftWorld.getHandle();
|
|
||||||
|
|
||||||
Entity createdEntity = createEntityFromId(state.getType().getId(), 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, SpawnReason.CUSTOM);
|
|
||||||
return createdEntity.getBukkitEntity();
|
|
||||||
} else {
|
|
||||||
logger.debug("Invalid entity " + state.getType().getId());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
|
||||||
Block block;
|
|
||||||
try {
|
|
||||||
block = IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
if (block == null) {
|
|
||||||
logger.warn("Failed to find properties for " + blockType.getId());
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
Map<String, Property<?>> properties = Maps.newLinkedHashMap();
|
|
||||||
BlockStateList<Block, IBlockData> blockStateList = block.getStates();
|
|
||||||
for (IBlockState state : blockStateList.d()) {
|
|
||||||
Property property;
|
|
||||||
if (state instanceof BlockStateBoolean) {
|
|
||||||
property = new BooleanProperty(state.a(), ImmutableList.copyOf(state.getValues()));
|
|
||||||
} else if (state instanceof BlockStateDirection) {
|
|
||||||
property = new DirectionalProperty(state.a(),
|
|
||||||
(List<Direction>) state.getValues().stream().map(e -> Direction.valueOf(((INamable) e).getName().toUpperCase())).collect(Collectors.toList()));
|
|
||||||
} else if (state instanceof BlockStateEnum) {
|
|
||||||
property = new EnumProperty(state.a(),
|
|
||||||
(List<String>) state.getValues().stream().map(e -> ((INamable) e).getName()).collect(Collectors.toList()));
|
|
||||||
} else if (state instanceof BlockStateInteger) {
|
|
||||||
property = new IntegerProperty(state.a(), ImmutableList.copyOf(state.getValues()));
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.put(property.getName(), property);
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts from a non-native NMS NBT structure to a native WorldEdit NBT
|
|
||||||
* structure.
|
|
||||||
*
|
|
||||||
* @param foreign non-native NMS NBT structure
|
|
||||||
* @return native WorldEdit NBT structure
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public Tag toNative(NBTBase foreign) {
|
|
||||||
if (foreign == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (foreign instanceof NBTTagCompound) {
|
|
||||||
Map<String, Tag> values = new HashMap<>();
|
|
||||||
Set<String> foreignKeys = ((NBTTagCompound) foreign).getKeys(); // 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).asByte());
|
|
||||||
} else if (foreign instanceof NBTTagByteArray) {
|
|
||||||
return new ByteArrayTag(((NBTTagByteArray) foreign).getBytes()); // data
|
|
||||||
} else if (foreign instanceof NBTTagDouble) {
|
|
||||||
return new DoubleTag(((NBTTagDouble) foreign).asDouble()); // getDouble
|
|
||||||
} else if (foreign instanceof NBTTagFloat) {
|
|
||||||
return new FloatTag(((NBTTagFloat) foreign).asFloat());
|
|
||||||
} else if (foreign instanceof NBTTagInt) {
|
|
||||||
return new IntTag(((NBTTagInt) foreign).asInt());
|
|
||||||
} else if (foreign instanceof NBTTagIntArray) {
|
|
||||||
return new IntArrayTag(((NBTTagIntArray) foreign).getInts()); // data
|
|
||||||
} else if (foreign instanceof NBTTagLongArray) {
|
|
||||||
return new LongArrayTag(((NBTTagLongArray) foreign).getLongs()); // data
|
|
||||||
} else if (foreign instanceof NBTTagList) {
|
|
||||||
try {
|
|
||||||
return toNativeList((NBTTagList) foreign);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.warn("Failed to convert NBTTagList", e);
|
|
||||||
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
|
|
||||||
}
|
|
||||||
} else if (foreign instanceof NBTTagLong) {
|
|
||||||
return new LongTag(((NBTTagLong) foreign).asLong());
|
|
||||||
} else if (foreign instanceof NBTTagShort) {
|
|
||||||
return new ShortTag(((NBTTagShort) foreign).asShort());
|
|
||||||
} else if (foreign instanceof NBTTagString) {
|
|
||||||
return new StringTag(foreign.asString());
|
|
||||||
} else if (foreign instanceof NBTTagEnd) {
|
|
||||||
return new EndTag();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a foreign NBT list tag into a native WorldEdit one.
|
|
||||||
*
|
|
||||||
* @param foreign the foreign tag
|
|
||||||
* @return the converted tag
|
|
||||||
* @throws NoSuchFieldException on error
|
|
||||||
* @throws SecurityException on error
|
|
||||||
* @throws IllegalArgumentException on error
|
|
||||||
* @throws IllegalAccessException on error
|
|
||||||
*/
|
|
||||||
public ListTag toNativeList(NBTTagList foreign) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
|
||||||
List<Tag> values = new ArrayList<>();
|
|
||||||
int type = foreign.getTypeId();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a WorldEdit-native NBT structure to a NMS structure.
|
|
||||||
*
|
|
||||||
* @param foreign structure to convert
|
|
||||||
* @return non-native structure
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
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 LongArrayTag) {
|
|
||||||
return new NBTTagLongArray(((LongArrayTag) foreign).getValue());
|
|
||||||
} else if (foreign instanceof ListTag) {
|
|
||||||
NBTTagList tag = new NBTTagList();
|
|
||||||
ListTag 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OptionalInt getInternalBlockStateId(BlockState state) {
|
|
||||||
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
|
||||||
IBlockData mcState = material.getCraftBlockData().getState();
|
|
||||||
return OptionalInt.of(Block.REGISTRY_ID.getId(mcState));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState adapt(BlockData blockData) {
|
|
||||||
CraftBlockData cbd = ((CraftBlockData) blockData);
|
|
||||||
IBlockData ibd = cbd.getState();
|
|
||||||
return adapt(ibd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockState adapt(IBlockData ibd) {
|
|
||||||
return BlockTypesCache.states[adaptToInt(ibd)];
|
|
||||||
}
|
|
||||||
|
|
||||||
public int adaptToInt(IBlockData ibd) {
|
|
||||||
try {
|
|
||||||
int id = Block.REGISTRY_ID.getId(ibd);
|
|
||||||
return idbToStateOrdinal[id];
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
init();
|
|
||||||
return adaptToInt(ibd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public char adaptToChar(IBlockData ibd) {
|
|
||||||
try {
|
|
||||||
int id = Block.REGISTRY_ID.getId(ibd);
|
|
||||||
return idbToStateOrdinal[id];
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
init();
|
|
||||||
return adaptToChar(ibd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockData adapt(BlockStateHolder state) {
|
|
||||||
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
|
|
||||||
return material.getCraftBlockData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) {
|
|
||||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutTileEntityData(
|
|
||||||
new BlockPosition(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
|
||||||
7,
|
|
||||||
(NBTTagCompound) fromNative(nbtData)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyAndLightBlock(Location position, BlockState previousType) {
|
|
||||||
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendFakeOP(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityStatus(
|
|
||||||
((CraftPlayer) player).getHandle(), (byte) 28
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
|
|
||||||
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
|
|
||||||
PlayerChunk map = BukkitAdapter_1_14.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ());
|
|
||||||
if (map != null && map.hasBeenLoaded()) {
|
|
||||||
boolean flag = false;
|
|
||||||
PlayerChunk.d players = map.players;
|
|
||||||
Stream<EntityPlayer> stream = players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag);
|
|
||||||
|
|
||||||
EntityPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle();
|
|
||||||
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
|
|
||||||
.forEach(entityPlayer -> {
|
|
||||||
synchronized (packet) {
|
|
||||||
PacketPlayOutMapChunk nmsPacket = (PacketPlayOutMapChunk) packet.getNativePacket();
|
|
||||||
if (nmsPacket == null) {
|
|
||||||
nmsPacket = MapChunkUtil_1_14.create(nmsWorld, this, packet);
|
|
||||||
packet.setNativePacket(nmsPacket);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
FaweCache.IMP.CHUNK_FLAG.get().set(true);
|
|
||||||
entityPlayer.playerConnection.sendPacket(nmsPacket);
|
|
||||||
} finally {
|
|
||||||
FaweCache.IMP.CHUNK_FLAG.get().set(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static EnumDirection adapt(Direction face) {
|
|
||||||
switch (face) {
|
|
||||||
case NORTH: return EnumDirection.NORTH;
|
|
||||||
case SOUTH: return EnumDirection.SOUTH;
|
|
||||||
case WEST: return EnumDirection.WEST;
|
|
||||||
case EAST: return EnumDirection.EAST;
|
|
||||||
case DOWN: return EnumDirection.DOWN;
|
|
||||||
case UP:
|
|
||||||
default:
|
|
||||||
return EnumDirection.UP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LoadingCache<WorldServer, FakePlayer_v1_14_R4> fakePlayers = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(FakePlayer_v1_14_R4::new));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
|
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
|
||||||
WorldServer worldServer = craftWorld.getHandle();
|
|
||||||
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack
|
|
||||||
? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1)));
|
|
||||||
stack.setTag((NBTTagCompound) fromNative(item.getNbtData()));
|
|
||||||
|
|
||||||
FakePlayer_v1_14_R4 fakePlayer;
|
|
||||||
try {
|
|
||||||
fakePlayer = fakePlayers.get(worldServer);
|
|
||||||
} catch (ExecutionException ignored) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fakePlayer.a(EnumHand.MAIN_HAND, stack);
|
|
||||||
fakePlayer.setLocation(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
|
|
||||||
(float) face.toVector().toYaw(), (float) face.toVector().toPitch());
|
|
||||||
|
|
||||||
final BlockPosition blockPos = new BlockPosition(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
|
||||||
final Vec3D blockVec = new Vec3D(blockPos);
|
|
||||||
final EnumDirection enumFacing = adapt(face);
|
|
||||||
MovingObjectPositionBlock rayTrace = new MovingObjectPositionBlock(blockVec, enumFacing, blockPos, false);
|
|
||||||
ItemActionContext context = new ItemActionContext(fakePlayer, EnumHand.MAIN_HAND, rayTrace);
|
|
||||||
EnumInteractionResult result = stack.placeItem(context, EnumHand.MAIN_HAND);
|
|
||||||
if (result != EnumInteractionResult.SUCCESS) {
|
|
||||||
if (worldServer.getType(blockPos).interact(worldServer, fakePlayer, EnumHand.MAIN_HAND, rayTrace)) {
|
|
||||||
result = EnumInteractionResult.SUCCESS;
|
|
||||||
} else {
|
|
||||||
result = stack.getItem().a(worldServer, fakePlayer, EnumHand.MAIN_HAND).a();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result == EnumInteractionResult.SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
|
|
||||||
ItemStack stack = new ItemStack(IRegistry.ITEM.get(MinecraftKey.a(item.getType().getId())), item.getAmount());
|
|
||||||
stack.setTag(((NBTTagCompound) fromNative(item.getNbtData())));
|
|
||||||
return CraftItemStack.asCraftMirror(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
|
||||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
|
||||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
|
||||||
weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag())));
|
|
||||||
return weStack;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package com.boydti.fawe.bukkit.adapter.mc1_14.test;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.ProtocolManager;
|
|
||||||
import com.comphenix.protocol.events.ListenerPriority;
|
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedBlockData;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TestChunkPacketSend {
|
|
||||||
public TestChunkPacketSend(Plugin plugin) {
|
|
||||||
// Disable all sound effects
|
|
||||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
|
||||||
protocolManager.addPacketListener(
|
|
||||||
new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
if (event.getPacketType() != PacketType.Play.Server.MAP_CHUNK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PacketContainer packet = event.getPacket();
|
|
||||||
StructureModifier<Byte> bytes = packet.getBytes();
|
|
||||||
StructureModifier<WrappedBlockData> blockData = packet.getBlockData();
|
|
||||||
List<WrappedBlockData> values = blockData.getValues();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -192,7 +192,7 @@ public class AsyncBlock implements Block {
|
|||||||
@Override
|
@Override
|
||||||
public void setType(@NotNull Material type) {
|
public void setType(@NotNull Material type) {
|
||||||
try {
|
try {
|
||||||
world.setBlock(x, y, z, BukkitAdapter.adapt(type).getDefaultState());
|
world.setBlock(x, y, z, BukkitAdapter.asBlockType(type).getDefaultState());
|
||||||
} catch (WorldEditException e) {
|
} catch (WorldEditException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -353,10 +353,6 @@ public enum BukkitAdapter {
|
|||||||
public static BlockState adapt(@NotNull BlockData blockData) {
|
public static BlockState adapt(@NotNull BlockData blockData) {
|
||||||
return getAdapter().adapt(blockData);
|
return getAdapter().adapt(blockData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockType adapt(Material material) {
|
|
||||||
return getAdapter().adapt(material);
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
private static Map<String, BlockData> blockDataCache = new HashMap<>();
|
private static Map<String, BlockData> blockDataCache = new HashMap<>();
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +127,7 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> registerBlocks() {
|
public Collection<String> values() {
|
||||||
ArrayList<String> blocks = new ArrayList<>();
|
ArrayList<String> blocks = new ArrayList<>();
|
||||||
for (Material m : Material.values()) {
|
for (Material m : Material.values()) {
|
||||||
if (!m.isLegacy() && m.isBlock()) {
|
if (!m.isLegacy() && m.isBlock()) {
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
|
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public class BukkitItemRegistry extends BundledItemRegistry {
|
public class BukkitItemRegistry extends BundledItemRegistry {
|
||||||
|
@Override
|
||||||
|
public Collection<String> values() {
|
||||||
|
ArrayList<String> values = new ArrayList<>();
|
||||||
|
for (Material m : Material.values()) {
|
||||||
|
if (!m.isLegacy() && (m.isBlock() || m.isItem())) {
|
||||||
|
String id = m.getKey().toString();
|
||||||
|
values.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||||
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
|
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
|
||||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||||
|
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
|
||||||
import com.sk89q.worldedit.world.registry.BundledRegistries;
|
import com.sk89q.worldedit.world.registry.BundledRegistries;
|
||||||
import com.sk89q.worldedit.world.registry.EntityRegistry;
|
import com.sk89q.worldedit.world.registry.EntityRegistry;
|
||||||
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
|
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
|
||||||
@ -34,6 +35,7 @@ class BukkitRegistries extends BundledRegistries {
|
|||||||
|
|
||||||
private static final BukkitRegistries INSTANCE = new BukkitRegistries();
|
private static final BukkitRegistries INSTANCE = new BukkitRegistries();
|
||||||
private final BlockRegistry blockRegistry = new BukkitBlockRegistry();
|
private final BlockRegistry blockRegistry = new BukkitBlockRegistry();
|
||||||
|
private final ItemRegistry itemRegistry = new BukkitItemRegistry();
|
||||||
private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry();
|
private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry();
|
||||||
private final EntityRegistry entityRegistry = new BukkitEntityRegistry();
|
private final EntityRegistry entityRegistry = new BukkitEntityRegistry();
|
||||||
private final BlockCategoryRegistry blockCategoryRegistry = new BukkitBlockCategoryRegistry();
|
private final BlockCategoryRegistry blockCategoryRegistry = new BukkitBlockCategoryRegistry();
|
||||||
@ -79,4 +81,8 @@ class BukkitRegistries extends BundledRegistries {
|
|||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemRegistry getItemRegistry() {
|
||||||
|
return itemRegistry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,9 @@ package com.sk89q.worldedit.bukkit;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
||||||
|
|
||||||
import com.bekvon.bukkit.residence.commands.message;
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.bukkit.FaweBukkit;
|
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||||
import com.boydti.fawe.bukkit.adapter.mc1_14.Spigot_v1_14_R4;
|
import com.boydti.fawe.bukkit.adapter.mc1_14.FAWE_Spigot_v1_14_R4;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.sk89q.util.yaml.YAMLProcessor;
|
import com.sk89q.util.yaml.YAMLProcessor;
|
||||||
@ -50,7 +49,6 @@ import com.sk89q.worldedit.world.block.BlockCategory;
|
|||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||||
import com.sk89q.worldedit.world.item.ItemCategory;
|
import com.sk89q.worldedit.world.item.ItemCategory;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
|
||||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -84,7 +82,6 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.metadata.MetadataValue;
|
import org.bukkit.metadata.MetadataValue;
|
||||||
@ -251,9 +248,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
|||||||
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
|
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
|
||||||
BiomeType.REGISTRY.register("minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
|
BiomeType.REGISTRY.register("minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
|
||||||
}
|
}
|
||||||
// Block & Item
|
/*// Block & Item
|
||||||
for (Material material : Material.values()) {
|
for (Material material : Material.values()) {
|
||||||
/*
|
|
||||||
if (material.isBlock() && !material.isLegacy()) {
|
if (material.isBlock() && !material.isLegacy()) {
|
||||||
BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
|
BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
|
||||||
// TODO Use something way less hacky than this.
|
// TODO Use something way less hacky than this.
|
||||||
@ -277,11 +273,11 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (material.isItem() && !material.isLegacy()) {
|
if (material.isItem() && !material.isLegacy()) {
|
||||||
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
|
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Entity
|
// Entity
|
||||||
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
|
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
|
||||||
String mcid = entityType.getName();
|
String mcid = entityType.getName();
|
||||||
@ -371,7 +367,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
|
|||||||
// Attempt to load a Bukkit adapter
|
// Attempt to load a Bukkit adapter
|
||||||
BukkitImplLoader adapterLoader = new BukkitImplLoader();
|
BukkitImplLoader adapterLoader = new BukkitImplLoader();
|
||||||
try {
|
try {
|
||||||
adapterLoader.addClass(Spigot_v1_14_R4.class);
|
adapterLoader.addClass(FAWE_Spigot_v1_14_R4.class);
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import com.sk89q.jnbt.CompoundTag;
|
|||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
@ -36,17 +37,24 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for adapters of various Bukkit implementations.
|
* An interface for adapters of various Bukkit implementations.
|
||||||
*/
|
*/
|
||||||
@ -67,6 +75,19 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
@Nullable
|
@Nullable
|
||||||
DataFixer getDataFixer();
|
DataFixer getDataFixer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if {@link #tickWatchdog()} is implemented
|
||||||
|
*/
|
||||||
|
default boolean supportsWatchdog() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tick the server watchdog, if possible.
|
||||||
|
*/
|
||||||
|
default void tickWatchdog() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the block at the given location.
|
* Get the block at the given location.
|
||||||
*
|
*
|
||||||
@ -83,11 +104,7 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
* @param notifyAndLight notify and light if set
|
* @param notifyAndLight notify and light if set
|
||||||
* @return true if a block was likely changed
|
* @return true if a block was likely changed
|
||||||
*/
|
*/
|
||||||
default boolean setBlock(Location location, BlockStateHolder<?> state, boolean notifyAndLight) {
|
boolean setBlock(Location location, BlockStateHolder<?> state, boolean notifyAndLight);
|
||||||
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean setBlock(Chunk chunk, int x, int y, int z, BlockStateHolder<?> state, boolean update);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the simulation that the block at the given location has
|
* Notifies the simulation that the block at the given location has
|
||||||
@ -142,13 +159,6 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
*/
|
*/
|
||||||
void sendFakeOP(Player player);
|
void sendFakeOP(Player player);
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a fake chunk packet to a player
|
|
||||||
* @param player
|
|
||||||
* @param packet
|
|
||||||
*/
|
|
||||||
void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulates a player using an item.
|
* Simulates a player using an item.
|
||||||
*
|
*
|
||||||
@ -178,10 +188,24 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
*/
|
*/
|
||||||
BaseItemStack adapt(ItemStack itemStack);
|
BaseItemStack adapt(ItemStack itemStack);
|
||||||
|
|
||||||
boolean isChunkInUse(Chunk chunk);
|
default OptionalInt getInternalBlockStateId(BlockData data) {
|
||||||
|
return getInternalBlockStateId(BukkitAdapter.adapt(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the internal ID for a given state, if possible.
|
||||||
|
*
|
||||||
|
* @param state The block state
|
||||||
|
* @return the internal ID of the state
|
||||||
|
*/
|
||||||
|
default OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FAWE ADDITIONS
|
||||||
default BlockMaterial getMaterial(BlockType blockType) {
|
default BlockMaterial getMaterial(BlockType blockType) {
|
||||||
return null;
|
return getMaterial(blockType.getDefaultState());
|
||||||
}
|
}
|
||||||
|
|
||||||
default BlockMaterial getMaterial(BlockState blockState) {
|
default BlockMaterial getMaterial(BlockState blockState) {
|
||||||
@ -201,12 +225,11 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the internal ID for a given state, if possible.
|
* Send a fake chunk packet to a player
|
||||||
*
|
* @param player
|
||||||
* @param state The block state
|
* @param packet
|
||||||
* @return the internal ID of the state
|
|
||||||
*/
|
*/
|
||||||
default OptionalInt getInternalBlockStateId(BlockState state) {
|
default void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
|
||||||
return OptionalInt.empty();
|
throw new UnsupportedOperationException("Cannot send fake chunks");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -155,6 +155,7 @@ public class BukkitImplLoader {
|
|||||||
*/
|
*/
|
||||||
public BukkitImplAdapter loadAdapter() throws AdapterLoadException {
|
public BukkitImplAdapter loadAdapter() throws AdapterLoadException {
|
||||||
for (String className : adapterCandidates) {
|
for (String className : adapterCandidates) {
|
||||||
|
System.out.println("Try load " + className);
|
||||||
try {
|
try {
|
||||||
Class<?> cls = Class.forName(className);
|
Class<?> cls = Class.forName(className);
|
||||||
if (cls.isSynthetic()) continue;
|
if (cls.isSynthetic()) continue;
|
||||||
@ -168,6 +169,7 @@ public class BukkitImplLoader {
|
|||||||
log.warn("Failed to load the Bukkit adapter class '" + className +
|
log.warn("Failed to load the Bukkit adapter class '" + className +
|
||||||
"' that is not supposed to be raising this error", e);
|
"' that is not supposed to be raising this error", e);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
if (className.equals(customCandidate)) {
|
if (className.equals(customCandidate)) {
|
||||||
log.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
|
log.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,11 @@ public abstract class CachedBukkitAdapter implements IBukkitAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockType adapt(Material material) {
|
public BlockType asBlockType(Material material) {
|
||||||
try {
|
try {
|
||||||
return BlockTypesCache.values[blockTypes[material.ordinal()]];
|
return BlockTypesCache.values[blockTypes[material.ordinal()]];
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
if (init()) return adapt(material);
|
if (init()) return asBlockType(material);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
|
|||||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
@ -208,7 +210,9 @@ public interface IBukkitAdapter {
|
|||||||
* @param material The material
|
* @param material The material
|
||||||
* @return The itemtype
|
* @return The itemtype
|
||||||
*/
|
*/
|
||||||
ItemType asItemType(Material material);
|
default ItemType asItemType(Material material) {
|
||||||
|
return ItemTypes.get(material.getKey().toString());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
|
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
|
||||||
@ -216,9 +220,10 @@ public interface IBukkitAdapter {
|
|||||||
* @param blockData The Bukkit BlockData
|
* @param blockData The Bukkit BlockData
|
||||||
* @return The WorldEdit BlockState
|
* @return The WorldEdit BlockState
|
||||||
*/
|
*/
|
||||||
BlockState adapt(BlockData blockData);
|
default BlockState adapt(BlockData blockData) {
|
||||||
|
String id = blockData.getAsString();
|
||||||
BlockType adapt(Material material);
|
return BlockState.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
|
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
|
||||||
@ -226,7 +231,9 @@ public interface IBukkitAdapter {
|
|||||||
* @param block The WorldEdit BlockStateHolder
|
* @param block The WorldEdit BlockStateHolder
|
||||||
* @return The Bukkit BlockData
|
* @return The Bukkit BlockData
|
||||||
*/
|
*/
|
||||||
BlockData adapt(BlockStateHolder block);
|
default BlockData adapt(BlockStateHolder block) {
|
||||||
|
return Bukkit.createBlockData(block.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack
|
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack
|
||||||
|
@ -0,0 +1,278 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitPlayer;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||||
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
|
||||||
|
BukkitImplAdapter<T> getParent();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default int getDataVersion() {
|
||||||
|
return getParent().getDataVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
default DataFixer getDataFixer() {
|
||||||
|
return getParent().getDataFixer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean supportsWatchdog() {
|
||||||
|
return getParent().supportsWatchdog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void tickWatchdog() {
|
||||||
|
getParent().tickWatchdog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BaseBlock getBlock(Location location) {
|
||||||
|
return getParent().getBlock(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight) {
|
||||||
|
return getParent().setBlock(location, state, notifyAndLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void notifyAndLightBlock(Location position, BlockState previousType) {
|
||||||
|
getParent().notifyAndLightBlock(position, previousType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
default BaseEntity getEntity(Entity entity) {
|
||||||
|
return getParent().getEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
default Entity createEntity(Location location, BaseEntity state) {
|
||||||
|
return getParent().createEntity(location, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||||
|
return getParent().getProperties(blockType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) {
|
||||||
|
getParent().sendFakeNBT(player, pos, nbtData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendFakeOP(Player player) {
|
||||||
|
getParent().sendFakeOP(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean simulateItemUse(World world, BlockVector3 position, BaseItem item, Direction face) {
|
||||||
|
return getParent().simulateItemUse(world, position, item, face);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default ItemStack adapt(BaseItemStack item) {
|
||||||
|
return getParent().adapt(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BaseItemStack adapt(ItemStack itemStack) {
|
||||||
|
return getParent().adapt(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default OptionalInt getInternalBlockStateId(BlockData data) {
|
||||||
|
return getParent().getInternalBlockStateId(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
return getParent().getInternalBlockStateId(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockMaterial getMaterial(BlockType blockType) {
|
||||||
|
return getParent().getMaterial(blockType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockMaterial getMaterial(BlockState blockState) {
|
||||||
|
return getParent().getMaterial(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Tag toNative(T foreign) {
|
||||||
|
return getParent().toNative(foreign);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default T fromNative(Tag foreign) {
|
||||||
|
return getParent().fromNative(foreign);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
default World createWorld(WorldCreator creator) {
|
||||||
|
return getParent().createWorld(creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void sendFakeChunk(World world, Player player, ChunkPacket packet) {
|
||||||
|
getParent().sendFakeChunk(world, player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BukkitWorld asBukkitWorld(com.sk89q.worldedit.world.World world) {
|
||||||
|
return getParent().asBukkitWorld(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default World adapt(com.sk89q.worldedit.world.World world) {
|
||||||
|
return getParent().adapt(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Location adapt(World world, Vector3 position) {
|
||||||
|
return getParent().adapt(world, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Location adapt(World world, BlockVector3 position) {
|
||||||
|
return getParent().adapt(world, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Location adapt(World world, com.sk89q.worldedit.util.Location location) {
|
||||||
|
return getParent().adapt(world, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Vector3 asVector(Location location) {
|
||||||
|
return getParent().asVector(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockVector3 asBlockVector(Location location) {
|
||||||
|
return getParent().asBlockVector(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default com.sk89q.worldedit.entity.Entity adapt(Entity entity) {
|
||||||
|
return getParent().adapt(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Material adapt(ItemType itemType) {
|
||||||
|
return getParent().adapt(itemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Material adapt(BlockType blockType) {
|
||||||
|
return getParent().adapt(blockType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default EntityType adapt(com.sk89q.worldedit.world.entity.EntityType entityType) {
|
||||||
|
return getParent().adapt(entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockType asBlockType(Material material) {
|
||||||
|
return getParent().asBlockType(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default ItemType asItemType(Material material) {
|
||||||
|
return getParent().asItemType(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockState adapt(BlockData blockData) {
|
||||||
|
return getParent().adapt(blockData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockData adapt(BlockStateHolder block) {
|
||||||
|
return getParent().adapt(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BukkitPlayer adapt(Player player) {
|
||||||
|
return getParent().adapt(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Player adapt(com.sk89q.worldedit.entity.Player player) {
|
||||||
|
return getParent().adapt(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Biome adapt(BiomeType biomeType) {
|
||||||
|
return getParent().adapt(biomeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BiomeType adapt(Biome biome) {
|
||||||
|
return getParent().adapt(biome);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean equals(BlockType blockType, Material type) {
|
||||||
|
return getParent().equals(blockType, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default com.sk89q.worldedit.world.World adapt(World world) {
|
||||||
|
return getParent().adapt(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default GameMode adapt(org.bukkit.GameMode gameMode) {
|
||||||
|
return getParent().adapt(gameMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default com.sk89q.worldedit.world.entity.EntityType adapt(EntityType entityType) {
|
||||||
|
return getParent().adapt(entityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default BlockState asBlockState(ItemStack itemStack) {
|
||||||
|
return getParent().asBlockState(itemStack);
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
public class SimpleBukkitAdapter extends CachedBukkitAdapter {
|
public class SimpleBukkitAdapter extends CachedBukkitAdapter {
|
||||||
private BlockData[][] blockDataCache;
|
private BlockData[][] blockDataCache;
|
||||||
|
|
||||||
public boolean init() {
|
private boolean init() {
|
||||||
if (blockDataCache != null) return false;
|
if (blockDataCache != null) return false;
|
||||||
this.blockDataCache = new BlockData[BlockTypes.size()][];
|
this.blockDataCache = new BlockData[BlockTypes.size()][];
|
||||||
blockDataCache[0] = new BlockData[] {Material.AIR.createBlockData()};
|
blockDataCache[0] = new BlockData[] {Material.AIR.createBlockData()};
|
||||||
|
@ -144,6 +144,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
BlockState state = null;
|
BlockState state = null;
|
||||||
try {
|
try {
|
||||||
String palettePart = fix(entry.getKey());
|
String palettePart = fix(entry.getKey());
|
||||||
|
System.out.println("Read " + palettePart);
|
||||||
state = BlockState.get(palettePart);
|
state = BlockState.get(palettePart);
|
||||||
} catch (InputParseException e) {
|
} catch (InputParseException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -179,7 +179,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
|
|||||||
// Suggest property
|
// Suggest property
|
||||||
String input = charSequence.toString();
|
String input = charSequence.toString();
|
||||||
BlockType finalType = type;
|
BlockType finalType = type;
|
||||||
throw new SuggestInputParseException("Invalid property " + charSequence + ":" + input + " for type " + type, input, () ->
|
throw new SuggestInputParseException("Invalid property " + key + ":" + input + " for type " + type, input, () ->
|
||||||
finalType.getProperties().stream()
|
finalType.getProperties().stream()
|
||||||
.map(Property::getName)
|
.map(Property::getName)
|
||||||
.filter(p -> StringMan.blockStateMatches(input, p))
|
.filter(p -> StringMan.blockStateMatches(input, p))
|
||||||
@ -196,6 +196,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
|
|||||||
case '=': {
|
case '=': {
|
||||||
charSequence.setSubstring(last, i);
|
charSequence.setSubstring(last, i);
|
||||||
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
|
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
|
||||||
|
if (property == null) System.out.println("No prop " + charSequence + " | " + type.getPropertyMap());
|
||||||
last = i + 1;
|
last = i + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -741,6 +741,7 @@ public final class BlockTypes {
|
|||||||
private static Field[] fieldsTmp;
|
private static Field[] fieldsTmp;
|
||||||
private static JoinedCharSequence joined;
|
private static JoinedCharSequence joined;
|
||||||
private static int initIndex = 0;
|
private static int initIndex = 0;
|
||||||
|
|
||||||
public static BlockType init() {
|
public static BlockType init() {
|
||||||
if (fieldsTmp == null) {
|
if (fieldsTmp == null) {
|
||||||
fieldsTmp = BlockTypes.class.getDeclaredFields();
|
fieldsTmp = BlockTypes.class.getDeclaredFields();
|
||||||
|
@ -176,7 +176,7 @@ public class BlockTypesCache {
|
|||||||
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
||||||
Registries registries = platform.getRegistries();
|
Registries registries = platform.getRegistries();
|
||||||
BlockRegistry blockReg = registries.getBlockRegistry();
|
BlockRegistry blockReg = registries.getBlockRegistry();
|
||||||
Collection<String> blocks = blockReg.registerBlocks();
|
Collection<String> blocks = blockReg.values();
|
||||||
Map<String, String> blockMap = blocks.stream().collect(Collectors.toMap(item -> item.charAt(item.length() - 1) == ']' ? item.substring(0, item.indexOf('[')) : item, item -> item));
|
Map<String, String> blockMap = blocks.stream().collect(Collectors.toMap(item -> item.charAt(item.length() - 1) == ']' ? item.substring(0, item.indexOf('[')) : item, item -> item));
|
||||||
|
|
||||||
int size = blockMap.size();
|
int size = blockMap.size();
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.sk89q.worldedit.world.block;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Platform;
|
||||||
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
|
import com.sk89q.worldedit.world.registry.ItemRegistry;
|
||||||
|
import com.sk89q.worldedit.world.registry.Registries;
|
||||||
|
|
||||||
|
public final class ItemTypesCache {
|
||||||
|
public static void init() {}
|
||||||
|
|
||||||
|
static {
|
||||||
|
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
||||||
|
Registries registries = platform.getRegistries();
|
||||||
|
ItemRegistry itemReg = registries.getItemRegistry();
|
||||||
|
for (String key : itemReg.values()) {
|
||||||
|
ItemType item = new ItemType(key);
|
||||||
|
ItemType.REGISTRY.register(key, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -77,7 +77,7 @@ public interface BlockRegistry {
|
|||||||
/**
|
/**
|
||||||
* Register all blocks
|
* Register all blocks
|
||||||
*/
|
*/
|
||||||
default Collection<String> registerBlocks() {
|
default Collection<String> values() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ package com.sk89q.worldedit.world.registry;
|
|||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public interface ItemRegistry {
|
public interface ItemRegistry {
|
||||||
|
|
||||||
@ -34,4 +36,10 @@ public interface ItemRegistry {
|
|||||||
@Nullable
|
@Nullable
|
||||||
String getName(ItemType itemType);
|
String getName(ItemType itemType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register all items
|
||||||
|
*/
|
||||||
|
default Collection<String> values() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren