1.21.6 dev
Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: Noah van der Aa <ndvdaa@gmail.com> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
This commit is contained in:
committed by
Nassim Jahnke
parent
39203a65e0
commit
a24f9b204c
@@ -1,17 +1,17 @@
|
||||
package com.destroystokyo.paper.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.world.level.pathfinder.Node;
|
||||
import net.minecraft.world.level.pathfinder.Path;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.world.level.pathfinder.Node;
|
||||
import net.minecraft.world.level.pathfinder.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder {
|
||||
|
||||
@@ -23,7 +23,7 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde
|
||||
|
||||
@Override
|
||||
public Mob getEntity() {
|
||||
return (Mob) entity.getBukkitEntity();
|
||||
return (Mob) this.entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
public void setHandle(net.minecraft.world.entity.Mob entity) {
|
||||
|
||||
@@ -1,189 +1,211 @@
|
||||
package com.destroystokyo.paper.entity.ai;
|
||||
|
||||
import com.destroystokyo.paper.entity.RangedEntity;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import io.papermc.paper.entity.SchoolableFish;
|
||||
import io.papermc.paper.util.ObfHelper;
|
||||
import it.unimi.dsi.fastutil.ints.Int2BooleanFunction;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.world.entity.ai.goal.Goal;
|
||||
import net.minecraft.world.entity.monster.RangedAttackMob;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.*;
|
||||
|
||||
public class MobGoalHelper {
|
||||
|
||||
private static final BiMap<String, String> deobfuscationMap = HashBiMap.create();
|
||||
private static final Map<Class<? extends Goal>, Class<? extends Mob>> entityClassCache = new HashMap<>();
|
||||
private static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> bukkitMap = new HashMap<>();
|
||||
|
||||
static final Set<String> ignored = new HashSet<>();
|
||||
|
||||
static {
|
||||
// TODO these kinda should be checked on each release, in case obfuscation changes
|
||||
deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee");
|
||||
|
||||
ignored.add("goal_selector_1");
|
||||
ignored.add("goal_selector_2");
|
||||
ignored.add("selector_1");
|
||||
ignored.add("selector_2");
|
||||
ignored.add("wrapped");
|
||||
|
||||
private static final Map<Class<? extends Goal>, Class<? extends Mob>> GENERIC_TYPE_CACHE = new HashMap<>();
|
||||
public static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> BUKKIT_BRIDGE = Util.make(new LinkedHashMap<>(), map -> {
|
||||
//<editor-fold defaultstate="collapsed" desc="bukkitMap Entities">
|
||||
// Start generate - MobGoalHelper#bukkitMap
|
||||
// @GeneratedFrom 1.21.5
|
||||
bukkitMap.put(net.minecraft.world.entity.Mob.class, Mob.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Animal.class, Animals.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Bee.class, Bee.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Cat.class, Cat.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Cod.class, Cod.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Cow.class, Cow.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.camel.Camel.class, Camel.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Monster.class, Monster.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Panda.class, Panda.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Pig.class, Pig.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.raid.Raider.class, Raider.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Stray.class, Stray.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Slime.class, Slime.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Spider.class, Spider.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Squid.class, Squid.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Vex.class, Vex.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.npc.Villager.class, Villager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Witch.class, Witch.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Husk.class, Husk.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Strider.class, Strider.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class);
|
||||
bukkitMap.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class);
|
||||
// End generate - MobGoalHelper#bukkitMap
|
||||
// Start generate - MobGoalHelper#BUKKIT_BRIDGE
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
map.put(net.minecraft.world.entity.Mob.class, Mob.class);
|
||||
map.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class);
|
||||
map.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class);
|
||||
map.put(net.minecraft.world.entity.animal.Animal.class, Animals.class);
|
||||
map.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class);
|
||||
map.put(net.minecraft.world.entity.animal.Bee.class, Bee.class);
|
||||
map.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class);
|
||||
map.put(net.minecraft.world.entity.animal.Cat.class, Cat.class);
|
||||
map.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class);
|
||||
map.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class);
|
||||
map.put(net.minecraft.world.entity.animal.Cod.class, Cod.class);
|
||||
map.put(net.minecraft.world.entity.animal.Cow.class, Cow.class);
|
||||
map.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class);
|
||||
map.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class);
|
||||
map.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class);
|
||||
map.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class);
|
||||
map.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class);
|
||||
map.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class);
|
||||
map.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class);
|
||||
map.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class);
|
||||
map.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class);
|
||||
map.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class);
|
||||
map.put(net.minecraft.world.entity.animal.Fox.class, Fox.class);
|
||||
map.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class);
|
||||
map.put(net.minecraft.world.entity.monster.Giant.class, Giant.class);
|
||||
map.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class);
|
||||
map.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class);
|
||||
map.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class);
|
||||
map.put(net.minecraft.world.entity.animal.camel.Camel.class, Camel.class);
|
||||
map.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class);
|
||||
map.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class);
|
||||
map.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class);
|
||||
map.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class);
|
||||
map.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class);
|
||||
map.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class);
|
||||
map.put(net.minecraft.world.entity.monster.Monster.class, Monster.class);
|
||||
map.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class);
|
||||
map.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class);
|
||||
map.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class);
|
||||
map.put(net.minecraft.world.entity.animal.Panda.class, Panda.class);
|
||||
map.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class);
|
||||
map.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class);
|
||||
map.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class);
|
||||
map.put(net.minecraft.world.entity.animal.Pig.class, Pig.class);
|
||||
map.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class);
|
||||
map.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class);
|
||||
map.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class);
|
||||
map.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class);
|
||||
map.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class);
|
||||
map.put(net.minecraft.world.entity.raid.Raider.class, Raider.class);
|
||||
map.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class);
|
||||
map.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class);
|
||||
map.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class);
|
||||
map.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class);
|
||||
map.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class);
|
||||
map.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class);
|
||||
map.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class);
|
||||
map.put(net.minecraft.world.entity.monster.Stray.class, Stray.class);
|
||||
map.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class);
|
||||
map.put(net.minecraft.world.entity.monster.Slime.class, Slime.class);
|
||||
map.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class);
|
||||
map.put(net.minecraft.world.entity.monster.Spider.class, Spider.class);
|
||||
map.put(net.minecraft.world.entity.animal.Squid.class, Squid.class);
|
||||
map.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class);
|
||||
map.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class);
|
||||
map.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class);
|
||||
map.put(net.minecraft.world.entity.monster.Vex.class, Vex.class);
|
||||
map.put(net.minecraft.world.entity.npc.Villager.class, Villager.class);
|
||||
map.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class);
|
||||
map.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class);
|
||||
map.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class);
|
||||
map.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class);
|
||||
map.put(net.minecraft.world.entity.monster.Witch.class, Witch.class);
|
||||
map.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class);
|
||||
map.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class);
|
||||
map.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class);
|
||||
map.put(net.minecraft.world.entity.monster.Husk.class, Husk.class);
|
||||
map.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class);
|
||||
map.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class);
|
||||
map.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class);
|
||||
map.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class);
|
||||
map.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class);
|
||||
map.put(net.minecraft.world.entity.monster.Strider.class, Strider.class);
|
||||
map.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class);
|
||||
map.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class);
|
||||
map.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class);
|
||||
map.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class);
|
||||
map.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class);
|
||||
map.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class);
|
||||
map.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class);
|
||||
map.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class);
|
||||
map.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class);
|
||||
map.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class);
|
||||
map.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class);
|
||||
map.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class);
|
||||
map.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class);
|
||||
map.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class);
|
||||
map.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class);
|
||||
map.put(net.minecraft.world.entity.animal.HappyGhast.class, HappyGhast.class);
|
||||
// End generate - MobGoalHelper#BUKKIT_BRIDGE
|
||||
//</editor-fold>
|
||||
}
|
||||
});
|
||||
|
||||
// TODO these kinda should be checked on each release, in case nested classes changes
|
||||
private static final Map<String, String> NESTED_CLASS_NAMES = Util.make(new HashMap<>(), map -> {
|
||||
map.put("AbstractSkeleton$1", "AbstractSkeletonMelee");
|
||||
|
||||
// remove duplicate
|
||||
map.put("TraderLlama$TraderLlamaDefendWanderingTraderGoal", "TraderLlamaDefendWanderingTraderGoal");
|
||||
map.put("AbstractIllager$RaiderOpenDoorGoal", "RaiderOpenDoorGoal");
|
||||
|
||||
// weird enderman case
|
||||
map.put("EnderMan.EndermanFreezeWhenLookedAt", "EndermanFreezeWhenLookedAt");
|
||||
map.put("EnderMan.EndermanLeaveBlockGoal", "EndermanLeaveBlockGoal");
|
||||
map.put("EnderMan.EndermanTakeBlockGoal", "EndermanTakeBlockGoal");
|
||||
map.put("EnderMan.EndermanLookForPlayerGoal", "EndermanLookForPlayerGoal");
|
||||
});
|
||||
|
||||
private static final Set<Class<? extends Mob>> NO_SPECIFIER = Set.of(
|
||||
Mob.class,
|
||||
Creature.class,
|
||||
Animals.class,
|
||||
RangedEntity.class,
|
||||
Tameable.class,
|
||||
Monster.class,
|
||||
PufferFish.class // weird case
|
||||
);
|
||||
|
||||
private static String getPathName(Class<? extends Mob> type, Class<?> holderClass, String name) {
|
||||
String pathName = name.substring(name.lastIndexOf('.') + 1);
|
||||
boolean needRename = false;
|
||||
|
||||
public static String getUsableName(Class<?> clazz) {
|
||||
String name = io.papermc.paper.util.MappingEnvironment.reobf() ? ObfHelper.INSTANCE.deobfClassName(clazz.getName()) : clazz.getName();
|
||||
name = name.substring(name.lastIndexOf(".") + 1);
|
||||
boolean flag = false;
|
||||
// inner classes
|
||||
if (name.contains("$")) {
|
||||
String cut = name.substring(name.indexOf("$") + 1);
|
||||
if (cut.length() <= 2) {
|
||||
name = name.replace("Entity", "");
|
||||
name = name.replace("$", "_");
|
||||
flag = true;
|
||||
} else {
|
||||
// mapped, wooo
|
||||
name = cut;
|
||||
int firstInnerDelimiter = pathName.indexOf('$');
|
||||
if (firstInnerDelimiter != -1) {
|
||||
String innerClassNames = pathName.substring(firstInnerDelimiter + 1);
|
||||
for (String innerClassName : innerClassNames.split("\\$")) {
|
||||
if (NumberUtils.isDigits(innerClassName)) {
|
||||
needRename = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!needRename && !NESTED_CLASS_NAMES.containsKey(pathName)) {
|
||||
pathName = innerClassNames;
|
||||
}
|
||||
}
|
||||
name = name.replace("TargetGoal", "");
|
||||
name = name.replace("Goal", "");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (char c : name.toCharArray()) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
sb.append("_");
|
||||
sb.append(Character.toLowerCase(c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
|
||||
if (!NESTED_CLASS_NAMES.containsKey(pathName)) {
|
||||
if (needRename) {
|
||||
throw new IllegalStateException("need to map " + name + " (" + pathName + ")");
|
||||
}
|
||||
}
|
||||
name = sb.toString();
|
||||
name = name.replaceFirst("_", "");
|
||||
|
||||
if (flag && !deobfuscationMap.containsKey(name.toLowerCase(java.util.Locale.ROOT)) && !ignored.contains(name)) {
|
||||
System.out.println("need to map " + clazz.getName() + " (" + name.toLowerCase(java.util.Locale.ROOT) + ")");
|
||||
String prefix = null;
|
||||
if (!NO_SPECIFIER.contains(type)) {
|
||||
prefix = type.getSimpleName();
|
||||
} else if (!net.minecraft.world.entity.Mob.class.isAssignableFrom(holderClass)) {
|
||||
prefix = holderClass.getSimpleName();
|
||||
}
|
||||
if (prefix != null && !pathName.startsWith(prefix)) {
|
||||
pathName = prefix + pathName;
|
||||
}
|
||||
} else {
|
||||
pathName = NESTED_CLASS_NAMES.get(pathName);
|
||||
}
|
||||
|
||||
// did we rename this key?
|
||||
return deobfuscationMap.getOrDefault(name, name);
|
||||
pathName = pathName.replace("TargetGoal", ""); // replace last? reverse search?
|
||||
pathName = pathName.replace("Goal", "");
|
||||
pathName = pathName.replace("Abstract", "");
|
||||
pathName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pathName);
|
||||
|
||||
return pathName;
|
||||
}
|
||||
|
||||
public static EnumSet<GoalType> vanillaToPaper(Goal goal) {
|
||||
@@ -197,20 +219,13 @@ public class MobGoalHelper {
|
||||
}
|
||||
|
||||
public static GoalType vanillaToPaper(Goal.Flag type) {
|
||||
switch (type) {
|
||||
case MOVE:
|
||||
return GoalType.MOVE;
|
||||
case LOOK:
|
||||
return GoalType.LOOK;
|
||||
case JUMP:
|
||||
return GoalType.JUMP;
|
||||
case UNKNOWN_BEHAVIOR:
|
||||
return GoalType.UNKNOWN_BEHAVIOR;
|
||||
case TARGET:
|
||||
return GoalType.TARGET;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown vanilla mob goal type " + type.name());
|
||||
}
|
||||
return switch (type) {
|
||||
case MOVE -> GoalType.MOVE;
|
||||
case LOOK -> GoalType.LOOK;
|
||||
case JUMP -> GoalType.JUMP;
|
||||
case UNKNOWN_BEHAVIOR -> GoalType.UNKNOWN_BEHAVIOR;
|
||||
case TARGET -> GoalType.TARGET;
|
||||
};
|
||||
}
|
||||
|
||||
public static EnumSet<Goal.Flag> paperToVanilla(EnumSet<GoalType> types) {
|
||||
@@ -222,41 +237,57 @@ public class MobGoalHelper {
|
||||
}
|
||||
|
||||
public static Goal.Flag paperToVanilla(GoalType type) {
|
||||
switch (type) {
|
||||
case MOVE:
|
||||
return Goal.Flag.MOVE;
|
||||
case LOOK:
|
||||
return Goal.Flag.LOOK;
|
||||
case JUMP:
|
||||
return Goal.Flag.JUMP;
|
||||
case UNKNOWN_BEHAVIOR:
|
||||
return Goal.Flag.UNKNOWN_BEHAVIOR;
|
||||
case TARGET:
|
||||
return Goal.Flag.TARGET;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown paper mob goal type " + type.name());
|
||||
}
|
||||
return switch (type) {
|
||||
case MOVE -> Goal.Flag.MOVE;
|
||||
case LOOK -> Goal.Flag.LOOK;
|
||||
case JUMP -> Goal.Flag.JUMP;
|
||||
case UNKNOWN_BEHAVIOR -> Goal.Flag.UNKNOWN_BEHAVIOR;
|
||||
case TARGET -> Goal.Flag.TARGET;
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends Mob> GoalKey<T> getKey(Class<? extends Goal> goalClass) {
|
||||
String name = getUsableName(goalClass);
|
||||
if (ignored.contains(name)) {
|
||||
//noinspection unchecked
|
||||
return (GoalKey<T>) GoalKey.of(Mob.class, NamespacedKey.minecraft(name));
|
||||
Class<T> type = getGenericType(goalClass);
|
||||
|
||||
String name = goalClass.getName();
|
||||
if (io.papermc.paper.util.MappingEnvironment.reobf()) {
|
||||
name = ObfHelper.INSTANCE.deobfClassName(name);
|
||||
}
|
||||
return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name));
|
||||
|
||||
Class<?> holderClass = getTopLevelClass(goalClass);
|
||||
name = getPathName(type, holderClass, name);
|
||||
return GoalKey.of(type, NamespacedKey.minecraft(name));
|
||||
}
|
||||
|
||||
public static <T extends Mob> Class<T> getEntity(Class<? extends Goal> goalClass) {
|
||||
private static final Int2BooleanFunction[] VISIBILITY_SEARCH_STEP = {
|
||||
Modifier::isPublic,
|
||||
Modifier::isProtected,
|
||||
mod -> (mod & 0b111) == 0, // package-private
|
||||
Modifier::isPrivate,
|
||||
};
|
||||
|
||||
private static final Comparator<Constructor<?>> VISIBILITY_ORDER = Comparator.comparingInt(constructor -> {
|
||||
int mod = constructor.getModifiers();
|
||||
for (int i = 0; i < VISIBILITY_SEARCH_STEP.length; i++) {
|
||||
Int2BooleanFunction visibility = VISIBILITY_SEARCH_STEP[i];
|
||||
if (visibility.test(mod)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Unknown visibility: " + mod);
|
||||
});
|
||||
|
||||
private static <T extends Mob> Class<T> getGenericType(Class<? extends Goal> goalClass) {
|
||||
//noinspection unchecked
|
||||
return (Class<T>) entityClassCache.computeIfAbsent(goalClass, key -> {
|
||||
for (Constructor<?> ctor : key.getDeclaredConstructors()) {
|
||||
for (int i = 0; i < ctor.getParameterCount(); i++) {
|
||||
Class<?> param = ctor.getParameterTypes()[i];
|
||||
if (net.minecraft.world.entity.Mob.class.isAssignableFrom(param)) {
|
||||
return (Class<T>) GENERIC_TYPE_CACHE.computeIfAbsent(goalClass, key -> {
|
||||
Constructor<?>[] constructors = key.getDeclaredConstructors();
|
||||
Arrays.sort(constructors, VISIBILITY_ORDER);
|
||||
for (Constructor<?> constructor : constructors) {
|
||||
for (Class<?> paramType : constructor.getParameterTypes()) {
|
||||
if (net.minecraft.world.entity.Mob.class.isAssignableFrom(paramType)) {
|
||||
//noinspection unchecked
|
||||
return toBukkitClass((Class<? extends net.minecraft.world.entity.Mob>) param);
|
||||
} else if (RangedAttackMob.class.isAssignableFrom(param)) {
|
||||
return toBukkitClass((Class<? extends net.minecraft.world.entity.Mob>) paramType);
|
||||
} else if (RangedAttackMob.class.isAssignableFrom(paramType)) {
|
||||
return RangedEntity.class;
|
||||
}
|
||||
}
|
||||
@@ -265,10 +296,24 @@ public class MobGoalHelper {
|
||||
});
|
||||
}
|
||||
|
||||
public static Class<? extends Mob> toBukkitClass(Class<? extends net.minecraft.world.entity.Mob> nmsClass) {
|
||||
Class<? extends Mob> bukkitClass = bukkitMap.get(nmsClass);
|
||||
private static Class<?> getTopLevelClass(Class<?> clazz) {
|
||||
Class<?> topLevelClass = clazz;
|
||||
Class<?> upperClass = clazz;
|
||||
|
||||
while(true) {
|
||||
upperClass = upperClass.getEnclosingClass();
|
||||
if (upperClass == null) {
|
||||
return topLevelClass;
|
||||
}
|
||||
|
||||
topLevelClass = upperClass;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<? extends Mob> toBukkitClass(Class<? extends net.minecraft.world.entity.Mob> internalClass) {
|
||||
Class<? extends Mob> bukkitClass = BUKKIT_BRIDGE.get(internalClass);
|
||||
if (bukkitClass == null) {
|
||||
throw new RuntimeException("Can't figure out applicable bukkit entity for nms entity " + nmsClass); // maybe just return Mob?
|
||||
throw new RuntimeException("Can't figure out applicable bukkit entity for internal entity " + internalClass); // maybe just return Mob?
|
||||
}
|
||||
return bukkitClass;
|
||||
}
|
||||
|
||||
@@ -21,41 +21,45 @@ public class PaperGoal<T extends Mob> implements com.destroystokyo.paper.entity.
|
||||
}
|
||||
|
||||
public Goal getHandle() {
|
||||
return handle;
|
||||
return this.handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldActivate() {
|
||||
return handle.canUse();
|
||||
return this.handle.canUse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldStayActive() {
|
||||
return handle.canContinueToUse();
|
||||
return this.handle.canContinueToUse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
handle.start();
|
||||
this.handle.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
handle.stop();
|
||||
this.handle.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
handle.tick();
|
||||
this.handle.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoalKey<T> getKey() {
|
||||
return key;
|
||||
return this.key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<GoalType> getTypes() {
|
||||
return types;
|
||||
return this.types;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.key.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.destroystokyo.paper.loottable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.papermc.paper.configuration.WorldConfiguration;
|
||||
import io.papermc.paper.configuration.type.DurationOrDisabled;
|
||||
import java.util.HashMap;
|
||||
@@ -14,6 +16,8 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.world.RandomizableContainer;
|
||||
import net.minecraft.world.entity.vehicle.ContainerEntity;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
@@ -164,53 +168,38 @@ public class PaperLootableInventoryData {
|
||||
private static final String NUM_REFILLS = "numRefills";
|
||||
private static final String LOOTED_PLAYERS = "lootedPlayers";
|
||||
|
||||
public void loadNbt(final CompoundTag base) {
|
||||
final Optional<CompoundTag> compOpt = base.getCompound(ROOT);
|
||||
if (compOpt.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CompoundTag comp = compOpt.get();
|
||||
this.lastFill = comp.getLongOr(LAST_FILL, -1);
|
||||
this.nextRefill = comp.getLongOr(NEXT_REFILL, -1);
|
||||
this.numRefills = comp.getIntOr(NUM_REFILLS, 0);
|
||||
final ListTag list = comp.getListOrEmpty(LOOTED_PLAYERS);
|
||||
final int size = list.size();
|
||||
if (size > 0) {
|
||||
this.lootedPlayers = new HashMap<>(list.size());
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.getCompound(i).ifPresent(tag -> {
|
||||
tag.read("UUID", UUIDUtil.CODEC).ifPresent(uuid -> {
|
||||
this.lootedPlayers.put(uuid, tag.getLongOr("Time", 0));
|
||||
});
|
||||
});
|
||||
public void loadNbt(final ValueInput input) {
|
||||
final ValueInput data = input.childOrEmpty(ROOT);
|
||||
this.lastFill = data.getLongOr(LAST_FILL, -1);
|
||||
this.nextRefill = data.getLongOr(NEXT_REFILL, -1);
|
||||
this.numRefills = data.getIntOr(NUM_REFILLS, 0);
|
||||
final ValueInput.TypedInputList<SerializedLootedPlayerEntry> list = data.listOrEmpty(LOOTED_PLAYERS, SerializedLootedPlayerEntry.CODEC);
|
||||
if (!list.isEmpty()) {
|
||||
this.lootedPlayers = new HashMap<>();
|
||||
list.forEach(serializedLootedPlayerEntry -> lootedPlayers.put(serializedLootedPlayerEntry.uuid, serializedLootedPlayerEntry.time));
|
||||
}
|
||||
}
|
||||
|
||||
public void saveNbt(final CompoundTag base) {
|
||||
final CompoundTag comp = new CompoundTag();
|
||||
public void saveNbt(final ValueOutput output) {
|
||||
final ValueOutput data = output.child(ROOT);
|
||||
if (this.nextRefill != -1) {
|
||||
comp.putLong(NEXT_REFILL, this.nextRefill);
|
||||
data.putLong(NEXT_REFILL, this.nextRefill);
|
||||
}
|
||||
if (this.lastFill != -1) {
|
||||
comp.putLong(LAST_FILL, this.lastFill);
|
||||
data.putLong(LAST_FILL, this.lastFill);
|
||||
}
|
||||
if (this.numRefills != 0) {
|
||||
comp.putInt(NUM_REFILLS, this.numRefills);
|
||||
data.putInt(NUM_REFILLS, this.numRefills);
|
||||
}
|
||||
if (this.lootedPlayers != null && !this.lootedPlayers.isEmpty()) {
|
||||
final ListTag list = new ListTag();
|
||||
final ValueOutput.TypedOutputList<SerializedLootedPlayerEntry> list = data.list(LOOTED_PLAYERS, SerializedLootedPlayerEntry.CODEC);
|
||||
for (final Map.Entry<UUID, Long> entry : this.lootedPlayers.entrySet()) {
|
||||
final CompoundTag cmp = new CompoundTag();
|
||||
cmp.store("UUID", UUIDUtil.CODEC, entry.getKey());
|
||||
cmp.putLong("Time", entry.getValue());
|
||||
list.add(cmp);
|
||||
list.add(new SerializedLootedPlayerEntry(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
comp.put(LOOTED_PLAYERS, list);
|
||||
}
|
||||
|
||||
if (!comp.isEmpty()) {
|
||||
base.put(ROOT, comp);
|
||||
if (data.isEmpty()) {
|
||||
output.discard(ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,4 +231,14 @@ public class PaperLootableInventoryData {
|
||||
@Nullable Long getLastLooted(final UUID player) {
|
||||
return this.lootedPlayers != null ? this.lootedPlayers.get(player) : null;
|
||||
}
|
||||
|
||||
record SerializedLootedPlayerEntry(UUID uuid, long time) {
|
||||
public static final Codec<SerializedLootedPlayerEntry> CODEC = RecordCodecBuilder.create(
|
||||
instance -> instance.group(
|
||||
UUIDUtil.CODEC.fieldOf("UUID").forGetter(SerializedLootedPlayerEntry::uuid),
|
||||
Codec.LONG.optionalFieldOf("Time", 0L).forGetter(SerializedLootedPlayerEntry::time)
|
||||
)
|
||||
.apply(instance, SerializedLootedPlayerEntry::new)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ public record ServerBuildInfoImpl(
|
||||
.orElse(BRAND_PAPER_ID),
|
||||
getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME)
|
||||
.orElse(BRAND_PAPER_NAME),
|
||||
SharedConstants.getCurrentVersion().getId(),
|
||||
SharedConstants.getCurrentVersion().getName(),
|
||||
SharedConstants.getCurrentVersion().id(),
|
||||
SharedConstants.getCurrentVersion().name(),
|
||||
getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER)
|
||||
.map(Integer::parseInt)
|
||||
.map(OptionalInt::of)
|
||||
|
||||
@@ -10,10 +10,10 @@ import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List<String> aliases, @Nullable String helpCommandNamespace, boolean serverSideOnly) {
|
||||
public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List<String> aliases, @Nullable String helpCommandNamespace) {
|
||||
|
||||
public APICommandMeta(final @Nullable PluginMeta pluginMeta, final @Nullable String description) {
|
||||
this(pluginMeta, description, Collections.emptyList(), null, false);
|
||||
this(pluginMeta, description, Collections.emptyList(), null);
|
||||
}
|
||||
|
||||
public APICommandMeta {
|
||||
@@ -26,6 +26,6 @@ public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String d
|
||||
}
|
||||
|
||||
public APICommandMeta withAliases(List<String> registeredAliases) {
|
||||
return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace, this.serverSideOnly);
|
||||
return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwn
|
||||
}
|
||||
|
||||
public @Unmodifiable Set<String> registerWithFlagsInternal(final @Nullable PluginMeta pluginMeta, final String namespace, final @Nullable String helpNamespaceOverride, final LiteralCommandNode<CommandSourceStack> node, final @Nullable String description, final Collection<String> aliases, final Set<CommandRegistrationFlag> flags) {
|
||||
final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride, flags.contains(CommandRegistrationFlag.SERVER_ONLY));
|
||||
final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride);
|
||||
final String literal = node.getLiteral();
|
||||
final LiteralCommandNode<CommandSourceStack> pluginLiteral = PaperBrigadier.copyLiteral(namespace + ":" + literal, node);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ public final class MobcapsCommand implements PaperSubcommand {
|
||||
}
|
||||
|
||||
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||
final ServerLevel level = serverPlayer.serverLevel();
|
||||
final ServerLevel level = serverPlayer.level();
|
||||
|
||||
if (!level.paperConfig().entities.spawning.perPlayerMobSpawns) {
|
||||
sender.sendMessage(Component.text("Use '/paper mobcaps' for worlds where per-player mob spawning is disabled.", NamedTextColor.RED));
|
||||
|
||||
@@ -184,7 +184,6 @@ public final class DataComponentAdapters {
|
||||
register(DataComponents.RABBIT_VARIANT, nms -> Rabbit.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.Rabbit.Variant.byId(api.ordinal()));
|
||||
register(DataComponents.PIG_VARIANT, CraftPig.CraftVariant::minecraftHolderToBukkit, CraftPig.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.COW_VARIANT, CraftCow.CraftVariant::minecraftHolderToBukkit, CraftCow.CraftVariant::bukkitToMinecraftHolder);
|
||||
// TODO: We should probably find a better pattern for handling this which retains the EitherHolder, this does kinda suck in terms of exposure, however
|
||||
register(DataComponents.CHICKEN_VARIANT, nms -> CraftChicken.CraftVariant.minecraftHolderToBukkit(nms.unwrap(CraftRegistry.getMinecraftRegistry()).orElseThrow()), api -> new EitherHolder<>(CraftChicken.CraftVariant.bukkitToMinecraftHolder(api)));
|
||||
register(DataComponents.FROG_VARIANT, CraftFrog.CraftVariant::minecraftHolderToBukkit, CraftFrog.CraftVariant::bukkitToMinecraftHolder);
|
||||
register(DataComponents.HORSE_VARIANT, nms -> Horse.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.horse.Variant.byId(api.ordinal()));
|
||||
|
||||
@@ -3,13 +3,13 @@ package io.papermc.paper.datacomponent.item;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import io.papermc.paper.text.Filtered;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.util.TriState;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.world.item.component.OminousBottleAmplifier;
|
||||
import org.bukkit.JukeboxSong;
|
||||
@@ -171,11 +171,11 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr
|
||||
}
|
||||
|
||||
@Override
|
||||
public UseRemainder useRemainder(final ItemStack itemStack) {
|
||||
Preconditions.checkArgument(itemStack != null, "Item cannot be null");
|
||||
Preconditions.checkArgument(!itemStack.isEmpty(), "Remaining item cannot be empty!");
|
||||
public UseRemainder useRemainder(final ItemStack stack) {
|
||||
Preconditions.checkArgument(stack != null, "Item cannot be null");
|
||||
Preconditions.checkArgument(!stack.isEmpty(), "Remaining item cannot be empty!");
|
||||
return new PaperUseRemainder(
|
||||
new net.minecraft.world.item.component.UseRemainder(CraftItemStack.asNMSCopy(itemStack))
|
||||
new net.minecraft.world.item.component.UseRemainder(CraftItemStack.asNMSCopy(stack))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr
|
||||
@Override
|
||||
public Repairable repairable(final RegistryKeySet<ItemType> types) {
|
||||
return new PaperRepairable(new net.minecraft.world.item.enchantment.Repairable(
|
||||
PaperRegistrySets.convertToNms(Registries.ITEM, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), types)
|
||||
PaperRegistrySets.convertToNms(Registries.ITEM, Conversions.global().lookup(), types)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import io.papermc.paper.datacomponent.item.blocksattacks.PaperDamageReduction;
|
||||
import io.papermc.paper.datacomponent.item.blocksattacks.PaperItemDamageFunction;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.damage.DamageType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public record PaperBlocksAttacks(
|
||||
net.minecraft.world.item.component.BlocksAttacks impl
|
||||
@@ -65,7 +65,7 @@ public record PaperBlocksAttacks(
|
||||
|
||||
private float blockDelaySeconds;
|
||||
private float disableCooldownScale = 1.0F;
|
||||
private List<DamageReduction> damageReductions = new ArrayList<>();
|
||||
private List<DamageReduction> damageReductions = new ObjectArrayList<>();
|
||||
private ItemDamageFunction itemDamage = new PaperItemDamageFunction(net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT);
|
||||
private @Nullable TagKey<DamageType> bypassedBy;
|
||||
private @Nullable Key blockSound;
|
||||
@@ -87,11 +87,16 @@ public record PaperBlocksAttacks(
|
||||
|
||||
@Override
|
||||
public Builder addDamageReduction(final DamageReduction reduction) {
|
||||
Preconditions.checkArgument(reduction.horizontalBlockingAngle() >= 0, "horizontalBlockingAngle must be non-negative, was %s", reduction.horizontalBlockingAngle());
|
||||
this.damageReductions.add(reduction);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder damageReductions(final List<DamageReduction> reductions) {
|
||||
this.damageReductions = new ObjectArrayList<>(reductions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder itemDamage(final ItemDamageFunction function) {
|
||||
this.itemDamage = function;
|
||||
@@ -105,30 +110,24 @@ public record PaperBlocksAttacks(
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder blockSound(@Nullable final Key sound) {
|
||||
public Builder blockSound(final @Nullable Key sound) {
|
||||
this.blockSound = sound;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder disableSound(@Nullable final Key sound) {
|
||||
public Builder disableSound(final @Nullable Key sound) {
|
||||
this.disableSound = sound;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder damageReductions(final List<DamageReduction> reductions) {
|
||||
this.damageReductions = new ArrayList<>(reductions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlocksAttacks build() {
|
||||
return new PaperBlocksAttacks(new net.minecraft.world.item.component.BlocksAttacks(
|
||||
this.blockDelaySeconds,
|
||||
this.disableCooldownScale,
|
||||
this.damageReductions.stream().map(damageReduction -> ((PaperDamageReduction) damageReduction).getHandle()).toList(),
|
||||
((PaperItemDamageFunction) itemDamage).getHandle(),
|
||||
((PaperItemDamageFunction) this.itemDamage).getHandle(),
|
||||
Optional.ofNullable(this.bypassedBy).map(PaperRegistries::toNms),
|
||||
Optional.ofNullable(this.blockSound).map(PaperAdventure::resolveSound),
|
||||
Optional.ofNullable(this.disableSound).map(PaperAdventure::resolveSound)
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
|
||||
import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation;
|
||||
import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffects;
|
||||
import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffect;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.util.List;
|
||||
@@ -49,7 +49,7 @@ public record PaperConsumable(
|
||||
|
||||
@Override
|
||||
public @Unmodifiable List<ConsumeEffect> consumeEffects() {
|
||||
return MCUtil.transformUnmodifiable(this.impl.onConsumeEffects(), PaperConsumableEffects::fromNms);
|
||||
return MCUtil.transformUnmodifiable(this.impl.onConsumeEffects(), PaperConsumableEffect::fromNms);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,14 +98,14 @@ public record PaperConsumable(
|
||||
|
||||
@Override
|
||||
public Builder addEffect(final ConsumeEffect effect) {
|
||||
this.effects.add(PaperConsumableEffects.toNms(effect));
|
||||
this.effects.add(PaperConsumableEffect.toNms(effect));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder addEffects(final List<ConsumeEffect> effects) {
|
||||
for (final ConsumeEffect effect : effects) {
|
||||
this.effects.add(PaperConsumableEffects.toNms(effect));
|
||||
this.effects.add(PaperConsumableEffect.toNms(effect));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
|
||||
import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffects;
|
||||
import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffect;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -19,7 +19,7 @@ public record PaperDeathProtection(
|
||||
|
||||
@Override
|
||||
public @Unmodifiable List<ConsumeEffect> deathEffects() {
|
||||
return MCUtil.transformUnmodifiable(this.impl.deathEffects(), PaperConsumableEffects::fromNms);
|
||||
return MCUtil.transformUnmodifiable(this.impl.deathEffects(), PaperConsumableEffect::fromNms);
|
||||
}
|
||||
|
||||
static final class BuilderImpl implements Builder {
|
||||
@@ -28,14 +28,14 @@ public record PaperDeathProtection(
|
||||
|
||||
@Override
|
||||
public Builder addEffect(final ConsumeEffect effect) {
|
||||
this.effects.add(PaperConsumableEffects.toNms(effect));
|
||||
this.effects.add(PaperConsumableEffect.toNms(effect));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder addEffects(final List<ConsumeEffect> effects) {
|
||||
for (final ConsumeEffect effect : effects) {
|
||||
this.effects.add(PaperConsumableEffects.toNms(effect));
|
||||
this.effects.add(PaperConsumableEffect.toNms(effect));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import java.util.Optional;
|
||||
@@ -20,7 +21,7 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public record PaperEquippable(
|
||||
net.minecraft.world.item.equipment.Equippable impl
|
||||
@@ -82,6 +83,16 @@ public record PaperEquippable(
|
||||
return this.impl.equipOnInteract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeSheared() {
|
||||
return this.impl.canBeSheared();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key shearSound() {
|
||||
return PaperAdventure.asAdventure(this.impl.shearingSound().value().location());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new BuilderImpl(this.slot())
|
||||
@@ -92,7 +103,9 @@ public record PaperEquippable(
|
||||
.dispensable(this.dispensable())
|
||||
.swappable(this.swappable())
|
||||
.damageOnHurt(this.damageOnHurt())
|
||||
.equipOnInteract(this.equipOnInteract());
|
||||
.equipOnInteract(this.equipOnInteract())
|
||||
.shearSound(this.shearSound())
|
||||
.canBeSheared(this.canBeSheared());
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +120,8 @@ public record PaperEquippable(
|
||||
private boolean swappable = true;
|
||||
private boolean damageOnHurt = true;
|
||||
private boolean equipOnInteract;
|
||||
private boolean canBeSheared = false;
|
||||
private Holder<SoundEvent> shearSound = BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP);
|
||||
|
||||
BuilderImpl(final EquipmentSlot equipmentSlot) {
|
||||
this.equipmentSlot = CraftEquipmentSlot.getNMS(equipmentSlot);
|
||||
@@ -137,7 +152,7 @@ public record PaperEquippable(
|
||||
@Override
|
||||
public Builder allowedEntities(final @Nullable RegistryKeySet<EntityType> allowedEntities) {
|
||||
this.allowedEntities = Optional.ofNullable(allowedEntities)
|
||||
.map((set) -> PaperRegistrySets.convertToNms(Registries.ENTITY_TYPE, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), set));
|
||||
.map((set) -> PaperRegistrySets.convertToNms(Registries.ENTITY_TYPE, Conversions.global().lookup(), set));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -165,6 +180,18 @@ public record PaperEquippable(
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder canBeSheared(final boolean canBeSheared) {
|
||||
this.canBeSheared = canBeSheared;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder shearSound(final Key shearSound) {
|
||||
this.shearSound = PaperAdventure.resolveSound(shearSound);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Equippable build() {
|
||||
return new PaperEquippable(
|
||||
@@ -177,7 +204,9 @@ public record PaperEquippable(
|
||||
this.dispensable,
|
||||
this.swappable,
|
||||
this.damageOnHurt,
|
||||
this.equipOnInteract
|
||||
this.equipOnInteract,
|
||||
this.canBeSheared,
|
||||
this.shearSound
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import io.papermc.paper.block.BlockPredicate;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.advancements.critereon.DataComponentMatchers;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
|
||||
@@ -25,6 +25,7 @@ public record PaperItemAdventurePredicate(
|
||||
public net.minecraft.world.item.AdventureModePredicate getHandle() {
|
||||
return this.impl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPredicate> predicates() {
|
||||
return convert(this.impl);
|
||||
@@ -37,7 +38,7 @@ public record PaperItemAdventurePredicate(
|
||||
@Override
|
||||
public ItemAdventurePredicate.Builder addPredicate(final BlockPredicate predicate) {
|
||||
this.predicates.add(new net.minecraft.advancements.critereon.BlockPredicate(Optional.ofNullable(predicate.blocks()).map(
|
||||
blocks -> PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), blocks)
|
||||
blocks -> PaperRegistrySets.convertToNms(Registries.BLOCK, Conversions.global().lookup(), blocks)
|
||||
), Optional.empty(), Optional.empty(), DataComponentMatchers.ANY)); // TODO DataComponentMatchers
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public record PaperItemArmorTrim(
|
||||
BuilderImpl(final ArmorTrim armorTrim) {
|
||||
this.armorTrim = armorTrim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemArmorTrim.Builder armorTrim(final ArmorTrim armorTrim) {
|
||||
this.armorTrim = armorTrim;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplay;
|
||||
import io.papermc.paper.datacomponent.item.attribute.PaperAttributeModifierDisplay;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import java.util.List;
|
||||
@@ -21,7 +23,8 @@ public record PaperItemAttributeModifiers(
|
||||
private static List<Entry> convert(final net.minecraft.world.item.component.ItemAttributeModifiers nmsModifiers) {
|
||||
return MCUtil.transformUnmodifiable(nmsModifiers.modifiers(), nms -> new PaperEntry(
|
||||
CraftAttribute.minecraftHolderToBukkit(nms.attribute()),
|
||||
CraftAttributeInstance.convert(nms.modifier(), nms.slot())
|
||||
CraftAttributeInstance.convert(nms.modifier(), nms.slot()),
|
||||
PaperAttributeModifierDisplay.fromNms(nms.display())
|
||||
));
|
||||
}
|
||||
|
||||
@@ -35,7 +38,7 @@ public record PaperItemAttributeModifiers(
|
||||
return convert(this.impl);
|
||||
}
|
||||
|
||||
public record PaperEntry(Attribute attribute, AttributeModifier modifier) implements ItemAttributeModifiers.Entry {
|
||||
public record PaperEntry(Attribute attribute, AttributeModifier modifier, AttributeModifierDisplay display) implements ItemAttributeModifiers.Entry {
|
||||
}
|
||||
|
||||
static final class BuilderImpl implements ItemAttributeModifiers.Builder {
|
||||
@@ -43,12 +46,7 @@ public record PaperItemAttributeModifiers(
|
||||
private final List<net.minecraft.world.item.component.ItemAttributeModifiers.Entry> entries = new ObjectArrayList<>();
|
||||
|
||||
@Override
|
||||
public Builder addModifier(final Attribute attribute, final AttributeModifier modifier) {
|
||||
return this.addModifier(attribute, modifier, modifier.getSlotGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers.Builder addModifier(final Attribute attribute, final AttributeModifier modifier, final EquipmentSlotGroup equipmentSlotGroup) {
|
||||
public ItemAttributeModifiers.Builder addModifier(final Attribute attribute, final AttributeModifier modifier, final EquipmentSlotGroup equipmentSlotGroup, final AttributeModifierDisplay display) {
|
||||
Preconditions.checkArgument(
|
||||
this.entries.stream().noneMatch(e ->
|
||||
e.modifier().id().equals(CraftNamespacedKey.toMinecraft(modifier.getKey())) && e.attribute().is(CraftNamespacedKey.toMinecraft(attribute.getKey()))
|
||||
@@ -60,7 +58,8 @@ public record PaperItemAttributeModifiers(
|
||||
this.entries.add(new net.minecraft.world.item.component.ItemAttributeModifiers.Entry(
|
||||
CraftAttribute.bukkitToMinecraftHolder(attribute),
|
||||
CraftAttributeInstance.convert(modifier),
|
||||
CraftEquipmentSlot.getNMSGroup(equipmentSlotGroup)
|
||||
CraftEquipmentSlot.getNMSGroup(equipmentSlotGroup),
|
||||
PaperAttributeModifierDisplay.toNms(display)
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public record PaperItemContainerContents(
|
||||
this.items.size() + stacks.size()
|
||||
);
|
||||
MCUtil.addAndConvert(this.items, stacks, stack -> {
|
||||
Preconditions.checkArgument(stack != null, "Cannot pass null itemstacks!");
|
||||
Preconditions.checkArgument(stack != null, "Cannot pass null item!");
|
||||
return CraftItemStack.asNMSCopy(stack);
|
||||
});
|
||||
return this;
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import io.papermc.paper.util.MCUtil;
|
||||
@@ -10,12 +11,11 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.util.TriState;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import org.bukkit.block.BlockType;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public record PaperItemTool(
|
||||
net.minecraft.world.item.component.Tool impl
|
||||
@@ -85,7 +85,7 @@ public record PaperItemTool(
|
||||
@Override
|
||||
public Builder addRule(final Rule rule) {
|
||||
this.rules.add(new net.minecraft.world.item.component.Tool.Rule(
|
||||
PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), rule.blocks()),
|
||||
PaperRegistrySets.convertToNms(Registries.BLOCK, Conversions.global().lookup(), rule.blocks()),
|
||||
Optional.ofNullable(rule.speed()),
|
||||
Optional.ofNullable(rule.correctForDrops().toBoolean())
|
||||
));
|
||||
|
||||
@@ -14,8 +14,8 @@ import org.bukkit.craftbukkit.potion.CraftPotionUtil;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public record PaperPotionContents(
|
||||
net.minecraft.world.item.alchemy.PotionContents impl
|
||||
|
||||
@@ -13,8 +13,10 @@ import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.minecraft.util.StringUtil;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public record PaperResolvableProfile(
|
||||
net.minecraft.world.item.component.ResolvableProfile impl
|
||||
|
||||
@@ -28,7 +28,6 @@ public record PaperUseCooldown(
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
static final class BuilderImpl implements Builder {
|
||||
|
||||
private final float seconds;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public class AttributeModifierDisplayBridgeImpl implements AttributeModifierDisplayBridge {
|
||||
|
||||
@Override
|
||||
public AttributeModifierDisplay.Default reset() {
|
||||
return new PaperDefaultDisplay(new ItemAttributeModifiers.Display.Default());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeModifierDisplay.Hidden hidden() {
|
||||
return new PaperHiddenDisplay(new ItemAttributeModifiers.Display.Hidden());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeModifierDisplay.OverrideText override(final ComponentLike text) {
|
||||
return new PaperOverrideTextDisplay(new ItemAttributeModifiers.Display.OverrideText(PaperAdventure.asVanilla(text.asComponent())));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
|
||||
public interface PaperAttributeModifierDisplay<T extends ItemAttributeModifiers.Display> extends Handleable<T> {
|
||||
|
||||
static AttributeModifierDisplay fromNms(ItemAttributeModifiers.Display display) {
|
||||
return switch (display) {
|
||||
case ItemAttributeModifiers.Display.Default def -> new PaperDefaultDisplay(def);
|
||||
case ItemAttributeModifiers.Display.Hidden hidden -> new PaperHiddenDisplay(hidden);
|
||||
case ItemAttributeModifiers.Display.OverrideText override -> new PaperOverrideTextDisplay(override);
|
||||
default -> throw new UnsupportedOperationException("Don't know how to convert " + display.getClass());
|
||||
};
|
||||
}
|
||||
|
||||
static ItemAttributeModifiers.Display toNms(AttributeModifierDisplay display) {
|
||||
if (display instanceof PaperAttributeModifierDisplay<?> modifierDisplay) {
|
||||
return modifierDisplay.getHandle();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Must implement handleable!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
|
||||
public record PaperDefaultDisplay(
|
||||
ItemAttributeModifiers.Display.Default impl
|
||||
) implements AttributeModifierDisplay.Default, PaperAttributeModifierDisplay<ItemAttributeModifiers.Display.Default> {
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers.Display.Default getHandle() {
|
||||
return this.impl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
|
||||
public record PaperHiddenDisplay(
|
||||
ItemAttributeModifiers.Display.Hidden impl
|
||||
) implements AttributeModifierDisplay.Hidden, PaperAttributeModifierDisplay<ItemAttributeModifiers.Display.Hidden> {
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers.Display.Hidden getHandle() {
|
||||
return this.impl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.world.item.component.ItemAttributeModifiers;
|
||||
|
||||
public record PaperOverrideTextDisplay(
|
||||
ItemAttributeModifiers.Display.OverrideText impl
|
||||
) implements AttributeModifierDisplay.OverrideText, PaperAttributeModifierDisplay<ItemAttributeModifiers.Display.OverrideText> {
|
||||
|
||||
@Override
|
||||
public Component text() {
|
||||
return PaperAdventure.asAdventure(this.impl.component());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemAttributeModifiers.Display.OverrideText getHandle() {
|
||||
return this.impl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Relating to attribute modifier display for components.
|
||||
*/
|
||||
@NullMarked
|
||||
package io.papermc.paper.datacomponent.item.attribute;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
@@ -1,9 +1,7 @@
|
||||
package io.papermc.paper.datacomponent.item.blocksattacks;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@NullMarked
|
||||
public class BlocksAttacksBridgeImpl implements BlocksAttacksBridge {
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item.blocksattacks;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import net.minecraft.core.HolderSet;
|
||||
@@ -9,7 +10,7 @@ import net.minecraft.core.registries.Registries;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.damage.DamageType;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import java.util.Optional;
|
||||
|
||||
public record PaperDamageReduction(
|
||||
@@ -44,19 +45,19 @@ public record PaperDamageReduction(
|
||||
static final class BuilderImpl implements Builder {
|
||||
|
||||
private Optional<HolderSet<net.minecraft.world.damagesource.DamageType>> type = Optional.empty();
|
||||
private float horizontalBlockingAngle = 90f;
|
||||
private float base = 0;
|
||||
private float factor = 0;
|
||||
private float horizontalBlockingAngle = 90.0F;
|
||||
private float base = 0.0F;
|
||||
private float factor = 1.0F;
|
||||
|
||||
@Override
|
||||
public Builder type(final @Nullable RegistryKeySet<DamageType> type) {
|
||||
this.type = Optional.ofNullable(type)
|
||||
.map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider, set));
|
||||
.map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, Conversions.global().lookup(), set));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder horizontalBlockingAngle(@Positive final float horizontalBlockingAngle) {
|
||||
public Builder horizontalBlockingAngle(final @Positive float horizontalBlockingAngle) {
|
||||
Preconditions.checkArgument(horizontalBlockingAngle > 0, "horizontalBlockingAngle must be positive and not zero, was %s", horizontalBlockingAngle);
|
||||
this.horizontalBlockingAngle = horizontalBlockingAngle;
|
||||
return this;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.papermc.paper.datacomponent.item.blocksattacks;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.world.item.component.BlocksAttacks;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.checkerframework.checker.index.qual.NonNegative;
|
||||
|
||||
@@ -35,12 +36,12 @@ public record PaperItemDamageFunction(
|
||||
|
||||
static final class BuilderImpl implements Builder {
|
||||
|
||||
private float threshold;
|
||||
private float base;
|
||||
private float factor;
|
||||
private float threshold = BlocksAttacks.ItemDamageFunction.DEFAULT.threshold();
|
||||
private float base = BlocksAttacks.ItemDamageFunction.DEFAULT.base();
|
||||
private float factor = BlocksAttacks.ItemDamageFunction.DEFAULT.factor();
|
||||
|
||||
@Override
|
||||
public Builder threshold(@NonNegative final float threshold) {
|
||||
public Builder threshold(final @NonNegative float threshold) {
|
||||
Preconditions.checkArgument(threshold >= 0, "threshold must be non-negative, was %s", threshold);
|
||||
this.threshold = threshold;
|
||||
return this;
|
||||
|
||||
@@ -3,20 +3,18 @@ package io.papermc.paper.datacomponent.item.consumable;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@ApiStatus.Internal
|
||||
@NullMarked
|
||||
public class ConsumableTypesBridgeImpl implements ConsumableTypesBridge {
|
||||
|
||||
@@ -35,7 +33,7 @@ public class ConsumableTypesBridgeImpl implements ConsumableTypesBridge {
|
||||
public ConsumeEffect.RemoveStatusEffects removeStatusEffects(final RegistryKeySet<PotionEffectType> effectTypes) {
|
||||
return new PaperRemoveStatusEffects(
|
||||
new net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect(
|
||||
PaperRegistrySets.convertToNms(Registries.MOB_EFFECT, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), effectTypes)
|
||||
PaperRegistrySets.convertToNms(Registries.MOB_EFFECT, Conversions.global().lookup(), effectTypes)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import static io.papermc.paper.util.MCUtil.transformUnmodifiable;
|
||||
|
||||
public record PaperApplyStatusEffects(
|
||||
ApplyStatusEffectsConsumeEffect impl
|
||||
) implements ConsumeEffect.ApplyStatusEffects, PaperConsumableEffectImpl<ApplyStatusEffectsConsumeEffect> {
|
||||
) implements ConsumeEffect.ApplyStatusEffects, PaperConsumableEffect<ApplyStatusEffectsConsumeEffect> {
|
||||
|
||||
@Override
|
||||
public List<PotionEffect> effects() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package io.papermc.paper.datacomponent.item.consumable;
|
||||
|
||||
import net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect;
|
||||
|
||||
public record PaperClearAllStatusEffects(
|
||||
net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect impl
|
||||
) implements ConsumeEffect.ClearAllStatusEffects, PaperConsumableEffectImpl<net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect> {
|
||||
) implements ConsumeEffect.ClearAllStatusEffects, PaperConsumableEffect<ClearAllStatusEffectsConsumeEffect> {
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect getHandle() {
|
||||
|
||||
@@ -2,16 +2,15 @@ package io.papermc.paper.datacomponent.item.consumable;
|
||||
|
||||
import net.minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffect;
|
||||
import net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect;
|
||||
import net.minecraft.world.item.consume_effects.ConsumeEffect;
|
||||
import net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect;
|
||||
import net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect;
|
||||
import net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
|
||||
public final class PaperConsumableEffects {
|
||||
public interface PaperConsumableEffect<T extends ConsumeEffect> extends Handleable<T> {
|
||||
|
||||
private PaperConsumableEffects() {
|
||||
}
|
||||
|
||||
public static ConsumeEffect fromNms(net.minecraft.world.item.consume_effects.ConsumeEffect consumable) {
|
||||
static io.papermc.paper.datacomponent.item.consumable.ConsumeEffect fromNms(net.minecraft.world.item.consume_effects.ConsumeEffect consumable) {
|
||||
return switch (consumable) {
|
||||
case ApplyStatusEffectsConsumeEffect effect -> new PaperApplyStatusEffects(effect);
|
||||
case ClearAllStatusEffectsConsumeEffect effect -> new PaperClearAllStatusEffects(effect);
|
||||
@@ -22,8 +21,8 @@ public final class PaperConsumableEffects {
|
||||
};
|
||||
}
|
||||
|
||||
public static net.minecraft.world.item.consume_effects.ConsumeEffect toNms(ConsumeEffect effect) {
|
||||
if (effect instanceof PaperConsumableEffectImpl<?> consumableEffect) {
|
||||
static net.minecraft.world.item.consume_effects.ConsumeEffect toNms(io.papermc.paper.datacomponent.item.consumable.ConsumeEffect effect) {
|
||||
if (effect instanceof PaperConsumableEffect<?> consumableEffect) {
|
||||
return consumableEffect.getHandle();
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Must implement handleable!");
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.papermc.paper.datacomponent.item.consumable;
|
||||
|
||||
import net.minecraft.world.item.consume_effects.ConsumeEffect;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
|
||||
public interface PaperConsumableEffectImpl<T extends ConsumeEffect> extends Handleable<T> {
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect;
|
||||
|
||||
public record PaperPlaySound(
|
||||
PlaySoundConsumeEffect impl
|
||||
) implements ConsumeEffect.PlaySound, PaperConsumableEffectImpl<PlaySoundConsumeEffect> {
|
||||
) implements ConsumeEffect.PlaySound, PaperConsumableEffect<PlaySoundConsumeEffect> {
|
||||
|
||||
@Override
|
||||
public Key sound() {
|
||||
|
||||
@@ -3,11 +3,12 @@ package io.papermc.paper.datacomponent.item.consumable;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.set.PaperRegistrySets;
|
||||
import io.papermc.paper.registry.set.RegistryKeySet;
|
||||
import net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public record PaperRemoveStatusEffects(
|
||||
net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect impl
|
||||
) implements ConsumeEffect.RemoveStatusEffects, PaperConsumableEffectImpl<net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect> {
|
||||
) implements ConsumeEffect.RemoveStatusEffects, PaperConsumableEffect<RemoveStatusEffectsConsumeEffect> {
|
||||
|
||||
@Override
|
||||
public RegistryKeySet<PotionEffectType> removeEffects() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package io.papermc.paper.datacomponent.item.consumable;
|
||||
|
||||
import net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect;
|
||||
|
||||
public record PaperTeleportRandomly(
|
||||
net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect impl
|
||||
) implements ConsumeEffect.TeleportRandomly, PaperConsumableEffectImpl<net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect> {
|
||||
) implements ConsumeEffect.TeleportRandomly, PaperConsumableEffect<TeleportRandomlyConsumeEffect> {
|
||||
@Override
|
||||
public float diameter() {
|
||||
return this.impl.diameter();
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package io.papermc.paper.entity.activation;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.FlyingMob;
|
||||
import net.minecraft.world.entity.PathfinderMob;
|
||||
import net.minecraft.world.entity.ambient.AmbientCreature;
|
||||
import net.minecraft.world.entity.animal.AgeableWaterCreature;
|
||||
import net.minecraft.world.entity.animal.WaterAnimal;
|
||||
import net.minecraft.world.entity.monster.Enemy;
|
||||
import net.minecraft.world.entity.monster.Ghast;
|
||||
import net.minecraft.world.entity.monster.Phantom;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.raid.Raider;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -33,7 +34,7 @@ public enum ActivationType {
|
||||
return ActivationType.WATER;
|
||||
} else if (entity instanceof Villager) {
|
||||
return ActivationType.VILLAGER;
|
||||
} else if (entity instanceof FlyingMob && entity instanceof Enemy) {
|
||||
} else if (entity instanceof Ghast || entity instanceof Phantom) { // TODO: some kind of better distinction here?
|
||||
return ActivationType.FLYING_MONSTER;
|
||||
} else if (entity instanceof Raider) {
|
||||
return ActivationType.RAIDER;
|
||||
|
||||
@@ -320,7 +320,6 @@ class PaperPluginInstanceManager {
|
||||
|
||||
}
|
||||
|
||||
// TODO: Implement event part in future patch (paper patch move up, this patch is lower)
|
||||
private void handlePluginException(String msg, Throwable ex, Plugin plugin) {
|
||||
Bukkit.getServer().getLogger().log(Level.SEVERE, msg, ex);
|
||||
this.pluginManager.callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin)));
|
||||
|
||||
@@ -12,8 +12,10 @@ import io.papermc.paper.registry.data.PaperDamageTypeRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperFrogVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperGameEventRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperJukeboxSongRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperPigVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperSoundEventRegistryEntry;
|
||||
import io.papermc.paper.registry.data.PaperWolfVariantRegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
@@ -95,7 +97,7 @@ public final class PaperRegistries {
|
||||
static {
|
||||
REGISTRY_ENTRIES = List.of(
|
||||
// Start generate - RegistryDefinitions
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
// built-in
|
||||
start(Registries.GAME_EVENT, RegistryKey.GAME_EVENT).craft(GameEvent.class, CraftGameEvent::new).writable(PaperGameEventRegistryEntry.PaperBuilder::new),
|
||||
start(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE).craft(StructureType.class, CraftStructureType::new).build(),
|
||||
@@ -108,7 +110,7 @@ public final class PaperRegistries {
|
||||
start(Registries.MENU, RegistryKey.MENU).craft(MenuType.class, CraftMenuType::new).build(),
|
||||
start(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE).craft(Attribute.class, CraftAttribute::new).serializationUpdater(FieldRename.ATTRIBUTE_RENAME).build(),
|
||||
start(Registries.FLUID, RegistryKey.FLUID).craft(Fluid.class, CraftFluid::new).build(),
|
||||
start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new, true).build(),
|
||||
start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new, true).create(PaperSoundEventRegistryEntry.PaperBuilder::new, RegistryEntryMeta.RegistryModificationApiSupport.NONE),
|
||||
start(Registries.DATA_COMPONENT_TYPE, RegistryKey.DATA_COMPONENT_TYPE).craft(DataComponentTypes.class, PaperDataComponentType::of).build(),
|
||||
|
||||
// data-driven
|
||||
@@ -120,9 +122,9 @@ public final class PaperRegistries {
|
||||
start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).writable(PaperWolfVariantRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.WOLF_SOUND_VARIANT, RegistryKey.WOLF_SOUND_VARIANT).craft(Wolf.SoundVariant.class, CraftWolf.CraftSoundVariant::new).build(),
|
||||
start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).serializationUpdater(FieldRename.ENCHANTMENT_RENAME).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(),
|
||||
start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).writable(PaperJukeboxSongRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new, true).writable(PaperBannerPatternRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new, true).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new, true).build().delayed(),
|
||||
start(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT).craft(Cat.Type.class, CraftCat.CraftType::new).writable(PaperCatTypeRegistryEntry.PaperBuilder::new).delayed(),
|
||||
start(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT).craft(Frog.Variant.class, CraftFrog.CraftVariant::new).writable(PaperFrogVariantRegistryEntry.PaperBuilder::new).delayed(),
|
||||
|
||||
@@ -97,12 +97,12 @@ public class PaperRegistryAccess implements RegistryAccess {
|
||||
return registry;
|
||||
}
|
||||
|
||||
public <M> void registerReloadableRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry) {
|
||||
this.registerRegistry(resourceKey, registry, true);
|
||||
public <M> void registerReloadableRegistry(final net.minecraft.core.Registry<M> registry) {
|
||||
this.registerRegistry(registry, true);
|
||||
}
|
||||
|
||||
public <M> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry) {
|
||||
this.registerRegistry(resourceKey, registry, false);
|
||||
public <M> void registerRegistry(final net.minecraft.core.Registry<M> registry) {
|
||||
this.registerRegistry(registry, false);
|
||||
}
|
||||
|
||||
public <M> void lockReferenceHolders(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey) {
|
||||
@@ -115,8 +115,8 @@ public class PaperRegistryAccess implements RegistryAccess {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // this method should be called right after any new MappedRegistry instances are created to later be used by the server.
|
||||
private <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry, final boolean replace) {
|
||||
final RegistryEntry<M, B> entry = PaperRegistries.getEntry(resourceKey);
|
||||
private <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final net.minecraft.core.Registry<M> registry, final boolean replace) {
|
||||
final RegistryEntry<M, B> entry = PaperRegistries.getEntry(registry.key());
|
||||
if (entry == null) { // skip registries that don't have API entries
|
||||
return;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class PaperRegistryAccess implements RegistryAccess {
|
||||
// if the registry holder is delayed, and the entry is marked as "delayed", then load the holder with the CraftRegistry instance that wraps the actual nms Registry.
|
||||
((RegistryHolder.Delayed<B, R>) registryHolder).loadFrom(delayedEntry, registry);
|
||||
} else {
|
||||
throw new IllegalArgumentException(resourceKey + " has already been created");
|
||||
throw new IllegalArgumentException(registry.key() + " has already been created");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,28 @@ package io.papermc.paper.registry;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class PaperRegistryBuilderFactory<M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> implements RegistryBuilderFactory<A, B> { // TODO remove Keyed
|
||||
|
||||
private final ResourceKey<? extends Registry<M>> registryKey;
|
||||
private final Conversions conversions;
|
||||
private final PaperRegistryBuilder.Filler<M, A, B> builderFiller;
|
||||
private final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter;
|
||||
private final Function<ResourceKey<M>, Optional<M>> existingValueGetter;
|
||||
private @Nullable B builder;
|
||||
|
||||
public PaperRegistryBuilderFactory(final Conversions conversions, final PaperRegistryBuilder.Filler<M, A, B> builderFiller, final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter) {
|
||||
public PaperRegistryBuilderFactory(
|
||||
final ResourceKey<? extends Registry<M>> registryKey,
|
||||
final Conversions conversions,
|
||||
final PaperRegistryBuilder.Filler<M, A, B> builderFiller,
|
||||
final Function<ResourceKey<M>, Optional<M>> existingValueGetter
|
||||
) {
|
||||
this.registryKey = registryKey;
|
||||
this.conversions = conversions;
|
||||
this.builderFiller = builderFiller;
|
||||
this.existingValueGetter = existingValueGetter;
|
||||
@@ -42,10 +51,10 @@ public class PaperRegistryBuilderFactory<M, A extends Keyed, B extends PaperRegi
|
||||
@Override
|
||||
public B copyFrom(final TypedKey<A> key) {
|
||||
this.validate();
|
||||
final M existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(key));
|
||||
if (existing == null) {
|
||||
final Optional<M> existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(this.registryKey, key));
|
||||
if (existing.isEmpty()) {
|
||||
throw new IllegalArgumentException("Key " + key + " doesn't exist");
|
||||
}
|
||||
return this.builder = this.builderFiller.fill(this.conversions, existing);
|
||||
return this.builder = this.builderFiller.fill(this.conversions, existing.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@ import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEvent;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryEventMap;
|
||||
import io.papermc.paper.registry.event.RegistryEventProvider;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEvent;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryComposeEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryComposeEvent;
|
||||
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
|
||||
import io.papermc.paper.registry.event.type.RegistryEntryAddEventTypeImpl;
|
||||
import io.papermc.paper.registry.event.type.RegistryLifecycleEventType;
|
||||
@@ -37,7 +38,7 @@ public class PaperRegistryListenerManager {
|
||||
public static final PaperRegistryListenerManager INSTANCE = new PaperRegistryListenerManager();
|
||||
|
||||
public final RegistryEventMap valueAddEventTypes = new RegistryEventMap("value add");
|
||||
public final RegistryEventMap freezeEventTypes = new RegistryEventMap("freeze");
|
||||
public final RegistryEventMap composeEventType = new RegistryEventMap("compose");
|
||||
|
||||
private PaperRegistryListenerManager() {
|
||||
}
|
||||
@@ -60,7 +61,7 @@ public class PaperRegistryListenerManager {
|
||||
* For {@link Registry#register(Registry, ResourceKey, Object)}
|
||||
*/
|
||||
public <M> M registerWithListeners(final Registry<M> registry, final ResourceKey<M> key, final M nms) {
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, PaperRegistryListenerManager::registerWithInstance, BuiltInRegistries.BUILT_IN_CONVERSIONS);
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, PaperRegistryListenerManager::registerWithInstance, BuiltInRegistries.STATIC_ACCESS_CONVERSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +75,7 @@ public class PaperRegistryListenerManager {
|
||||
* For {@link Registry#registerForHolder(Registry, ResourceKey, Object)}
|
||||
*/
|
||||
public <M> Holder.Reference<M> registerForHolderWithListeners(final Registry<M> registry, final ResourceKey<M> key, final M nms) {
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, WritableRegistry::register, BuiltInRegistries.BUILT_IN_CONVERSIONS);
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, WritableRegistry::register, BuiltInRegistries.STATIC_ACCESS_CONVERSIONS);
|
||||
}
|
||||
|
||||
public <M> void registerWithListeners(
|
||||
@@ -157,28 +158,28 @@ public class PaperRegistryListenerManager {
|
||||
|
||||
public <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> void runFreezeListeners(final ResourceKey<? extends Registry<M>> resourceKey, final Conversions conversions) {
|
||||
final RegistryEntry<M, T> entry = PaperRegistries.getEntry(resourceKey);
|
||||
if (entry == null || !entry.meta().modificationApiSupport().canAdd() || !this.freezeEventTypes.hasHandlers(entry.apiKey())) {
|
||||
if (entry == null || !entry.meta().modificationApiSupport().canAdd() || !this.composeEventType.hasHandlers(entry.apiKey())) {
|
||||
return;
|
||||
}
|
||||
final RegistryEntryMeta.Buildable<M, T, B> writableEntry = (RegistryEntryMeta.Buildable<M, T, B>) entry.meta();
|
||||
final WritableCraftRegistry<M, T, B> writableRegistry = PaperRegistryAccess.instance().getWritableRegistry(entry.apiKey());
|
||||
final RegistryFreezeEventImpl<T, B> event = writableEntry.createFreezeEvent(writableRegistry, conversions);
|
||||
LifecycleEventRunner.INSTANCE.callEvent(this.freezeEventTypes.getEventType(entry.apiKey()), event);
|
||||
final RegistryComposeEventImpl<T, B> event = writableEntry.createPostLoadEvent(writableRegistry, conversions);
|
||||
LifecycleEventRunner.INSTANCE.callEvent(this.composeEventType.getEventType(entry.apiKey()), event);
|
||||
}
|
||||
|
||||
public <T, B extends RegistryBuilder<T>> RegistryEntryAddEventType<T, B> getRegistryValueAddEventType(final RegistryEventProvider<T, B> type) {
|
||||
final RegistryEntry<?, ?> entry = PaperRegistries.getEntry(type.registryKey());
|
||||
if (entry == null || !entry.meta().modificationApiSupport().canModify()) {
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support RegistryEntryAddEvent");
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support " + RegistryEntryAddEvent.class.getSimpleName());
|
||||
}
|
||||
return this.valueAddEventTypes.getOrCreate(type.registryKey(), RegistryEntryAddEventTypeImpl::new);
|
||||
}
|
||||
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> getRegistryFreezeEventType(final RegistryEventProvider<T, B> type) {
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<T, B>> getRegistryComposeEventType(final RegistryEventProvider<T, B> type) {
|
||||
final RegistryEntry<?, ?> entry = PaperRegistries.getEntry(type.registryKey());
|
||||
if (entry == null || !entry.meta().modificationApiSupport().canAdd()) {
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support RegistryFreezeEvent");
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support " + RegistryComposeEvent.class.getSimpleName());
|
||||
}
|
||||
return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new);
|
||||
return this.composeEventType.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
|
||||
public void register(final TypedKey<T> key, final Consumer<RegistryBuilderFactory<T, B>> value, final Conversions conversions) {
|
||||
final ResourceKey<M> resourceKey = PaperRegistries.toNms(key);
|
||||
this.registry.validateWrite(resourceKey);
|
||||
final PaperRegistryBuilderFactory<M, T, B> builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta.builderFiller(), this.registry.temporaryUnfrozenMap::get);
|
||||
final PaperRegistryBuilderFactory<M, T, B> builderFactory = new PaperRegistryBuilderFactory<>(this.registry.key(), conversions, this.meta.builderFiller(), this.registry::getValueForCopying);
|
||||
value.accept(builderFactory);
|
||||
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
|
||||
this.registry,
|
||||
|
||||
@@ -1,34 +1,4 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilderFactory;
|
||||
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
|
||||
@SuppressWarnings("BoundedWildcard")
|
||||
public final class InlinedRegistryBuilderProviderImpl implements InlinedRegistryBuilderProvider {
|
||||
|
||||
private static <M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> A create(final ResourceKey<? extends Registry<M>> registryKey, final Consumer<PaperRegistryBuilderFactory<M, A, B>> value) {
|
||||
final RegistryEntryMeta.Buildable<M, A, B> buildableMeta = PaperRegistries.getBuildableMeta(registryKey);
|
||||
Preconditions.checkArgument(buildableMeta.registryTypeMapper().supportsDirectHolders(), "Registry type mapper must support direct holders");
|
||||
final PaperRegistryBuilderFactory<M, A, B> builderFactory = new PaperRegistryBuilderFactory<>(Conversions.global(), buildableMeta.builderFiller(), CraftRegistry.getMinecraftRegistry(buildableMeta.mcKey())::getValue);
|
||||
value.accept(builderFactory);
|
||||
return buildableMeta.registryTypeMapper().createBukkit(Holder.direct(builderFactory.requireBuilder().build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Art createPaintingVariant(final Consumer<RegistryBuilderFactory<Art, ? extends PaintingVariantRegistryEntry.Builder>> value) {
|
||||
return create(Registries.PAINTING_VARIANT, value::accept);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.holder.PaperRegistryHolders;
|
||||
import io.papermc.paper.registry.holder.RegistryHolder;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.item.JukeboxSong;
|
||||
import net.minecraft.world.level.redstone.Redstone;
|
||||
import org.bukkit.Sound;
|
||||
import org.checkerframework.checker.index.qual.Positive;
|
||||
import org.jetbrains.annotations.Range;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.registry.data.util.Checks.asArgument;
|
||||
import static io.papermc.paper.registry.data.util.Checks.asArgumentMinExclusive;
|
||||
import static io.papermc.paper.registry.data.util.Checks.asArgumentRange;
|
||||
import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
|
||||
public class PaperJukeboxSongRegistryEntry implements JukeboxSongRegistryEntry {
|
||||
|
||||
protected final Conversions conversions;
|
||||
protected @Nullable Holder<SoundEvent> soundEvent;
|
||||
protected @Nullable Component description;
|
||||
protected @Nullable Float lengthInSeconds;
|
||||
protected OptionalInt comparatorOutput = OptionalInt.empty();
|
||||
|
||||
public PaperJukeboxSongRegistryEntry(final Conversions conversions, final @Nullable JukeboxSong internal) {
|
||||
this.conversions = conversions;
|
||||
|
||||
if (internal == null) {
|
||||
return;
|
||||
}
|
||||
this.soundEvent = internal.soundEvent();
|
||||
this.description = internal.description();
|
||||
this.lengthInSeconds = internal.lengthInSeconds();
|
||||
this.comparatorOutput = OptionalInt.of(internal.comparatorOutput());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryHolder<Sound, SoundEventRegistryEntry> soundEvent() {
|
||||
final Holder<SoundEvent> current = asConfigured(this.soundEvent, "soundEvent");
|
||||
return PaperRegistryHolders.create(current, e -> new PaperSoundEventRegistryEntry(this.conversions, e));
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.kyori.adventure.text.Component description() {
|
||||
return this.conversions.asAdventure(asConfigured(this.description, "description"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float lengthInSeconds() {
|
||||
return asConfigured(this.lengthInSeconds, "lengthInSeconds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int comparatorOutput() {
|
||||
return asConfigured(this.comparatorOutput, "comparatorOutput");
|
||||
}
|
||||
|
||||
public static final class PaperBuilder extends PaperJukeboxSongRegistryEntry implements JukeboxSongRegistryEntry.Builder, PaperRegistryBuilder<JukeboxSong, org.bukkit.JukeboxSong> {
|
||||
|
||||
public PaperBuilder(final Conversions conversions, final @Nullable JukeboxSong internal) {
|
||||
super(conversions, internal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSongRegistryEntry.Builder soundEvent(final TypedKey<Sound> soundEvent) {
|
||||
this.soundEvent = this.conversions.getReferenceHolder(PaperRegistries.toNms(asArgument(soundEvent, "soundEvent")));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSongRegistryEntry.Builder soundEvent(final Consumer<RegistryBuilderFactory<Sound, ? extends SoundEventRegistryEntry.Builder>> soundEvent) {
|
||||
this.soundEvent = this.conversions.createHolderFromBuilder(Registries.SOUND_EVENT, asArgument(soundEvent, "soundEvent"));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder soundEvent(final RegistryHolder<Sound, SoundEventRegistryEntry> soundEvent) {
|
||||
this.soundEvent = PaperRegistryHolders.convert(soundEvent, this.conversions);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSongRegistryEntry.Builder description(final net.kyori.adventure.text.Component description) {
|
||||
this.description = this.conversions.asVanilla(asArgument(description, "description"));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSongRegistryEntry.Builder lengthInSeconds(final @Positive float lengthInSeconds) {
|
||||
this.lengthInSeconds = asArgumentMinExclusive(lengthInSeconds, "lengthInSeconds", 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSongRegistryEntry.Builder comparatorOutput(final @Range(from = 0, to = 15) int comparatorOutput) {
|
||||
this.comparatorOutput = OptionalInt.of(asArgumentRange(comparatorOutput, "comparatorOutput", Redstone.SIGNAL_MIN, Redstone.SIGNAL_MAX));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxSong build() {
|
||||
return new JukeboxSong(
|
||||
asConfigured(this.soundEvent, "soundEvent"),
|
||||
asConfigured(this.description, "description"),
|
||||
this.lengthInSeconds(),
|
||||
this.comparatorOutput()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package io.papermc.paper.registry.data;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import org.bukkit.Sound;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static io.papermc.paper.registry.data.util.Checks.asArgument;
|
||||
import static io.papermc.paper.registry.data.util.Checks.asConfigured;
|
||||
|
||||
/**
|
||||
* Not actually used for modifying {@link net.minecraft.core.registries.Registries#SOUND_EVENT}
|
||||
* but for creating direct holders for other registries and direct {@link org.bukkit.craftbukkit.CraftSound}s.
|
||||
*/
|
||||
public class PaperSoundEventRegistryEntry implements SoundEventRegistryEntry {
|
||||
|
||||
protected final Conversions conversions;
|
||||
protected @Nullable ResourceLocation location;
|
||||
protected @Nullable Float fixedRange;
|
||||
|
||||
public PaperSoundEventRegistryEntry(final Conversions conversions, final @Nullable SoundEvent soundEvent) {
|
||||
this.conversions = conversions;
|
||||
if (soundEvent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.location = soundEvent.location();
|
||||
this.fixedRange = soundEvent.fixedRange().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key location() {
|
||||
return PaperAdventure.asAdventure(asConfigured(this.location, "location"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Float fixedRange() {
|
||||
return this.fixedRange;
|
||||
}
|
||||
|
||||
public static final class PaperBuilder extends PaperSoundEventRegistryEntry implements SoundEventRegistryEntry.Builder, PaperRegistryBuilder<SoundEvent, Sound> {
|
||||
|
||||
public PaperBuilder(final Conversions conversions, final @Nullable SoundEvent soundEvent) {
|
||||
super(conversions, soundEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEventRegistryEntry.Builder location(final Key location) {
|
||||
this.location = PaperAdventure.asVanilla(asArgument(location, "location"));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEventRegistryEntry.Builder fixedRange(final @Nullable Float fixedRange) {
|
||||
this.fixedRange = fixedRange;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent build() {
|
||||
return new SoundEvent(asConfigured(this.location, "location"), Optional.ofNullable(this.fixedRange));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,13 @@ public final class Checks {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float asArgumentMinExclusive(final float value, final String field, final float min) {
|
||||
if (value <= min) {
|
||||
throw new IllegalArgumentException("argument " + field + " must be (" + min + ",+inf)");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private Checks() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,20 @@ import com.google.common.base.Preconditions;
|
||||
import com.mojang.serialization.JavaOps;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.adventure.WrapperAwareSerializer;
|
||||
import java.util.Optional;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilderFactory;
|
||||
import io.papermc.paper.registry.data.client.ClientTextureAsset;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import java.util.function.Consumer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -22,15 +29,7 @@ public class Conversions {
|
||||
if (globalInstance == null) {
|
||||
final RegistryAccess globalAccess = CraftRegistry.getMinecraftRegistry();
|
||||
Preconditions.checkState(globalAccess != null, "Global registry access is not available");
|
||||
globalInstance = new Conversions(new RegistryOps.RegistryInfoLookup() {
|
||||
@Override
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(final ResourceKey<? extends Registry<? extends T>> registryRef) {
|
||||
final Registry<T> registry = globalAccess.lookupOrThrow(registryRef);
|
||||
return Optional.of(
|
||||
new RegistryOps.RegistryInfo<>(registry, registry, registry.registryLifecycle())
|
||||
);
|
||||
}
|
||||
});
|
||||
globalInstance = new Conversions(new RegistryOps.HolderLookupAdapter(globalAccess));
|
||||
}
|
||||
return globalInstance;
|
||||
}
|
||||
@@ -47,6 +46,10 @@ public class Conversions {
|
||||
return this.lookup;
|
||||
}
|
||||
|
||||
public <M> Holder.Reference<M> getReferenceHolder(final ResourceKey<M> key) {
|
||||
return this.lookup.lookup(key.registryKey()).orElseThrow().getter().getOrThrow(key);
|
||||
}
|
||||
|
||||
@Contract("null -> null; !null -> !null")
|
||||
public net.minecraft.network.chat.@Nullable Component asVanilla(final @Nullable Component adventure) {
|
||||
if (adventure == null) return null;
|
||||
@@ -70,4 +73,33 @@ public class Conversions {
|
||||
PaperAdventure.asVanilla(clientTextureAsset.texturePath())
|
||||
);
|
||||
}
|
||||
|
||||
private static <M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> RegistryEntryMeta.Buildable<M, A, B> getDirectHolderBuildableMeta(final ResourceKey<? extends Registry<M>> registryKey) {
|
||||
final RegistryEntryMeta.Buildable<M, A, B> buildableMeta = PaperRegistries.getBuildableMeta(registryKey);
|
||||
Preconditions.checkArgument(buildableMeta.registryTypeMapper().supportsDirectHolders(), "Registry type mapper must support direct holders");
|
||||
return buildableMeta;
|
||||
}
|
||||
|
||||
public <M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> A createApiInstanceFromBuilder(final ResourceKey<? extends Registry<M>> registryKey, final Consumer<? super PaperRegistryBuilderFactory<M, A, B>> value) {
|
||||
final RegistryEntryMeta.Buildable<M, A, B> meta = getDirectHolderBuildableMeta(registryKey);
|
||||
final PaperRegistryBuilderFactory<M, A, B> builderFactory = this.createRegistryBuilderFactory(registryKey, meta);
|
||||
value.accept(builderFactory);
|
||||
return meta.registryTypeMapper().createBukkit(Holder.direct(builderFactory.requireBuilder().build()));
|
||||
}
|
||||
|
||||
public <M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> Holder<M> createHolderFromBuilder(final ResourceKey<? extends Registry<M>> registryKey, final Consumer<? super PaperRegistryBuilderFactory<M, A, B>> value) {
|
||||
final RegistryEntryMeta.Buildable<M, A, B> meta = getDirectHolderBuildableMeta(registryKey);
|
||||
final PaperRegistryBuilderFactory<M, A, B> builderFactory = this.createRegistryBuilderFactory(registryKey, meta);
|
||||
value.accept(builderFactory);
|
||||
return Holder.direct(builderFactory.requireBuilder().build());
|
||||
}
|
||||
|
||||
private <M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> PaperRegistryBuilderFactory<M, A, B> createRegistryBuilderFactory(
|
||||
final ResourceKey<? extends Registry<M>> registryKey,
|
||||
final RegistryEntryMeta.Buildable<M, A, B> buildableMeta
|
||||
) {
|
||||
final HolderLookup.RegistryLookup<M> lookupForBuilders = this.lookup.lookupForValueCopyViaBuilders().lookupOrThrow(registryKey);
|
||||
return new PaperRegistryBuilderFactory<>(registryKey, this, buildableMeta.builderFiller(), lookupForBuilders::getValueForCopying);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class RegistryEntryBuilder<M, A extends Keyed> { // TODO remove Keyed
|
||||
return this.create(filler, WRITABLE);
|
||||
}
|
||||
|
||||
private <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> create(final PaperRegistryBuilder.Filler<M, A, B> filler, final RegistryEntryMeta.RegistryModificationApiSupport support) {
|
||||
public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> create(final PaperRegistryBuilder.Filler<M, A, B> filler, final RegistryEntryMeta.RegistryModificationApiSupport support) {
|
||||
return new RegistryEntryImpl<>(new RegistryEntryMeta.Buildable<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, this.serializationUpdater, filler, support));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.WritableCraftRegistry;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryComposeEventImpl;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
@@ -106,8 +106,8 @@ public sealed interface RegistryEntryMeta<M, A extends Keyed> permits RegistryEn
|
||||
return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions);
|
||||
}
|
||||
|
||||
public RegistryFreezeEventImpl<A, B> createFreezeEvent(final WritableCraftRegistry<M, A, B> writableRegistry, final Conversions conversions) {
|
||||
return new RegistryFreezeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions);
|
||||
public RegistryComposeEventImpl<A, B> createPostLoadEvent(final WritableCraftRegistry<M, A, B> writableRegistry, final Conversions conversions) {
|
||||
return new RegistryComposeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,7 +12,7 @@ import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public record RegistryFreezeEventImpl<T, B extends RegistryBuilder<T>>(
|
||||
public record RegistryComposeEventImpl<T, B extends RegistryBuilder<T>>(
|
||||
RegistryKey<T> registryKey,
|
||||
WritableRegistry<T, B> registry,
|
||||
Conversions conversions
|
||||
@@ -18,7 +18,7 @@ public class RegistryEventTypeProviderImpl implements RegistryEventTypeProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> registryFreeze(final RegistryEventProvider<T, B> type) {
|
||||
return PaperRegistryListenerManager.INSTANCE.getRegistryFreezeEventType(type);
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryComposeEvent<T, B>> registryCompose(final RegistryEventProvider<T, B> type) {
|
||||
return PaperRegistryListenerManager.INSTANCE.getRegistryComposeEventType(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.papermc.paper.registry.holder;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
record InlinedRegistryHolderImpl<API, ENTRY, M>(ENTRY entry, Holder.Direct<M> holder) implements RegistryHolder.Inlined<API, ENTRY> {
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.papermc.paper.registry.holder;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.Holder;
|
||||
|
||||
public final class PaperRegistryHolders {
|
||||
|
||||
public static <API, ENTRY, M> RegistryHolder<API, ENTRY> create(final Holder<M> holder, final Function<M, ENTRY> entryCreator) {
|
||||
return switch (holder) {
|
||||
case final Holder.Direct<M> direct -> new InlinedRegistryHolderImpl<>(entryCreator.apply(direct.value()), direct);
|
||||
case final Holder.Reference<M> reference -> new ReferenceRegistryHolderImpl<>(PaperRegistries.fromNms(reference.key()));
|
||||
default -> throw new IllegalArgumentException("Unsupported holder type: " + holder.getClass().getName());
|
||||
};
|
||||
}
|
||||
|
||||
public static <API, ENTRY, M> Holder<M> convert(final RegistryHolder<API, ENTRY> holder, final Conversions conversions) {
|
||||
return switch (holder) {
|
||||
case final RegistryHolder.Reference<API, ENTRY> ref -> conversions.getReferenceHolder(PaperRegistries.toNms(ref.key()));
|
||||
case final RegistryHolder.Inlined<API, ENTRY> inlined -> ((InlinedRegistryHolderImpl<API, ENTRY, M>) inlined).holder();
|
||||
};
|
||||
}
|
||||
|
||||
private PaperRegistryHolders() {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.papermc.paper.registry.holder;
|
||||
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
record ReferenceRegistryHolderImpl<API, ENTRY>(TypedKey<API> key) implements RegistryHolder.Reference<API, ENTRY> {
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class PaperFeatureFlagProviderImpl implements FeatureFlagProvider {
|
||||
|
||||
public static final BiMap<FeatureFlag, net.minecraft.world.flag.FeatureFlag> FLAGS = ImmutableBiMap.of(
|
||||
// Start generate - PaperFeatureFlagProviderImpl#FLAGS
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
FeatureFlag.MINECART_IMPROVEMENTS, FeatureFlags.MINECART_IMPROVEMENTS,
|
||||
FeatureFlag.REDSTONE_EXPERIMENTS, FeatureFlags.REDSTONE_EXPERIMENTS,
|
||||
FeatureFlag.TRADE_REBALANCE, FeatureFlags.TRADE_REBALANCE,
|
||||
|
||||
@@ -10,11 +10,14 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.core.GlobalPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.game.ClientboundTagQueryPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import net.minecraft.stats.ServerStatsCounter;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.BanEntry;
|
||||
@@ -196,7 +199,8 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
}
|
||||
|
||||
private CompoundTag getData() {
|
||||
return this.storage.load(this.profile.getName(), this.profile.getId().toString()).orElse(null);
|
||||
// This method does not use the problem reporter
|
||||
return this.storage.load(this.profile.getName(), this.profile.getId().toString(), ProblemReporter.DISCARDING).orElse(null);
|
||||
}
|
||||
|
||||
private CompoundTag getBukkitData() {
|
||||
|
||||
@@ -198,7 +198,6 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
BlockPos pos = CraftLocation.toBlockPosition(location);
|
||||
BlockStateListPopulator populator = new BlockStateListPopulator(this.getHandle());
|
||||
boolean result = this.generateTree(populator, this.getHandle().getMinecraftWorld().getChunkSource().getGenerator(), pos, new RandomSourceWrapper(random), treeType);
|
||||
populator.refreshTiles();
|
||||
populator.placeSomeBlocks(predicate == null ? ($ -> true) : predicate);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,8 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
return cached;
|
||||
}
|
||||
|
||||
final Optional<Holder.Reference<M>> holderOptional = this.minecraftRegistry.get(CraftNamespacedKey.toMinecraft(namespacedKey));
|
||||
// Important to use the ResourceKey<?> "get" method below because it will work before registry is frozen
|
||||
final Optional<Holder.Reference<M>> holderOptional = this.minecraftRegistry.get(MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey));
|
||||
final Holder.Reference<M> holder;
|
||||
if (holderOptional.isPresent()) {
|
||||
holder = holderOptional.get();
|
||||
@@ -215,12 +216,9 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
// to create something to fill the API constant fields, so we create a dummy reference holder.
|
||||
holder = Holder.Reference.createStandAlone(this.invalidHolderOwner, MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey));
|
||||
} else {
|
||||
holder = null;
|
||||
}
|
||||
final B bukkit = this.createBukkit(holder);
|
||||
if (bukkit == null) {
|
||||
return null;
|
||||
}
|
||||
final B bukkit = this.createBukkit(holder);
|
||||
|
||||
this.cache.put(namespacedKey, bukkit);
|
||||
|
||||
@@ -250,10 +248,6 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
}
|
||||
|
||||
public B createBukkit(Holder<M> minecraft) {
|
||||
if (minecraft == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.minecraftToBukkit.createBukkit(minecraft);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.bukkit.entity.EntityType;
|
||||
|
||||
public enum CraftStatistic {
|
||||
// Start generate - CraftStatisticCustom
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
ANIMALS_BRED(Stats.ANIMALS_BRED),
|
||||
AVIATE_ONE_CM(Stats.AVIATE_ONE_CM),
|
||||
BELL_RING(Stats.BELL_RING),
|
||||
@@ -46,6 +46,7 @@ public enum CraftStatistic {
|
||||
CAULDRON_FILLED(Stats.FILL_CAULDRON),
|
||||
FISH_CAUGHT(Stats.FISH_CAUGHT),
|
||||
FLY_ONE_CM(Stats.FLY_ONE_CM),
|
||||
HAPPY_GHAST_ONE_CM(Stats.HAPPY_GHAST_ONE_CM),
|
||||
HORSE_ONE_CM(Stats.HORSE_ONE_CM),
|
||||
DISPENSER_INSPECTED(Stats.INSPECT_DISPENSER),
|
||||
DROPPER_INSPECTED(Stats.INSPECT_DROPPER),
|
||||
@@ -99,7 +100,7 @@ public enum CraftStatistic {
|
||||
WALK_UNDER_WATER_ONE_CM(Stats.WALK_UNDER_WATER_ONE_CM),
|
||||
// End generate - CraftStatisticCustom
|
||||
// Start generate - CraftStatisticType
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
BREAK_ITEM(ResourceLocation.withDefaultNamespace("broken")),
|
||||
CRAFT_ITEM(ResourceLocation.withDefaultNamespace("crafted")),
|
||||
DROP(ResourceLocation.withDefaultNamespace("dropped")),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.bukkit.craftbukkit;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
@@ -12,6 +14,7 @@ import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilderImpl;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -19,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -40,6 +44,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
@@ -243,7 +248,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public BiomeProvider vanillaBiomeProvider() {
|
||||
net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource;
|
||||
ServerChunkCache serverCache = this.getHandle().chunkSource;
|
||||
|
||||
final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator();
|
||||
net.minecraft.world.level.biome.BiomeSource biomeSource;
|
||||
@@ -421,8 +426,21 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public Chunk[] getLoadedChunks() {
|
||||
List<ChunkHolder> chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.world); // Paper
|
||||
return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new);
|
||||
ServerChunkCache serverChunkCache = this.getHandle().chunkSource;
|
||||
ReferenceList<Chunk> chunks = new ReferenceList<>(new Chunk[serverChunkCache.fullChunks.size()]);
|
||||
|
||||
for (PrimitiveIterator.OfLong iterator = serverChunkCache.fullChunks.keyIterator(); iterator.hasNext();) {
|
||||
long chunk = iterator.nextLong();
|
||||
chunks.add(new CraftChunk(this.world, CoordinateUtils.getChunkX(chunk), CoordinateUtils.getChunkZ(chunk)));
|
||||
}
|
||||
|
||||
Chunk[] raw = chunks.getRawDataUnchecked();
|
||||
int size = chunks.size();
|
||||
if (raw.length == size) {
|
||||
// always true when on main
|
||||
return raw;
|
||||
}
|
||||
return Arrays.copyOf(raw, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -631,7 +649,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Set<Chunk> chunks = new HashSet<>();
|
||||
|
||||
for (long coord : this.getHandle().getForceLoadedChunks()) {
|
||||
chunks.add(this.getChunkAt(ChunkPos.getX(coord), ChunkPos.getZ(coord)));
|
||||
chunks.add(new CraftChunk(this.getHandle(), ChunkPos.getX(coord), ChunkPos.getZ(coord)));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableCollection(chunks);
|
||||
@@ -828,7 +846,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
CraftPlayer cp = (CraftPlayer) p;
|
||||
if (cp.getHandle().connection == null) continue;
|
||||
|
||||
cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@ package org.bukkit.craftbukkit;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.util.PathConverter;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
public class Main {
|
||||
public static final java.time.Instant BOOT_TIME = java.time.Instant.now(); // Paper - track initial start time
|
||||
public static boolean useJline = true;
|
||||
@@ -25,41 +25,40 @@ public class Main {
|
||||
// Paper end - Reset loggers after shutdown
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Todo: Installation script
|
||||
if (System.getProperty("jdk.nio.maxCachedBufferSize") == null) System.setProperty("jdk.nio.maxCachedBufferSize", "262144"); // Paper - cap per-thread NIO cache size; https://www.evanjones.ca/java-bytebuffer-leak.html
|
||||
OptionParser parser = new OptionParser() {
|
||||
{
|
||||
this.acceptsAll(Main.asList("?", "help"), "Show the help");
|
||||
this.acceptsAll(asList("?", "help"), "Show the help");
|
||||
|
||||
this.acceptsAll(Main.asList("c", "config"), "Properties file to use")
|
||||
this.acceptsAll(asList("c", "config"), "Properties file to use")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("server.properties"))
|
||||
.describedAs("Properties file");
|
||||
|
||||
this.acceptsAll(Main.asList("P", "plugins"), "Plugin directory to use")
|
||||
this.acceptsAll(asList("P", "plugins"), "Plugin directory to use")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("plugins"))
|
||||
.describedAs("Plugin directory");
|
||||
|
||||
this.acceptsAll(Main.asList("h", "host", "server-ip"), "Host to listen on")
|
||||
this.acceptsAll(asList("h", "host", "server-ip"), "Host to listen on")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.describedAs("Hostname or IP");
|
||||
|
||||
this.acceptsAll(Main.asList("W", "world-dir", "universe", "world-container"), "World container")
|
||||
this.acceptsAll(asList("W", "world-dir", "universe", "world-container"), "World container")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("."))
|
||||
.describedAs("Directory containing worlds");
|
||||
|
||||
this.acceptsAll(Main.asList("w", "world", "level-name"), "World name")
|
||||
this.acceptsAll(asList("w", "world", "level-name"), "World name")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.describedAs("World name");
|
||||
|
||||
this.acceptsAll(Main.asList("p", "port", "server-port"), "Port to listen on")
|
||||
this.acceptsAll(asList("p", "port", "server-port"), "Port to listen on")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.describedAs("Port");
|
||||
@@ -73,99 +72,99 @@ public class Main {
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(new PathConverter());
|
||||
|
||||
this.acceptsAll(Main.asList("o", "online-mode"), "Whether to use online authentication")
|
||||
this.acceptsAll(asList("o", "online-mode"), "Whether to use online authentication")
|
||||
.withRequiredArg()
|
||||
.ofType(Boolean.class)
|
||||
.describedAs("Authentication");
|
||||
|
||||
this.acceptsAll(Main.asList("s", "size", "max-players"), "Maximum amount of players")
|
||||
this.acceptsAll(asList("s", "size", "max-players"), "Maximum amount of players")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.describedAs("Server size");
|
||||
|
||||
this.acceptsAll(Main.asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
|
||||
this.acceptsAll(asList("d", "date-format"), "Format of the date to display in the console (for log entries)")
|
||||
.withRequiredArg()
|
||||
.ofType(SimpleDateFormat.class)
|
||||
.describedAs("Log date format");
|
||||
|
||||
this.acceptsAll(Main.asList("log-pattern"), "Specfies the log filename pattern")
|
||||
this.accepts("log-pattern", "Specfies the log filename pattern")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.defaultsTo("server.log")
|
||||
.describedAs("Log filename");
|
||||
|
||||
this.acceptsAll(Main.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)")
|
||||
this.accepts("log-limit", "Limits the maximum size of the log file (0 = unlimited)")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.defaultsTo(0)
|
||||
.describedAs("Max log size");
|
||||
|
||||
this.acceptsAll(Main.asList("log-count"), "Specified how many log files to cycle through")
|
||||
this.accepts("log-count", "Specified how many log files to cycle through")
|
||||
.withRequiredArg()
|
||||
.ofType(Integer.class)
|
||||
.defaultsTo(1)
|
||||
.describedAs("Log count");
|
||||
|
||||
this.acceptsAll(Main.asList("log-append"), "Whether to append to the log file")
|
||||
this.accepts("log-append", "Whether to append to the log file")
|
||||
.withRequiredArg()
|
||||
.ofType(Boolean.class)
|
||||
.defaultsTo(true)
|
||||
.describedAs("Log append");
|
||||
|
||||
this.acceptsAll(Main.asList("log-strip-color"), "Strips color codes from log file");
|
||||
this.accepts("log-strip-color", "Strips color codes from log file");
|
||||
|
||||
this.acceptsAll(Main.asList("b", "bukkit-settings"), "File for bukkit settings")
|
||||
this.acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("bukkit.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
this.acceptsAll(Main.asList("C", "commands-settings"), "File for command settings")
|
||||
this.acceptsAll(asList("C", "commands-settings"), "File for command settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("commands.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
this.acceptsAll(Main.asList("forceUpgrade"), "Whether to force a world upgrade");
|
||||
this.acceptsAll(Main.asList("eraseCache"), "Whether to force cache erase during world upgrade");
|
||||
this.acceptsAll(Main.asList("recreateRegionFiles"), "Whether to recreate region files during world upgrade");
|
||||
this.accepts("forceUpgrade", "Whether to force a world upgrade");
|
||||
this.accepts("eraseCache", "Whether to force cache erase during world upgrade");
|
||||
this.accepts("recreateRegionFiles", "Whether to recreate region files during world upgrade");
|
||||
this.accepts("safeMode", "Loads level with vanilla datapack only"); // Paper
|
||||
this.acceptsAll(Main.asList("nogui"), "Disables the graphical console");
|
||||
this.accepts("nogui", "Disables the graphical console");
|
||||
|
||||
this.acceptsAll(Main.asList("nojline"), "Disables jline and emulates the vanilla console");
|
||||
this.accepts("nojline", "Disables jline and emulates the vanilla console");
|
||||
|
||||
this.acceptsAll(Main.asList("noconsole"), "Disables the console");
|
||||
this.accepts("noconsole", "Disables the console");
|
||||
|
||||
this.acceptsAll(Main.asList("v", "version"), "Show the CraftBukkit Version");
|
||||
this.acceptsAll(asList("v", "version"), "Show the CraftBukkit Version");
|
||||
|
||||
this.acceptsAll(Main.asList("demo"), "Demo mode");
|
||||
this.accepts("demo", "Demo mode");
|
||||
|
||||
this.acceptsAll(Main.asList("initSettings"), "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option
|
||||
this.accepts("initSettings", "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option
|
||||
|
||||
this.acceptsAll(Main.asList("S", "spigot-settings"), "File for spigot settings")
|
||||
this.acceptsAll(asList("S", "spigot-settings"), "File for spigot settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("spigot.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings")
|
||||
this.acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR))
|
||||
.describedAs("Config directory");
|
||||
acceptsAll(asList("paper", "paper-settings"), "File for Paper settings")
|
||||
this.acceptsAll(asList("paper", "paper-settings"), "File for Paper settings")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File("paper.yml"))
|
||||
.describedAs("Yml file");
|
||||
|
||||
acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.")
|
||||
this.acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.")
|
||||
.withRequiredArg()
|
||||
.ofType(File.class)
|
||||
.defaultsTo(new File[] {})
|
||||
.describedAs("Jar file");
|
||||
|
||||
acceptsAll(asList("server-name"), "Name of the server")
|
||||
this.accepts("server-name", "Name of the server")
|
||||
.withRequiredArg()
|
||||
.ofType(String.class)
|
||||
.defaultsTo("Unknown Server")
|
||||
@@ -246,8 +245,4 @@ public class Main {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> asList(String... params) {
|
||||
return Arrays.asList(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,7 @@ public final class CapturedBlockState extends CraftBlockState {
|
||||
@Override
|
||||
public boolean place(int flags) {
|
||||
boolean result = super.place(flags);
|
||||
|
||||
if (result) {
|
||||
this.addBees();
|
||||
}
|
||||
this.addBees();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import java.util.Objects;
|
||||
@@ -61,17 +60,17 @@ public class CraftBiome extends OldEnumHolderable<Biome, net.minecraft.world.lev
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespacedKey getKey() {
|
||||
public NamespacedKey getKey() {
|
||||
return LEGACY_CUSTOM_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull final Biome other) {
|
||||
public int compareTo(final Biome other) {
|
||||
return this.ordinal - other.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String name() {
|
||||
public String name() {
|
||||
return "CUSTOM";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import java.util.Set;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponentMap;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
@@ -9,8 +10,11 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.TileState;
|
||||
@@ -19,9 +23,12 @@ import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final T blockEntity;
|
||||
private final T snapshot;
|
||||
public boolean snapshotDisabled; // Paper
|
||||
@@ -67,10 +74,6 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
this.loadData(state.getSnapshotNBT());
|
||||
}
|
||||
|
||||
public void refreshSnapshot() {
|
||||
this.load(this.blockEntity);
|
||||
}
|
||||
|
||||
private RegistryAccess getRegistryAccess() {
|
||||
LevelAccessor worldHandle = this.getWorldHandle();
|
||||
return (worldHandle != null) ? worldHandle.registryAccess() : CraftRegistry.getMinecraftRegistry();
|
||||
@@ -97,14 +100,22 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
|
||||
// Loads the specified data into the snapshot BlockEntity.
|
||||
public void loadData(CompoundTag tag) {
|
||||
this.snapshot.loadWithComponents(tag, this.getRegistryAccess());
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
this.snapshot.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
|
||||
}
|
||||
this.load(this.snapshot);
|
||||
}
|
||||
|
||||
// copies the BlockEntity-specific data, retains the position
|
||||
private void copyData(T from, T to) {
|
||||
CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess());
|
||||
to.loadWithComponents(tag, this.getRegistryAccess());
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
to.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag));
|
||||
}
|
||||
}
|
||||
|
||||
// gets the wrapped BlockEntity
|
||||
@@ -143,13 +154,21 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
// Paper start - properly save blockentity itemstacks
|
||||
public CompoundTag getSnapshotCustomNbtOnly() {
|
||||
this.applyTo(this.snapshot);
|
||||
final CompoundTag nbt = this.snapshot.saveCustomOnly(this.getRegistryAccess());
|
||||
this.snapshot.removeComponentsFromTag(nbt);
|
||||
if (!nbt.isEmpty()) {
|
||||
// have to include the "id" if it's going to have block entity data
|
||||
this.snapshot.saveId(nbt);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWrappingWithContext(
|
||||
problemReporter,
|
||||
this.getRegistryAccess(),
|
||||
this.snapshot.saveCustomOnly(this.getRegistryAccess())
|
||||
);
|
||||
this.snapshot.removeComponentsFromTag(output);
|
||||
if (!output.isEmpty()) {
|
||||
// have to include the "id" if it's going to have block entity data
|
||||
this.snapshot.saveId(output);
|
||||
}
|
||||
return output.buildResult();
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -183,15 +202,14 @@ public abstract class CraftBlockEntityState<T extends BlockEntity> extends Craft
|
||||
|
||||
@Override
|
||||
public boolean place(int flags) {
|
||||
if (super.place(flags)) {
|
||||
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
|
||||
this.applyTo((T) blockEntity);
|
||||
blockEntity.setChanged();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
boolean result = super.place(flags);
|
||||
|
||||
return false;
|
||||
this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> {
|
||||
this.applyTo((T) blockEntity);
|
||||
blockEntity.setChanged();
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class CraftBlockStates {
|
||||
|
||||
static {
|
||||
// Start generate - CraftBlockEntityStates
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
register(BlockEntityType.BANNER, CraftBanner.class, CraftBanner::new);
|
||||
register(BlockEntityType.BARREL, CraftBarrel.class, CraftBarrel::new);
|
||||
register(BlockEntityType.BEACON, CraftBeacon.class, CraftBeacon::new);
|
||||
|
||||
@@ -2,7 +2,9 @@ package org.bukkit.craftbukkit.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.level.block.entity.ConduitBlockEntity;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.Location;
|
||||
@@ -83,7 +85,7 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
return false;
|
||||
}
|
||||
|
||||
net.minecraft.world.entity.LivingEntity currentTarget = conduit.destroyTarget;
|
||||
EntityReference<net.minecraft.world.entity.LivingEntity> currentTarget = conduit.destroyTarget;
|
||||
|
||||
if (target == null) {
|
||||
if (currentTarget == null) {
|
||||
@@ -91,17 +93,22 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
}
|
||||
|
||||
conduit.destroyTarget = null;
|
||||
conduit.destroyTargetUUID = null;
|
||||
} else {
|
||||
if (currentTarget != null && target.getUniqueId().equals(currentTarget.getUUID())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
conduit.destroyTarget = ((CraftLivingEntity) target).getHandle();
|
||||
conduit.destroyTargetUUID = target.getUniqueId();
|
||||
conduit.destroyTarget = new EntityReference<>(((CraftLivingEntity) target).getHandle());
|
||||
}
|
||||
|
||||
ConduitBlockEntity.updateDestroyTarget(conduit.getLevel(), this.getPosition(), this.data, conduit.effectBlocks, conduit, false);
|
||||
ConduitBlockEntity.updateAndAttackTarget(
|
||||
conduit.getLevel().getMinecraftWorld(),
|
||||
this.getPosition(),
|
||||
this.data,
|
||||
conduit,
|
||||
conduit.effectBlocks.size() >= ConduitBlockEntity.MIN_KILL_SIZE,
|
||||
false
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,14 +119,17 @@ public class CraftConduit extends CraftBlockEntityState<ConduitBlockEntity> impl
|
||||
return null;
|
||||
}
|
||||
|
||||
net.minecraft.world.entity.LivingEntity nmsEntity = conduit.destroyTarget;
|
||||
return (nmsEntity != null) ? (LivingEntity) nmsEntity.getBukkitEntity() : null;
|
||||
final net.minecraft.world.entity.LivingEntity nmsEntity = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
|
||||
return nmsEntity == null ? null : nmsEntity.getBukkitLivingEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTarget() {
|
||||
ConduitBlockEntity conduit = (ConduitBlockEntity) this.getBlockEntityFromWorld();
|
||||
return conduit != null && conduit.destroyTarget != null && conduit.destroyTarget.isAlive();
|
||||
if (conduit == null) return false;
|
||||
|
||||
final net.minecraft.world.entity.LivingEntity destroyTarget = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class);
|
||||
return destroyTarget != null && destroyTarget.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,8 +8,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.InclusiveRange;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
@@ -17,6 +19,8 @@ import net.minecraft.world.entity.EquipmentTable;
|
||||
import net.minecraft.world.level.BaseSpawner;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
@@ -46,8 +50,11 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.entityToSpawn());
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,9 +182,12 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
|
||||
if (spawnData == null) {
|
||||
return null;
|
||||
}
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) {
|
||||
ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.getEntityToSpawn());
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(valueInput);
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,8 +46,8 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
|
||||
@Override
|
||||
public void setBurnTime(short burnTime) {
|
||||
this.getSnapshot().litTimeRemaining = burnTime;
|
||||
// SPIGOT-844: Allow lighting and relighting using this API
|
||||
this.data = this.data.setValue(AbstractFurnaceBlock.LIT, burnTime > 0);
|
||||
this.data = this.data.trySetValue(AbstractFurnaceBlock.LIT, burnTime > 0);
|
||||
// only try, block data might have changed to something different that would not allow this property
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.UUID;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.block.TrialSpawnerBlock;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@@ -23,8 +23,8 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
public CraftTrialSpawner(World world, TrialSpawnerBlockEntity blockEntity) {
|
||||
super(world, blockEntity);
|
||||
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getNormalConfig(), this.getSnapshot());
|
||||
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().getOminousConfig(), this.getSnapshot());
|
||||
this.normalConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().normalConfig(), this.getSnapshot());
|
||||
this.ominousConfig = new CraftTrialSpawnerConfiguration(blockEntity.getTrialSpawner().ominousConfig(), this.getSnapshot());
|
||||
}
|
||||
|
||||
protected CraftTrialSpawner(CraftTrialSpawner state, Location location) {
|
||||
@@ -35,22 +35,22 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public long getCooldownEnd() {
|
||||
return this.getSnapshot().trialSpawner.getData().cooldownEndsAt;
|
||||
return this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCooldownEnd(long ticks) {
|
||||
this.getSnapshot().trialSpawner.getData().cooldownEndsAt = ticks;
|
||||
this.getSnapshot().trialSpawner.getStateData().cooldownEndsAt = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextSpawnAttempt() {
|
||||
return this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt;
|
||||
return this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNextSpawnAttempt(long ticks) {
|
||||
this.getSnapshot().trialSpawner.getData().nextMobSpawnsAt = ticks;
|
||||
this.getSnapshot().trialSpawner.getStateData().nextMobSpawnsAt = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,17 +60,17 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public void setCooldownLength(int ticks) {
|
||||
this.getSnapshot().trialSpawner.targetCooldownLength = ticks;
|
||||
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideTargetCooldownLength(ticks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
|
||||
return this.getSnapshot().trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
this.getSnapshot().trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
this.getSnapshot().trialSpawner.config = this.getSnapshot().trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,24 +160,26 @@ public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEn
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getNormalConfiguration() {
|
||||
return this.normalConfig;
|
||||
return this.normalConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getOminousConfiguration() {
|
||||
return this.ominousConfig;
|
||||
return this.ominousConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTo(TrialSpawnerBlockEntity blockEntity) {
|
||||
super.applyTo(blockEntity);
|
||||
|
||||
blockEntity.trialSpawner.normalConfig = Holder.direct(this.normalConfig.toMinecraft());
|
||||
blockEntity.trialSpawner.ominousConfig = Holder.direct(this.ominousConfig.toMinecraft());
|
||||
blockEntity.trialSpawner.config = blockEntity.trialSpawner.config.overrideConfigs(
|
||||
Holder.direct(this.normalConfig.toMinecraft()),
|
||||
Holder.direct(this.ominousConfig.toMinecraft())
|
||||
);
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return this.getSnapshot().getTrialSpawner().getData();
|
||||
private TrialSpawnerStateData getTrialData() {
|
||||
return this.getSnapshot().getTrialSpawner().getStateData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,16 +7,20 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.random.Weighted;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftLootTable;
|
||||
@@ -26,8 +30,12 @@ import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.spawner.TrialSpawnerConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final TrialSpawnerBlockEntity snapshot;
|
||||
|
||||
private int spawnRange;
|
||||
@@ -56,12 +64,21 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public EntityType getSpawnedType() {
|
||||
if (this.spawnPotentialsDefinition.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (this.spawnPotentialsDefinition.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(this.spawnPotentialsDefinition.unwrap().get(0).value().getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "TrialSpawnerConfiguration@" + snapshot.getBlockPos().toShortString(), LOGGER
|
||||
)) {
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.createGlobal(
|
||||
problemReporter,
|
||||
this.spawnPotentialsDefinition.unwrap().getFirst().value().getEntityToSpawn()
|
||||
)
|
||||
);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +91,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType);
|
||||
|
||||
SpawnData data = new SpawnData();
|
||||
data.getEntityToSpawn().putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
|
||||
data.getEntityToSpawn().putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
|
||||
this.getTrialData().nextSpawnData = Optional.of(data);
|
||||
this.spawnPotentialsDefinition = WeightedList.of(data);
|
||||
}
|
||||
@@ -121,7 +138,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return this.ticksBetweenSpawn;
|
||||
return this.ticksBetweenSpawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,16 +304,16 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return this.snapshot.trialSpawner.getRequiredPlayerRange();
|
||||
return this.snapshot.trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
this.snapshot.trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
this.snapshot.trialSpawner.config = this.snapshot.trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange);
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return this.snapshot.getTrialSpawner().getData();
|
||||
private TrialSpawnerStateData getTrialData() {
|
||||
return this.snapshot.getTrialSpawner().getStateData();
|
||||
}
|
||||
|
||||
protected TrialSpawnerConfig toMinecraft() {
|
||||
|
||||
@@ -362,7 +362,7 @@ public class CraftBlockData implements BlockData {
|
||||
static {
|
||||
//<editor-fold desc="CraftBlockData Registration" defaultstate="collapsed">
|
||||
// Start generate - CraftBlockData#MAP
|
||||
// @GeneratedFrom 1.21.5
|
||||
// @GeneratedFrom 1.21.6-rc1
|
||||
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);
|
||||
@@ -418,6 +418,7 @@ public class CraftBlockData implements BlockData {
|
||||
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.DriedGhastBlock.class, org.bukkit.craftbukkit.block.impl.CraftDriedGhast::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);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
||||
@@ -76,7 +79,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
|
||||
|
||||
@Override
|
||||
public java.util.UUID getOwnerUniqueId() {
|
||||
return this.getHandle().ownerUUID;
|
||||
return Optionull.map(this.getHandle().owner, EntityReference::getUUID);
|
||||
}
|
||||
// Paper end - More projectile API
|
||||
}
|
||||
|
||||
@@ -139,7 +139,11 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
|
||||
|
||||
@Override
|
||||
public void setRearing(boolean rearing) {
|
||||
this.getHandle().setForceStanding(rearing);
|
||||
if (rearing) {
|
||||
this.getHandle().setStanding(Integer.MAX_VALUE);
|
||||
} else {
|
||||
this.getHandle().clearStanding();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -22,12 +24,12 @@ public class CraftAnimals extends CraftAgeable implements Animals {
|
||||
|
||||
@Override
|
||||
public UUID getBreedCause() {
|
||||
return this.getHandle().loveCause;
|
||||
return Optionull.map(this.getHandle().loveCause, EntityReference::getUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBreedCause(UUID uuid) {
|
||||
this.getHandle().loveCause = uuid;
|
||||
this.getHandle().loveCause = uuid == null ? null : new EntityReference<>(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,9 +3,11 @@ package org.bukkit.craftbukkit.entity;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Particle;
|
||||
@@ -115,7 +117,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
|
||||
@Override
|
||||
public <T> void setParticle(Particle particle, T data) {
|
||||
this.getHandle().setParticle(CraftParticle.createParticleParam(particle, data));
|
||||
this.getHandle().setCustomParticle(CraftParticle.createParticleParam(particle, data));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,13 +228,12 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
||||
// Paper start - owner API
|
||||
@Override
|
||||
public java.util.UUID getOwnerUniqueId() {
|
||||
return this.getHandle().ownerUUID;
|
||||
return Optionull.map(this.getHandle().owner, EntityReference::getUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnerUniqueId(final java.util.UUID ownerUuid) {
|
||||
this.getHandle().setOwner(null);
|
||||
this.getHandle().ownerUUID = ownerUuid;
|
||||
this.getHandle().owner = ownerUuid == null ? null : new EntityReference<>(ownerUuid);
|
||||
}
|
||||
// Paper end
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo {
|
||||
|
||||
@Override
|
||||
public State getState() {
|
||||
return CraftArmadillo.stateToBukkit(this.getHandle().getState());
|
||||
return State.valueOf(this.getHandle().getState().name());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,22 +37,4 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo {
|
||||
this.getHandle().lastHurtByMob = null; // Clear this memory to not have the sensor trigger rollUp instantly for damaged armadillo
|
||||
this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, ArmadilloState.UNROLLING.animationDuration());
|
||||
}
|
||||
|
||||
public static State stateToBukkit(ArmadilloState state) {
|
||||
return switch (state) {
|
||||
case IDLE -> State.IDLE;
|
||||
case ROLLING -> State.ROLLING;
|
||||
case SCARED -> State.SCARED;
|
||||
case UNROLLING -> State.UNROLLING;
|
||||
};
|
||||
}
|
||||
|
||||
public static ArmadilloState stateToNMS(State state) {
|
||||
return switch (state) {
|
||||
case State.IDLE -> ArmadilloState.IDLE;
|
||||
case State.ROLLING -> ArmadilloState.ROLLING;
|
||||
case State.SCARED -> ArmadilloState.SCARED;
|
||||
case State.UNROLLING -> ArmadilloState.UNROLLING;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getBodyPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().bodyPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getBodyPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +82,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getLeftArmPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().leftArmPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getLeftArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,7 +92,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getRightArmPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().rightArmPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getRightArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,7 +102,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getLeftLegPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().leftLegPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getLeftLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +112,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getRightLegPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().rightLegPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getRightLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +122,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public EulerAngle getHeadPose() {
|
||||
return CraftArmorStand.fromNMS(this.getHandle().headPose);
|
||||
return CraftArmorStand.fromNMS(this.getHandle().getHeadPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -293,7 +293,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getBodyRotations() {
|
||||
return fromNMSRotations(this.getHandle().bodyPose);
|
||||
return fromNMSRotations(this.getHandle().getBodyPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -303,7 +303,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getLeftArmRotations() {
|
||||
return fromNMSRotations(this.getHandle().leftArmPose);
|
||||
return fromNMSRotations(this.getHandle().getLeftArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -313,7 +313,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getRightArmRotations() {
|
||||
return fromNMSRotations(this.getHandle().rightArmPose);
|
||||
return fromNMSRotations(this.getHandle().getRightArmPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -323,7 +323,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getLeftLegRotations() {
|
||||
return fromNMSRotations(this.getHandle().leftLegPose);
|
||||
return fromNMSRotations(this.getHandle().getLeftLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +333,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getRightLegRotations() {
|
||||
return fromNMSRotations(this.getHandle().rightLegPose);
|
||||
return fromNMSRotations(this.getHandle().getRightLegPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -343,7 +343,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.math.Rotations getHeadRotations() {
|
||||
return fromNMSRotations(this.getHandle().headPose);
|
||||
return fromNMSRotations(this.getHandle().getHeadPose());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.projectile.EyeOfEnder;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.bukkit.Location;
|
||||
@@ -22,7 +23,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
|
||||
|
||||
@Override
|
||||
public Location getTargetLocation() {
|
||||
return new Location(this.getWorld(), this.getHandle().tx, this.getHandle().ty, this.getHandle().tz, this.getHandle().getYRot(), this.getHandle().getXRot());
|
||||
return Optionull.map(this.getHandle().target, target -> CraftLocation.toBukkit(target, this.getWorld(), this.getHandle().getYRot(), this.getHandle().getXRot()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,7 +36,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
|
||||
public void setTargetLocation(Location location, boolean update) {
|
||||
// Paper end - Change EnderEye target without changing other things
|
||||
Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
|
||||
this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things
|
||||
this.getHandle().signalTo(CraftLocation.toVec3(location), update); // Paper - Change EnderEye target without changing other things
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.datacomponent.DataComponentType;
|
||||
import io.papermc.paper.entity.TeleportFlag;
|
||||
import java.util.HashSet;
|
||||
@@ -15,7 +16,6 @@ import io.papermc.paper.entity.LookAnchor;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.kyori.adventure.util.TriState;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
@@ -24,12 +24,16 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.server.network.ServerPlayerConnection;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.EntityEffect;
|
||||
@@ -73,8 +77,12 @@ import org.bukkit.util.Vector;
|
||||
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private static PermissibleBase perm;
|
||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
|
||||
@@ -979,12 +987,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
if (!this.getHandle().saveAsPassenger(tag, false, true, true)) {
|
||||
return null;
|
||||
}
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#toString", LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess()
|
||||
);
|
||||
if (!this.getHandle().saveAsPassenger(output, false, true, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return tag.toString();
|
||||
return output.buildResult().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1012,32 +1027,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
}
|
||||
|
||||
private Entity copy(net.minecraft.world.level.Level level) {
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
this.getHandle().saveAsPassenger(compoundTag, false, true, true);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#copy", LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(problemReporter, level.registryAccess());
|
||||
this.getHandle().saveAsPassenger(output, false, true, true);
|
||||
|
||||
return net.minecraft.world.entity.EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.LOAD, java.util.function.Function.identity());
|
||||
return net.minecraft.world.entity.EntityType.loadEntityRecursive(output.buildResult(), level, EntitySpawnReason.LOAD, java.util.function.Function.identity());
|
||||
}
|
||||
}
|
||||
|
||||
public void storeBukkitValues(CompoundTag c) {
|
||||
public void storeBukkitValues(ValueOutput output) {
|
||||
if (!this.persistentDataContainer.isEmpty()) {
|
||||
c.put("BukkitValues", this.persistentDataContainer.toTagCompound());
|
||||
output.store("BukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound());
|
||||
}
|
||||
}
|
||||
|
||||
public void readBukkitValues(CompoundTag c) {
|
||||
Tag base = c.get("BukkitValues");
|
||||
if (base instanceof CompoundTag) {
|
||||
this.persistentDataContainer.putAll((CompoundTag) base);
|
||||
}
|
||||
public void readBukkitValues(ValueInput input) {
|
||||
input.read("BukkitValues", CompoundTag.CODEC).ifPresent(this.persistentDataContainer::putAll);
|
||||
}
|
||||
|
||||
protected CompoundTag save() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "Entity#save", LOGGER
|
||||
)) {
|
||||
final TagValueOutput tagValueOutput = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess()
|
||||
);
|
||||
|
||||
tag.putString(Entity.ID_TAG, this.getHandle().getEncodeId()); // todo NPE?
|
||||
this.getHandle().saveWithoutId(tag);
|
||||
tagValueOutput.putString(Entity.TAG_ID, this.getHandle().getEncodeId(true));
|
||||
this.getHandle().saveWithoutId(tagValueOutput);
|
||||
|
||||
return tag;
|
||||
return tagValueOutput.buildResult();
|
||||
}
|
||||
}
|
||||
|
||||
// re-sends the spawn entity packet to updated values which cannot be updated otherwise
|
||||
|
||||
@@ -2,14 +2,19 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.entity.EntityFactory;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftEntityFactory implements EntityFactory {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final CraftEntityFactory instance;
|
||||
|
||||
static {
|
||||
@@ -30,7 +35,12 @@ public class CraftEntityFactory implements EntityFactory {
|
||||
throw new IllegalArgumentException("Could not parse Entity: " + input, e);
|
||||
}
|
||||
|
||||
EntityType<?> type = EntityType.by(tag).orElse(null);
|
||||
final EntityType<?> type;
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "createEntitySnapshot", LOGGER
|
||||
)) {
|
||||
type = EntityType.by(TagValueInput.createGlobal(problemReporter, tag)).orElse(null);
|
||||
}
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Could not parse Entity: " + input);
|
||||
}
|
||||
|
||||
@@ -2,16 +2,25 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.function.Function;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import net.minecraft.world.level.storage.TagValueOutput;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final CompoundTag data;
|
||||
private final EntityType type;
|
||||
|
||||
@@ -55,7 +64,11 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
Preconditions.checkArgument(internal != null, "Error creating new entity."); // This should only fail if the stored CompoundTag is malformed.
|
||||
internal.load(this.data);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "EntitySnapshot#createEntity", LOGGER
|
||||
)) {
|
||||
internal.load(TagValueInput.createGlobal(problemReporter, this.data));
|
||||
}
|
||||
|
||||
return internal;
|
||||
}
|
||||
@@ -65,12 +78,19 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CraftEntity entity) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
if (!entity.getHandle().saveAsPassenger(tag, false, false, false)) {
|
||||
return null;
|
||||
}
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "create@" + entity.getUniqueId(), LOGGER
|
||||
)) {
|
||||
final TagValueOutput output = TagValueOutput.createWithContext(
|
||||
problemReporter,
|
||||
CraftRegistry.getMinecraftRegistry()
|
||||
);
|
||||
if (!entity.getHandle().saveAsPassenger(output, false, false, false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CraftEntitySnapshot(tag, entity.getType());
|
||||
return new CraftEntitySnapshot(output.buildResult(), entity.getType());
|
||||
}
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CompoundTag tag, EntityType type) {
|
||||
@@ -82,7 +102,13 @@ public class CraftEntitySnapshot implements EntitySnapshot {
|
||||
}
|
||||
|
||||
public static CraftEntitySnapshot create(CompoundTag tag) {
|
||||
EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
return CraftEntitySnapshot.create(tag, type);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "create", LOGGER
|
||||
)) {
|
||||
EntityType type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.createGlobal(problemReporter, tag)
|
||||
).map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
return CraftEntitySnapshot.create(tag, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ import org.bukkit.entity.GlowSquid;
|
||||
import org.bukkit.entity.Goat;
|
||||
import org.bukkit.entity.Guardian;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.HappyGhast;
|
||||
import org.bukkit.entity.Hoglin;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Husk;
|
||||
@@ -352,6 +353,7 @@ public final class CraftEntityTypes {
|
||||
register(new EntityTypeData<>(EntityType.BREEZE, Breeze.class, CraftBreeze::new, createLiving(net.minecraft.world.entity.EntityType.BREEZE)));
|
||||
register(new EntityTypeData<>(EntityType.ARMADILLO, Armadillo.class, CraftArmadillo::new, createLiving(net.minecraft.world.entity.EntityType.ARMADILLO)));
|
||||
register(new EntityTypeData<>(EntityType.CREAKING, Creaking.class, CraftCreaking::new, createLiving(net.minecraft.world.entity.EntityType.CREAKING)));
|
||||
register(new EntityTypeData<>(EntityType.HAPPY_GHAST, HappyGhast.class, CraftHappyGhast::new, createLiving(net.minecraft.world.entity.EntityType.HAPPY_GHAST)));
|
||||
|
||||
Function<SpawnData, net.minecraft.world.entity.boss.enderdragon.EnderDragon> dragonFunction = createLiving(net.minecraft.world.entity.EntityType.ENDER_DRAGON);
|
||||
register(new EntityTypeData<>(EntityType.ENDER_DRAGON, EnderDragon.class, CraftEnderDragon::new, spawnData -> {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.world.entity.FlyingMob;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Flying;
|
||||
|
||||
public class CraftFlying extends CraftMob implements Flying {
|
||||
|
||||
public CraftFlying(CraftServer server, FlyingMob entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlyingMob getHandle() {
|
||||
return (FlyingMob) this.entity;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Ghast;
|
||||
|
||||
public class CraftGhast extends CraftFlying implements Ghast, CraftEnemy {
|
||||
public class CraftGhast extends CraftMob implements Ghast, CraftEnemy {
|
||||
|
||||
public CraftGhast(CraftServer server, net.minecraft.world.entity.monster.Ghast entity) {
|
||||
super(server, entity);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.HappyGhast;
|
||||
|
||||
public class CraftHappyGhast extends CraftAnimals implements HappyGhast {
|
||||
public CraftHappyGhast(final CraftServer server, final net.minecraft.world.entity.animal.HappyGhast entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -18,11 +19,13 @@ import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.TamableAnimal;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
@@ -38,6 +41,7 @@ import net.minecraft.world.level.block.BedBlock;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -78,9 +82,11 @@ import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private CraftInventoryPlayer inventory;
|
||||
private final CraftInventory enderChest;
|
||||
protected final PermissibleBase perm = new PermissibleBase(this);
|
||||
@@ -175,7 +181,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
return null;
|
||||
}
|
||||
|
||||
net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).server.getLevel(respawnConfig.dimension());
|
||||
net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).getServer().getLevel(respawnConfig.dimension());
|
||||
if (level == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -769,8 +775,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getShoulderEntityLeft() {
|
||||
if (!this.getHandle().getShoulderEntityLeft().isEmpty()) {
|
||||
Optional<Entity> shoulder = EntityType.create(this.getHandle().getShoulderEntityLeft(), this.getHandle().level(), EntitySpawnReason.LOAD);
|
||||
return shoulder.map(Entity::getBukkitEntity).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) {
|
||||
return EntityType.create(
|
||||
TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityLeft()),
|
||||
this.getHandle().level(),
|
||||
EntitySpawnReason.LOAD
|
||||
).map(Entity::getBukkitEntity).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -778,6 +789,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void setShoulderEntityLeft(org.bukkit.entity.Entity entity) {
|
||||
if (entity != null) {
|
||||
Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey());
|
||||
}
|
||||
this.getHandle().setShoulderEntityLeft(entity == null ? new CompoundTag() : ((CraftEntity) entity).save());
|
||||
if (entity != null) {
|
||||
entity.remove();
|
||||
@@ -787,8 +801,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getShoulderEntityRight() {
|
||||
if (!this.getHandle().getShoulderEntityRight().isEmpty()) {
|
||||
Optional<Entity> shoulder = EntityType.create(this.getHandle().getShoulderEntityRight(), this.getHandle().level(), EntitySpawnReason.LOAD);
|
||||
return shoulder.map(Entity::getBukkitEntity).orElse(null);
|
||||
try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) {
|
||||
return EntityType.create(
|
||||
TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityRight()),
|
||||
this.getHandle().level(),
|
||||
EntitySpawnReason.LOAD
|
||||
).map(Entity::getBukkitEntity).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -796,6 +815,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void setShoulderEntityRight(org.bukkit.entity.Entity entity) {
|
||||
if (entity != null) {
|
||||
Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey());
|
||||
}
|
||||
this.getHandle().setShoulderEntityRight(entity == null ? new CompoundTag() : ((CraftEntity) entity).save());
|
||||
if (entity != null) {
|
||||
entity.remove();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import java.util.UUID;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.Optionull;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
@@ -136,11 +138,11 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
|
||||
@Override
|
||||
public void setThrower(UUID uuid) {
|
||||
this.getHandle().thrower = uuid;
|
||||
this.getHandle().thrower = uuid == null ? null : new EntityReference<>(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getThrower() {
|
||||
return this.getHandle().thrower;
|
||||
return Optionull.map(this.getHandle().thrower, EntityReference::getUUID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import com.google.common.base.Preconditions;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.entity.vehicle.MinecartSpawner;
|
||||
import net.minecraft.world.level.SpawnData;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -34,8 +36,14 @@ public class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMin
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "getSpawnedType@" + this.getUniqueId(), LOGGER
|
||||
)) {
|
||||
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(
|
||||
TagValueInput.create(problemReporter, getHandle().registryAccess(), spawnData.getEntityToSpawn())
|
||||
);
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
import org.bukkit.entity.Phantom;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
public class CraftPhantom extends CraftMob implements Phantom, CraftEnemy {
|
||||
|
||||
public CraftPhantom(CraftServer server, net.minecraft.world.entity.monster.Phantom entity) {
|
||||
super(server, entity);
|
||||
@@ -50,7 +50,6 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
|
||||
@Override
|
||||
public void setAnchorLocation(Location location) {
|
||||
com.google.common.base.Preconditions.checkArgument(location != null, "location cannot be null");
|
||||
this.getHandle().anchorPoint = location == null ? null : CraftLocation.toBlockPosition(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
@@ -120,6 +121,8 @@ import net.minecraft.world.level.border.BorderChangeListener;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
||||
import net.minecraft.world.level.saveddata.maps.MapId;
|
||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import net.minecraft.world.level.storage.ValueOutput;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -1530,7 +1533,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public void loadData() {
|
||||
this.server.getHandle().playerIo.load(this.getHandle());
|
||||
this.server.getHandle().playerIo.load(this.getHandle(), ProblemReporter.DISCARDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1560,7 +1563,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
final ServerPlayer.RespawnConfig respawnConfig = this.getHandle().getRespawnConfig();
|
||||
if (respawnConfig == null) return null;
|
||||
|
||||
final ServerLevel world = this.getHandle().server.getLevel(respawnConfig.dimension());
|
||||
final ServerLevel world = this.getHandle().getServer().getLevel(respawnConfig.dimension());
|
||||
if (world == null) return null;
|
||||
|
||||
if (!loadLocationAndValidate) {
|
||||
@@ -1885,7 +1888,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
|
||||
|
||||
final int possibleDurabilityFromXp = net.minecraft.world.item.enchantment.EnchantmentHelper.modifyDurabilityToRepairFromXp(
|
||||
handle.serverLevel(), itemstack, amount
|
||||
handle.level(), itemstack, amount
|
||||
);
|
||||
int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue());
|
||||
final int consumedExperience = i > 0 ? i * amount / possibleDurabilityFromXp : possibleDurabilityFromXp; // Paper - taken from ExperienceOrb#repairPlayerItems + prevent division by 0
|
||||
@@ -2234,11 +2237,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
ServerGamePacketListenerImpl connection = handle.connection;
|
||||
|
||||
// Respawn the player then update their position and selected slot
|
||||
ServerLevel level = handle.serverLevel();
|
||||
ServerLevel level = handle.level();
|
||||
connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(handle.createCommonSpawnInfo(level), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA));
|
||||
handle.onUpdateAbilities();
|
||||
connection.internalTeleport(net.minecraft.world.entity.PositionMoveRotation.of(this.getHandle()), java.util.Collections.emptySet());
|
||||
net.minecraft.server.players.PlayerList playerList = handle.server.getPlayerList();
|
||||
net.minecraft.server.players.PlayerList playerList = handle.getServer().getPlayerList();
|
||||
playerList.sendPlayerPermissionLevel(handle, false);
|
||||
playerList.sendLevelInfo(handle, level);
|
||||
playerList.sendAllPlayerInfo(handle);
|
||||
@@ -2351,9 +2354,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
// Paper end - getLastPlayed replacement API
|
||||
|
||||
public void readExtraData(CompoundTag tag) {
|
||||
public void readExtraData(ValueInput input) {
|
||||
this.hasPlayedBefore = true;
|
||||
tag.getCompound("bukkit").ifPresent(data -> {
|
||||
input.child("bukkit").ifPresent(data -> {
|
||||
this.firstPlayed = data.getLongOr("firstPlayed", 0);
|
||||
this.lastPlayed = data.getLongOr("lastPlayed", 0);
|
||||
|
||||
@@ -2366,14 +2369,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
});
|
||||
}
|
||||
|
||||
public void setExtraData(CompoundTag tag) {
|
||||
public void setExtraData(ValueOutput output) {
|
||||
this.lastSaveTime = System.currentTimeMillis(); // Paper
|
||||
|
||||
if (!tag.contains("bukkit")) {
|
||||
tag.put("bukkit", new CompoundTag());
|
||||
}
|
||||
|
||||
CompoundTag data = tag.getCompoundOrEmpty("bukkit");
|
||||
ValueOutput data = output.child("bukkit");
|
||||
ServerPlayer handle = this.getHandle();
|
||||
data.putInt("newExp", handle.newExp);
|
||||
data.putInt("newTotalExp", handle.newTotalExp);
|
||||
@@ -2385,11 +2384,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
data.putString("lastKnownName", handle.getScoreboardName());
|
||||
|
||||
// Paper start - persist for use in offline save data
|
||||
if (!tag.contains("Paper")) {
|
||||
tag.put("Paper", new CompoundTag());
|
||||
}
|
||||
|
||||
CompoundTag paper = tag.getCompoundOrEmpty("Paper");
|
||||
ValueOutput paper = output.child("Paper");
|
||||
paper.putLong("LastLogin", handle.loginTime);
|
||||
paper.putLong("LastSeen", System.currentTimeMillis());
|
||||
// Paper end
|
||||
@@ -3016,7 +3011,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void updateCommands() {
|
||||
if (this.getHandle().connection == null) return;
|
||||
|
||||
this.getHandle().server.getCommands().sendCommands(this.getHandle());
|
||||
this.getHandle().getServer().getCommands().sendCommands(this.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -57,7 +58,7 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed {
|
||||
@Override
|
||||
public void setSource(Entity source) {
|
||||
if (source instanceof LivingEntity) {
|
||||
this.getHandle().owner = ((CraftLivingEntity) source).getHandle();
|
||||
this.getHandle().owner = new EntityReference<>(((CraftLivingEntity) source).getHandle());
|
||||
} else {
|
||||
this.getHandle().owner = null;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.EntityReference;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.CraftLocation;
|
||||
@@ -20,13 +21,13 @@ public class CraftVex extends CraftMonster implements Vex {
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Mob getSummoner() {
|
||||
net.minecraft.world.entity.Mob owner = getHandle().getOwner();
|
||||
net.minecraft.world.entity.Mob owner = this.getHandle().getOwner();
|
||||
return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummoner(org.bukkit.entity.Mob summoner) {
|
||||
getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
|
||||
this.getHandle().owner = summoner == null ? null : new EntityReference<>(((CraftMob) summoner).getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,6 +27,7 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Leashable;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.animal.AbstractFish;
|
||||
import net.minecraft.world.entity.animal.AbstractGolem;
|
||||
@@ -881,7 +882,7 @@ public class CraftEventFactory {
|
||||
public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean showDeathMessages, boolean keepInventory) {
|
||||
CraftPlayer entity = victim.getBukkitEntity();
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage, showDeathMessages);
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.level(), damageSource.getEntity()), 0, deathMessage, showDeathMessages);
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
populateFields(victim, event); // Paper - make cancellable
|
||||
@@ -1490,10 +1491,56 @@ public class CraftEventFactory {
|
||||
Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter));
|
||||
}
|
||||
|
||||
public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Entity entity, net.minecraft.world.entity.player.Player player, InteractionHand hand, boolean dropLeash) {
|
||||
public static boolean handlePlayerUnleashEntityEvent(
|
||||
final Leashable leashable,
|
||||
final net.minecraft.world.entity.player.@Nullable Player player,
|
||||
final @Nullable InteractionHand hand,
|
||||
final boolean dropLeash,
|
||||
final boolean resendState
|
||||
) {
|
||||
if (!(leashable instanceof final Entity entity)) return true;
|
||||
return handlePlayerUnleashEntityEvent(entity, player, hand, dropLeash, resendState);
|
||||
}
|
||||
|
||||
public static boolean handlePlayerUnleashEntityEvent(
|
||||
final Entity entity,
|
||||
final net.minecraft.world.entity.player.@Nullable Player player,
|
||||
final @Nullable InteractionHand hand,
|
||||
final boolean dropLeash,
|
||||
final boolean resendState
|
||||
) {
|
||||
if (player == null || hand == null) {
|
||||
if (entity instanceof final Leashable leashable) {
|
||||
if (dropLeash) leashable.dropLeash();
|
||||
else leashable.removeLeash();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(hand), dropLeash);
|
||||
entity.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
if (event.isCancelled()) {
|
||||
if (resendState && entity instanceof final Leashable leashable) {
|
||||
((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(entity, leashable.getLeashHolder()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entity instanceof final Leashable leashable) {
|
||||
if (event.isDropLeash()) leashable.dropLeash();
|
||||
else leashable.removeLeash();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean handlePlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
if (!(leashed instanceof final Entity leashedEntity)) return false;
|
||||
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand).callEvent();
|
||||
}
|
||||
|
||||
public static @Nullable PlayerLeashEntityEvent callPlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
if (!(leashed instanceof final Entity leashedEntity)) return null;
|
||||
return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand);
|
||||
}
|
||||
|
||||
public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(Entity entity, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) {
|
||||
|
||||
@@ -7,9 +7,11 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
@@ -17,6 +19,7 @@ import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.storage.TagValueInput;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -30,9 +33,12 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.generator.LimitedRegion;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRegion {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final WeakReference<WorldGenLevel> weakAccess;
|
||||
private final int centerChunkX;
|
||||
private final int centerChunkZ;
|
||||
@@ -271,7 +277,16 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
|
||||
if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) {
|
||||
throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false));
|
||||
}
|
||||
getHandle().getBlockEntity(pos).loadWithComponents(((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT(), this.getHandle().registryAccess());
|
||||
|
||||
try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector(
|
||||
() -> "CraftLimitedRegion@" + pos.toShortString(), LOGGER
|
||||
)) {
|
||||
getHandle().getBlockEntity(pos).loadWithComponents(TagValueInput.create(
|
||||
problemReporter,
|
||||
this.getHandle().registryAccess(),
|
||||
((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,12 +20,12 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public ItemStack getSaddle() {
|
||||
return this.getItem(HorseInventoryMenu.SLOT_SADDLE); // Paper
|
||||
return this.getItem(HorseInventoryMenu.SLOT_SADDLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSaddle(ItemStack stack) {
|
||||
this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack); // Paper
|
||||
this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack);
|
||||
}
|
||||
|
||||
public Container getMainInventory() {
|
||||
@@ -88,14 +88,17 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(final int index) {
|
||||
if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getSaddleInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0);
|
||||
return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item);
|
||||
} else {
|
||||
int shiftedIndex = index;
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
@@ -107,16 +110,16 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr
|
||||
|
||||
@Override
|
||||
public void setItem(final int index, final ItemStack item) {
|
||||
if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index == HorseInventoryMenu.SLOT_SADDLE) {
|
||||
this.getSaddleInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item));
|
||||
} else {
|
||||
int shiftedIndex = index;
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
if (index > HorseInventoryMenu.SLOT_SADDLE) {
|
||||
if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) {
|
||||
shiftedIndex--;
|
||||
}
|
||||
this.getMainInventory().setItem(shiftedIndex, CraftItemStack.asNMSCopy(item));
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
|
||||
import java.util.List;
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPlayerInventoryPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
@@ -71,14 +72,25 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
@Override
|
||||
public void setItem(int index, ItemStack item) {
|
||||
// Paper start - Validate setItem index
|
||||
if (index < 0 || index > 40) {
|
||||
throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 40");
|
||||
if (index < 0 || index > 42) {
|
||||
throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 42");
|
||||
}
|
||||
// Paper end - Validate setItem index
|
||||
super.setItem(index, item);
|
||||
if (this.getHolder() == null) return;
|
||||
|
||||
ServerPlayer player = ((CraftPlayer) this.getHolder()).getHandle();
|
||||
if (player.connection == null) return;
|
||||
// Of course, these are not part of the player inventory "menu" because these slots are not accessible.
|
||||
// However they are technically part of the player inventory.
|
||||
// This is a poor representation by this API, but basically instead send a player inventory update packet.
|
||||
// This will allow updates to the player inventory rather than through the menu.
|
||||
// TODO: This could be something worth cleaning up in the future.
|
||||
if (index > 40) {
|
||||
player.connection.send(new ClientboundSetPlayerInventoryPacket(index, CraftItemStack.asNMSCopy(item)));
|
||||
return;
|
||||
}
|
||||
|
||||
// PacketPlayOutSetSlot places the items differently than setItem()
|
||||
//
|
||||
// Between, and including, index 9 (the first index outside of the hotbar) and index 35 (the last index before
|
||||
@@ -123,11 +135,8 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
switch (slot) {
|
||||
case HAND -> this.setItemInMainHand(item);
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD ->
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE ->
|
||||
this.getInventory().equipment.set(CraftEquipmentSlot.getNMS(slot), CraftItemStack.asNMSCopy(item));
|
||||
case BODY -> throw new IllegalArgumentException("BODY is not valid for players!"); // Paper end
|
||||
default ->
|
||||
throw new IllegalArgumentException("Could not set slot " + slot + " - not a valid slot for PlayerInventory");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,10 +151,7 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
return switch (slot) {
|
||||
case HAND -> this.getItemInMainHand();
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot)));
|
||||
case BODY -> throw new IllegalArgumentException("BODY is not valid for players!");
|
||||
default ->
|
||||
throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory");
|
||||
case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot)));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -253,12 +259,12 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i
|
||||
|
||||
@Override
|
||||
public ItemStack[] getExtraContents() {
|
||||
return this.asCraftMirror(List.of(this.getInventory().equipment.get(net.minecraft.world.entity.EquipmentSlot.OFFHAND)));
|
||||
return this.asCraftMirror(this.getInventory().getExtraContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraContents(ItemStack[] items) {
|
||||
this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 1);
|
||||
this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user