diff --git a/settings.gradle b/settings.gradle index 39ee460..8af9af0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,9 +19,9 @@ include 'v1_7_R4' include 'v1_8_R3' include 'v1_12_R1' include 'v1_16_R3' -include 'v1_17_R1' +include 'v117' include 'v1181' include 'v1182' +include 'v119' include 'v1191' -include 'v1192' -include 'v119' \ No newline at end of file +include 'v1192' \ No newline at end of file diff --git a/src/main/java/com/bgsoftware/wildloaders/WildLoadersPlugin.java b/src/main/java/com/bgsoftware/wildloaders/WildLoadersPlugin.java index 6c23b5f..7b2a730 100644 --- a/src/main/java/com/bgsoftware/wildloaders/WildLoadersPlugin.java +++ b/src/main/java/com/bgsoftware/wildloaders/WildLoadersPlugin.java @@ -98,13 +98,15 @@ public final class WildLoadersPlugin extends JavaPlugin implements WildLoaders { private boolean loadNMSAdapter() { String version = null; - if (ServerVersion.isLessThan(ServerVersion.v1_18)) { + if (ServerVersion.isLessThan(ServerVersion.v1_17)) { version = getServer().getClass().getPackage().getName().split("\\.")[3]; } else { ReflectMethod getDataVersion = new ReflectMethod<>(UnsafeValues.class, "getDataVersion"); int dataVersion = getDataVersion.invoke(Bukkit.getUnsafe()); List> versions = Arrays.asList( + new Pair<>(2729, null), + new Pair<>(2730, "v117"), new Pair<>(2865, "v1181"), new Pair<>(2975, "v1182"), new Pair<>(3105, "v119"), diff --git a/v117/build.gradle b/v117/build.gradle new file mode 100644 index 0000000..40ab87a --- /dev/null +++ b/v117/build.gradle @@ -0,0 +1,34 @@ +plugins { + id("io.papermc.paperweight.userdev") version "1.3.8" +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(16)) + } +} + +dependencies { + paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.17.1-R0.1-SNAPSHOT") + compileOnly project(":API") + compileOnly parent +} + +shadowJar { + archiveFileName = "${project.name}-exclude.jar" +} + +assemble { + dependsOn(reobfJar) +} + +tasks { + reobfJar { + File outputFile = new File(parent.projectDir, "archive/reobf/${project.name}.jar") + outputJar.set(layout.buildDirectory.file(outputFile.getPath())) + } +} + +if (project.hasProperty('nms.compile_v1_17') && !Boolean.valueOf(project.findProperty("nms.compile_v1_17").toString())) { + project.tasks.all { task -> task.enabled = false } +} \ No newline at end of file diff --git a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/EntityHolograms.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/EntityHologram.java similarity index 51% rename from v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/EntityHolograms.java rename to v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/EntityHologram.java index 87efb18..21441da 100644 --- a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/EntityHolograms.java +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/EntityHologram.java @@ -1,56 +1,54 @@ -package com.bgsoftware.wildloaders.nms.v1_17_R1; +package com.bgsoftware.wildloaders.nms.v117; import com.bgsoftware.wildloaders.api.holograms.Hologram; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.chat.IChatBaseComponent; -import net.minecraft.sounds.SoundEffect; -import net.minecraft.world.EnumHand; -import net.minecraft.world.EnumInteractionResult; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EnumItemSlot; -import net.minecraft.world.entity.decoration.EntityArmorStand; -import net.minecraft.world.entity.player.EntityHuman; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.World; -import net.minecraft.world.phys.AxisAlignedBB; -import net.minecraft.world.phys.Vec3D; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftArmorStand; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage; -import javax.annotation.Nullable; +public final class EntityHologram extends ArmorStand implements Hologram { -@SuppressWarnings("unused") -public final class EntityHolograms extends EntityArmorStand implements Hologram { - - private static final AxisAlignedBB EMPTY_BOUND = new AxisAlignedBB(0D, 0D, 0D, 0D, 0D, 0D); + private static final AABB EMPTY_BOUND = new AABB(0D, 0D, 0D, 0D, 0D, 0D); private CraftEntity bukkitEntity; - public EntityHolograms(World world, double x, double y, double z){ - super(world, x, y, z); + public EntityHologram(ServerLevel serverLevel, double x, double y, double z) { + super(serverLevel, x, y, z); + setInvisible(true); setSmall(true); - setArms(false); + setShowArms(false); setNoGravity(true); - setBasePlate(true); + setNoBasePlate(true); setMarker(true); + super.collides = false; - super.setCustomNameVisible(true); - super.a(EMPTY_BOUND); + super.setCustomNameVisible(true); // Custom name visible + super.setBoundingBox(EMPTY_BOUND); } @Override public void setHologramName(String name) { - super.setCustomName(CraftChatMessage.fromString(name)[0]); + super.setCustomName(CraftChatMessage.fromStringOrNull(name)); } @Override public void removeHologram() { - super.a(Entity.RemovalReason.b); + super.remove(RemovalReason.DISCARDED); } @Override @@ -63,8 +61,8 @@ public final class EntityHolograms extends EntityArmorStand implements Hologram // Disable normal ticking for this entity. // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity. - if (this.z) { - this.z = false; + if (this.onGround) { + this.onGround = false; } } @@ -73,40 +71,40 @@ public final class EntityHolograms extends EntityArmorStand implements Hologram // Disable normal ticking for this entity. // Workaround to force EntityTrackerEntry to send a teleport packet immediately after spawning this entity. - if (this.z) { - this.z = false; + if (this.onGround) { + this.onGround = false; } } @Override - public void saveData(NBTTagCompound nbttagcompound) { + public void addAdditionalSaveData(CompoundTag compoundTag) { // Do not save NBT. } @Override - public boolean d(NBTTagCompound nbttagcompound) { + public boolean saveAsPassenger(CompoundTag compoundTag) { // Do not save NBT. return false; } @Override - public NBTTagCompound save(NBTTagCompound nbttagcompound) { + public CompoundTag saveWithoutId(CompoundTag compoundTag) { // Do not save NBT. - return nbttagcompound; + return compoundTag; } @Override - public void load(NBTTagCompound nbttagcompound) { + public void readAdditionalSaveData(CompoundTag compoundTag) { // Do not load NBT. } @Override - public void loadData(NBTTagCompound nbttagcompound) { + public void load(CompoundTag compoundTag) { // Do not load NBT. } @Override - public boolean isInvulnerable(DamageSource source) { + public boolean isInvulnerableTo(DamageSource source) { /* * The field Entity.invulnerable is private. * It's only used while saving NBTTags, but since the entity would be killed @@ -116,47 +114,43 @@ public final class EntityHolograms extends EntityArmorStand implements Hologram } @Override - public boolean isCollidable() { + public boolean repositionEntityAfterLoad() { return false; } @Override - public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { + public void setCustomName(Component component) { // Locks the custom name. } @Override - public void setCustomNameVisible(boolean flag) { + public void setCustomNameVisible(boolean visible) { // Locks the custom name. } @Override - public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) { + public InteractionResult interactAt(Player player, Vec3 hitPos, InteractionHand hand) { // Prevent stand being equipped - return EnumInteractionResult.d; + return InteractionResult.PASS; } @Override - public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { + public void setSlot(EquipmentSlot equipmentSlot, ItemStack itemStack, boolean silent) { // Prevent stand being equipped } @Override - public AxisAlignedBB cs() { + public AABB getBoundingBoxForCulling() { return EMPTY_BOUND; } - public void forceSetBoundingBox(AxisAlignedBB boundingBox) { - super.a(boundingBox); - } - @Override - public void playSound(SoundEffect soundeffect, float f, float f1) { + public void playSound(SoundEvent soundEvent, float volume, float pitch) { // Remove sounds. } @Override - public void a(Entity.RemovalReason entity_removalreason) { + public void remove(RemovalReason removalReason) { // Prevent being killed. } diff --git a/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/NMSAdapter.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/NMSAdapter.java new file mode 100644 index 0000000..90868eb --- /dev/null +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/NMSAdapter.java @@ -0,0 +1,171 @@ +package com.bgsoftware.wildloaders.nms.v117; + +import com.bgsoftware.wildloaders.api.loaders.ChunkLoader; +import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader; +import com.bgsoftware.wildloaders.nms.v117.loader.ChunkLoaderBlockEntity; +import com.bgsoftware.wildloaders.nms.v117.npc.ChunkLoaderNPCWrapper; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.SpawnerBlockEntity; +import net.minecraft.world.level.chunk.LevelChunk; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_17_R1.CraftServer; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; + +import java.util.UUID; + +public final class NMSAdapter implements com.bgsoftware.wildloaders.nms.NMSAdapter { + + @Override + public String getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String def) { + ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem); + CompoundTag compoundTag = itemStack.getTag(); + return compoundTag == null || !compoundTag.contains(key, 8) ? def : compoundTag.getString(key); + } + + @Override + public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, String value) { + ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem); + CompoundTag compoundTag = itemStack.getOrCreateTag(); + + compoundTag.putString(key, value); + + return CraftItemStack.asBukkitCopy(itemStack); + } + + @Override + public long getTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long def) { + ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem); + CompoundTag compoundTag = itemStack.getTag(); + return compoundTag == null || !compoundTag.contains(key, 4) ? def : compoundTag.getLong(key); + } + + @Override + public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack bukkitItem, String key, long value) { + ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem); + CompoundTag compoundTag = itemStack.getOrCreateTag(); + + compoundTag.putLong(key, value); + + return CraftItemStack.asBukkitCopy(itemStack); + } + + @Override + public org.bukkit.inventory.ItemStack getPlayerSkull(org.bukkit.inventory.ItemStack bukkitItem, String texture) { + ItemStack itemStack = CraftItemStack.asNMSCopy(bukkitItem); + CompoundTag compoundTag = itemStack.getOrCreateTag(); + + CompoundTag skullOwner = compoundTag.contains("SkullOwner") ? + compoundTag.getCompound("SkullOwner") : new CompoundTag(); + + CompoundTag properties = new CompoundTag(); + ListTag textures = new ListTag(); + CompoundTag signature = new CompoundTag(); + + signature.putString("Value", texture); + textures.add(signature); + + properties.put("textures", textures); + + skullOwner.put("Properties", properties); + skullOwner.putString("Id", UUID.randomUUID().toString()); + + compoundTag.put("SkullOwner", skullOwner); + + return CraftItemStack.asBukkitCopy(itemStack); + } + + @Override + public com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC createNPC(Location location, UUID uuid) { + return new ChunkLoaderNPCWrapper(((CraftServer) Bukkit.getServer()).getServer(), location, uuid); + } + + @Override + public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) { + Location loaderLoc = chunkLoader.getLocation(); + World bukkitWorld = loaderLoc.getWorld(); + + if (bukkitWorld == null) + throw new IllegalArgumentException("Cannot create loader in null world."); + + ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle(); + BlockPos blockPos = new BlockPos(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ()); + + ChunkLoaderBlockEntity ChunkLoaderBlockEntity = new ChunkLoaderBlockEntity(chunkLoader, serverLevel, blockPos); + serverLevel.addBlockEntityTicker(ChunkLoaderBlockEntity.getTicker()); + + for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) { + LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle(); + levelChunk.getBlockEntities().values().stream() + .filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity) + .forEach(blockEntity -> { + ((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = -1; + }); + + ChunkPos chunkPos = levelChunk.getPos(); + serverLevel.setChunkForced(chunkPos.x, chunkPos.z, true); + } + + return ChunkLoaderBlockEntity; + } + + @Override + public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) { + Location loaderLoc = chunkLoader.getLocation(); + World bukkitWorld = loaderLoc.getWorld(); + + if (bukkitWorld == null) + throw new IllegalArgumentException("Cannot remove loader in null world."); + + ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle(); + BlockPos blockPos = new BlockPos(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ()); + + long chunkPosLong = ChunkPos.asLong(blockPos.getX() >> 4, blockPos.getZ() >> 4); + ChunkLoaderBlockEntity chunkLoaderBlockEntity = ChunkLoaderBlockEntity.chunkLoaderBlockEntityMap.remove(chunkPosLong); + + if (chunkLoaderBlockEntity != null) { + chunkLoaderBlockEntity.holograms.forEach(EntityHologram::removeHologram); + chunkLoaderBlockEntity.removed = true; + } + + if (spawnParticle) + serverLevel.levelEvent(null, 2001, blockPos, Block.getId(serverLevel.getBlockState(blockPos))); + + for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) { + LevelChunk levelChunk = ((CraftChunk) bukkitChunk).getHandle(); + levelChunk.getBlockEntities().values().stream() + .filter(blockEntity -> blockEntity instanceof SpawnerBlockEntity) + .forEach(blockEntity -> { + ((SpawnerBlockEntity) blockEntity).getSpawner().requiredPlayerRange = 16; + }); + + ChunkPos chunkPos = levelChunk.getPos(); + serverLevel.setChunkForced(chunkPos.x, chunkPos.z, false); + } + } + + @Override + public void updateSpawner(Location location, boolean reset) { + World bukkitWorld = location.getWorld(); + + if (bukkitWorld == null) + throw new IllegalArgumentException("Cannot remove loader in null world."); + + ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle(); + BlockPos blockPos = new BlockPos(location.getX(), location.getY(), location.getZ()); + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos); + if (blockEntity instanceof SpawnerBlockEntity spawnerBlockEntity) + spawnerBlockEntity.getSpawner().requiredPlayerRange = reset ? 16 : -1; + } + +} diff --git a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoader.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntity.java similarity index 61% rename from v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoader.java rename to v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntity.java index bb2e28a..aaefbb6 100644 --- a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoader.java +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntity.java @@ -1,17 +1,16 @@ -package com.bgsoftware.wildloaders.nms.v1_17_R1.loader; +package com.bgsoftware.wildloaders.nms.v117.loader; import com.bgsoftware.wildloaders.api.holograms.Hologram; import com.bgsoftware.wildloaders.api.loaders.ChunkLoader; import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader; import com.bgsoftware.wildloaders.loaders.WChunkLoader; -import com.bgsoftware.wildloaders.nms.v1_17_R1.EntityHolograms; -import com.bgsoftware.wildloaders.nms.v1_17_R1.NMSAdapter; -import net.minecraft.core.BlockPosition; -import net.minecraft.world.level.ChunkCoordIntPair; -import net.minecraft.world.level.World; +import com.bgsoftware.wildloaders.nms.v117.EntityHologram; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.TileEntity; -import net.minecraft.world.level.block.entity.TileEntityTypes; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; import java.util.ArrayList; import java.util.Collection; @@ -20,28 +19,32 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public final class TileEntityChunkLoader extends TileEntity implements ITileEntityChunkLoader { +public final class ChunkLoaderBlockEntity extends BlockEntity implements ITileEntityChunkLoader { - public static final Map tileEntityChunkLoaderMap = new HashMap<>(); + public static final Map chunkLoaderBlockEntityMap = new HashMap<>(); - public final List holograms = new ArrayList<>(); + public final List holograms = new ArrayList<>(); private final WChunkLoader chunkLoader; private final Block loaderBlock; - public final TileEntityChunkLoaderTicker ticker; + private final ChunkLoaderBlockEntityTicker ticker; + private final ServerLevel serverLevel; + private final BlockPos blockPos; private short currentTick = 20; private short daysAmount, hoursAmount, minutesAmount, secondsAmount; public boolean removed = false; - public TileEntityChunkLoader(ChunkLoader chunkLoader, World world, BlockPosition blockPosition) { - super(TileEntityTypes.v, blockPosition, world.getType(blockPosition)); + public ChunkLoaderBlockEntity(ChunkLoader chunkLoader, ServerLevel serverLevel, BlockPos blockPos) { + super(BlockEntityType.COMMAND_BLOCK, blockPos, serverLevel.getBlockState(blockPos)); this.chunkLoader = (WChunkLoader) chunkLoader; - this.ticker = new TileEntityChunkLoaderTicker(this); + this.ticker = new ChunkLoaderBlockEntityTicker(this); + this.blockPos = blockPos; + this.serverLevel = serverLevel; - setWorld(world); + setLevel(serverLevel); - loaderBlock = world.getType(blockPosition).getBlock(); + loaderBlock = serverLevel.getBlockState(blockPos).getBlock(); if (!this.chunkLoader.isInfinite()) { long timeLeft = chunkLoader.getTimeLeft(); @@ -58,16 +61,16 @@ public final class TileEntityChunkLoader extends TileEntity implements ITileEnti secondsAmount = (short) timeLeft; } - tileEntityChunkLoaderMap.put(ChunkCoordIntPair.pair(blockPosition.getX() >> 4, blockPosition.getZ() >> 4), this); + long chunkPosLong = ChunkPos.asLong(blockPos.getX() >> 4, blockPos.getZ() >> 4); + chunkLoaderBlockEntityMap.put(chunkPosLong, this); List hologramLines = this.chunkLoader.getHologramLines(); - double currentY = getPosition().getY() + 1; + double currentY = blockPos.getY() + 1; for (int i = hologramLines.size(); i > 0; i--) { - EntityHolograms hologram = new EntityHolograms(world, - getPosition().getX() + 0.5, currentY, getPosition().getZ() + 0.5); + EntityHologram hologram = new EntityHologram(serverLevel, blockPos.getX() + 0.5, currentY, blockPos.getZ() + 0.5); updateName(hologram, hologramLines.get(i - 1)); - world.addEntity(hologram); + serverLevel.addFreshEntity(hologram); currentY += 0.23; holograms.add(hologram); } @@ -79,8 +82,7 @@ public final class TileEntityChunkLoader extends TileEntity implements ITileEnti currentTick = 0; - assert this.n != null; - if (chunkLoader.isNotActive() || this.n.getType(getPosition()).getBlock() != loaderBlock) { + if (chunkLoader.isNotActive() || this.serverLevel.getBlockState(this.blockPos).getBlock() != loaderBlock) { chunkLoader.remove(); return; } @@ -92,7 +94,7 @@ public final class TileEntityChunkLoader extends TileEntity implements ITileEnti int hologramsAmount = holograms.size(); for (int i = hologramsAmount; i > 0; i--) { - EntityHolograms hologram = holograms.get(hologramsAmount - i); + EntityHologram hologram = holograms.get(hologramsAmount - i); updateName(hologram, hologramLines.get(i - 1)); } @@ -125,7 +127,11 @@ public final class TileEntityChunkLoader extends TileEntity implements ITileEnti return removed || super.isRemoved(); } - private void updateName(EntityHolograms hologram, String line) { + public ChunkLoaderBlockEntityTicker getTicker() { + return ticker; + } + + private void updateName(EntityHologram hologram, String line) { assert chunkLoader.getWhoPlaced().getName() != null; hologram.setHologramName(line .replace("{0}", chunkLoader.getWhoPlaced().getName()) diff --git a/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntityTicker.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntityTicker.java new file mode 100644 index 0000000..0bfc704 --- /dev/null +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/loader/ChunkLoaderBlockEntityTicker.java @@ -0,0 +1,30 @@ +package com.bgsoftware.wildloaders.nms.v117.loader; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.entity.TickingBlockEntity; + +public record ChunkLoaderBlockEntityTicker( + ChunkLoaderBlockEntity chunkLoaderBlockEntity) implements TickingBlockEntity { + + @Override + public void tick() { + chunkLoaderBlockEntity.tick(); + } + + @Override + public boolean isRemoved() { + return chunkLoaderBlockEntity.isRemoved(); + } + + @Override + public BlockPos getPos() { + return chunkLoaderBlockEntity.getBlockPos(); + } + + @Override + public String getType() { + return BlockEntityType.getKey(chunkLoaderBlockEntity.getType()) + ""; + } + +} diff --git a/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderNPCWrapper.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderNPCWrapper.java new file mode 100644 index 0000000..5977eac --- /dev/null +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderNPCWrapper.java @@ -0,0 +1,38 @@ +package com.bgsoftware.wildloaders.nms.v117.npc; + +import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class ChunkLoaderNPCWrapper implements ChunkLoaderNPC { + + private final ChunkLoaderPlayer chunkLoaderPlayer; + + public ChunkLoaderNPCWrapper(MinecraftServer minecraftServer, Location location, UUID uuid) { + this.chunkLoaderPlayer = new ChunkLoaderPlayer(minecraftServer, location, uuid); + } + + @Override + public UUID getUniqueId() { + return this.chunkLoaderPlayer.getUUID(); + } + + @Override + public void die() { + this.chunkLoaderPlayer.discard(); + } + + @Override + public Location getLocation() { + return getPlayer().getLocation(); + } + + @Override + public Player getPlayer() { + return this.chunkLoaderPlayer.getBukkitEntity(); + } + +} diff --git a/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderPlayer.java b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderPlayer.java new file mode 100644 index 0000000..45a750f --- /dev/null +++ b/v117/src/main/java/com/bgsoftware/wildloaders/nms/v117/npc/ChunkLoaderPlayer.java @@ -0,0 +1,140 @@ +package com.bgsoftware.wildloaders.nms.v117.npc; + +import com.bgsoftware.common.reflection.ReflectMethod; +import com.bgsoftware.wildloaders.handlers.NPCHandler; +import com.bgsoftware.wildloaders.npc.DummyChannel; +import com.mojang.authlib.GameProfile; +import net.minecraft.core.BlockPos; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.game.ServerboundChatPacket; +import net.minecraft.network.protocol.game.ServerboundContainerClickPacket; +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; +import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket; +import net.minecraft.network.protocol.game.ServerboundUseItemPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerPlayerGameMode; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.level.GameType; +import net.minecraft.world.phys.AABB; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; + +import java.util.UUID; + +public final class ChunkLoaderPlayer extends ServerPlayer { + + private static final ReflectMethod SET_GAMEMODE = new ReflectMethod<>(ServerPlayerGameMode.class, + 1, GameType.class, GameType.class); + + private final ServerLevel serverLevel; + private final AABB boundingBox; + + private boolean dieCall = false; + + public ChunkLoaderPlayer(MinecraftServer minecraftServer, Location location, UUID uuid) { + super(minecraftServer, ((CraftWorld) location.getWorld()).getHandle(), + new GameProfile(uuid, NPCHandler.getName(location.getWorld().getName()))); + + this.serverLevel = getLevel(); + this.boundingBox = new AABB(new BlockPos(location.getX(), location.getY(), location.getZ())); + + this.connection = new DummyServerGamePacketListenerImpl(minecraftServer, this); + + SET_GAMEMODE.invoke(this.gameMode, GameType.CREATIVE, null); + clientViewDistance = 1; + + fauxSleeping = true; + + spawnIn(this.serverLevel); + moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + + this.serverLevel.addNewPlayer(this); + + super.setBoundingBox(this.boundingBox); + } + + @Override + public AABB getBoundingBoxForCulling() { + return this.boundingBox; + } + + @Override + public void remove(RemovalReason removalReason) { + if (!dieCall) { + dieCall = true; + this.serverLevel.removePlayerImmediately(this, RemovalReason.UNLOADED_WITH_PLAYER); + dieCall = false; + } else { + super.remove(removalReason); + } + } + + public static class DummyConnection extends Connection { + + DummyConnection() { + super(PacketFlow.SERVERBOUND); + this.channel = new DummyChannel(); + this.address = null; + } + + } + + public static class DummyServerGamePacketListenerImpl extends ServerGamePacketListenerImpl { + + DummyServerGamePacketListenerImpl(MinecraftServer minecraftServer, ServerPlayer serverPlayer) { + super(minecraftServer, new DummyConnection(), serverPlayer); + } + + @Override + public void handleContainerClick(ServerboundContainerClickPacket containerClickPacket) { + // Do nothing. + } + + @Override + public void handleMovePlayer(ServerboundMovePlayerPacket movePlayerPacket) { + // Do nothing. + } + + @Override + public void handleSignUpdate(ServerboundSignUpdatePacket signUpdatePacket) { + // Do nothing. + } + + @Override + public void handlePlayerAction(ServerboundPlayerActionPacket playerActionPacket) { + // Do nothing. + } + + @Override + public void handleUseItem(ServerboundUseItemPacket useItemPacket) { + // Do nothing. + } + + @Override + public void handleSetCarriedItem(ServerboundSetCarriedItemPacket setCarriedItemPacket) { + // Do nothing. + } + + @Override + public void handleChat(ServerboundChatPacket chatPacket) { + // Do nothing. + } + + @Override + public void disconnect(String s) { + + } + + public void send(Packet packet) { + // Do nothing. + } + + } + +} diff --git a/v1_17_R1/build.gradle b/v1_17_R1/build.gradle deleted file mode 100644 index 20587f4..0000000 --- a/v1_17_R1/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -group 'v1_17_R1' - -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(16)) - } -} - -dependencies { - compileOnly "org.spigotmc:v1_17_R1-Paper:latest" - compileOnly project(":API") - compileOnly parent -} - -if (project.hasProperty('nms.compile_v1_17') && !Boolean.valueOf(project.findProperty("nms.compile_v1_17").toString())) { - project.tasks.all { task -> task.enabled = false } -} \ No newline at end of file diff --git a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/ChunkLoaderNPC.java b/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/ChunkLoaderNPC.java deleted file mode 100644 index b8d5245..0000000 --- a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/ChunkLoaderNPC.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.bgsoftware.wildloaders.nms.v1_17_R1; - -import com.bgsoftware.common.reflection.ReflectMethod; -import com.bgsoftware.wildloaders.handlers.NPCHandler; -import com.bgsoftware.wildloaders.npc.DummyChannel; -import com.mojang.authlib.GameProfile; -import net.minecraft.core.BlockPosition; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.protocol.EnumProtocolDirection; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.PacketPlayInBlockDig; -import net.minecraft.network.protocol.game.PacketPlayInBlockPlace; -import net.minecraft.network.protocol.game.PacketPlayInChat; -import net.minecraft.network.protocol.game.PacketPlayInFlying; -import net.minecraft.network.protocol.game.PacketPlayInHeldItemSlot; -import net.minecraft.network.protocol.game.PacketPlayInUpdateSign; -import net.minecraft.network.protocol.game.PacketPlayInWindowClick; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.server.level.PlayerInteractManager; -import net.minecraft.server.level.WorldServer; -import net.minecraft.server.network.PlayerConnection; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.EnumGamemode; -import net.minecraft.world.phys.AxisAlignedBB; -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.entity.Player; - -import java.util.UUID; - -public final class ChunkLoaderNPC extends EntityPlayer implements com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC { - - private static final ReflectMethod SET_GAMEMODE = new ReflectMethod<>(PlayerInteractManager.class, - 1, EnumGamemode.class, EnumGamemode.class); - - private final AxisAlignedBB boundingBox; - - private boolean dieCall = false; - - public ChunkLoaderNPC(MinecraftServer minecraftServer, Location location, UUID uuid) { - super(minecraftServer, ((CraftWorld) location.getWorld()).getHandle(), - new GameProfile(uuid, NPCHandler.getName(location.getWorld().getName()))); - - this.boundingBox = new AxisAlignedBB(new BlockPosition(location.getX(), location.getY(), location.getZ())); - - this.b = new DummyPlayerConnection(minecraftServer, this); - - SET_GAMEMODE.invoke(this.d, EnumGamemode.b, null); - clientViewDistance = 1; - - fauxSleeping = true; - - spawnIn(getWorld()); - setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - ((WorldServer) getWorld()).addPlayerJoin(this); - - super.a(this.boundingBox); - } - - @Override - public UUID getUniqueId() { - return super.getUniqueID(); - } - - @Override - public AxisAlignedBB cs() { - return this.boundingBox; - } - - @Override - public void a(Entity.RemovalReason removalReason) { - if (!dieCall) { - dieCall = true; - removePlayer(getWorldServer(), this); - dieCall = false; - } else { - super.a(removalReason); - } - } - - @Override - public Location getLocation() { - return getBukkitEntity().getLocation(); - } - - @Override - public Player getPlayer() { - return getBukkitEntity(); - } - - private static void removePlayer(WorldServer worldServer, EntityPlayer entityPlayer) { - worldServer.a(entityPlayer, RemovalReason.d); - } - - public static class DummyNetworkManager extends NetworkManager { - - DummyNetworkManager() { - super(EnumProtocolDirection.a); - this.k = new DummyChannel(); - this.l = null; - } - - } - - public static class DummyPlayerConnection extends PlayerConnection { - - DummyPlayerConnection(MinecraftServer minecraftServer, EntityPlayer entityPlayer) { - super(minecraftServer, new DummyNetworkManager(), entityPlayer); - } - - public void a(PacketPlayInWindowClick packetPlayInWindowClick) { - - } - - public void a(PacketPlayInFlying packetPlayInFlying) { - - } - - public void a(PacketPlayInUpdateSign packetPlayInUpdateSign) { - - } - - public void a(PacketPlayInBlockDig packetPlayInBlockDig) { - - } - - public void a(PacketPlayInBlockPlace packetPlayInBlockPlace) { - - } - - public void disconnect(String s) { - - } - - public void a(PacketPlayInHeldItemSlot packetPlayInHeldItemSlot) { - - } - - public void a(PacketPlayInChat packetPlayInChat) { - - } - - public void sendPacket(Packet packet) { - - } - - } - -} diff --git a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/NMSAdapter.java b/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/NMSAdapter.java deleted file mode 100644 index aa84d90..0000000 --- a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/NMSAdapter.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.bgsoftware.wildloaders.nms.v1_17_R1; - -import com.bgsoftware.common.reflection.ReflectMethod; -import com.bgsoftware.wildloaders.WildLoadersPlugin; -import com.bgsoftware.wildloaders.api.loaders.ChunkLoader; -import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader; -import com.bgsoftware.wildloaders.nms.v1_17_R1.loader.TileEntityChunkLoader; -import net.minecraft.core.BlockPosition; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagLong; -import net.minecraft.nbt.NBTTagString; -import net.minecraft.server.level.WorldServer; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.ChunkCoordIntPair; -import net.minecraft.world.level.World; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.TickingBlockEntity; -import net.minecraft.world.level.block.entity.TileEntity; -import net.minecraft.world.level.block.entity.TileEntityMobSpawner; -import net.minecraft.world.level.block.state.IBlockData; -import net.minecraft.world.level.chunk.Chunk; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers; - -import java.util.UUID; - -public final class NMSAdapter implements com.bgsoftware.wildloaders.nms.NMSAdapter { - - @Override - public String getTag(org.bukkit.inventory.ItemStack itemStack, String key, String def) { - ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); - NBTTagCompound tagCompound = nmsItem.getOrCreateTag(); - - if (!tagCompound.hasKeyOfType(key, 8)) - return def; - - return tagCompound.getString(key); - } - - @Override - public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack itemStack, String key, String value) { - ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); - NBTTagCompound tagCompound = nmsItem.getOrCreateTag(); - - tagCompound.set(key, NBTTagString.a(value)); - - nmsItem.setTag(tagCompound); - - return CraftItemStack.asBukkitCopy(nmsItem); - } - - @Override - public long getTag(org.bukkit.inventory.ItemStack itemStack, String key, long def) { - ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); - NBTTagCompound tagCompound = nmsItem.getOrCreateTag(); - - if (!tagCompound.hasKeyOfType(key, 4)) - return def; - - return tagCompound.getLong(key); - } - - @Override - public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack itemStack, String key, long value) { - ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); - NBTTagCompound tagCompound = nmsItem.getOrCreateTag(); - - tagCompound.set(key, NBTTagLong.a(value)); - - nmsItem.setTag(tagCompound); - - return CraftItemStack.asBukkitCopy(nmsItem); - } - - @Override - public org.bukkit.inventory.ItemStack getPlayerSkull(org.bukkit.inventory.ItemStack itemStack, String texture) { - ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack); - - NBTTagCompound nbtTagCompound = nmsItem.getOrCreateTag(); - - NBTTagCompound skullOwner = nbtTagCompound.hasKey("SkullOwner") ? nbtTagCompound.getCompound("SkullOwner") : new NBTTagCompound(); - - NBTTagCompound properties = new NBTTagCompound(); - - NBTTagList textures = new NBTTagList(); - NBTTagCompound signature = new NBTTagCompound(); - signature.setString("Value", texture); - textures.add(signature); - - properties.set("textures", textures); - - skullOwner.set("Properties", properties); - skullOwner.setString("Id", UUID.randomUUID().toString()); - - nbtTagCompound.set("SkullOwner", skullOwner); - - nmsItem.setTag(nbtTagCompound); - - return CraftItemStack.asBukkitCopy(nmsItem); - } - - @Override - public com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC createNPC(Location location, UUID uuid) { - return new ChunkLoaderNPC(((CraftServer) Bukkit.getServer()).getServer(), location, uuid); - } - - @Override - public ITileEntityChunkLoader createLoader(ChunkLoader chunkLoader) { - Location loaderLoc = chunkLoader.getLocation(); - assert loaderLoc.getWorld() != null; - WorldServer world = ((CraftWorld) loaderLoc.getWorld()).getHandle(); - BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ()); - - TileEntityChunkLoader tileEntityChunkLoader = new TileEntityChunkLoader(chunkLoader, world, blockPosition); - world.a(tileEntityChunkLoader.ticker); - - for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) { - Chunk chunk = ((CraftChunk) bukkitChunk).getHandle(); - chunk.l.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner) - .forEach(tileEntity -> ((TileEntityMobSpawner) tileEntity).getSpawner().n = -1); - - world.setForceLoaded(chunk.getPos().b, chunk.getPos().c, true); - } - - return tileEntityChunkLoader; - } - - @Override - public void removeLoader(ChunkLoader chunkLoader, boolean spawnParticle) { - Location loaderLoc = chunkLoader.getLocation(); - assert loaderLoc.getWorld() != null; - WorldServer world = ((CraftWorld) loaderLoc.getWorld()).getHandle(); - BlockPosition blockPosition = new BlockPosition(loaderLoc.getX(), loaderLoc.getY(), loaderLoc.getZ()); - - long tileEntityLong = ChunkCoordIntPair.pair(blockPosition.getX() >> 4, blockPosition.getZ() >> 4); - TileEntityChunkLoader tileEntityChunkLoader = TileEntityChunkLoader.tileEntityChunkLoaderMap.remove(tileEntityLong); - if (tileEntityChunkLoader != null) { - tileEntityChunkLoader.holograms.forEach(EntityHolograms::removeHologram); - tileEntityChunkLoader.removed = true; - } - - if (spawnParticle) - world.a(null, 2001, blockPosition, Block.getCombinedId(world.getType(blockPosition))); - - for (org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) { - Chunk chunk = ((CraftChunk) bukkitChunk).getHandle(); - chunk.l.values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner) - .forEach(tileEntity -> ((TileEntityMobSpawner) tileEntity).getSpawner().n = 16); - - world.setForceLoaded(chunk.getPos().b, chunk.getPos().c, false); - } - } - - @Override - public void updateSpawner(Location location, boolean reset) { - assert location.getWorld() != null; - World world = ((CraftWorld) location.getWorld()).getHandle(); - - BlockPosition blockPosition = new BlockPosition(location.getX(), location.getY(), location.getZ()); - IBlockData blockData = world.getType(blockPosition); - TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) world.getTileEntity(blockPosition); - - if (mobSpawner == null) - return; - - mobSpawner.getSpawner().n = reset ? 16 : -1; - } - -} diff --git a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoaderTicker.java b/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoaderTicker.java deleted file mode 100644 index d01867a..0000000 --- a/v1_17_R1/src/main/java/com/bgsoftware/wildloaders/nms/v1_17_R1/loader/TileEntityChunkLoaderTicker.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.bgsoftware.wildloaders.nms.v1_17_R1.loader; - -import net.minecraft.core.BlockPosition; -import net.minecraft.world.level.block.entity.TickingBlockEntity; -import net.minecraft.world.level.block.entity.TileEntityTypes; - -public record TileEntityChunkLoaderTicker(TileEntityChunkLoader tileEntityChunkLoader) implements TickingBlockEntity { - - @Override - public void a() { - tileEntityChunkLoader.tick(); - } - - @Override - public boolean b() { - return tileEntityChunkLoader.isRemoved(); - } - - @Override - public BlockPosition c() { - return tileEntityChunkLoader.getPosition(); - } - - @Override - public String d() { - return TileEntityTypes.a(tileEntityChunkLoader.getTileType()) + ""; - } -}