mirror of https://github.com/PaperMC/Paper.git
CraftBlockData mapping
This commit is contained in:
parent
6ff47f215f
commit
59252a0fd1
|
@ -26,13 +26,16 @@ tasks.register<JavaExec>("generate") {
|
|||
classpath(sourceSets.main.map { it.runtimeClasspath })
|
||||
args(file("generated").toString(),
|
||||
project(":paper-api").sourceSets["main"].java.srcDirs.first().toString(),
|
||||
file("generatedServerTest").toString())
|
||||
file("generatedServerTest").toString(),
|
||||
project(":paper-server").sourceSets["main"].java.srcDirs.first().toString())
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
systemProperty("paper.generator.rewriter.container", file("generated").toString()) // todo move to the sourceset
|
||||
systemProperty("paper.generator.rewriter.container.api", file("generated").toString()) // todo move to the sourceset
|
||||
systemProperty("paper.generator.rewriter.container.server", file("generatedServerTest").toString()) // todo move to the sourceset
|
||||
inputs.dir("generated")
|
||||
inputs.dir("generatedServerTest")
|
||||
}
|
||||
|
||||
group = "io.papermc.paper"
|
||||
|
|
|
@ -0,0 +1,769 @@
|
|||
package org.bukkit.craftbukkit.block.data;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.SoundGroup;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.BlockSupport;
|
||||
import org.bukkit.block.PistonMoveReaction;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.structure.Mirror;
|
||||
import org.bukkit.block.structure.StructureRotation;
|
||||
import org.bukkit.craftbukkit.CraftSoundGroup;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockStates;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockSupport;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemType;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CraftBlockData implements BlockData {
|
||||
|
||||
private net.minecraft.world.level.block.state.BlockState state;
|
||||
private Map<Property<?>, Comparable<?>> parsedStates;
|
||||
|
||||
protected CraftBlockData() {
|
||||
throw new AssertionError("Template Constructor");
|
||||
}
|
||||
|
||||
protected CraftBlockData(net.minecraft.world.level.block.state.BlockState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getMaterial() {
|
||||
return this.state.getBukkitMaterial(); // Paper - optimise getType calls
|
||||
}
|
||||
|
||||
public net.minecraft.world.level.block.state.BlockState getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a given BlockStateEnum's value as its Bukkit counterpart.
|
||||
*
|
||||
* @param nms the NMS state to convert
|
||||
* @param bukkit the Bukkit class
|
||||
* @param <B> the type
|
||||
* @return the matching Bukkit type
|
||||
*/
|
||||
protected <B extends Enum<B>> B get(EnumProperty<?> nms, Class<B> bukkit) {
|
||||
return CraftBlockData.toBukkit(this.state.getValue(nms), bukkit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all values from the given BlockStateEnum to their appropriate
|
||||
* Bukkit counterpart.
|
||||
*
|
||||
* @param nms the NMS state to get values from
|
||||
* @param bukkit the bukkit class to convert the values to
|
||||
* @param <B> the bukkit class type
|
||||
* @return an immutable Set of values in their appropriate Bukkit type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <B extends Enum<B>> Set<B> getValues(EnumProperty<?> nms, Class<B> bukkit) {
|
||||
ImmutableSet.Builder<B> values = ImmutableSet.builder();
|
||||
|
||||
for (Enum<?> e : nms.getPossibleValues()) {
|
||||
values.add(CraftBlockData.toBukkit(e, bukkit));
|
||||
}
|
||||
|
||||
return values.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given {@link EnumProperty} with the matching enum from Bukkit.
|
||||
*
|
||||
* @param nms the NMS BlockStateEnum to set
|
||||
* @param bukkit the matching Bukkit Enum
|
||||
* @param <B> the Bukkit type
|
||||
* @param <N> the NMS type
|
||||
*/
|
||||
protected <B extends Enum<B>, N extends Enum<N> & StringRepresentable> void set(EnumProperty<N> nms, Enum<B> bukkit) {
|
||||
this.parsedStates = null;
|
||||
this.state = this.state.setValue(nms, CraftBlockData.toNMS(bukkit, nms.getValueClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData merge(BlockData data) {
|
||||
CraftBlockData craft = (CraftBlockData) data;
|
||||
Preconditions.checkArgument(craft.parsedStates != null, "Data not created via string parsing");
|
||||
Preconditions.checkArgument(this.state.getBlock() == craft.state.getBlock(), "States have different types (got %s, expected %s)", data, this);
|
||||
|
||||
CraftBlockData clone = (CraftBlockData) this.clone();
|
||||
clone.parsedStates = null;
|
||||
|
||||
for (Property parsed : craft.parsedStates.keySet()) {
|
||||
clone.state = clone.state.setValue(parsed, craft.state.getValue(parsed));
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(BlockData data) {
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(data instanceof CraftBlockData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CraftBlockData craft = (CraftBlockData) data;
|
||||
if (this.state.getBlock() != craft.state.getBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fastpath an exact match
|
||||
boolean exactMatch = this.equals(data);
|
||||
|
||||
// If that failed, do a merge and check
|
||||
if (!exactMatch && craft.parsedStates != null) {
|
||||
return this.merge(data).equals(this);
|
||||
}
|
||||
|
||||
return exactMatch;
|
||||
}
|
||||
|
||||
private static final Map<Class<? extends Enum<?>>, Enum<?>[]> ENUM_VALUES = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - cache block data strings; make thread safe
|
||||
|
||||
/**
|
||||
* Convert an NMS Enum (usually a BlockStateEnum) to its appropriate Bukkit
|
||||
* enum from the given class.
|
||||
*
|
||||
* @throws IllegalStateException if the Enum could not be converted
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <B extends Enum<B>> B toBukkit(Enum<?> nms, Class<B> bukkit) {
|
||||
if (nms instanceof Direction) {
|
||||
return (B) CraftBlock.notchToBlockFace((Direction) nms);
|
||||
}
|
||||
return (B) CraftBlockData.ENUM_VALUES.computeIfAbsent(bukkit, Class::getEnumConstants)[nms.ordinal()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a given Bukkit enum to its matching NMS enum type.
|
||||
*
|
||||
* @param bukkit the Bukkit enum to convert
|
||||
* @param nms the NMS class
|
||||
* @return the matching NMS type
|
||||
* @throws IllegalStateException if the Enum could not be converted
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <N extends Enum<N> & StringRepresentable> N toNMS(Enum<?> bukkit, Class<N> nms) {
|
||||
if (bukkit instanceof BlockFace) {
|
||||
return (N) CraftBlock.blockFaceToNotch((BlockFace) bukkit);
|
||||
}
|
||||
return (N) CraftBlockData.ENUM_VALUES.computeIfAbsent(nms, Class::getEnumConstants)[bukkit.ordinal()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value of a given state.
|
||||
*
|
||||
* @param ibs the state to check
|
||||
* @param <T> the type
|
||||
* @return the current value of the given state
|
||||
*/
|
||||
protected <T extends Comparable<T>> T get(Property<T> ibs) {
|
||||
// Straight integer or boolean getter
|
||||
return this.state.getValue(ibs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specified state's value.
|
||||
*
|
||||
* @param ibs the state to set
|
||||
* @param v the new value
|
||||
* @param <T> the state's type
|
||||
* @param <V> the value's type. Must match the state's type.
|
||||
*/
|
||||
public <T extends Comparable<T>, V extends T> void set(Property<T> ibs, V v) {
|
||||
// Straight integer or boolean setter
|
||||
this.parsedStates = null;
|
||||
this.state = this.state.setValue(ibs, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return this.toString(this.state.getValues());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString(boolean hideUnspecified) {
|
||||
return (hideUnspecified && this.parsedStates != null) ? this.toString(this.parsedStates) : this.getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData clone() {
|
||||
try {
|
||||
return (BlockData) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new AssertionError("Clone not supported", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftBlockData{" + this.getAsString() + "}";
|
||||
}
|
||||
|
||||
// Mimicked from BlockDataAbstract#toString()
|
||||
public String toString(Map<Property<?>, Comparable<?>> states) {
|
||||
StringBuilder stateString = new StringBuilder(BuiltInRegistries.BLOCK.getKey(this.state.getBlock()).toString());
|
||||
|
||||
if (!states.isEmpty()) {
|
||||
stateString.append('[');
|
||||
stateString.append(states.entrySet().stream().map(StateHolder.PROPERTY_ENTRY_TO_STRING_FUNCTION).collect(Collectors.joining(",")));
|
||||
stateString.append(']');
|
||||
}
|
||||
|
||||
return stateString.toString();
|
||||
}
|
||||
|
||||
public CompoundTag toStates() {
|
||||
CompoundTag compound = new CompoundTag();
|
||||
|
||||
for (Map.Entry<Property<?>, Comparable<?>> entry : this.state.getValues().entrySet()) {
|
||||
Property iblockstate = (Property) entry.getKey();
|
||||
|
||||
compound.putString(iblockstate.getName(), iblockstate.getName(entry.getValue()));
|
||||
}
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof CraftBlockData && this.state.equals(((CraftBlockData) obj).state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.state.hashCode();
|
||||
}
|
||||
|
||||
protected static BooleanProperty getBoolean(String name) {
|
||||
throw new AssertionError("Template Method");
|
||||
}
|
||||
|
||||
protected static BooleanProperty getBoolean(String name, boolean optional) {
|
||||
throw new AssertionError("Template Method");
|
||||
}
|
||||
|
||||
protected static EnumProperty<?> getEnum(String name) {
|
||||
throw new AssertionError("Template Method");
|
||||
}
|
||||
|
||||
protected static IntegerProperty getInteger(String name) {
|
||||
throw new AssertionError("Template Method");
|
||||
}
|
||||
|
||||
protected static BooleanProperty getBoolean(Class<? extends Block> block, String name) {
|
||||
return (BooleanProperty) CraftBlockData.getState(block, name, false);
|
||||
}
|
||||
|
||||
protected static BooleanProperty getBoolean(Class<? extends Block> block, String name, boolean optional) {
|
||||
return (BooleanProperty) CraftBlockData.getState(block, name, optional);
|
||||
}
|
||||
|
||||
protected static EnumProperty<?> getEnum(Class<? extends Block> block, String name) {
|
||||
return (EnumProperty<?>) CraftBlockData.getState(block, name, false);
|
||||
}
|
||||
|
||||
protected static IntegerProperty getInteger(Class<? extends Block> block, String name) {
|
||||
return (IntegerProperty) CraftBlockData.getState(block, name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specified {@link Property} from a given block's class with a
|
||||
* given name
|
||||
*
|
||||
* @param block the class to retrieve the state from
|
||||
* @param name the name of the state to retrieve
|
||||
* @param optional if the state can be null
|
||||
* @return the specified state or null
|
||||
* @throws IllegalStateException if the state is null and {@code optional}
|
||||
* is false.
|
||||
*/
|
||||
private static Property<?> getState(Class<? extends Block> block, String name, boolean optional) {
|
||||
Property<?> state = null;
|
||||
|
||||
for (Block instance : BuiltInRegistries.BLOCK) {
|
||||
if (instance.getClass() == block) {
|
||||
if (state == null) {
|
||||
state = instance.getStateDefinition().getProperty(name);
|
||||
} else {
|
||||
Property<?> newState = instance.getStateDefinition().getProperty(name);
|
||||
|
||||
Preconditions.checkState(state == newState, "State mistmatch %s,%s", state, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Preconditions.checkState(optional || state != null, "Null state for %s,%s", block, name);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum value allowed by the BlockStateInteger.
|
||||
*
|
||||
* @param state the state to check
|
||||
* @return the minimum value allowed
|
||||
*/
|
||||
protected static int getMin(IntegerProperty state) {
|
||||
return state.min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum value allowed by the BlockStateInteger.
|
||||
*
|
||||
* @param state the state to check
|
||||
* @return the maximum value allowed
|
||||
*/
|
||||
protected static int getMax(IntegerProperty state) {
|
||||
return state.max;
|
||||
}
|
||||
|
||||
public static final BlockFace[] ROTATION_CYCLE = {
|
||||
BlockFace.SOUTH, BlockFace.SOUTH_SOUTH_WEST, BlockFace.SOUTH_WEST, BlockFace.WEST_SOUTH_WEST,
|
||||
BlockFace.WEST, BlockFace.WEST_NORTH_WEST, BlockFace.NORTH_WEST, BlockFace.NORTH_NORTH_WEST,
|
||||
BlockFace.NORTH, BlockFace.NORTH_NORTH_EAST, BlockFace.NORTH_EAST, BlockFace.EAST_NORTH_EAST,
|
||||
BlockFace.EAST, BlockFace.EAST_SOUTH_EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH_SOUTH_EAST
|
||||
};
|
||||
|
||||
//
|
||||
private static final Map<Class<? extends Block>, Function<net.minecraft.world.level.block.state.BlockState, CraftBlockData>> MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
//<editor-fold desc="CraftBlockData Registration" defaultstate="collapsed">
|
||||
// Paper start - Generated/CraftBlockData#MAP
|
||||
// @GeneratedFrom 1.20.4
|
||||
register(net.minecraft.world.level.block.AmethystClusterBlock.class, org.bukkit.craftbukkit.block.impl.CraftAmethystCluster::new);
|
||||
register(net.minecraft.world.level.block.AnvilBlock.class, org.bukkit.craftbukkit.block.impl.CraftAnvil::new);
|
||||
register(net.minecraft.world.level.block.AttachedStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftAttachedStem::new);
|
||||
register(net.minecraft.world.level.block.BambooStalkBlock.class, org.bukkit.craftbukkit.block.impl.CraftBambooStalk::new);
|
||||
register(net.minecraft.world.level.block.BannerBlock.class, org.bukkit.craftbukkit.block.impl.CraftBanner::new);
|
||||
register(net.minecraft.world.level.block.BarrelBlock.class, org.bukkit.craftbukkit.block.impl.CraftBarrel::new);
|
||||
register(net.minecraft.world.level.block.BarrierBlock.class, org.bukkit.craftbukkit.block.impl.CraftBarrier::new);
|
||||
register(net.minecraft.world.level.block.BaseCoralFanBlock.class, org.bukkit.craftbukkit.block.impl.CraftBaseCoralFan::new);
|
||||
register(net.minecraft.world.level.block.BaseCoralPlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftBaseCoralPlant::new);
|
||||
register(net.minecraft.world.level.block.BaseCoralWallFanBlock.class, org.bukkit.craftbukkit.block.impl.CraftBaseCoralWallFan::new);
|
||||
register(net.minecraft.world.level.block.BedBlock.class, org.bukkit.craftbukkit.block.impl.CraftBed::new);
|
||||
register(net.minecraft.world.level.block.BeehiveBlock.class, org.bukkit.craftbukkit.block.impl.CraftBeehive::new);
|
||||
register(net.minecraft.world.level.block.BeetrootBlock.class, org.bukkit.craftbukkit.block.impl.CraftBeetroot::new);
|
||||
register(net.minecraft.world.level.block.BellBlock.class, org.bukkit.craftbukkit.block.impl.CraftBell::new);
|
||||
register(net.minecraft.world.level.block.BigDripleafBlock.class, org.bukkit.craftbukkit.block.impl.CraftBigDripleaf::new);
|
||||
register(net.minecraft.world.level.block.BigDripleafStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftBigDripleafStem::new);
|
||||
register(net.minecraft.world.level.block.BlastFurnaceBlock.class, org.bukkit.craftbukkit.block.impl.CraftBlastFurnace::new);
|
||||
register(net.minecraft.world.level.block.BrewingStandBlock.class, org.bukkit.craftbukkit.block.impl.CraftBrewingStand::new);
|
||||
register(net.minecraft.world.level.block.BrushableBlock.class, org.bukkit.craftbukkit.block.impl.CraftBrushable::new);
|
||||
register(net.minecraft.world.level.block.BubbleColumnBlock.class, org.bukkit.craftbukkit.block.impl.CraftBubbleColumn::new);
|
||||
register(net.minecraft.world.level.block.ButtonBlock.class, org.bukkit.craftbukkit.block.impl.CraftButton::new);
|
||||
register(net.minecraft.world.level.block.CactusBlock.class, org.bukkit.craftbukkit.block.impl.CraftCactus::new);
|
||||
register(net.minecraft.world.level.block.CakeBlock.class, org.bukkit.craftbukkit.block.impl.CraftCake::new);
|
||||
register(net.minecraft.world.level.block.CalibratedSculkSensorBlock.class, org.bukkit.craftbukkit.block.impl.CraftCalibratedSculkSensor::new);
|
||||
register(net.minecraft.world.level.block.CampfireBlock.class, org.bukkit.craftbukkit.block.impl.CraftCampfire::new);
|
||||
register(net.minecraft.world.level.block.CandleBlock.class, org.bukkit.craftbukkit.block.impl.CraftCandle::new);
|
||||
register(net.minecraft.world.level.block.CandleCakeBlock.class, org.bukkit.craftbukkit.block.impl.CraftCandleCake::new);
|
||||
register(net.minecraft.world.level.block.CarrotBlock.class, org.bukkit.craftbukkit.block.impl.CraftCarrot::new);
|
||||
register(net.minecraft.world.level.block.CarvedPumpkinBlock.class, org.bukkit.craftbukkit.block.impl.CraftCarvedPumpkin::new);
|
||||
register(net.minecraft.world.level.block.CaveVinesBlock.class, org.bukkit.craftbukkit.block.impl.CraftCaveVines::new);
|
||||
register(net.minecraft.world.level.block.CaveVinesPlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftCaveVinesPlant::new);
|
||||
register(net.minecraft.world.level.block.CeilingHangingSignBlock.class, org.bukkit.craftbukkit.block.impl.CraftCeilingHangingSign::new);
|
||||
register(net.minecraft.world.level.block.ChainBlock.class, org.bukkit.craftbukkit.block.impl.CraftChain::new);
|
||||
register(net.minecraft.world.level.block.CherryLeavesBlock.class, org.bukkit.craftbukkit.block.impl.CraftCherryLeaves::new);
|
||||
register(net.minecraft.world.level.block.ChestBlock.class, org.bukkit.craftbukkit.block.impl.CraftChest::new);
|
||||
register(net.minecraft.world.level.block.ChiseledBookShelfBlock.class, org.bukkit.craftbukkit.block.impl.CraftChiseledBookShelf::new);
|
||||
register(net.minecraft.world.level.block.ChorusFlowerBlock.class, org.bukkit.craftbukkit.block.impl.CraftChorusFlower::new);
|
||||
register(net.minecraft.world.level.block.ChorusPlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftChorusPlant::new);
|
||||
register(net.minecraft.world.level.block.CocoaBlock.class, org.bukkit.craftbukkit.block.impl.CraftCocoa::new);
|
||||
register(net.minecraft.world.level.block.CommandBlock.class, org.bukkit.craftbukkit.block.impl.CraftCommandBlock::new);
|
||||
register(net.minecraft.world.level.block.ComparatorBlock.class, org.bukkit.craftbukkit.block.impl.CraftComparator::new);
|
||||
register(net.minecraft.world.level.block.ComposterBlock.class, org.bukkit.craftbukkit.block.impl.CraftComposter::new);
|
||||
register(net.minecraft.world.level.block.ConduitBlock.class, org.bukkit.craftbukkit.block.impl.CraftConduit::new);
|
||||
register(net.minecraft.world.level.block.CopperBulbBlock.class, org.bukkit.craftbukkit.block.impl.CraftCopperBulb::new);
|
||||
register(net.minecraft.world.level.block.CoralFanBlock.class, org.bukkit.craftbukkit.block.impl.CraftCoralFan::new);
|
||||
register(net.minecraft.world.level.block.CoralPlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftCoralPlant::new);
|
||||
register(net.minecraft.world.level.block.CoralWallFanBlock.class, org.bukkit.craftbukkit.block.impl.CraftCoralWallFan::new);
|
||||
register(net.minecraft.world.level.block.CrafterBlock.class, org.bukkit.craftbukkit.block.impl.CraftCrafter::new);
|
||||
register(net.minecraft.world.level.block.CropBlock.class, org.bukkit.craftbukkit.block.impl.CraftCrop::new);
|
||||
register(net.minecraft.world.level.block.DaylightDetectorBlock.class, org.bukkit.craftbukkit.block.impl.CraftDaylightDetector::new);
|
||||
register(net.minecraft.world.level.block.DecoratedPotBlock.class, org.bukkit.craftbukkit.block.impl.CraftDecoratedPot::new);
|
||||
register(net.minecraft.world.level.block.DetectorRailBlock.class, org.bukkit.craftbukkit.block.impl.CraftDetectorRail::new);
|
||||
register(net.minecraft.world.level.block.DispenserBlock.class, org.bukkit.craftbukkit.block.impl.CraftDispenser::new);
|
||||
register(net.minecraft.world.level.block.DoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoor::new);
|
||||
register(net.minecraft.world.level.block.DoublePlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoublePlant::new);
|
||||
register(net.minecraft.world.level.block.DropperBlock.class, org.bukkit.craftbukkit.block.impl.CraftDropper::new);
|
||||
register(net.minecraft.world.level.block.EndPortalFrameBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndPortalFrame::new);
|
||||
register(net.minecraft.world.level.block.EndRodBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndRod::new);
|
||||
register(net.minecraft.world.level.block.EnderChestBlock.class, org.bukkit.craftbukkit.block.impl.CraftEnderChest::new);
|
||||
register(net.minecraft.world.level.block.EquipableCarvedPumpkinBlock.class, org.bukkit.craftbukkit.block.impl.CraftEquipableCarvedPumpkin::new);
|
||||
register(net.minecraft.world.level.block.FarmBlock.class, org.bukkit.craftbukkit.block.impl.CraftFarm::new);
|
||||
register(net.minecraft.world.level.block.FenceBlock.class, org.bukkit.craftbukkit.block.impl.CraftFence::new);
|
||||
register(net.minecraft.world.level.block.FenceGateBlock.class, org.bukkit.craftbukkit.block.impl.CraftFenceGate::new);
|
||||
register(net.minecraft.world.level.block.FireBlock.class, org.bukkit.craftbukkit.block.impl.CraftFire::new);
|
||||
register(net.minecraft.world.level.block.FrostedIceBlock.class, org.bukkit.craftbukkit.block.impl.CraftFrostedIce::new);
|
||||
register(net.minecraft.world.level.block.FurnaceBlock.class, org.bukkit.craftbukkit.block.impl.CraftFurnace::new);
|
||||
register(net.minecraft.world.level.block.GlazedTerracottaBlock.class, org.bukkit.craftbukkit.block.impl.CraftGlazedTerracotta::new);
|
||||
register(net.minecraft.world.level.block.GlowLichenBlock.class, org.bukkit.craftbukkit.block.impl.CraftGlowLichen::new);
|
||||
register(net.minecraft.world.level.block.GrassBlock.class, org.bukkit.craftbukkit.block.impl.CraftGrass::new);
|
||||
register(net.minecraft.world.level.block.GrindstoneBlock.class, org.bukkit.craftbukkit.block.impl.CraftGrindstone::new);
|
||||
register(net.minecraft.world.level.block.HangingRootsBlock.class, org.bukkit.craftbukkit.block.impl.CraftHangingRoots::new);
|
||||
register(net.minecraft.world.level.block.HayBlock.class, org.bukkit.craftbukkit.block.impl.CraftHay::new);
|
||||
register(net.minecraft.world.level.block.HopperBlock.class, org.bukkit.craftbukkit.block.impl.CraftHopper::new);
|
||||
register(net.minecraft.world.level.block.HugeMushroomBlock.class, org.bukkit.craftbukkit.block.impl.CraftHugeMushroom::new);
|
||||
register(net.minecraft.world.level.block.InfestedRotatedPillarBlock.class, org.bukkit.craftbukkit.block.impl.CraftInfestedRotatedPillar::new);
|
||||
register(net.minecraft.world.level.block.IronBarsBlock.class, org.bukkit.craftbukkit.block.impl.CraftIronBars::new);
|
||||
register(net.minecraft.world.level.block.JigsawBlock.class, org.bukkit.craftbukkit.block.impl.CraftJigsaw::new);
|
||||
register(net.minecraft.world.level.block.JukeboxBlock.class, org.bukkit.craftbukkit.block.impl.CraftJukebox::new);
|
||||
register(net.minecraft.world.level.block.KelpBlock.class, org.bukkit.craftbukkit.block.impl.CraftKelp::new);
|
||||
register(net.minecraft.world.level.block.LadderBlock.class, org.bukkit.craftbukkit.block.impl.CraftLadder::new);
|
||||
register(net.minecraft.world.level.block.LanternBlock.class, org.bukkit.craftbukkit.block.impl.CraftLantern::new);
|
||||
register(net.minecraft.world.level.block.LayeredCauldronBlock.class, org.bukkit.craftbukkit.block.impl.CraftLayeredCauldron::new);
|
||||
register(net.minecraft.world.level.block.LeavesBlock.class, org.bukkit.craftbukkit.block.impl.CraftLeaves::new);
|
||||
register(net.minecraft.world.level.block.LecternBlock.class, org.bukkit.craftbukkit.block.impl.CraftLectern::new);
|
||||
register(net.minecraft.world.level.block.LeverBlock.class, org.bukkit.craftbukkit.block.impl.CraftLever::new);
|
||||
register(net.minecraft.world.level.block.LightBlock.class, org.bukkit.craftbukkit.block.impl.CraftLight::new);
|
||||
register(net.minecraft.world.level.block.LightningRodBlock.class, org.bukkit.craftbukkit.block.impl.CraftLightningRod::new);
|
||||
register(net.minecraft.world.level.block.LiquidBlock.class, org.bukkit.craftbukkit.block.impl.CraftLiquid::new);
|
||||
register(net.minecraft.world.level.block.LoomBlock.class, org.bukkit.craftbukkit.block.impl.CraftLoom::new);
|
||||
register(net.minecraft.world.level.block.MangroveLeavesBlock.class, org.bukkit.craftbukkit.block.impl.CraftMangroveLeaves::new);
|
||||
register(net.minecraft.world.level.block.MangrovePropaguleBlock.class, org.bukkit.craftbukkit.block.impl.CraftMangrovePropagule::new);
|
||||
register(net.minecraft.world.level.block.MangroveRootsBlock.class, org.bukkit.craftbukkit.block.impl.CraftMangroveRoots::new);
|
||||
register(net.minecraft.world.level.block.MyceliumBlock.class, org.bukkit.craftbukkit.block.impl.CraftMycelium::new);
|
||||
register(net.minecraft.world.level.block.NetherPortalBlock.class, org.bukkit.craftbukkit.block.impl.CraftNetherPortal::new);
|
||||
register(net.minecraft.world.level.block.NetherWartBlock.class, org.bukkit.craftbukkit.block.impl.CraftNetherWart::new);
|
||||
register(net.minecraft.world.level.block.NoteBlock.class, org.bukkit.craftbukkit.block.impl.CraftNoteBlock::new);
|
||||
register(net.minecraft.world.level.block.ObserverBlock.class, org.bukkit.craftbukkit.block.impl.CraftObserver::new);
|
||||
register(net.minecraft.world.level.block.PiglinWallSkullBlock.class, org.bukkit.craftbukkit.block.impl.CraftPiglinWallSkull::new);
|
||||
register(net.minecraft.world.level.block.PinkPetalsBlock.class, org.bukkit.craftbukkit.block.impl.CraftPinkPetals::new);
|
||||
register(net.minecraft.world.level.block.PitcherCropBlock.class, org.bukkit.craftbukkit.block.impl.CraftPitcherCrop::new);
|
||||
register(net.minecraft.world.level.block.PlayerHeadBlock.class, org.bukkit.craftbukkit.block.impl.CraftPlayerHead::new);
|
||||
register(net.minecraft.world.level.block.PlayerWallHeadBlock.class, org.bukkit.craftbukkit.block.impl.CraftPlayerWallHead::new);
|
||||
register(net.minecraft.world.level.block.PointedDripstoneBlock.class, org.bukkit.craftbukkit.block.impl.CraftPointedDripstone::new);
|
||||
register(net.minecraft.world.level.block.PotatoBlock.class, org.bukkit.craftbukkit.block.impl.CraftPotato::new);
|
||||
register(net.minecraft.world.level.block.PoweredRailBlock.class, org.bukkit.craftbukkit.block.impl.CraftPoweredRail::new);
|
||||
register(net.minecraft.world.level.block.PressurePlateBlock.class, org.bukkit.craftbukkit.block.impl.CraftPressurePlate::new);
|
||||
register(net.minecraft.world.level.block.RailBlock.class, org.bukkit.craftbukkit.block.impl.CraftRail::new);
|
||||
register(net.minecraft.world.level.block.RedStoneOreBlock.class, org.bukkit.craftbukkit.block.impl.CraftRedStoneOre::new);
|
||||
register(net.minecraft.world.level.block.RedStoneWireBlock.class, org.bukkit.craftbukkit.block.impl.CraftRedStoneWire::new);
|
||||
register(net.minecraft.world.level.block.RedstoneLampBlock.class, org.bukkit.craftbukkit.block.impl.CraftRedstoneLamp::new);
|
||||
register(net.minecraft.world.level.block.RedstoneTorchBlock.class, org.bukkit.craftbukkit.block.impl.CraftRedstoneTorch::new);
|
||||
register(net.minecraft.world.level.block.RedstoneWallTorchBlock.class, org.bukkit.craftbukkit.block.impl.CraftRedstoneWallTorch::new);
|
||||
register(net.minecraft.world.level.block.RepeaterBlock.class, org.bukkit.craftbukkit.block.impl.CraftRepeater::new);
|
||||
register(net.minecraft.world.level.block.RespawnAnchorBlock.class, org.bukkit.craftbukkit.block.impl.CraftRespawnAnchor::new);
|
||||
register(net.minecraft.world.level.block.RotatedPillarBlock.class, org.bukkit.craftbukkit.block.impl.CraftRotatedPillar::new);
|
||||
register(net.minecraft.world.level.block.SaplingBlock.class, org.bukkit.craftbukkit.block.impl.CraftSapling::new);
|
||||
register(net.minecraft.world.level.block.ScaffoldingBlock.class, org.bukkit.craftbukkit.block.impl.CraftScaffolding::new);
|
||||
register(net.minecraft.world.level.block.SculkCatalystBlock.class, org.bukkit.craftbukkit.block.impl.CraftSculkCatalyst::new);
|
||||
register(net.minecraft.world.level.block.SculkSensorBlock.class, org.bukkit.craftbukkit.block.impl.CraftSculkSensor::new);
|
||||
register(net.minecraft.world.level.block.SculkShriekerBlock.class, org.bukkit.craftbukkit.block.impl.CraftSculkShrieker::new);
|
||||
register(net.minecraft.world.level.block.SculkVeinBlock.class, org.bukkit.craftbukkit.block.impl.CraftSculkVein::new);
|
||||
register(net.minecraft.world.level.block.SeaPickleBlock.class, org.bukkit.craftbukkit.block.impl.CraftSeaPickle::new);
|
||||
register(net.minecraft.world.level.block.ShulkerBoxBlock.class, org.bukkit.craftbukkit.block.impl.CraftShulkerBox::new);
|
||||
register(net.minecraft.world.level.block.SkullBlock.class, org.bukkit.craftbukkit.block.impl.CraftSkull::new);
|
||||
register(net.minecraft.world.level.block.SlabBlock.class, org.bukkit.craftbukkit.block.impl.CraftSlab::new);
|
||||
register(net.minecraft.world.level.block.SmallDripleafBlock.class, org.bukkit.craftbukkit.block.impl.CraftSmallDripleaf::new);
|
||||
register(net.minecraft.world.level.block.SmokerBlock.class, org.bukkit.craftbukkit.block.impl.CraftSmoker::new);
|
||||
register(net.minecraft.world.level.block.SnifferEggBlock.class, org.bukkit.craftbukkit.block.impl.CraftSnifferEgg::new);
|
||||
register(net.minecraft.world.level.block.SnowLayerBlock.class, org.bukkit.craftbukkit.block.impl.CraftSnowLayer::new);
|
||||
register(net.minecraft.world.level.block.SnowyDirtBlock.class, org.bukkit.craftbukkit.block.impl.CraftSnowyDirt::new);
|
||||
register(net.minecraft.world.level.block.StainedGlassPaneBlock.class, org.bukkit.craftbukkit.block.impl.CraftStainedGlassPane::new);
|
||||
register(net.minecraft.world.level.block.StairBlock.class, org.bukkit.craftbukkit.block.impl.CraftStair::new);
|
||||
register(net.minecraft.world.level.block.StandingSignBlock.class, org.bukkit.craftbukkit.block.impl.CraftStandingSign::new);
|
||||
register(net.minecraft.world.level.block.StemBlock.class, org.bukkit.craftbukkit.block.impl.CraftStem::new);
|
||||
register(net.minecraft.world.level.block.StonecutterBlock.class, org.bukkit.craftbukkit.block.impl.CraftStonecutter::new);
|
||||
register(net.minecraft.world.level.block.StructureBlock.class, org.bukkit.craftbukkit.block.impl.CraftStructureBlock::new);
|
||||
register(net.minecraft.world.level.block.SugarCaneBlock.class, org.bukkit.craftbukkit.block.impl.CraftSugarCane::new);
|
||||
register(net.minecraft.world.level.block.SweetBerryBushBlock.class, org.bukkit.craftbukkit.block.impl.CraftSweetBerryBush::new);
|
||||
register(net.minecraft.world.level.block.TallFlowerBlock.class, org.bukkit.craftbukkit.block.impl.CraftTallFlower::new);
|
||||
register(net.minecraft.world.level.block.TallSeagrassBlock.class, org.bukkit.craftbukkit.block.impl.CraftTallSeagrass::new);
|
||||
register(net.minecraft.world.level.block.TargetBlock.class, org.bukkit.craftbukkit.block.impl.CraftTarget::new);
|
||||
register(net.minecraft.world.level.block.TntBlock.class, org.bukkit.craftbukkit.block.impl.CraftTnt::new);
|
||||
register(net.minecraft.world.level.block.TorchflowerCropBlock.class, org.bukkit.craftbukkit.block.impl.CraftTorchflowerCrop::new);
|
||||
register(net.minecraft.world.level.block.TrapDoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftTrapDoor::new);
|
||||
register(net.minecraft.world.level.block.TrappedChestBlock.class, org.bukkit.craftbukkit.block.impl.CraftTrappedChest::new);
|
||||
register(net.minecraft.world.level.block.TrialSpawnerBlock.class, org.bukkit.craftbukkit.block.impl.CraftTrialSpawner::new);
|
||||
register(net.minecraft.world.level.block.TripWireBlock.class, org.bukkit.craftbukkit.block.impl.CraftTripWire::new);
|
||||
register(net.minecraft.world.level.block.TripWireHookBlock.class, org.bukkit.craftbukkit.block.impl.CraftTripWireHook::new);
|
||||
register(net.minecraft.world.level.block.TurtleEggBlock.class, org.bukkit.craftbukkit.block.impl.CraftTurtleEgg::new);
|
||||
register(net.minecraft.world.level.block.TwistingVinesBlock.class, org.bukkit.craftbukkit.block.impl.CraftTwistingVines::new);
|
||||
register(net.minecraft.world.level.block.VineBlock.class, org.bukkit.craftbukkit.block.impl.CraftVine::new);
|
||||
register(net.minecraft.world.level.block.WallBannerBlock.class, org.bukkit.craftbukkit.block.impl.CraftWallBanner::new);
|
||||
register(net.minecraft.world.level.block.WallBlock.class, org.bukkit.craftbukkit.block.impl.CraftWall::new);
|
||||
register(net.minecraft.world.level.block.WallHangingSignBlock.class, org.bukkit.craftbukkit.block.impl.CraftWallHangingSign::new);
|
||||
register(net.minecraft.world.level.block.WallSignBlock.class, org.bukkit.craftbukkit.block.impl.CraftWallSign::new);
|
||||
register(net.minecraft.world.level.block.WallSkullBlock.class, org.bukkit.craftbukkit.block.impl.CraftWallSkull::new);
|
||||
register(net.minecraft.world.level.block.WallTorchBlock.class, org.bukkit.craftbukkit.block.impl.CraftWallTorch::new);
|
||||
register(net.minecraft.world.level.block.WaterloggedTransparentBlock.class, org.bukkit.craftbukkit.block.impl.CraftWaterloggedTransparent::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperBulbBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperBulb::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperDoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperDoor::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperGrateBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperGrate::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperSlabBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperSlab::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperStairBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperStair::new);
|
||||
register(net.minecraft.world.level.block.WeatheringCopperTrapDoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeatheringCopperTrapDoor::new);
|
||||
register(net.minecraft.world.level.block.WeepingVinesBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeepingVines::new);
|
||||
register(net.minecraft.world.level.block.WeightedPressurePlateBlock.class, org.bukkit.craftbukkit.block.impl.CraftWeightedPressurePlate::new);
|
||||
register(net.minecraft.world.level.block.WitherSkullBlock.class, org.bukkit.craftbukkit.block.impl.CraftWitherSkull::new);
|
||||
register(net.minecraft.world.level.block.WitherWallSkullBlock.class, org.bukkit.craftbukkit.block.impl.CraftWitherWallSkull::new);
|
||||
register(net.minecraft.world.level.block.piston.MovingPistonBlock.class, org.bukkit.craftbukkit.block.impl.CraftMovingPiston::new);
|
||||
register(net.minecraft.world.level.block.piston.PistonBaseBlock.class, org.bukkit.craftbukkit.block.impl.CraftPistonBase::new);
|
||||
register(net.minecraft.world.level.block.piston.PistonHeadBlock.class, org.bukkit.craftbukkit.block.impl.CraftPistonHead::new);
|
||||
// Paper end - Generated/CraftBlockData#MAP
|
||||
//</editor-fold>
|
||||
}
|
||||
|
||||
private static void register(Class<? extends Block> nms, Function<net.minecraft.world.level.block.state.BlockState, CraftBlockData> bukkit) {
|
||||
Preconditions.checkState(CraftBlockData.MAP.put(nms, bukkit) == null, "Duplicate mapping %s->%s", nms, bukkit);
|
||||
}
|
||||
|
||||
// Paper start - cache block data strings
|
||||
private static Map<String, CraftBlockData> stringDataCache = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
// cache all of the default states at startup, will not cache ones with the custom states inside of the
|
||||
// brackets in a different order, though
|
||||
reloadCache();
|
||||
}
|
||||
|
||||
public static void reloadCache() {
|
||||
stringDataCache.clear();
|
||||
Block.BLOCK_STATE_REGISTRY.forEach(blockData -> stringDataCache.put(blockData.toString(), blockData.createCraftBlockData()));
|
||||
}
|
||||
// Paper end - cache block data strings
|
||||
|
||||
public static CraftBlockData newData(Material material, String data) {
|
||||
Preconditions.checkArgument(material == null || material.isBlock(), "Cannot get data for not block %s", material);
|
||||
|
||||
// Paper start - cache block data strings
|
||||
if (material != null) {
|
||||
Block block = CraftBlockType.bukkitToMinecraft(material);
|
||||
if (block != null) {
|
||||
net.minecraft.resources.ResourceLocation key = BuiltInRegistries.BLOCK.getKey(block);
|
||||
data = data == null ? key.toString() : key + data;
|
||||
}
|
||||
}
|
||||
|
||||
CraftBlockData cached = stringDataCache.computeIfAbsent(data, s -> createNewData(null, s));
|
||||
return (CraftBlockData) cached.clone();
|
||||
}
|
||||
|
||||
private static CraftBlockData createNewData(Material material, String data) {
|
||||
// Paper end - cache block data strings
|
||||
net.minecraft.world.level.block.state.BlockState blockData;
|
||||
Block block = CraftBlockType.bukkitToMinecraft(material);
|
||||
Map<Property<?>, Comparable<?>> parsed = null;
|
||||
|
||||
// Data provided, use it
|
||||
if (data != null) {
|
||||
try {
|
||||
// Material provided, force that material in
|
||||
if (block != null) {
|
||||
data = BuiltInRegistries.BLOCK.getKey(block) + data;
|
||||
}
|
||||
|
||||
StringReader reader = new StringReader(data);
|
||||
BlockStateParser.BlockResult arg = BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK.asLookup(), reader, false);
|
||||
Preconditions.checkArgument(!reader.canRead(), "Spurious trailing data: " + data);
|
||||
|
||||
blockData = arg.blockState();
|
||||
parsed = arg.properties();
|
||||
} catch (CommandSyntaxException ex) {
|
||||
throw new IllegalArgumentException("Could not parse data: " + data, ex);
|
||||
}
|
||||
} else {
|
||||
blockData = block.defaultBlockState();
|
||||
}
|
||||
|
||||
CraftBlockData craft = CraftBlockData.fromData(blockData);
|
||||
craft.parsedStates = parsed;
|
||||
return craft;
|
||||
}
|
||||
|
||||
// Paper start - optimize creating BlockData to not need a map lookup
|
||||
static {
|
||||
// Initialize cached data for all IBlockData instances after registration
|
||||
Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(net.minecraft.world.level.block.state.BlockState::createCraftBlockData);
|
||||
}
|
||||
public static CraftBlockData fromData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
return data.createCraftBlockData();
|
||||
}
|
||||
|
||||
public static CraftBlockData createData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
// Paper end
|
||||
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundGroup getSoundGroup() {
|
||||
return CraftSoundGroup.getSoundGroup(this.state.getSoundType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightEmission() {
|
||||
return this.state.getLightEmission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
return this.state.canOcclude();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresCorrectToolForDrops() {
|
||||
return this.state.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreferredTool(ItemStack tool) {
|
||||
Preconditions.checkArgument(tool != null, "tool must not be null");
|
||||
|
||||
net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(tool);
|
||||
return CraftBlockData.isPreferredTool(this.state, nms);
|
||||
}
|
||||
|
||||
public static boolean isPreferredTool(net.minecraft.world.level.block.state.BlockState iblockdata, net.minecraft.world.item.ItemStack nmsItem) {
|
||||
return !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PistonMoveReaction getPistonMoveReaction() {
|
||||
return PistonMoveReaction.getById(this.state.getPistonPushReaction().ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(org.bukkit.block.Block block) {
|
||||
Preconditions.checkArgument(block != null, "block must not be null");
|
||||
|
||||
CraftBlock craftBlock = (CraftBlock) block;
|
||||
return this.state.canSurvive(craftBlock.getCraftWorld().getHandle(), craftBlock.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Location location) {
|
||||
Preconditions.checkArgument(location != null, "location must not be null");
|
||||
|
||||
CraftWorld world = (CraftWorld) location.getWorld();
|
||||
Preconditions.checkArgument(world != null, "location must not have a null world");
|
||||
|
||||
BlockPos position = CraftLocation.toBlockPosition(location);
|
||||
return this.state.canSurvive(world.getHandle(), position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFaceSturdy(BlockFace face, BlockSupport support) {
|
||||
Preconditions.checkArgument(face != null, "face must not be null");
|
||||
Preconditions.checkArgument(support != null, "support must not be null");
|
||||
|
||||
return this.state.isFaceSturdy(EmptyBlockGetter.INSTANCE, BlockPos.ZERO, CraftBlock.blockFaceToNotch(face), CraftBlockSupport.toNMS(support));
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@Override
|
||||
public org.bukkit.util.VoxelShape getCollisionShape(Location location) {
|
||||
Preconditions.checkArgument(location != null, "location must not be null");
|
||||
|
||||
CraftWorld world = (CraftWorld) location.getWorld();
|
||||
Preconditions.checkArgument(world != null, "location must not have a null world");
|
||||
|
||||
BlockPos position = CraftLocation.toBlockPosition(location);
|
||||
net.minecraft.world.phys.shapes.VoxelShape shape = this.state.getCollisionShape(world.getHandle(), position);
|
||||
return new org.bukkit.craftbukkit.util.CraftVoxelShape(shape);
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
public Color getMapColor() {
|
||||
return Color.fromRGB(this.state.getMapColor(null, null).col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getPlacementMaterial() {
|
||||
return CraftItemType.minecraftToBukkit(this.state.getBlock().asItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(StructureRotation rotation) {
|
||||
this.state = this.state.rotate(Rotation.valueOf(rotation.name()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mirror(Mirror mirror) {
|
||||
this.state = this.state.mirror(net.minecraft.world.level.block.Mirror.valueOf(mirror.name()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(BlockData blockData) {
|
||||
CraftBlockData other = (CraftBlockData) blockData;
|
||||
net.minecraft.world.level.block.state.BlockState nms = other.state;
|
||||
for (Property<?> property : this.state.getBlock().getStateDefinition().getProperties()) {
|
||||
if (nms.hasProperty(property)) {
|
||||
nms = this.copyProperty(this.state, nms, property);
|
||||
}
|
||||
}
|
||||
|
||||
other.state = nms;
|
||||
}
|
||||
|
||||
private <T extends Comparable<T>> net.minecraft.world.level.block.state.BlockState copyProperty(net.minecraft.world.level.block.state.BlockState source, net.minecraft.world.level.block.state.BlockState target, Property<T> property) {
|
||||
return target.setValue(property, source.getValue(property));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BlockState createBlockState() {
|
||||
return CraftBlockStates.getBlockState(this.state, null);
|
||||
}
|
||||
|
||||
// Paper start - destroy speed API
|
||||
@Override
|
||||
public float getDestroySpeed(final ItemStack itemStack, final boolean considerEnchants) {
|
||||
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.unwrap(itemStack);
|
||||
float speed = nmsItemStack.getDestroySpeed(this.state);
|
||||
if (speed > 1.0F && considerEnchants) {
|
||||
int enchantLevel = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BLOCK_EFFICIENCY, nmsItemStack);
|
||||
if (enchantLevel > 0) {
|
||||
speed += enchantLevel * enchantLevel + 1;
|
||||
}
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
// Paper end - destroy speed API
|
||||
|
||||
// Paper start - Block tick API
|
||||
@Override
|
||||
public boolean isRandomlyTicked() {
|
||||
return this.state.isRandomlyTicking();
|
||||
}
|
||||
// Paper end - Block tick API
|
||||
}
|
|
@ -4,6 +4,7 @@ import io.papermc.generator.rewriter.CompositeRewriter;
|
|||
import io.papermc.generator.rewriter.SourceRewriter;
|
||||
import io.papermc.generator.rewriter.types.EnumCloneRewriter;
|
||||
import io.papermc.generator.rewriter.types.EnumRegistryRewriter;
|
||||
import io.papermc.generator.rewriter.types.simple.CraftBlockDataMapping;
|
||||
import io.papermc.generator.rewriter.types.simple.MapPaletteRewriter;
|
||||
import io.papermc.generator.rewriter.types.RegistryFieldRewriter;
|
||||
import io.papermc.generator.rewriter.types.TagRewriter;
|
||||
|
@ -194,6 +195,10 @@ public interface Generators {
|
|||
new MapPaletteRewriter("MapPalette#colors"),
|
||||
};
|
||||
|
||||
SourceRewriter[] SERVER_REWRITE = {
|
||||
new CraftBlockDataMapping("CraftBlockData#MAP")
|
||||
};
|
||||
|
||||
private static <T, A> SourceGenerator simpleKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
|
||||
return new GeneratedKeyType<>(className, apiType, "io.papermc.paper.registry.keys", registryKey, apiRegistryKey, publicCreateKeyMethod);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public final class Main {
|
|||
public static final RegistryAccess.Frozen REGISTRY_ACCESS;
|
||||
public static final TagResult EXPERIMENTAL_TAGS;
|
||||
public static Path generatedPath;
|
||||
public static Path generatedServerPath;
|
||||
|
||||
static {
|
||||
SharedConstants.tryDetectVersion();
|
||||
|
@ -59,10 +60,13 @@ public final class Main {
|
|||
LOGGER.info("Running API generators...");
|
||||
|
||||
Main.generatedPath = Path.of(args[0]); // todo remove
|
||||
Main.generatedServerPath = Path.of(args[2]); // todo remove
|
||||
try {
|
||||
generate(Main.generatedPath, Generators.API);
|
||||
apply(Path.of(args[1]), Generators.API_REWRITE);
|
||||
generateCraftBlockData(Path.of(args[2]));
|
||||
|
||||
generateCraftBlockData(Main.generatedServerPath);
|
||||
apply(Path.of(args[3]), Generators.SERVER_REWRITE);
|
||||
} catch (final RuntimeException ex) {
|
||||
throw ex;
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package io.papermc.generator.rewriter;
|
||||
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record ClassNamed(String packageName, String simpleName, String dottedNestedName, @Nullable Class<?> clazz) {
|
||||
|
||||
public ClassNamed(Class<?> clazz) {
|
||||
this(clazz.getPackageName(), clazz.getSimpleName(), ClassHelper.retrieveFullNestedName(clazz), clazz);
|
||||
}
|
||||
|
||||
// the class name shouldn't have any '$' char in it
|
||||
// otherwise it will be interpreted as a nested class
|
||||
public static ClassNamed of(String packageName, String name) {
|
||||
int nestedIndex = name.lastIndexOf('$');
|
||||
final String simpleName;
|
||||
final String nestedName;
|
||||
if (nestedIndex != -1) {
|
||||
simpleName = name.substring(nestedIndex + 1);
|
||||
nestedName = name.replace('$', '.');
|
||||
} else {
|
||||
simpleName = name;
|
||||
nestedName = name;
|
||||
}
|
||||
return new ClassNamed(packageName, simpleName, nestedName, null);
|
||||
}
|
||||
|
||||
public String rootClassSimpleName() {
|
||||
if (this.clazz != null) {
|
||||
return ClassHelper.getRootClass(this.clazz).getSimpleName();
|
||||
}
|
||||
|
||||
int dotIndex = this.dottedNestedName.indexOf('.');
|
||||
if (dotIndex != -1) {
|
||||
return this.dottedNestedName.substring(0, dotIndex);
|
||||
}
|
||||
return this.dottedNestedName;
|
||||
}
|
||||
|
||||
public String rootClassCanonicalName() {
|
||||
return this.packageName + '.' + this.rootClassSimpleName();
|
||||
}
|
||||
|
||||
public String canonicalName() {
|
||||
if (this.clazz != null) {
|
||||
return this.clazz.getCanonicalName();
|
||||
}
|
||||
|
||||
return this.packageName + '.' + this.dottedNestedName;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package io.papermc.generator.rewriter;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -14,7 +13,7 @@ public class CompositeRewriter extends SearchReplaceRewriter {
|
|||
|
||||
private final Map<String, SearchReplaceRewriter> patternsInfo;
|
||||
|
||||
private CompositeRewriter(Class<?> rewriteClass, List<SearchReplaceRewriter> rewriters) {
|
||||
private CompositeRewriter(ClassNamed rewriteClass, List<SearchReplaceRewriter> rewriters) {
|
||||
super(rewriteClass, null, false);
|
||||
this.patternsInfo = rewriters.stream().collect(Collectors.toMap(rewriter -> rewriter.pattern, rewriter -> rewriter));
|
||||
}
|
||||
|
@ -32,13 +31,14 @@ public class CompositeRewriter extends SearchReplaceRewriter {
|
|||
|
||||
public static CompositeRewriter bind(List<SearchReplaceRewriter> rewriters) {
|
||||
Preconditions.checkArgument(!rewriters.isEmpty(), "Rewriter list cannot be empty!");
|
||||
Class<?> rewriteClass = rewriters.get(0).rewriteClass;
|
||||
Class<?> rootClass = ClassHelper.getRootClass(rewriteClass);
|
||||
ClassNamed rewriteClass = rewriters.get(0).rewriteClass;
|
||||
String rootClassName = rewriteClass.rootClassCanonicalName();
|
||||
|
||||
for (SearchReplaceRewriter rewriter : rewriters) {
|
||||
Preconditions.checkState(!(rewriter instanceof CompositeRewriter), "Nested composite rewriters are not allowed!");
|
||||
Preconditions.checkArgument(rewriter.pattern != null, "Rewriter pattern cannot be null!");
|
||||
Preconditions.checkState(rewriteClass.getPackageName().equals(rewriter.rewriteClass.getPackageName()) &&
|
||||
rootClass == ClassHelper.getRootClass(rewriter.rewriteClass), "Composite rewriter only works for one file!");
|
||||
Preconditions.checkState(rewriteClass.packageName().equals(rewriter.rewriteClass.packageName()) &&
|
||||
rootClassName.equals(rewriter.rewriteClass.rootClassCanonicalName()), "Composite rewriter only works for one file!");
|
||||
}
|
||||
|
||||
return new CompositeRewriter(rewriteClass, rewriters);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.papermc.generator.rewriter;
|
||||
|
||||
import io.papermc.generator.rewriter.utils.ImportCollector;
|
||||
import io.papermc.generator.rewriter.context.ImportCollector;
|
||||
|
||||
public record SearchMetadata(ImportCollector importCollector, String indent, String replacedContent, int line) {
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ import com.google.common.base.Preconditions;
|
|||
import com.google.common.collect.Sets;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.rewriter.context.ImportCollector;
|
||||
import io.papermc.generator.rewriter.context.ImportTypeCollector;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import io.papermc.generator.rewriter.utils.ImportCollector;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.paper.generated.GeneratedFrom;
|
||||
import net.minecraft.SharedConstants;
|
||||
|
@ -33,11 +34,15 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
@VisibleForTesting
|
||||
public static final String GENERATED_COMMENT_FORMAT = "// %s - Generated/%s"; // {0} = PAPER_START_FORMAT|PAPER_END_FORMAT {1} = pattern
|
||||
|
||||
protected final Class<?> rewriteClass;
|
||||
protected final ClassNamed rewriteClass;
|
||||
protected final String pattern;
|
||||
protected final boolean equalsSize;
|
||||
|
||||
public SearchReplaceRewriter(Class<?> rewriteClass, String pattern, boolean equalsSize) {
|
||||
this(new ClassNamed(rewriteClass), pattern, equalsSize);
|
||||
}
|
||||
|
||||
public SearchReplaceRewriter(ClassNamed rewriteClass, String pattern, boolean equalsSize) {
|
||||
this.rewriteClass = rewriteClass;
|
||||
this.pattern = pattern;
|
||||
this.equalsSize = equalsSize;
|
||||
|
@ -67,11 +72,18 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
Set<String> foundPatterns = new HashSet<>();
|
||||
StringBuilder strippedContent = null;
|
||||
|
||||
Class<?> rootClass = ClassHelper.getRootClass(this.rewriteClass);
|
||||
ImportCollector importCollector = new ImportCollector(rootClass);
|
||||
final ImportCollector importCollector;
|
||||
String rootClassDeclaration = null;
|
||||
|
||||
String indent = Formatting.incrementalIndent(INDENT_UNIT, rootClass);
|
||||
String rootClassDeclaration = "%s %s".formatted(ClassHelper.getDeclaredType(rootClass), rootClass.getSimpleName());
|
||||
if (this.rewriteClass.clazz() != null) {
|
||||
Class<?> rootClass = ClassHelper.getRootClass(this.rewriteClass.clazz());
|
||||
importCollector = new ImportTypeCollector(rootClass);
|
||||
rootClassDeclaration = "%s %s".formatted(ClassHelper.getDeclaredType(rootClass), this.rewriteClass.rootClassSimpleName());
|
||||
} else {
|
||||
importCollector = ImportCollector.NO_OP; // for now skip the import collector for server gen
|
||||
}
|
||||
|
||||
String indent = Formatting.incrementalIndent(INDENT_UNIT, this.rewriteClass);
|
||||
boolean inBody = false;
|
||||
int i = 0;
|
||||
while (true) {
|
||||
|
@ -81,9 +93,9 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
}
|
||||
|
||||
// collect import to avoid fqn when not needed
|
||||
if (!inBody) {
|
||||
if (importCollector != ImportCollector.NO_OP && !inBody) {
|
||||
if (line.startsWith("import ") && line.endsWith(";")) {
|
||||
importCollector.consume(line);
|
||||
((ImportTypeCollector) importCollector).consume(line);
|
||||
}
|
||||
if (line.contains(rootClassDeclaration)) { // might fail on comments but good enough
|
||||
inBody = true;
|
||||
|
@ -93,7 +105,7 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
Optional<String> endPattern = this.searchPattern(line, indent, PAPER_END_FORMAT, patterns);
|
||||
if (endPattern.isPresent()) {
|
||||
if (this.foundRewriter == null) {
|
||||
throw new IllegalStateException("Start generated comment missing for pattern " + endPattern.get() + " in class " + this.rewriteClass.getSimpleName() + " at line " + (i + 1));
|
||||
throw new IllegalStateException("Start generated comment missing for pattern " + endPattern.get() + " in class " + this.rewriteClass.simpleName() + " at line " + (i + 1));
|
||||
}
|
||||
if (this.foundRewriter.pattern.equals(endPattern.get())) {
|
||||
if (!this.foundRewriter.equalsSize) {
|
||||
|
@ -104,7 +116,7 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
}
|
||||
this.foundRewriter = null;
|
||||
} else {
|
||||
throw new IllegalStateException("End generated comment doesn't match for pattern " + this.foundRewriter.pattern + " in " + this.rewriteClass.getSimpleName() + " at line " + (i + 1));
|
||||
throw new IllegalStateException("End generated comment doesn't match for pattern " + this.foundRewriter.pattern + " in " + this.rewriteClass.simpleName() + " at line " + (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +137,7 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
Optional<String> startPattern = this.searchPattern(line, null, PAPER_START_FORMAT, patterns);
|
||||
if (startPattern.isPresent()) {
|
||||
if (this.foundRewriter != null) {
|
||||
throw new IllegalStateException("Nested generated comments are not allowed for " + this.rewriteClass.getSimpleName() + " at line " + (i + 1));
|
||||
throw new IllegalStateException("Nested generated comments are not allowed for " + this.rewriteClass.simpleName() + " at line " + (i + 1));
|
||||
}
|
||||
int startPatternIndex = line.indexOf(GENERATED_COMMENT_FORMAT.formatted(PAPER_START_FORMAT, startPattern.get()));
|
||||
indent = " ".repeat(startPatternIndex); // update indent based on the comments for flexibility
|
||||
|
@ -143,7 +155,7 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
}
|
||||
|
||||
if (this.foundRewriter != null) {
|
||||
throw new IllegalStateException("End generated comment " + this.foundRewriter.pattern + " missing for " + this.rewriteClass.getSimpleName());
|
||||
throw new IllegalStateException("End generated comment " + this.foundRewriter.pattern + " missing for " + this.rewriteClass.simpleName());
|
||||
}
|
||||
|
||||
Set<String> diff = Sets.difference(patterns, foundPatterns);
|
||||
|
@ -155,8 +167,8 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
@Override
|
||||
public void writeToFile(Path parent) throws IOException {
|
||||
String filePath = "%s/%s.java".formatted(
|
||||
this.rewriteClass.getPackageName().replace('.', '/'),
|
||||
ClassHelper.getRootClass(this.rewriteClass).getSimpleName()
|
||||
this.rewriteClass.packageName().replace('.', '/'),
|
||||
this.rewriteClass.rootClassSimpleName()
|
||||
);
|
||||
|
||||
Path path = parent.resolve(filePath);
|
||||
|
@ -166,7 +178,12 @@ public class SearchReplaceRewriter implements SourceRewriter {
|
|||
}
|
||||
|
||||
// Files.writeString(path, content.toString(), StandardCharsets.UTF_8); // todo
|
||||
Path createdPath = Main.generatedPath.resolve(filePath);
|
||||
Path createdPath;
|
||||
if (path.toString().contains("Paper/Paper-API/src/")) {
|
||||
createdPath = Main.generatedPath.resolve(filePath);
|
||||
} else {
|
||||
createdPath = Main.generatedServerPath.resolve(filePath);
|
||||
}
|
||||
Files.createDirectories(createdPath.getParent());
|
||||
Files.writeString(createdPath, content.toString(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package io.papermc.generator.rewriter.context;
|
||||
|
||||
public interface ImportCollector {
|
||||
|
||||
ImportCollector NO_OP = new ImportCollector() {
|
||||
@Override
|
||||
public String getStaticAlias(final String fqn) {
|
||||
return fqn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName(final Class<?> clazz) {
|
||||
return clazz.getCanonicalName();
|
||||
}
|
||||
};
|
||||
|
||||
String getStaticAlias(String fqn);
|
||||
|
||||
String getTypeName(Class<?> clazz);
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.papermc.generator.rewriter.utils;
|
||||
package io.papermc.generator.rewriter.context;
|
||||
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
@ -7,7 +7,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ImportCollector {
|
||||
public class ImportTypeCollector implements ImportCollector {
|
||||
|
||||
private final Map<Class<?>, String> typeCache = new HashMap<>();
|
||||
|
||||
|
@ -17,7 +17,7 @@ public class ImportCollector {
|
|||
|
||||
private final Class<?> rewriteClass;
|
||||
|
||||
public ImportCollector(Class<?> rewriteClass) {
|
||||
public ImportTypeCollector(Class<?> rewriteClass) {
|
||||
this.rewriteClass = rewriteClass;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package io.papermc.generator.rewriter.types;
|
||||
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EnumCloneRewriter<T extends Enum<T>, A extends Enum<A>> extends EnumRewriter<T, A> { // not really a clone anymore
|
||||
|
@ -7,6 +8,10 @@ public class EnumCloneRewriter<T extends Enum<T>, A extends Enum<A>> extends Enu
|
|||
private final Class<T> basedOn;
|
||||
|
||||
public EnumCloneRewriter(final Class<A> rewriteClass, final Class<T> basedOn, final String pattern, boolean equalsSize) {
|
||||
this(new ClassNamed(rewriteClass), basedOn, pattern, equalsSize);
|
||||
}
|
||||
|
||||
public EnumCloneRewriter(final ClassNamed rewriteClass, final Class<T> basedOn, final String pattern, boolean equalsSize) {
|
||||
super(rewriteClass, pattern, equalsSize);
|
||||
this.basedOn = basedOn;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.google.common.base.Suppliers;
|
|||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import io.papermc.generator.utils.RegistryUtils;
|
||||
import net.minecraft.core.Holder;
|
||||
|
@ -25,6 +26,10 @@ public class EnumRegistryRewriter<T, A extends Enum<A>> extends EnumRewriter<Hol
|
|||
private final boolean hasParams;
|
||||
|
||||
public EnumRegistryRewriter(final Class<A> rewriteClass, final ResourceKey<? extends Registry<T>> registryKey, final String pattern, final boolean hasParams) {
|
||||
this(new ClassNamed(rewriteClass), registryKey, pattern, hasParams);
|
||||
}
|
||||
|
||||
public EnumRegistryRewriter(final ClassNamed rewriteClass, final ResourceKey<? extends Registry<T>> registryKey, final String pattern, final boolean hasParams) {
|
||||
super(rewriteClass, pattern, false);
|
||||
this.registry = Main.REGISTRY_ACCESS.registryOrThrow(registryKey);
|
||||
this.experimentalKeys = Suppliers.memoize(() -> RegistryUtils.collectExperimentalDataDrivenKeys(this.registry));
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.papermc.generator.rewriter.types;
|
|||
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.SearchReplaceRewriter;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import java.util.Iterator;
|
||||
|
@ -15,6 +16,10 @@ public abstract class EnumRewriter<T, A extends Enum<A>> extends SearchReplaceRe
|
|||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected EnumRewriter(final ClassNamed rewriteClass, final String pattern, final boolean equalsSize) {
|
||||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected abstract Iterable<T> getValues();
|
||||
|
||||
protected abstract String rewriteEnumName(T item);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.papermc.generator.rewriter.types;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Suppliers;
|
||||
import io.papermc.generator.Main;
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
|
@ -19,7 +20,6 @@ import java.lang.reflect.Modifier;
|
|||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -68,8 +68,9 @@ public class RegistryFieldRewriter<T, A> extends SearchReplaceRewriter {
|
|||
return;
|
||||
}
|
||||
|
||||
Preconditions.checkState(this.rewriteClass.clazz() != null, "This rewriter doesn't support server gen!");
|
||||
try {
|
||||
this.rewriteClass.getDeclaredMethod(this.fetchMethod, String.class);
|
||||
this.rewriteClass.clazz().getDeclaredMethod(this.fetchMethod, String.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -93,10 +94,10 @@ public class RegistryFieldRewriter<T, A> extends SearchReplaceRewriter {
|
|||
if (!this.isInterface) {
|
||||
builder.append("%s %s %s ".formatted(PUBLIC, STATIC, FINAL));
|
||||
}
|
||||
builder.append(this.rewriteClass.getSimpleName()).append(' ').append(this.rewriteFieldName(reference));
|
||||
builder.append(this.rewriteClass.simpleName()).append(' ').append(this.rewriteFieldName(reference));
|
||||
builder.append(" = ");
|
||||
if (this.fetchMethod == null) {
|
||||
builder.append("%s.%s.get(%s.minecraft(%s))".formatted(org.bukkit.Registry.class.getSimpleName(), REGISTRY_FIELD_NAMES.get(this.rewriteClass), NamespacedKey.class.getSimpleName(), quoted(pathKey)));
|
||||
builder.append("%s.%s.get(%s.minecraft(%s))".formatted(org.bukkit.Registry.class.getSimpleName(), REGISTRY_FIELD_NAMES.get(this.rewriteClass.clazz()), NamespacedKey.class.getSimpleName(), quoted(pathKey)));
|
||||
} else {
|
||||
builder.append("%s(%s)".formatted(this.fetchMethod, quoted(pathKey)));
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.papermc.generator.rewriter.types;
|
|||
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.SearchReplaceRewriter;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -14,6 +15,10 @@ public abstract class SwitchCaseRewriter extends SearchReplaceRewriter {
|
|||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected SwitchCaseRewriter(final ClassNamed rewriteClass, final String pattern, final boolean equalsSize) {
|
||||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected abstract Iterable<String> getCases();
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.papermc.generator.rewriter.types;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.SearchReplaceRewriter;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
@ -15,6 +16,10 @@ public abstract class SwitchRewriter<T> extends SearchReplaceRewriter {
|
|||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected SwitchRewriter(final ClassNamed rewriteClass, final String pattern, final boolean equalsSize) {
|
||||
super(rewriteClass, pattern, equalsSize);
|
||||
}
|
||||
|
||||
protected record Return<T>(T object, String code) {}
|
||||
|
||||
protected Return<T> returnOf(T object, String code) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.papermc.generator.Main;
|
|||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.SearchReplaceRewriter;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
@ -39,6 +40,10 @@ public class TagRewriter extends SearchReplaceRewriter {
|
|||
super(rewriteClass, pattern, false);
|
||||
}
|
||||
|
||||
public TagRewriter(final ClassNamed rewriteClass, final String pattern) {
|
||||
super(rewriteClass, pattern, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void insert(final SearchMetadata metadata, final StringBuilder builder) {
|
||||
for (int i = 0, len = TAG_REGISTRIES.size(); i < len; i++) {
|
||||
|
@ -71,7 +76,7 @@ public class TagRewriter extends SearchReplaceRewriter {
|
|||
}
|
||||
|
||||
builder.append(metadata.indent());
|
||||
builder.append("%s<%s>".formatted(this.rewriteClass.getSimpleName(), tagRegistry.apiType().getSimpleName())).append(' ').append(fieldName);
|
||||
builder.append("%s<%s>".formatted(this.rewriteClass.simpleName(), tagRegistry.apiType().getSimpleName())).append(' ').append(fieldName);
|
||||
builder.append(" = ");
|
||||
builder.append("%s.getTag(%s, %s.minecraft(%s), %s.class)".formatted(Bukkit.class.getSimpleName(), registryFieldName, NamespacedKey.class.getSimpleName(), quoted(keyPath), tagRegistry.apiType().getSimpleName()));
|
||||
builder.append(';');
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package io.papermc.generator.rewriter.types;
|
||||
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
|
||||
public final class Types {
|
||||
|
||||
public static final String BASE_PACKAGE = "org.bukkit.craftbukkit";
|
||||
public static final String BLOCKDATA_IMPL_PACKAGE = BASE_PACKAGE + ".block.impl";
|
||||
|
||||
public static final ClassNamed CRAFT_BLOCKDATA = ClassNamed.of(BASE_PACKAGE + ".block.data", "CraftBlockData");
|
||||
|
||||
public static final ClassNamed CRAFT_BLOCK = ClassNamed.of(BASE_PACKAGE + ".block", "CraftBlock");
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package io.papermc.generator.rewriter.types.simple;
|
||||
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.SearchReplaceRewriter;
|
||||
import io.papermc.generator.rewriter.types.Types;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
|
||||
public class CraftBlockDataMapping extends SearchReplaceRewriter {
|
||||
|
||||
public CraftBlockDataMapping(final String pattern) {
|
||||
super(Types.CRAFT_BLOCKDATA, pattern, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void insert(final SearchMetadata metadata, final StringBuilder builder) {
|
||||
BlockStateMapping.MAPPING.entrySet().stream().sorted(Formatting.alphabeticKeyOrder(entry -> entry.getKey().getCanonicalName())).forEach(entry -> {
|
||||
builder.append(metadata.indent());
|
||||
builder.append("register(%s.class, %s.%s::new);".formatted(entry.getKey().getCanonicalName(), Types.BLOCKDATA_IMPL_PACKAGE, entry.getValue().impl()));
|
||||
builder.append('\n');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -141,9 +141,9 @@ public class MemoryKeyRewriter extends SearchReplaceRewriter {
|
|||
|
||||
builder.append(metadata.indent());
|
||||
builder.append("%s %s %s ".formatted(PUBLIC, STATIC, FINAL));
|
||||
builder.append("%s<%s>".formatted(this.rewriteClass.getSimpleName(), apiMemoryType.getSimpleName())).append(' ').append(this.rewriteFieldName(reference));
|
||||
builder.append("%s<%s>".formatted(this.rewriteClass.simpleName(), apiMemoryType.getSimpleName())).append(' ').append(this.rewriteFieldName(reference));
|
||||
builder.append(" = ");
|
||||
builder.append("new %s<>(%s.minecraft(%s), %s.class)".formatted(this.rewriteClass.getSimpleName(), NamespacedKey.class.getSimpleName(), quoted(pathKey), apiMemoryType.getSimpleName()));
|
||||
builder.append("new %s<>(%s.minecraft(%s), %s.class)".formatted(this.rewriteClass.simpleName(), NamespacedKey.class.getSimpleName(), quoted(pathKey), apiMemoryType.getSimpleName()));
|
||||
builder.append(';');
|
||||
|
||||
builder.append('\n');
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.papermc.generator.rewriter.utils;
|
||||
|
||||
import io.papermc.generator.rewriter.SearchMetadata;
|
||||
import io.papermc.generator.rewriter.context.ImportCollector;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import io.papermc.generator.utils.Formatting;
|
||||
import net.minecraft.world.flag.FeatureFlag;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.papermc.generator.types.craftblockdata;
|
||||
package io.papermc.generator.types;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
|
||||
|
@ -9,7 +9,4 @@ public final class Types {
|
|||
public static final ClassName CRAFT_BLOCKDATA = ClassName.get(BASE_PACKAGE + ".block.data", "CraftBlockData");
|
||||
|
||||
public static final ClassName CRAFT_BLOCK = ClassName.get(BASE_PACKAGE + ".block", "CraftBlock");
|
||||
|
||||
public static final String INDEX_VARIABLE = "index";
|
||||
public static final String ENTRY_VARIABLE = "entry";
|
||||
}
|
|
@ -8,6 +8,7 @@ import com.squareup.javapoet.MethodSpec;
|
|||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.Types;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataPropertyMaker;
|
||||
import io.papermc.generator.types.craftblockdata.property.PropertyMaker;
|
||||
|
@ -17,6 +18,7 @@ import io.papermc.generator.types.craftblockdata.property.holder.converter.DataC
|
|||
import io.papermc.generator.types.craftblockdata.property.holder.converter.DataConverters;
|
||||
import io.papermc.generator.utils.Annotations;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.BrewingStandBlock;
|
||||
|
@ -182,7 +184,7 @@ public class CraftBlockDataGenerator<T extends BlockData> extends StructuredGene
|
|||
NamingManager.AccessKeyword accessKeyword = FLUENT_KEYWORD.getOrDefault(firstProperty, dataPropertyMaker.getKeyword());
|
||||
NamingManager naming = new NamingManager(accessKeyword, CaseFormat.UPPER_UNDERSCORE, NamingManager.stripFieldAccessKeyword(dataPropertyMaker.getBaseName()));
|
||||
|
||||
ParameterSpec indexParameter = ParameterSpec.builder(dataPropertyMaker.getIndexClass(), dataPropertyMaker.getIndexClass() == Integer.TYPE ? Types.INDEX_VARIABLE : naming.paramName(dataPropertyMaker.getIndexClass()), FINAL).build();
|
||||
ParameterSpec indexParameter = ParameterSpec.builder(dataPropertyMaker.getIndexClass(), dataPropertyMaker.getIndexClass() == Integer.TYPE ? CommonVariable.INDEX : naming.paramName(dataPropertyMaker.getIndexClass()), FINAL).build();
|
||||
|
||||
// get
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
|||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.Types;
|
||||
import io.papermc.generator.types.Types;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.ArrayAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.DataAppender;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.appender.ListAppender;
|
||||
|
@ -19,6 +19,7 @@ import io.papermc.generator.types.craftblockdata.property.holder.appender.MapApp
|
|||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.utils.BlockStateMapping;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
@ -80,8 +81,8 @@ public class DataPropertyWriter<T extends Property<?>> extends DataPropertyWrite
|
|||
if (this.type == DataHolderType.MAP && ClassHelper.eraseType(((ParameterizedType) this.field.getGenericType()).getActualTypeArguments()[0]) == Direction.class &&
|
||||
this.indexClass == BlockFace.class) { // Direction -> BlockFace
|
||||
// convert the key manually only this one is needed for now
|
||||
fieldBuilder.initializer("$[$T.$L.entrySet().stream()\n.collect($T.toMap(entry -> $T.notchToBlockFace(entry.getKey()), entry -> entry.getValue()))$]",
|
||||
this.blockClass, this.field.getName(), Collectors.class, Types.CRAFT_BLOCK);
|
||||
fieldBuilder.initializer("$[$1T.$2L.entrySet().stream()\n.collect($3T.toMap($4L -> $5T.notchToBlockFace($4L.getKey()), $4L -> $4L.getValue()))$]",
|
||||
this.blockClass, this.field.getName(), Collectors.class, CommonVariable.MAP_ENTRY, Types.CRAFT_BLOCK);
|
||||
} else {
|
||||
fieldBuilder.initializer("$T.$L", this.blockClass, this.field.getName());
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import com.squareup.javapoet.ParameterSpec;
|
|||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.Types;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -26,11 +26,11 @@ public class ArrayAppender implements DataAppender {
|
|||
String collectFieldName = naming.getVariableNameWrapper().post("s").concat();
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(naming.getMethodNameWrapper().post("s").concat());
|
||||
methodBuilder.addStatement("$T $L = $T.builder()", ParameterizedTypeName.get(ImmutableSet.Builder.class, Integer.class), collectFieldName, ImmutableSet.class);
|
||||
methodBuilder.beginControlFlow("for (int $1L = 0, len = $2N.length; $1L < len; $1L++)", Types.INDEX_VARIABLE, field);
|
||||
methodBuilder.beginControlFlow("for (int $1L = 0, len = $2N.length; $1L < len; $1L++)", CommonVariable.INDEX, field);
|
||||
{
|
||||
methodBuilder.beginControlFlow("if (" + childConverter.rawGetExprent().formatted("$N[$N]") + ")", field, indexParameter);
|
||||
{
|
||||
methodBuilder.addStatement("$L.add($L)", collectFieldName, Types.INDEX_VARIABLE);
|
||||
methodBuilder.addStatement("$L.add($L)", collectFieldName, CommonVariable.INDEX);
|
||||
}
|
||||
methodBuilder.endControlFlow();
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@ import com.squareup.javapoet.ParameterSpec;
|
|||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.Types;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -33,11 +33,11 @@ public class ListAppender implements DataAppender {
|
|||
String collectFieldName = naming.getVariableNameWrapper().post("s").concat();
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(methodName.post("s").concat());
|
||||
methodBuilder.addStatement("$T $L = $T.builder()", ParameterizedTypeName.get(ImmutableSet.Builder.class, Integer.class), collectFieldName, ImmutableSet.class);
|
||||
methodBuilder.beginControlFlow("for (int $1L = 0, size = $2N.size(); $1L < size; $1L++)", Types.INDEX_VARIABLE, field);
|
||||
methodBuilder.beginControlFlow("for (int $1L = 0, size = $2N.size(); $1L < size; $1L++)", CommonVariable.INDEX, field);
|
||||
{
|
||||
methodBuilder.beginControlFlow("if (" + childConverter.rawGetExprent().formatted("$N.get($N)") + ")", field, indexParameter);
|
||||
{
|
||||
methodBuilder.addStatement("$L.add($L)", collectFieldName, Types.INDEX_VARIABLE);
|
||||
methodBuilder.addStatement("$L.add($L)", collectFieldName, CommonVariable.INDEX);
|
||||
}
|
||||
methodBuilder.endControlFlow();
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import com.squareup.javapoet.ParameterSpec;
|
|||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import io.papermc.generator.types.StructuredGenerator;
|
||||
import io.papermc.generator.types.craftblockdata.Types;
|
||||
import io.papermc.generator.types.craftblockdata.property.converter.ConverterBase;
|
||||
import io.papermc.generator.types.craftblockdata.property.holder.DataHolderType;
|
||||
import io.papermc.generator.utils.CommonVariable;
|
||||
import io.papermc.generator.utils.NamingManager;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import java.util.Collections;
|
||||
|
@ -30,11 +30,11 @@ public class MapAppender implements DataAppender {
|
|||
String collectFieldName = naming.getVariableNameWrapper().post("s").concat();
|
||||
MethodSpec.Builder methodBuilder = generator.createMethod(naming.getMethodNameWrapper().post("s").concat());
|
||||
methodBuilder.addStatement("$T $L = $T.builder()", ParameterizedTypeName.get(ClassName.get(ImmutableSet.Builder.class), indexParameter.type), collectFieldName, ImmutableSet.class);
|
||||
methodBuilder.beginControlFlow("for ($T $N : $N.entrySet())", ParameterizedTypeName.get(ClassName.get(Map.Entry.class), indexParameter.type, ClassName.get(BooleanProperty.class)), Types.ENTRY_VARIABLE, field);
|
||||
methodBuilder.beginControlFlow("for ($T $N : $N.entrySet())", ParameterizedTypeName.get(ClassName.get(Map.Entry.class), indexParameter.type, ClassName.get(BooleanProperty.class)), CommonVariable.MAP_ENTRY, field);
|
||||
{
|
||||
methodBuilder.beginControlFlow("if (" + childConverter.rawGetExprent().formatted("$L.getValue()") + ")", Types.ENTRY_VARIABLE);
|
||||
methodBuilder.beginControlFlow("if (" + childConverter.rawGetExprent().formatted("$L.getValue()") + ")", CommonVariable.MAP_ENTRY);
|
||||
{
|
||||
methodBuilder.addStatement("$L.add($N.getKey())", collectFieldName, Types.ENTRY_VARIABLE);
|
||||
methodBuilder.addStatement("$L.add($N.getKey())", collectFieldName, CommonVariable.MAP_ENTRY);
|
||||
}
|
||||
methodBuilder.endControlFlow();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package io.papermc.generator.utils;
|
||||
|
||||
public final class CommonVariable {
|
||||
|
||||
public static final String INDEX = "index";
|
||||
public static final String MAP_ENTRY = "entry";
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.papermc.generator.utils;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import io.papermc.generator.rewriter.ClassNamed;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
@ -71,14 +72,29 @@ public final class Formatting {
|
|||
return Optional.of(resourcePath.substring(tagsIndex + tagDir.length() + 1, dotIndex)); // namespace/tags/registry_key/[tag_key].json
|
||||
}
|
||||
|
||||
public static String incrementalIndent(String unit, Class<?> clazz) {
|
||||
Class<?> parent = clazz.getEnclosingClass();
|
||||
public static int countOccurrences(String value, char match) {
|
||||
int count = 0;
|
||||
for (int i = 0, len = value.length(); i < len; i++) {
|
||||
if (value.charAt(i) == match) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static String incrementalIndent(String unit, ClassNamed classNamed) {
|
||||
if (classNamed.clazz() == null) {
|
||||
return unit.repeat(countOccurrences(classNamed.dottedNestedName(), '.'));
|
||||
}
|
||||
|
||||
Class<?> parent = classNamed.clazz().getEnclosingClass();
|
||||
StringBuilder indentBuilder = new StringBuilder(unit);
|
||||
while (parent != null) {
|
||||
indentBuilder.append(unit);
|
||||
parent = parent.getEnclosingClass();
|
||||
}
|
||||
return indentBuilder.toString();
|
||||
|
||||
}
|
||||
|
||||
public static String quoted(String value) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.papermc.generator.rewriter;
|
|||
|
||||
import io.papermc.generator.Generators;
|
||||
import io.papermc.generator.rewriter.utils.Annotations;
|
||||
import io.papermc.generator.utils.ClassHelper;
|
||||
import io.papermc.paper.generated.GeneratedFrom;
|
||||
import net.minecraft.SharedConstants;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
@ -16,7 +15,8 @@ import java.nio.file.Path;
|
|||
|
||||
public class OldGeneratedCodeTest {
|
||||
|
||||
private static final String CONTAINER = System.getProperty("paper.generator.rewriter.container");
|
||||
private static final String API_CONTAINER = System.getProperty("paper.generator.rewriter.container.api");
|
||||
private static final String SERVER_CONTAINER = System.getProperty("paper.generator.rewriter.container.server");
|
||||
|
||||
private static String CURRENT_VERSION;
|
||||
|
||||
|
@ -26,33 +26,32 @@ public class OldGeneratedCodeTest {
|
|||
CURRENT_VERSION = SharedConstants.getCurrentVersion().getName();
|
||||
}
|
||||
|
||||
private boolean versionDependant(SearchReplaceRewriter srt) {
|
||||
private boolean versionDependent(SearchReplaceRewriter srt) {
|
||||
if (srt instanceof CompositeRewriter compositeRewriter) {
|
||||
boolean versionDependant = false;
|
||||
boolean versionDependent = false;
|
||||
for (SearchReplaceRewriter rewriter : compositeRewriter.getRewriters()) {
|
||||
if (!rewriter.equalsSize) {
|
||||
versionDependant = true;
|
||||
versionDependent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return versionDependant;
|
||||
return versionDependent;
|
||||
}
|
||||
return !srt.equalsSize;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOutdatedCode() throws IOException {
|
||||
for (SourceRewriter rewriter : Generators.API_REWRITE) {
|
||||
if (!(rewriter instanceof SearchReplaceRewriter srt) || !versionDependant(srt)) {
|
||||
private void checkOutdated(String container, SourceRewriter[] rewriters) throws IOException {
|
||||
for (SourceRewriter rewriter : rewriters) {
|
||||
if (!(rewriter instanceof SearchReplaceRewriter srt) || !versionDependent(srt)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String filePath = "%s/%s.java".formatted(
|
||||
srt.rewriteClass.getPackageName().replace('.', '/'),
|
||||
ClassHelper.getRootClass(srt.rewriteClass).getSimpleName()
|
||||
srt.rewriteClass.packageName().replace('.', '/'),
|
||||
srt.rewriteClass.rootClassSimpleName()
|
||||
);
|
||||
|
||||
Path path = Path.of(CONTAINER, filePath);
|
||||
Path path = Path.of(container, filePath);
|
||||
if (!Files.exists(path)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -78,7 +77,7 @@ public class OldGeneratedCodeTest {
|
|||
String generatedVersion = nextLine.substring(generatedIndex + generatedComment.length());
|
||||
Assertions.assertEquals(CURRENT_VERSION, generatedVersion,
|
||||
"Code at line %s in %s is marked as being generated in version %s when the current version is %s".formatted(
|
||||
lineCount, srt.rewriteClass.getCanonicalName(),
|
||||
lineCount, srt.rewriteClass.canonicalName(),
|
||||
generatedVersion, CURRENT_VERSION));
|
||||
}
|
||||
}
|
||||
|
@ -86,4 +85,10 @@ public class OldGeneratedCodeTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOutdatedCode() throws IOException {
|
||||
checkOutdated(API_CONTAINER, Generators.API_REWRITE);
|
||||
checkOutdated(SERVER_CONTAINER, Generators.SERVER_REWRITE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
||||
Date: Sat, 16 Mar 2024 18:58:41 +0100
|
||||
Subject: [PATCH] Code generation marker stub
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 80584646464b58406150f7146d68969a3353aaa8..ab4416b054612b831cd938b03ffcbfc3bc082ca2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -366,6 +366,7 @@ public class CraftBlockData implements BlockData {
|
||||
|
||||
static {
|
||||
//<editor-fold desc="CraftBlockData Registration" defaultstate="collapsed">
|
||||
+ // Paper start - Generated/CraftBlockData#MAP
|
||||
register(net.minecraft.world.level.block.AmethystClusterBlock.class, org.bukkit.craftbukkit.block.impl.CraftAmethystCluster::new);
|
||||
register(net.minecraft.world.level.block.BigDripleafBlock.class, org.bukkit.craftbukkit.block.impl.CraftBigDripleaf::new);
|
||||
register(net.minecraft.world.level.block.BigDripleafStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftBigDripleafStem::new);
|
||||
@@ -537,6 +538,7 @@ public class CraftBlockData implements BlockData {
|
||||
register(net.minecraft.world.level.block.piston.PistonBaseBlock.class, org.bukkit.craftbukkit.block.impl.CraftPistonBase::new);
|
||||
register(net.minecraft.world.level.block.piston.PistonHeadBlock.class, org.bukkit.craftbukkit.block.impl.CraftPistonHead::new);
|
||||
register(net.minecraft.world.level.block.piston.MovingPistonBlock.class, org.bukkit.craftbukkit.block.impl.CraftMovingPiston::new);
|
||||
+ // Paper end - Generated/CraftBlockData#MAP
|
||||
//</editor-fold>
|
||||
}
|
||||
|
Loading…
Reference in New Issue