Update to Minecraft 1.13-pre7

By: md_5 <git@md-5.net>
This commit is contained in:
CraftBukkit/Spigot
2018-07-15 10:00:00 +10:00
parent d1e91a8adb
commit 7e0a66fdd5
608 changed files with 17788 additions and 9378 deletions

View File

@@ -3,50 +3,35 @@ package org.bukkit.craftbukkit.util;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.Block;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.IBlockData;
import net.minecraft.server.World;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.block.CraftBlockState;
public class BlockStateListPopulator {
private final World world;
private final List<BlockState> list;
private final List<CraftBlockState> list;
public BlockStateListPopulator(World world) {
this(world, new ArrayList<BlockState>());
this(world, new ArrayList<CraftBlockState>());
}
public BlockStateListPopulator(World world, List<BlockState> list) {
public BlockStateListPopulator(World world, List<CraftBlockState> list) {
this.world = world;
this.list = list;
}
public void setTypeAndData(int x, int y, int z, Block block, int data, int light) {
BlockState state = world.getBlockAt(x, y, z).getState();
state.setTypeId(Block.getId(block));
state.setRawData((byte) data);
list.add(state);
}
public void setTypeId(int x, int y, int z, int type) {
BlockState state = world.getBlockAt(x, y, z).getState();
state.setTypeId(type);
public void setTypeUpdate(BlockPosition position, IBlockData data) {
CraftBlockState state = CraftBlockState.getBlockState(world, position);
state.setData(data);
list.add(state);
}
public void setTypeUpdate(int x, int y, int z, Block block) {
this.setType(x, y, z, block);
}
public void setTypeUpdate(BlockPosition position, IBlockData data) {
setTypeAndData(position.getX(), position.getY(), position.getZ(), data.getBlock(), data.getBlock().toLegacyData(data), 0);
}
public void setType(int x, int y, int z, Block block) {
BlockState state = world.getBlockAt(x, y, z).getState();
state.setTypeId(Block.getId(block));
public void setTypeAndData(BlockPosition position, IBlockData data, int flag) {
CraftBlockState state = CraftBlockState.getBlockState(world, position, flag);
state.setData(data);
list.add(state);
}
@@ -56,7 +41,7 @@ public class BlockStateListPopulator {
}
}
public List<BlockState> getList() {
public List<CraftBlockState> getList() {
return list;
}

View File

@@ -0,0 +1,268 @@
package org.bukkit.craftbukkit.util;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.bukkit.Material;
import org.bukkit.plugin.AuthorNagException;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
/**
* This file is imported from Commodore.
*
* @author md_5
*/
public class Commodore
{
private static final Set<String> EVIL = new HashSet<>( Arrays.asList(
"org/bukkit/World (III)I getBlockTypeIdAt",
"org/bukkit/World (Lorg/bukkit/Location;)I getBlockTypeIdAt",
"org/bukkit/block/Block ()I getTypeId",
"org/bukkit/block/Block (I)Z setTypeId",
"org/bukkit/block/Block (IZ)Z setTypeId",
"org/bukkit/block/Block (IBZ)Z setTypeIdAndData",
"org/bukkit/inventory/ItemStack ()I getTypeId",
"org/bukkit/inventory/ItemStack (I)V setTypeId"
) );
public static void main(String[] args)
{
OptionParser parser = new OptionParser();
OptionSpec<File> inputFlag = parser.acceptsAll( Arrays.asList( "i", "input" ) ).withRequiredArg().ofType( File.class ).required();
OptionSpec<File> outputFlag = parser.acceptsAll( Arrays.asList( "o", "output" ) ).withRequiredArg().ofType( File.class ).required();
OptionSet options = parser.parse( args );
File input = options.valueOf( inputFlag );
File output = options.valueOf( outputFlag );
if ( input.isDirectory() )
{
if ( !output.isDirectory() )
{
System.err.println( "If input directory specified, output directory required too" );
return;
}
for ( File in : input.listFiles() )
{
if ( in.getName().endsWith( ".jar" ) )
{
convert( in, new File( output, in.getName() ) );
}
}
} else
{
convert( input, output );
}
}
private static void convert(File in, File out)
{
System.out.println( "Attempting to convert " + in + " to " + out );
try
{
try ( JarFile inJar = new JarFile( in, false ) )
{
JarEntry entry = inJar.getJarEntry( ".commodore" );
if ( entry != null )
{
return;
}
try ( JarOutputStream outJar = new JarOutputStream( new FileOutputStream( out ) ) )
{
for ( Enumeration<JarEntry> entries = inJar.entries(); entries.hasMoreElements(); )
{
entry = entries.nextElement();
try ( InputStream is = inJar.getInputStream( entry ) )
{
byte[] b = ByteStreams.toByteArray( is );
if ( entry.getName().endsWith( ".class" ) )
{
b = convert( b, false );
entry = new JarEntry( entry.getName() );
}
outJar.putNextEntry( entry );
outJar.write( b );
}
}
outJar.putNextEntry( new ZipEntry( ".commodore" ) );
}
}
} catch ( Exception ex )
{
System.err.println( "Fatal error trying to convert " + in );
ex.printStackTrace();
}
}
public static byte[] convert(byte[] b, final boolean modern)
{
ClassReader cr = new ClassReader( b );
ClassWriter cw = new ClassWriter( cr, 0 );
cr.accept( new ClassVisitor( Opcodes.ASM6, cw )
{
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
{
return new MethodVisitor( api, super.visitMethod( access, name, desc, signature, exceptions ) )
{
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc)
{
if ( modern )
{
super.visitFieldInsn( opcode, owner, name, desc );
return;
}
if ( owner.equals( "org/bukkit/Material" ) )
{
try
{
Material.valueOf( "LEGACY_" + name );
} catch ( IllegalArgumentException ex )
{
throw new AuthorNagException( "No legacy enum constant for " + name + ". Did you forget to define api-version: 1.13 in your plugin.yml?" );
}
super.visitFieldInsn( opcode, owner, "LEGACY_" + name, desc );
return;
}
if ( owner.equals( "org/bukkit/Art" ) )
{
switch ( name )
{
case "BURNINGSKULL":
super.visitFieldInsn( opcode, owner, "BURNING_SKULL", desc );
return;
case "DONKEYKONG":
super.visitFieldInsn( opcode, owner, "DONKEY_KONG", desc );
return;
}
}
if ( owner.equals( "org/bukkit/Particle" ) )
{
switch ( name )
{
case "BLOCK_CRACK":
case "BLOCK_DUST":
case "FALLING_DUST":
super.visitFieldInsn( opcode, owner, "LEGACY_" + name, desc );
return;
}
}
super.visitFieldInsn( opcode, owner, name, desc );
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
{
if ( modern )
{
if ( owner.equals( "org/bukkit/Material" ) )
{
switch ( name )
{
case "values":
super.visitMethodInsn( opcode, "org/bukkit/craftbukkit/util/CraftLegacy", "modern_" + name, desc, itf );
return;
}
}
super.visitMethodInsn( opcode, owner, name, desc, itf );
return;
}
if ( owner.equals( "org/bukkit/ChunkSnapshot" ) && name.equals( "getBlockData" ) && desc.equals( "(III)I" ) )
{
super.visitMethodInsn( opcode, owner, "getData", desc, itf );
return;
}
Type retType = Type.getReturnType( desc );
if ( EVIL.contains( owner + " " + desc + " " + name )
|| ( owner.startsWith( "org/bukkit/block/" ) && ( desc + " " + name ).equals( "()I getTypeId" ) )
|| ( owner.startsWith( "org/bukkit/block/" ) && ( desc + " " + name ).equals( "(I)Z setTypeId" ) ) )
{
Type[] args = Type.getArgumentTypes( desc );
Type[] newArgs = new Type[ args.length + 1 ];
newArgs[0] = Type.getObjectType( owner );
System.arraycopy( args, 0, newArgs, 1, args.length );
super.visitMethodInsn( Opcodes.INVOKESTATIC, "org/bukkit/craftbukkit/util/CraftEvil", name, Type.getMethodDescriptor( retType, newArgs ), false );
return;
}
if ( owner.equals( "org/bukkit/Material" ) )
{
if ( name.equals( "getMaterial" ) && desc.equals( "(I)Lorg/bukkit/Material;" ) )
{
super.visitMethodInsn( opcode, "org/bukkit/craftbukkit/util/CraftEvil", name, desc, itf );
return;
}
switch ( name )
{
case "values":
case "valueOf":
case "getMaterial":
case "matchMaterial":
super.visitMethodInsn( opcode, "org/bukkit/craftbukkit/util/CraftLegacy", name, desc, itf );
return;
case "ordinal":
super.visitMethodInsn( Opcodes.INVOKESTATIC, "org/bukkit/craftbukkit/util/CraftLegacy", "ordinal", "(Lorg/bukkit/Material;)I", false );
return;
case "name":
case "toString":
super.visitMethodInsn( Opcodes.INVOKESTATIC, "org/bukkit/craftbukkit/util/CraftLegacy", name, "(Lorg/bukkit/Material;)Ljava/lang/String;", false );
return;
}
}
if ( retType.getSort() == Type.OBJECT && retType.getInternalName().equals( "org/bukkit/Material" ) && owner.startsWith( "org/bukkit" ) )
{
super.visitMethodInsn( opcode, owner, name, desc, itf );
super.visitMethodInsn( Opcodes.INVOKESTATIC, "org/bukkit/craftbukkit/util/CraftLegacy", "toLegacy", "(Lorg/bukkit/Material;)Lorg/bukkit/Material;", false );
return;
}
super.visitMethodInsn( opcode, owner, name, desc, itf );
}
};
}
}, 0 );
return cw.toByteArray();
}
}

View File

@@ -138,22 +138,30 @@ public final class CraftChatMessage {
}
}
public static IChatBaseComponent fromStringOrNull(String message) {
return (message == null) ? null : fromString(message)[0];
}
public static IChatBaseComponent[] fromString(String message) {
return fromString(message, false);
}
public static IChatBaseComponent[] fromString(String message, boolean keepNewlines) {
return new StringMessage(message, keepNewlines).getOutput();
}
public static String fromComponent(IChatBaseComponent component) {
return fromComponent(component, EnumChatFormat.BLACK);
}
public static String toJSON(IChatBaseComponent component) {
return IChatBaseComponent.ChatSerializer.a(component);
}
public static String fromComponent(IChatBaseComponent component, EnumChatFormat defaultColor) {
if (component == null) return "";
StringBuilder out = new StringBuilder();
for (IChatBaseComponent c : (Iterable<IChatBaseComponent>) component) {
ChatModifier modi = c.getChatModifier();
out.append(modi.getColor() == null ? defaultColor : modi.getColor());
@@ -185,7 +193,7 @@ public final class CraftChatMessage {
private static IChatBaseComponent fixComponent(IChatBaseComponent component, Matcher matcher) {
if (component instanceof ChatComponentText) {
ChatComponentText text = ((ChatComponentText) component);
String msg = text.g();
String msg = text.f();
if (matcher.reset(msg).find()) {
matcher.reset();
@@ -236,7 +244,7 @@ public final class CraftChatMessage {
}
if (component instanceof ChatMessage) {
Object[] subs = ((ChatMessage) component).j();
Object[] subs = ((ChatMessage) component).i();
for (int i = 0; i < subs.length; i++) {
Object comp = subs[i];
if (comp instanceof IChatBaseComponent) {

View File

@@ -0,0 +1,80 @@
package org.bukkit.craftbukkit.util;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.inventory.ItemStack;
/**
* @deprecated do not use for any reason
*/
@Deprecated
public class CraftEvil {
private static final Int2ObjectMap<Material> byId = new Int2ObjectLinkedOpenHashMap<>();
static {
for (Material material : Material.values()) {
Preconditions.checkState(!byId.containsKey(material.getId()), "Duplicate material ID for", material);
byId.put(material.getId(), material);
}
}
public static int getBlockTypeIdAt(World world, int x, int y, int z) {
return getId(world.getBlockAt(x, y, z).getType());
}
public static int getBlockTypeIdAt(World world, Location location) {
return getId(world.getBlockAt(location).getType());
}
public static int getTypeId(Block block) {
return getId(block.getType());
}
public static boolean setTypeId(Block block, int type) {
block.setType(getMaterial(type));
return true;
}
public static boolean setTypeId(Block block, int type, boolean applyPhysics) {
block.setType(getMaterial(type), applyPhysics);
return true;
}
public static boolean setTypeIdAndData(Block block, int type, byte data, boolean applyPhysics) {
block.setType(getMaterial(type), applyPhysics);
block.setData(data);
return true;
}
public static int getTypeId(BlockState state) {
return getId(state.getType());
}
public static boolean setTypeId(BlockState state, int type) {
state.setType(getMaterial(type));
return true;
}
public static int getTypeId(ItemStack stack) {
return getId(stack.getType());
}
public static void setTypeId(ItemStack stack, int type) {
stack.setType(getMaterial(type));
}
public static Material getMaterial(int id) {
return byId.get(id);
}
public static int getId(Material material) {
return CraftLegacy.toLegacy(material).getId();
}
}

View File

@@ -0,0 +1,366 @@
package org.bukkit.craftbukkit.util;
import com.google.common.base.Preconditions;
import com.mojang.datafixers.Dynamic;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import net.minecraft.server.Block;
import net.minecraft.server.BlockStateList;
import net.minecraft.server.Blocks;
import net.minecraft.server.DataConverterFlattenData;
import net.minecraft.server.DataConverterMaterialId;
import net.minecraft.server.DataConverterRegistry;
import net.minecraft.server.DataConverterTypes;
import net.minecraft.server.DispenserRegistry;
import net.minecraft.server.DynamicOpsNBT;
import net.minecraft.server.IBlockData;
import net.minecraft.server.IBlockState;
import net.minecraft.server.Item;
import net.minecraft.server.MinecraftKey;
import net.minecraft.server.NBTBase;
import net.minecraft.server.NBTTagCompound;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.material.MaterialData;
/**
* This class may seem unnecessarily slow and complicated/repetitive however it
* is able to handle a lot more edge cases and invertible transformations (many
* of which are not immediately obvious) than any other alternative. If you do
* make changes to this class please make sure to contribute them back
* https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse so
* that all may benefit.
*
* @deprecated legacy use only
*/
@Deprecated
public class CraftLegacy {
private static final Map<EntityType, Material> SPAWN_EGGS = new HashMap<>();
private static final Set<String> whitelistedStates = new HashSet<>(Arrays.asList("explode", "check_decay", "decayable"));
private static final Map<MaterialData, Item> materialToItem = new HashMap<>();
private static final Map<Item, MaterialData> itemToMaterial = new HashMap<>();
private static final Map<MaterialData, IBlockData> materialToData = new HashMap<>();
private static final Map<IBlockData, MaterialData> dataToMaterial = new HashMap<>();
private static final Map<MaterialData, Block> materialToBlock = new HashMap<>();
private static final Map<Block, MaterialData> blockToMaterial = new HashMap<>();
public static Material toLegacy(Material material) {
if (material == null || material.isLegacy()) {
return material;
}
return toLegacyData(material).getItemType();
}
public static MaterialData toLegacyData(Material material) {
Preconditions.checkArgument(!material.isLegacy(), "toLegacy on legacy Material");
MaterialData mappedData;
if (material.isBlock()) {
Block block = CraftMagicNumbers.getBlock(material);
IBlockData blockData = block.getBlockData();
// Try exact match first
mappedData = dataToMaterial.get(blockData);
// Fallback to any block
if (mappedData == null) {
mappedData = blockToMaterial.get(block);
// Fallback to matching item
if (mappedData == null) {
mappedData = itemToMaterial.get(block.getItem());
}
}
} else {
Item item = CraftMagicNumbers.getItem(material);
mappedData = itemToMaterial.get(item);
}
return (mappedData == null) ? new MaterialData(Material.LEGACY_AIR) : mappedData;
}
public static IBlockData fromLegacyData(Material material, Block block, byte data) {
Preconditions.checkArgument(material.isLegacy(), "fromLegacyData on modern Material");
MaterialData materialData = new MaterialData(material, data);
// Try exact match first
IBlockData converted = materialToData.get(materialData);
if (converted != null) {
return converted;
}
// Fallback to any block
Block convertedBlock = materialToBlock.get(materialData);
if (convertedBlock != null) {
return convertedBlock.getBlockData();
}
// Return existing block
return block.getBlockData();
}
public static Item fromLegacyData(Material material, Item item, short data) {
Preconditions.checkArgument(material.isLegacy(), "fromLegacyData on modern Material. Did you forget to define api-version: 1.13 in your plugin.yml?");
MaterialData materialData = new MaterialData(material, (byte) data);
if (material.isBlock()) {
// Try exact match first
IBlockData converted = materialToData.get(materialData);
if (converted != null) {
return converted.getBlock().getItem();
}
// Fallback to any block
Block convertedBlock = materialToBlock.get(materialData);
if (convertedBlock != null) {
return convertedBlock.getItem();
}
}
// Fallback to matching item
Item convertedItem = materialToItem.get(materialData);
if (convertedItem != null) {
return convertedItem;
}
// Return existing item
return item;
}
public static byte toLegacyData(IBlockData blockData) {
MaterialData mappedData;
// Try exact match first
mappedData = dataToMaterial.get(blockData);
// Fallback to any block
if (mappedData == null) {
mappedData = blockToMaterial.get(blockData.getBlock());
}
return (mappedData == null) ? 0 : mappedData.getData();
}
public static Material fromLegacy(Material material) {
return fromLegacy(new MaterialData(material));
}
public static Material fromLegacy(MaterialData materialData) {
Material material = materialData.getItemType();
if (material == null || !material.isLegacy()) {
return material;
}
Material mappedData = null;
if (material.isBlock()) {
// Try exact match first
IBlockData iblock = materialToData.get(materialData);
if (iblock != null) {
mappedData = CraftMagicNumbers.getMaterial(iblock.getBlock());
}
// Fallback to any block
if (mappedData == null) {
Block block = materialToBlock.get(materialData);
if (block != null) {
mappedData = CraftMagicNumbers.getMaterial(block);
}
}
}
// Fallback to matching item
if (mappedData == null) {
Item item = materialToItem.get(materialData);
if (item != null) {
mappedData = CraftMagicNumbers.getMaterial(item);
}
}
return (mappedData == null) ? Material.AIR : mappedData;
}
public static Material[] values() {
Material[] values = Material.values();
return Arrays.copyOfRange(values, Material.LEGACY_AIR.ordinal(), values.length);
}
public static Material valueOf(String name) {
return (name.startsWith(Material.LEGACY_PREFIX)) ? Material.valueOf(name) : Material.valueOf(Material.LEGACY_PREFIX + name);
}
public static Material getMaterial(String name) {
return (name.startsWith(Material.LEGACY_PREFIX)) ? Material.getMaterial(name) : Material.getMaterial(Material.LEGACY_PREFIX + name);
}
public static Material matchMaterial(String name) {
return (name.startsWith(Material.LEGACY_PREFIX)) ? Material.matchMaterial(name) : Material.matchMaterial(Material.LEGACY_PREFIX + name);
}
public static int ordinal(Material material) {
Preconditions.checkArgument(material.isLegacy(), "ordinal on modern Material");
return material.ordinal() - Material.LEGACY_AIR.ordinal();
}
public static String name(Material material) {
return material.name().substring(Material.LEGACY_PREFIX.length());
}
public static String toString(Material material) {
return name(material);
}
public static Material[] modern_values() {
Material[] values = Material.values();
return Arrays.copyOfRange(values, 0, Material.LEGACY_AIR.ordinal());
}
static {
SPAWN_EGGS.put(EntityType.BAT, Material.BAT_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.BLAZE, Material.BLAZE_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.CAVE_SPIDER, Material.CAVE_SPIDER_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.CHICKEN, Material.CHICKEN_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.COW, Material.COW_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.CREEPER, Material.CREEPER_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.ENDERMAN, Material.ENDERMAN_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.ENDERMITE, Material.ENDERMITE_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.GHAST, Material.GHAST_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.GUARDIAN, Material.GUARDIAN_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.HORSE, Material.HORSE_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.MAGMA_CUBE, Material.MAGMA_CUBE_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.MUSHROOM_COW, Material.MOOSHROOM_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.OCELOT, Material.OCELOT_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.PIG, Material.PIG_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.RABBIT, Material.RABBIT_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SHEEP, Material.SHEEP_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SHULKER, Material.SHULKER_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SILVERFISH, Material.SILVERFISH_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SKELETON, Material.SKELETON_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SLIME, Material.SLIME_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SPIDER, Material.SPIDER_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.SQUID, Material.SQUID_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.VILLAGER, Material.VILLAGER_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.WITCH, Material.WITCH_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.WOLF, Material.WOLF_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.PIG_ZOMBIE, Material.ZOMBIE_PIGMAN_SPAWN_EGG);
SPAWN_EGGS.put(EntityType.ZOMBIE, Material.ZOMBIE_SPAWN_EGG);
DispenserRegistry.c();
for (Material material : Material.values()) {
if (!material.isLegacy()) {
continue;
}
// Handle blocks
if (material.isBlock()) {
for (byte data = 0; data < 16; data++) {
MaterialData matData = new MaterialData(material, data);
Dynamic blockTag = DataConverterFlattenData.b(material.getId() << 4 | data);
// TODO: better skull conversion, chests
if (blockTag.getString("Name").contains("%%FILTER_ME%%")) {
continue;
}
String name = blockTag.getString("Name");
// TODO: need to fix
if (name.equals("minecraft:portal")) {
name = "minecraft:nether_portal";
}
Block block = Block.REGISTRY.get(new MinecraftKey(name));
IBlockData blockData = block.getBlockData();
BlockStateList states = block.getStates();
Optional<Dynamic> propMap = blockTag.get("Properties");
if (propMap.isPresent()) {
NBTTagCompound properties = (NBTTagCompound) propMap.get().getValue();
for (String dataKey : properties.getKeys()) {
IBlockState state = states.a(dataKey);
if (state == null) {
if (whitelistedStates.contains(dataKey)) {
continue;
}
throw new IllegalStateException("No state for " + dataKey);
}
Preconditions.checkState(!properties.getString(dataKey).isEmpty(), "Empty data string");
Optional opt = state.b(properties.getString(dataKey));
blockData = blockData.set(state, (Comparable) opt.get());
}
}
if (block == Blocks.AIR) {
continue;
}
materialToData.put(matData, blockData);
if (!dataToMaterial.containsKey(blockData)) {
dataToMaterial.put(blockData, matData);
}
materialToBlock.put(matData, block);
if (!blockToMaterial.containsKey(block)) {
blockToMaterial.put(block, matData);
}
}
}
// Handle items (and second fallback for blocks)
int maxData = material.getMaxDurability() == 0 ? 16 : 1;
// Manually do oldold spawn eggs
if (material == Material.LEGACY_MONSTER_EGG) {
maxData = 121; // Vilager + 1
}
for (byte data = 0; data < maxData; data++) {
// Manually skip invalid oldold spawn
if (material == Material.LEGACY_MONSTER_EGG /*&& data != 0 && EntityType.fromId(data) == null*/) { // Mojang broke 18w19b
continue;
}
// Skip non item stacks for now (18w19b)
if (DataConverterMaterialId.a(material.getId()) == null) {
continue;
}
MaterialData matData = new MaterialData(material, data);
NBTTagCompound stack = new NBTTagCompound();
stack.setInt("id", material.getId());
stack.setShort("Damage", data);
Dynamic<NBTBase> converted = DataConverterRegistry.a().update(DataConverterTypes.ITEM_STACK, new Dynamic<NBTBase>(DynamicOpsNBT.a, stack), -1, CraftMagicNumbers.DATA_VERSION);
String newId = converted.getString("id");
// Recover spawn eggs with invalid data
if (newId.equals("minecraft:spawn_egg")) {
newId = "minecraft:pig_spawn_egg";
}
// Preconditions.checkState(newId.contains("minecraft:"), "Unknown new material for " + matData);
Item newMaterial = Item.REGISTRY.get(new MinecraftKey(newId));
materialToItem.put(matData, newMaterial);
if (!itemToMaterial.containsKey(newMaterial)) {
itemToMaterial.put(newMaterial, matData);
}
}
for (Map.Entry<EntityType, Material> entry : SPAWN_EGGS.entrySet()) {
MaterialData matData = new MaterialData(Material.LEGACY_MONSTER_EGG, (byte) entry.getKey().getTypeId());
Item newMaterial = CraftMagicNumbers.getItem(entry.getValue());
materialToItem.put(matData, newMaterial);
itemToMaterial.put(newMaterial, matData);
}
}
}
}

View File

@@ -1,43 +1,41 @@
package org.bukkit.craftbukkit.util;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.server.AdvancementDataWorld;
import net.minecraft.server.AdvancementDataWorld;
import net.minecraft.server.Block;
import net.minecraft.server.Blocks;
import net.minecraft.server.ChatDeserializer;
import net.minecraft.server.IBlockData;
import net.minecraft.server.Item;
import net.minecraft.server.MinecraftKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.MojangsonParseException;
import net.minecraft.server.MojangsonParser;
import net.minecraft.server.NBTTagCompound;
import net.minecraft.server.StatisticList;
import org.bukkit.Achievement;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Statistic;
import org.bukkit.UnsafeValues;
import org.bukkit.advancement.Advancement;
import org.bukkit.craftbukkit.CraftStatistic;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.PluginAwareness;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.UnknownDependencyException;
@SuppressWarnings("deprecation")
public final class CraftMagicNumbers implements UnsafeValues {
@@ -45,81 +43,106 @@ public final class CraftMagicNumbers implements UnsafeValues {
private CraftMagicNumbers() {}
public static Block getBlock(org.bukkit.block.Block block) {
return getBlock(block.getType());
public static IBlockData getBlock(MaterialData material) {
return getBlock(material.getItemType(), material.getData());
}
@Deprecated
// A bad method for bad magic.
public static Block getBlock(int id) {
return getBlock(Material.getMaterial(id));
public static IBlockData getBlock(Material material, byte data) {
return CraftLegacy.fromLegacyData(CraftLegacy.toLegacy(material), getBlock(material), data);
}
@Deprecated
// A bad method for bad magic.
public static int getId(Block block) {
return Block.getId(block);
public static MaterialData getMaterial(IBlockData data) {
return CraftLegacy.toLegacy(getMaterial(data.getBlock())).getNewData(toLegacyData(data));
}
public static Item getItem(Material material, short data) {
if (material.isLegacy()) {
return CraftLegacy.fromLegacyData(CraftLegacy.toLegacy(material), getItem(material), data);
}
return getItem(material);
}
public static MaterialData getMaterialData(Item item) {
return CraftLegacy.toLegacyData(getMaterial(item));
}
// ========================================================================
private static final Map<Block, Material> BLOCK_MATERIAL = new HashMap<>();
private static final Map<Item, Material> ITEM_MATERIAL = new HashMap<>();
private static final Map<Material, Item> MATERIAL_ITEM = new HashMap<>();
private static final Map<Material, Block> MATERIAL_BLOCK = new HashMap<>();
static {
for (Block block : (Iterable<Block>) Block.REGISTRY) { // Eclipse fail
BLOCK_MATERIAL.put(block, Material.getMaterial(Block.REGISTRY.b(block).getKey().toUpperCase(Locale.ROOT)));
}
for (Item item : (Iterable<Item>) Item.REGISTRY) { // Eclipse fail
ITEM_MATERIAL.put(item, Material.getMaterial(Item.REGISTRY.b(item).getKey().toUpperCase(Locale.ROOT)));
}
for (Material material : Material.values()) {
MinecraftKey key = key(material);
MATERIAL_ITEM.put(material, Item.REGISTRY.get(key));
MATERIAL_BLOCK.put(material, Block.REGISTRY.get(key));
}
}
public static Material getMaterial(Block block) {
return Material.getMaterial(Block.getId(block));
}
public static Item getItem(Material material) {
// TODO: Don't use ID
Item item = Item.getById(material.getId());
return item;
}
@Deprecated
// A bad method for bad magic.
public static Item getItem(int id) {
return Item.getById(id);
}
@Deprecated
// A bad method for bad magic.
public static int getId(Item item) {
return Item.getId(item);
return BLOCK_MATERIAL.get(block);
}
public static Material getMaterial(Item item) {
// TODO: Don't use ID
Material material = Material.getMaterial(Item.getId(item));
return ITEM_MATERIAL.getOrDefault(item, Material.AIR);
}
if (material == null) {
return Material.AIR;
}
return material;
public static Item getItem(Material material) {
return MATERIAL_ITEM.get(material);
}
public static Block getBlock(Material material) {
if (material == null) {
return null;
}
// TODO: Don't use ID
Block block = Block.getById(material.getId());
return MATERIAL_BLOCK.get(material);
}
if (block == null) {
return Blocks.AIR;
public static MinecraftKey key(Material mat) {
if (mat.isLegacy()) {
mat = CraftLegacy.fromLegacy(mat);
}
return block;
return CraftNamespacedKey.toMinecraft(mat.getKey());
}
// ========================================================================
public static byte toLegacyData(IBlockData data) {
return CraftLegacy.toLegacyData(data);
}
@Override
public Material getMaterialFromInternalName(String name) {
return getMaterial((Item) Item.REGISTRY.get(new MinecraftKey(name)));
public Material toLegacy(Material material) {
return CraftLegacy.toLegacy(material);
}
@Override
public List<String> tabCompleteInternalMaterialName(String token, List<String> completions) {
ArrayList<String> results = Lists.newArrayList();
for (MinecraftKey key : (Set<MinecraftKey>)Item.REGISTRY.keySet()) {
results.add(key.toString());
}
return StringUtil.copyPartialMatches(token, results, completions);
public Material fromLegacy(Material material) {
return CraftLegacy.fromLegacy(material);
}
@Override
public Material fromLegacy(MaterialData material) {
return CraftLegacy.fromLegacy(material);
}
@Override
public BlockData fromLegacy(Material material, byte data) {
return CraftBlockData.fromData(getBlock(material, data));
}
public static final int DATA_VERSION = 1513;
@Override
public int getDataVersion() {
return DATA_VERSION;
}
@Override
@@ -128,7 +151,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
try {
nmsStack.setTag((NBTTagCompound) MojangsonParser.parse(arguments));
} catch (MojangsonParseException ex) {
} catch (CommandSyntaxException ex) {
Logger.getLogger(CraftMagicNumbers.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -137,29 +160,6 @@ public final class CraftMagicNumbers implements UnsafeValues {
return stack;
}
@Override
public Statistic getStatisticFromInternalName(String name) {
return CraftStatistic.getBukkitStatisticByName(name);
}
@Override
public Achievement getAchievementFromInternalName(String name) {
throw new UnsupportedOperationException("Not supported in this Minecraft version.");
}
@Override
public List<String> tabCompleteInternalStatisticOrAchievementName(String token, List<String> completions) {
List<String> matches = new ArrayList<String>();
Iterator iterator = StatisticList.stats.iterator();
while (iterator.hasNext()) {
String statistic = ((net.minecraft.server.Statistic) iterator.next()).name;
if (statistic.startsWith(token)) {
matches.add(statistic);
}
}
return matches;
}
@Override
public Advancement loadAdvancement(NamespacedKey key, String advancement) {
if (Bukkit.getAdvancement(key) != null) {
@@ -172,7 +172,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
Advancement bukkit = Bukkit.getAdvancement(key);
if (bukkit != null) {
File file = new File(MinecraftServer.getServer().getAdvancementData().folder, key.getNamespace() + File.separator + key.getKey() + ".json");
File file = new File(MinecraftServer.getServer().bukkitDataPackFolder, "data" + File.separator + key.getNamespace() + File.separator + "advancements" + File.separator + key.getKey() + ".json");
file.getParentFile().mkdirs();
try {
@@ -192,10 +192,34 @@ public final class CraftMagicNumbers implements UnsafeValues {
@Override
public boolean removeAdvancement(NamespacedKey key) {
File file = new File(MinecraftServer.getServer().getAdvancementData().folder, key.getNamespace() + File.separator + key.getKey() + ".json");
File file = new File(MinecraftServer.getServer().bukkitDataPackFolder, "data" + File.separator + key.getNamespace() + File.separator + "advancements" + File.separator + key.getKey() + ".json");
return file.delete();
}
@Override
public void checkSupported(PluginDescriptionFile pdf) {
if (pdf.getAPIVersion() != null) {
if (!pdf.getAPIVersion().equals("1.13")) {
throw new UnknownDependencyException("Unsupported API version " + pdf.getAPIVersion());
}
}
}
public static boolean isLegacy(PluginDescriptionFile pdf) {
return pdf.getAPIVersion() == null;
}
@Override
public byte[] processClass(PluginDescriptionFile pdf, byte[] clazz) {
try {
clazz = Commodore.convert(clazz, !isLegacy(pdf));
} catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Fatal error trying to convert " + pdf.getFullName(), ex);
}
return clazz;
}
/**
* This helper class represents the different NBT Tags.
* <p>

View File

@@ -0,0 +1,254 @@
package org.bukkit.craftbukkit.util;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import java.util.function.Predicate;
import net.minecraft.server.AxisAlignedBB;
import net.minecraft.server.BiomeBase;
import net.minecraft.server.Block;
import net.minecraft.server.BlockPosition;
import net.minecraft.server.DifficultyDamageScaler;
import net.minecraft.server.Entity;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.EnumDirection;
import net.minecraft.server.EnumSkyBlock;
import net.minecraft.server.Fluid;
import net.minecraft.server.FluidType;
import net.minecraft.server.GeneratorAccess;
import net.minecraft.server.HeightMap;
import net.minecraft.server.IBlockData;
import net.minecraft.server.IChunkAccess;
import net.minecraft.server.IChunkProvider;
import net.minecraft.server.IDataManager;
import net.minecraft.server.ParticleParam;
import net.minecraft.server.PersistentBase;
import net.minecraft.server.PersistentCollection;
import net.minecraft.server.SoundCategory;
import net.minecraft.server.SoundEffect;
import net.minecraft.server.TickList;
import net.minecraft.server.TileEntity;
import net.minecraft.server.VoxelShape;
import net.minecraft.server.World;
import net.minecraft.server.WorldBorder;
import net.minecraft.server.WorldData;
import net.minecraft.server.WorldProvider;
import org.bukkit.event.entity.CreatureSpawnEvent;
public class DummyGeneratorAccess implements GeneratorAccess {
public static final GeneratorAccess INSTANCE = new DummyGeneratorAccess();
private DummyGeneratorAccess() {
}
@Override
public long getSeed() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public TickList<Block> I() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public TickList<FluidType> H() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public IChunkAccess c(int i, int i1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public World getMinecraftWorld() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public WorldData getWorldData() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public DifficultyDamageScaler getDamageScaler(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T extends PersistentBase> T a(Function<String, T> fnctn, String string) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public PersistentCollection s_() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void a(String string, PersistentBase pb) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public IChunkProvider getChunkProvider() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public IDataManager getDataManager() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Random m() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void update(BlockPosition bp, Block block) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public BlockPosition getSpawn() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void a(EntityHuman eh, BlockPosition bp, SoundEffect se, SoundCategory sc, float f, float f1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void addParticle(ParticleParam pp, double d, double d1, double d2, double d3, double d4, double d5) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isEmpty(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public BiomeBase getBiome(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getBrightness(EnumSkyBlock esb, BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getLightLevel(BlockPosition bp, int i) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isChunkLoaded(int i, int i1, boolean bln) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean e(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int a(HeightMap.Type type, int i, int i1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public EntityHuman a(double d, double d1, double d2, double d3, Predicate<Entity> prdct) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int c() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public WorldBorder getWorldBorder() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean a(Entity entity, VoxelShape vs) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public List<Entity> getEntities(Entity entity, AxisAlignedBB aabb) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int a(BlockPosition bp, EnumDirection ed) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean e() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getSeaLevel() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public WorldProvider o() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public TileEntity getTileEntity(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public IBlockData getType(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Fluid b(BlockPosition bp) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) {
return false;
}
@Override
public boolean addEntity(Entity entity) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason reason) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean setAir(BlockPosition blockposition) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean setAir(BlockPosition blockposition, boolean flag) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@@ -1,70 +0,0 @@
package org.bukkit.craftbukkit.util;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.Block;
import net.minecraft.server.Blocks;
import net.minecraft.server.World;
import org.bukkit.BlockChangeDelegate;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.material.MaterialData;
public class StructureGrowDelegate implements BlockChangeDelegate {
private final CraftWorld world;
private final List<BlockState> blocks = new ArrayList<BlockState>();
public StructureGrowDelegate(World world) {
this.world = world.getWorld();
}
public boolean setRawTypeId(int x, int y, int z, int type) {
return setRawTypeIdAndData(x, y, z, type, 0);
}
public boolean setRawTypeIdAndData(int x, int y, int z, int type, int data) {
BlockState state = world.getBlockAt(x, y, z).getState();
state.setTypeId(type);
state.setData(new MaterialData(type, (byte) data));
blocks.add(state);
return true;
}
public boolean setTypeId(int x, int y, int z, int typeId) {
return setRawTypeId(x, y, z, typeId);
}
public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data) {
return setRawTypeIdAndData(x, y, z, typeId, data);
}
public int getTypeId(int x, int y, int z) {
for (BlockState state : blocks) {
if (state.getX() == x && state.getY() == y && state.getZ() == z) {
return state.getTypeId();
}
}
return world.getBlockTypeIdAt(x, y, z);
}
public int getHeight() {
return world.getMaxHeight();
}
public List<BlockState> getBlocks() {
return blocks;
}
public boolean isEmpty(int x, int y, int z) {
for (BlockState state : blocks) {
if (state.getX() == x && state.getY() == y && state.getZ() == z) {
return Block.getById(state.getTypeId()) == Blocks.AIR;
}
}
return world.getBlockAt(x, y, z).isEmpty();
}
}

View File

@@ -15,7 +15,7 @@ public final class CommandPermissions {
DefaultPermissions.registerPermission(PREFIX + "kill", "Allows the user to commit suicide", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(PREFIX + "me", "Allows the user to perform a chat action", PermissionDefault.TRUE, commands);
DefaultPermissions.registerPermission(PREFIX + "tell", "Allows the user to privately message another player", PermissionDefault.TRUE, commands);
DefaultPermissions.registerPermission(PREFIX + "msg", "Allows the user to privately message another player", PermissionDefault.TRUE, commands);
DefaultPermissions.registerPermission(PREFIX + "say", "Allows the user to talk as the console", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(PREFIX + "give", "Allows the user to give items to players", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(PREFIX + "teleport", "Allows the user to teleport players", PermissionDefault.OP, commands);