mirror of
https://github.com/BG-Software-LLC/WildLoaders.git
synced 2024-11-24 12:15:28 +01:00
Added 1.19 support (#46)
* Implemented nms support for 1.19 * Fixed 1.19 is not listed as a valid server version (#44)
This commit is contained in:
parent
d7d7a40b9a
commit
f30e43fd5f
@ -15,4 +15,5 @@ include 'v1_18_R1'
|
||||
include 'Hook_EpicSpawners7'
|
||||
include 'v1_18_R2'
|
||||
include 'Hook_Lands'
|
||||
include 'v1_19_R1'
|
||||
|
||||
|
@ -15,7 +15,8 @@ public enum ServerVersion {
|
||||
v1_15(115),
|
||||
v1_16(116),
|
||||
v1_17(117),
|
||||
v1_18(118);
|
||||
v1_18(118),
|
||||
v1_19(119);
|
||||
|
||||
private static final ServerVersion currentVersion;
|
||||
private static final String bukkitVersion;
|
||||
|
36
v1_19_R1/build.gradle
Normal file
36
v1_19_R1/build.gradle
Normal file
@ -0,0 +1,36 @@
|
||||
group 'v1_19_R1'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url "https://papermc.io/repo/repository/maven-public/" }
|
||||
maven { url "https://libraries.minecraft.net/" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly "org.spigotmc:v1_19_R1-Paper:git-02b5ec4"
|
||||
|
||||
compileOnly 'io.papermc.paper:paper-api:1.19-R0.1-SNAPSHOT'
|
||||
|
||||
compileOnly 'com.mojang:authlib:3.2.38'
|
||||
compileOnly 'com.mojang:datafixerupper:4.0.26'
|
||||
compileOnly 'com.mojang:brigadier:1.0.18'
|
||||
compileOnly 'com.google.guava:guava:31.1-jre'
|
||||
compileOnly 'com.google.code.gson:gson:2.9.0'
|
||||
compileOnly 'net.kyori:adventure-key:4.10.1'
|
||||
compileOnly 'net.kyori:examination-api:1.3.0'
|
||||
compileOnly 'net.kyori:adventure-api:4.10.1'
|
||||
compileOnly 'net.md-5:bungeecord-chat:1.16-R0.4'
|
||||
compileOnly 'io.netty:netty-all:4.1.77.Final'
|
||||
|
||||
compileOnly project(":API")
|
||||
compileOnly parent
|
||||
}
|
||||
|
||||
if (project.hasProperty('nms.compile_v1_19') && !Boolean.valueOf(project.findProperty("nms.compile_v1_19").toString())) {
|
||||
project.tasks.all { task -> task.enabled = false }
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.bgsoftware.wildloaders.nms;
|
||||
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
||||
import com.bgsoftware.wildloaders.npc.DummyChannel;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
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.WorldServer;
|
||||
import net.minecraft.server.network.PlayerConnection;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
import net.minecraft.world.phys.AxisAlignedBB;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.bgsoftware.wildloaders.nms.NMSMappings_v1_19_R1.*;
|
||||
|
||||
public final class ChunkLoaderNPC_v1_19_R1 extends EntityPlayer implements ChunkLoaderNPC {
|
||||
|
||||
private static final AxisAlignedBB EMPTY_BOUND = new AxisAlignedBB(0D, 0D, 0D, 0D, 0D, 0D);
|
||||
|
||||
private boolean dieCall = false;
|
||||
|
||||
public ChunkLoaderNPC_v1_19_R1(MinecraftServer minecraftServer, Location location, UUID uuid) {
|
||||
super(minecraftServer, ((CraftWorld) location.getWorld()).getHandle(),
|
||||
new GameProfile(uuid, NPCHandler.getName(location.getWorld().getName())), null);
|
||||
|
||||
this.b = new DummyPlayerConnection(minecraftServer, this);
|
||||
|
||||
NMSMappings_v1_19_R1.setGameModeForPlayer(this.d, EnumGamemode.b);
|
||||
clientViewDistance = 1;
|
||||
|
||||
fauxSleeping = true;
|
||||
|
||||
spawnIn(getWorld(this));
|
||||
moveTo(this, location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
addNewPlayer(getLevel(this), this);
|
||||
|
||||
super.a(EMPTY_BOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return super.cp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
ah();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB cA() {
|
||||
return EMPTY_BOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(RemovalReason removalReason) {
|
||||
if (!dieCall) {
|
||||
dieCall = true;
|
||||
removePlayer(getLevel(this), this);
|
||||
dieCall = false;
|
||||
} else {
|
||||
super.a(removalReason);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return getBukkitEntity().getLocation();
|
||||
}
|
||||
|
||||
private static void removePlayer(WorldServer worldServer, EntityPlayer entityPlayer) {
|
||||
worldServer.a(entityPlayer, RemovalReason.d);
|
||||
}
|
||||
|
||||
public static class DummyNetworkManager extends NetworkManager {
|
||||
|
||||
DummyNetworkManager() {
|
||||
super(EnumProtocolDirection.a);
|
||||
this.m = new DummyChannel();
|
||||
this.n = 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 a(Packet<?> packet) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package com.bgsoftware.wildloaders.nms;
|
||||
|
||||
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.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.EnumItemSlot;
|
||||
import net.minecraft.world.entity.decoration.EntityArmorStand;
|
||||
import net.minecraft.world.entity.player.EntityHuman;
|
||||
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 org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftArmorStand;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.util.CraftChatMessage;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class EntityHolograms_v1_19_R1 extends EntityArmorStand implements Hologram {
|
||||
|
||||
private static final AxisAlignedBB EMPTY_BOUND = new AxisAlignedBB(0D, 0D, 0D, 0D, 0D, 0D);
|
||||
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
public EntityHolograms_v1_19_R1(World world, double x, double y, double z){
|
||||
super(world, x, y, z);
|
||||
j(true); // Invisible
|
||||
a(true); // Small
|
||||
r(false); // Arms
|
||||
e(true); // No Gravity
|
||||
s(true); // Base Plate
|
||||
t(true); // Marker
|
||||
super.collides = false;
|
||||
super.n(true); // Custom name visible
|
||||
super.a(EMPTY_BOUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHologramName(String name) {
|
||||
super.b(CraftChatMessage.fromStringOrNull(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeHologram() {
|
||||
super.a(RemovalReason.b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.entity.Entity getEntity() {
|
||||
return getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void k() {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inactiveTick() {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b(NBTTagCompound nbttagcompound) {
|
||||
// Do not save NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean d(NBTTagCompound nbttagcompound) {
|
||||
// Do not save NBT.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound f(NBTTagCompound nbttagcompound) {
|
||||
// Do not save NBT.
|
||||
return nbttagcompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(NBTTagCompound nbttagcompound) {
|
||||
// Do not load NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g(NBTTagCompound nbttagcompound) {
|
||||
// Do not load NBT.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean b(DamageSource source) {
|
||||
/*
|
||||
* The field Entity.invulnerable is private.
|
||||
* It's only used while saving NBTTags, but since the entity would be killed
|
||||
* on chunk unload, we prefer to override isInvulnerable().
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bm() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(IChatBaseComponent ichatbasecomponent) {
|
||||
// Locks the custom name.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void n(boolean flag) {
|
||||
// Locks the custom name.
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumInteractionResult a(EntityHuman human, Vec3D vec3d, EnumHand enumhand) {
|
||||
// Prevent stand being equipped
|
||||
return EnumInteractionResult.d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack, boolean flag) {
|
||||
// Prevent stand being equipped
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB cA() {
|
||||
return EMPTY_BOUND;
|
||||
}
|
||||
|
||||
public void forceSetBoundingBox(AxisAlignedBB boundingBox) {
|
||||
super.a(boundingBox);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(SoundEffect soundeffect, float f, float f1) {
|
||||
// Remove sounds.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(RemovalReason entity_removalreason) {
|
||||
// Prevent being killed.
|
||||
}
|
||||
|
||||
@Override
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (bukkitEntity == null) {
|
||||
bukkitEntity = new CraftArmorStand((CraftServer) Bukkit.getServer(), this);
|
||||
}
|
||||
return bukkitEntity;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,333 @@
|
||||
package com.bgsoftware.wildloaders.nms;
|
||||
|
||||
import com.bgsoftware.common.reflection.ReflectMethod;
|
||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||
import com.bgsoftware.wildloaders.api.holograms.Hologram;
|
||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||
import com.bgsoftware.wildloaders.loaders.ITileEntityChunkLoader;
|
||||
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||
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.entity.TileEntityTypes;
|
||||
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_19_R1.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.bgsoftware.wildloaders.nms.NMSMappings_v1_19_R1.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class NMSAdapter_v1_19_R1 implements NMSAdapter {
|
||||
|
||||
private static final WildLoadersPlugin plugin = WildLoadersPlugin.getPlugin();
|
||||
|
||||
private static final ReflectMethod<TickingBlockEntity> CREATE_TICKING_BLOCK = new ReflectMethod<>(
|
||||
Chunk.class, "a", TileEntity.class, BlockEntityTicker.class);
|
||||
|
||||
@Override
|
||||
public String getTag(org.bukkit.inventory.ItemStack itemStack, String key, String def) {
|
||||
ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack);
|
||||
NBTTagCompound tagCompound = getOrCreateTag(nmsItem);
|
||||
|
||||
if(!contains(tagCompound, key, 8))
|
||||
return def;
|
||||
|
||||
return getString(tagCompound, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack itemStack, String key, String value) {
|
||||
ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack);
|
||||
NBTTagCompound tagCompound = getOrCreateTag(nmsItem);
|
||||
|
||||
put(tagCompound, key, NBTTagString.a(value));
|
||||
|
||||
return CraftItemStack.asBukkitCopy(nmsItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTag(org.bukkit.inventory.ItemStack itemStack, String key, long def) {
|
||||
ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack);
|
||||
NBTTagCompound tagCompound = getOrCreateTag(nmsItem);
|
||||
|
||||
if(!contains(tagCompound, key, 4))
|
||||
return def;
|
||||
|
||||
return getLong(tagCompound, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack setTag(org.bukkit.inventory.ItemStack itemStack, String key, long value) {
|
||||
ItemStack nmsItem = CraftItemStack.asNMSCopy(itemStack);
|
||||
NBTTagCompound tagCompound = getOrCreateTag(nmsItem);
|
||||
|
||||
put(tagCompound, key, NBTTagLong.a(value));
|
||||
|
||||
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 = getOrCreateTag(nmsItem);
|
||||
|
||||
NBTTagCompound skullOwner = NMSMappings_v1_19_R1.contains(nbtTagCompound, "SkullOwner") ?
|
||||
getCompound(nbtTagCompound, "SkullOwner") : new NBTTagCompound();
|
||||
|
||||
NBTTagCompound properties = new NBTTagCompound();
|
||||
|
||||
NBTTagList textures = new NBTTagList();
|
||||
NBTTagCompound signature = new NBTTagCompound();
|
||||
putString(signature, "Value", texture);
|
||||
textures.add(signature);
|
||||
|
||||
put(properties, "textures", textures);
|
||||
|
||||
put(skullOwner, "Properties", properties);
|
||||
putString(skullOwner,"Id", UUID.randomUUID().toString());
|
||||
|
||||
put(nbtTagCompound, "SkullOwner", skullOwner);
|
||||
|
||||
return CraftItemStack.asBukkitCopy(nmsItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkLoaderNPC createNPC(Location location, UUID uuid) {
|
||||
return new ChunkLoaderNPC_v1_19_R1(((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();
|
||||
getBlockEntities(chunk).values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner)
|
||||
.forEach(tileEntity -> getSpawner((TileEntityMobSpawner) tileEntity).m = -1);
|
||||
|
||||
ChunkCoordIntPair chunkCoords = getPos(chunk);
|
||||
|
||||
setChunkForced(world, chunkCoords.c, chunkCoords.d, 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.c(getX(blockPosition) >> 4, getZ(blockPosition) >> 4);
|
||||
TileEntityChunkLoader tileEntityChunkLoader = TileEntityChunkLoader.tileEntityChunkLoaderMap.remove(tileEntityLong);
|
||||
if(tileEntityChunkLoader != null) {
|
||||
tileEntityChunkLoader.holograms.forEach(EntityHolograms_v1_19_R1::removeHologram);
|
||||
tileEntityChunkLoader.removed = true;
|
||||
}
|
||||
|
||||
if(spawnParticle)
|
||||
world.a(null, 2001, blockPosition, getId(getBlockState(world, blockPosition)));
|
||||
|
||||
for(org.bukkit.Chunk bukkitChunk : chunkLoader.getLoadedChunks()) {
|
||||
Chunk chunk = ((CraftChunk) bukkitChunk).getHandle();
|
||||
getBlockEntities(chunk).values().stream().filter(tileEntity -> tileEntity instanceof TileEntityMobSpawner)
|
||||
.forEach(tileEntity -> getSpawner((TileEntityMobSpawner) tileEntity).m = 16);
|
||||
|
||||
ChunkCoordIntPair chunkCoords = getPos(chunk);
|
||||
|
||||
setChunkForced(world, chunkCoords.c, chunkCoords.d, 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 = getBlockState(world, blockPosition);
|
||||
TileEntityMobSpawner mobSpawner = (TileEntityMobSpawner) getBlockEntity(world, blockPosition);
|
||||
|
||||
if(mobSpawner == null)
|
||||
return;
|
||||
|
||||
getSpawner(mobSpawner).m = reset ? 16 : -1;
|
||||
}
|
||||
|
||||
private static final class TileEntityChunkLoader extends TileEntity implements ITileEntityChunkLoader {
|
||||
|
||||
private static final Map<Long, TileEntityChunkLoader> tileEntityChunkLoaderMap = new HashMap<>();
|
||||
|
||||
private final List<EntityHolograms_v1_19_R1> holograms = new ArrayList<>();
|
||||
private final WChunkLoader chunkLoader;
|
||||
private final Block loaderBlock;
|
||||
private final TileEntityChunkLoaderTicker ticker;
|
||||
|
||||
private short currentTick = 20;
|
||||
private short daysAmount, hoursAmount, minutesAmount, secondsAmount;
|
||||
private boolean removed = false;
|
||||
|
||||
TileEntityChunkLoader(ChunkLoader chunkLoader, World world, BlockPosition blockPosition){
|
||||
super(TileEntityTypes.v, blockPosition, getBlockState(world, blockPosition));
|
||||
|
||||
this.chunkLoader = (WChunkLoader) chunkLoader;
|
||||
this.ticker = new TileEntityChunkLoaderTicker(this);
|
||||
|
||||
a(world);
|
||||
|
||||
loaderBlock = getBlock(getBlockState(world, blockPosition));
|
||||
|
||||
if(!this.chunkLoader.isInfinite()) {
|
||||
long timeLeft = chunkLoader.getTimeLeft();
|
||||
|
||||
daysAmount = (short) (timeLeft / 86400);
|
||||
timeLeft = timeLeft % 86400;
|
||||
|
||||
hoursAmount = (short) (timeLeft / 3600);
|
||||
timeLeft = timeLeft % 3600;
|
||||
|
||||
minutesAmount = (short) (timeLeft / 60);
|
||||
timeLeft = timeLeft % 60;
|
||||
|
||||
secondsAmount = (short) timeLeft;
|
||||
}
|
||||
|
||||
tileEntityChunkLoaderMap.put(ChunkCoordIntPair.c(getX(blockPosition) >> 4, getZ(blockPosition) >> 4), this);
|
||||
|
||||
List<String> hologramLines = this.chunkLoader.getHologramLines();
|
||||
|
||||
double currentY = getY(getBlockPos(this)) + 1;
|
||||
for(int i = hologramLines.size(); i > 0; i--){
|
||||
EntityHolograms_v1_19_R1 hologram = new EntityHolograms_v1_19_R1(world,
|
||||
getX(getBlockPos(this)) + 0.5, currentY, getZ(getBlockPos(this)) + 0.5);
|
||||
updateName(hologram, hologramLines.get(i - 1));
|
||||
addFreshEntity(world, hologram);
|
||||
currentY += 0.23;
|
||||
holograms.add(hologram);
|
||||
}
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if(removed || ++currentTick <= 20)
|
||||
return;
|
||||
|
||||
currentTick = 0;
|
||||
|
||||
assert this.n != null;
|
||||
if(chunkLoader.isNotActive() || getBlock(getBlockState(this.n, getBlockPos(this))) != loaderBlock){
|
||||
chunkLoader.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if(chunkLoader.isInfinite())
|
||||
return;
|
||||
|
||||
List<String> hologramLines = chunkLoader.getHologramLines();
|
||||
|
||||
int hologramsAmount = holograms.size();
|
||||
for (int i = hologramsAmount; i > 0; i--) {
|
||||
EntityHolograms_v1_19_R1 hologram = holograms.get(hologramsAmount - i);
|
||||
updateName(hologram, hologramLines.get(i - 1));
|
||||
}
|
||||
|
||||
chunkLoader.tick();
|
||||
|
||||
if(!removed) {
|
||||
secondsAmount--;
|
||||
if (secondsAmount < 0) {
|
||||
secondsAmount = 59;
|
||||
minutesAmount--;
|
||||
if (minutesAmount < 0) {
|
||||
minutesAmount = 59;
|
||||
hoursAmount--;
|
||||
if (hoursAmount < 0) {
|
||||
hoursAmount = 23;
|
||||
daysAmount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Hologram> getHolograms() {
|
||||
return Collections.unmodifiableList(holograms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean r() {
|
||||
return removed || super.r();
|
||||
}
|
||||
|
||||
private void updateName(EntityHolograms_v1_19_R1 hologram, String line){
|
||||
assert chunkLoader.getWhoPlaced().getName() != null;
|
||||
hologram.setHologramName(line
|
||||
.replace("{0}", chunkLoader.getWhoPlaced().getName())
|
||||
.replace("{1}", daysAmount + "")
|
||||
.replace("{2}", hoursAmount + "")
|
||||
.replace("{3}", minutesAmount + "")
|
||||
.replace("{4}", secondsAmount + "")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private record TileEntityChunkLoaderTicker(
|
||||
TileEntityChunkLoader tileEntityChunkLoader) implements TickingBlockEntity {
|
||||
|
||||
@Override
|
||||
public void a() {
|
||||
tileEntityChunkLoader.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean b() {
|
||||
return tileEntityChunkLoader.r();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosition c() {
|
||||
return getBlockPos(tileEntityChunkLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String d() {
|
||||
return TileEntityTypes.a(getType(tileEntityChunkLoader)) + "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.bgsoftware.wildloaders.nms;
|
||||
|
||||
import com.bgsoftware.common.reflection.ReflectMethod;
|
||||
import net.minecraft.core.BaseBlockPosition;
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.server.level.PlayerInteractManager;
|
||||
import net.minecraft.server.level.WorldServer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.ChunkCoordIntPair;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
import net.minecraft.world.level.IWorldWriter;
|
||||
import net.minecraft.world.level.MobSpawnerAbstract;
|
||||
import net.minecraft.world.level.World;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.TileEntity;
|
||||
import net.minecraft.world.level.block.entity.TileEntityMobSpawner;
|
||||
import net.minecraft.world.level.block.entity.TileEntityTypes;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
import net.minecraft.world.level.chunk.IChunkAccess;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public final class NMSMappings_v1_19_R1 {
|
||||
|
||||
private static final ReflectMethod<Void> SET_GAMEMODE = new ReflectMethod<>(PlayerInteractManager.class,
|
||||
1, EnumGamemode.class, EnumGamemode.class);
|
||||
|
||||
private NMSMappings_v1_19_R1() {
|
||||
|
||||
}
|
||||
|
||||
public static NBTTagCompound getOrCreateTag(ItemStack itemStack) {
|
||||
return itemStack.v();
|
||||
}
|
||||
|
||||
public static boolean contains(NBTTagCompound nbtTagCompound, String key, int type) {
|
||||
return nbtTagCompound.b(key, type);
|
||||
}
|
||||
|
||||
public static String getString(NBTTagCompound nbtTagCompound, String key) {
|
||||
return nbtTagCompound.l(key);
|
||||
}
|
||||
|
||||
public static void put(NBTTagCompound nbtTagCompound, String key, NBTBase nbtBase) {
|
||||
nbtTagCompound.a(key, nbtBase);
|
||||
}
|
||||
|
||||
public static long getLong(NBTTagCompound nbtTagCompound, String key) {
|
||||
return nbtTagCompound.i(key);
|
||||
}
|
||||
|
||||
public static boolean contains(NBTTagCompound nbtTagCompound, String key) {
|
||||
return nbtTagCompound.e(key);
|
||||
}
|
||||
|
||||
public static NBTTagCompound getCompound(NBTTagCompound nbtTagCompound, String key) {
|
||||
return nbtTagCompound.p(key);
|
||||
}
|
||||
|
||||
public static void putString(NBTTagCompound nbtTagCompound, String key, String value) {
|
||||
nbtTagCompound.a(key, value);
|
||||
}
|
||||
|
||||
public static Map<BlockPosition, TileEntity> getBlockEntities(IChunkAccess chunkAccess) {
|
||||
return chunkAccess.i;
|
||||
}
|
||||
|
||||
public static ChunkCoordIntPair getPos(IChunkAccess chunk) {
|
||||
return chunk.f();
|
||||
}
|
||||
|
||||
public static MobSpawnerAbstract getSpawner(TileEntityMobSpawner tileEntityMobSpawner) {
|
||||
return tileEntityMobSpawner.d();
|
||||
}
|
||||
|
||||
public static void setChunkForced(WorldServer worldServer, int chunkX, int chunkZ, boolean load) {
|
||||
worldServer.a(chunkX, chunkZ, load);
|
||||
}
|
||||
|
||||
public static void addNewPlayer(WorldServer worldServer, EntityPlayer entityPlayer) {
|
||||
worldServer.c(entityPlayer);
|
||||
}
|
||||
|
||||
public static int getId(IBlockData blockData) {
|
||||
return Block.i(blockData);
|
||||
}
|
||||
|
||||
public static Block getBlock(IBlockData blockData) {
|
||||
return blockData.b();
|
||||
}
|
||||
|
||||
public static int getX(BaseBlockPosition baseBlockPosition) {
|
||||
return baseBlockPosition.u();
|
||||
}
|
||||
|
||||
public static int getY(BaseBlockPosition baseBlockPosition) {
|
||||
return baseBlockPosition.v();
|
||||
}
|
||||
|
||||
public static int getZ(BaseBlockPosition baseBlockPosition) {
|
||||
return baseBlockPosition.w();
|
||||
}
|
||||
|
||||
public static IBlockData getBlockState(World world, BlockPosition blockPosition) {
|
||||
return world.a_(blockPosition);
|
||||
}
|
||||
|
||||
public static TileEntity getBlockEntity(World world, BlockPosition blockPosition) {
|
||||
return world.c_(blockPosition);
|
||||
}
|
||||
|
||||
public static void addFreshEntity(IWorldWriter worldWriter, Entity entity) {
|
||||
worldWriter.b(entity);
|
||||
}
|
||||
|
||||
public static BlockPosition getBlockPos(TileEntity tileEntity) {
|
||||
return tileEntity.p();
|
||||
}
|
||||
|
||||
public static TileEntityTypes<?> getType(TileEntity tileEntity) {
|
||||
return tileEntity.v();
|
||||
}
|
||||
|
||||
public static void setGameModeForPlayer(PlayerInteractManager playerInteractManager, EnumGamemode gamemode) {
|
||||
SET_GAMEMODE.invoke(playerInteractManager, gamemode, null);
|
||||
}
|
||||
|
||||
public static World getWorld(Entity entity) {
|
||||
return entity.W();
|
||||
}
|
||||
|
||||
public static void moveTo(Entity entity, double x, double y, double z, float yaw, float pitch) {
|
||||
entity.b(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
public static WorldServer getLevel(EntityPlayer entityPlayer) {
|
||||
return entityPlayer.x();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user