From 39553af0cbd36a69887f2c2290f395ee60b477d4 Mon Sep 17 00:00:00 2001 From: Brian <48810871+MrBsng@users.noreply.github.com> Date: Fri, 3 May 2024 01:08:28 -0700 Subject: [PATCH] 2.0.1 - Adds Minecraft Version Check for animating heads - ReIntroduce the Geyser Event code that I had taken out before in hindsight. Accurately animate when joining server! - ToDo: Dimension Switch and Respawns are still inaccurate. --- pom.xml | 2 +- .../java/com/tbyt/AnimateHeadsForGeyser.java | 68 +++++++------------ src/main/java/com/tbyt/BedrockEvents.java | 32 +++++++++ src/main/java/com/tbyt/BedrockParity.java | 59 +++++++--------- 4 files changed, 80 insertions(+), 81 deletions(-) create mode 100644 src/main/java/com/tbyt/BedrockEvents.java diff --git a/pom.xml b/pom.xml index 4502344..49b2024 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.tbyt bedrockparity - 2.0.0 + 2.0.1 1.8 diff --git a/src/main/java/com/tbyt/AnimateHeadsForGeyser.java b/src/main/java/com/tbyt/AnimateHeadsForGeyser.java index 1828768..54e47c3 100644 --- a/src/main/java/com/tbyt/AnimateHeadsForGeyser.java +++ b/src/main/java/com/tbyt/AnimateHeadsForGeyser.java @@ -1,13 +1,6 @@ package com.tbyt; -//import java.io.ByteArrayOutputStream; -//import java.io.IOException; -//import java.io.ObjectOutputStream; import java.util.ArrayList; -//import java.util.Collection; -//import java.util.Iterator; -//import java.util.LinkedHashMap; - import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -19,18 +12,17 @@ import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.plugin.Plugin; +import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket; import org.geysermc.api.Geyser; +import org.geysermc.api.connection.Connection; import org.geysermc.floodgate.api.FloodgateApi; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.floodgate.api.player.FloodgatePlayer; - -//import com.google.gson.Gson; -//import com.google.gson.JsonElement; +import org.geysermc.geyser.api.connection.GeyserConnection; /* * Made by TBYT @@ -43,8 +35,10 @@ public class AnimateHeadsForGeyser implements Listener { private ArrayList headsToAnimate = new ArrayList(); private ArrayList animatedHeads = new ArrayList(); private int radius; + private GeyserConnection playerConn; - public AnimateHeadsForGeyser(Plugin plugin, int animateHeadBlockDistance) { + public AnimateHeadsForGeyser(Plugin plugin, @NonNull GeyserConnection playerConn, int animateHeadBlockDistance) { + this.playerConn = playerConn; this.plugin = plugin; radius = animateHeadBlockDistance; } @@ -54,8 +48,8 @@ public void geyserPlayerDimensionSwitch(PlayerChangedWorldEvent event) { if (!FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId())) return; - headsToAnimate = new ArrayList(); - animatedHeads = new ArrayList(); + headsToAnimate.clear(); + animatedHeads.clear(); } @EventHandler @@ -63,19 +57,19 @@ public void geyserPlayerDeath(PlayerRespawnEvent event) { if (!FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId())) return; - headsToAnimate = new ArrayList(); - animatedHeads = new ArrayList(); + headsToAnimate.clear(); + animatedHeads.clear(); } - public void animateForBedrockPlayer(FloodgatePlayer player){ + public void animateForBedrockPlayer() { Player BukkitPlayer = null; try { - BukkitPlayer = Bukkit.getPlayer(player.getCorrectUniqueId()); + BukkitPlayer = Bukkit.getPlayer(playerConn.javaUuid()); } - catch(IllegalArgumentException e) + catch(NullPointerException e) { - return; //may be null in the very first milliseconds of connecting to the server. + //Not sure if this is still the case anymore, todo: test for null. } if(BukkitPlayer==null) return; @@ -95,16 +89,16 @@ public void animateForBedrockPlayer(FloodgatePlayer player){ // send deanimate packet switch (currentMaterial) { case DRAGON_HEAD: - sendAnimatePacket(player, activeHead.getBlock(), 5, 0); + sendAnimatePacket(playerConn, activeHead.getBlock(), 5, 0); break; case DRAGON_WALL_HEAD: - sendAnimatePacket(player, activeHead.getBlock(), 5, 0); + sendAnimatePacket(playerConn, activeHead.getBlock(), 5, 0); break; case PIGLIN_HEAD: - sendAnimatePacket(player, activeHead.getBlock(), 6, 0); + sendAnimatePacket(playerConn, activeHead.getBlock(), 6, 0); break; case PIGLIN_WALL_HEAD: - sendAnimatePacket(player, activeHead.getBlock(), 6, 0); + sendAnimatePacket(playerConn, activeHead.getBlock(), 6, 0); break; default: break; @@ -140,16 +134,16 @@ public void animateForBedrockPlayer(FloodgatePlayer player){ Material materialOfBlock = headBlock.getType(); switch (materialOfBlock) { case DRAGON_HEAD: - sendAnimatePacket(player, headBlock, 5, 1); + sendAnimatePacket(playerConn, headBlock, 5, 1); break; case DRAGON_WALL_HEAD: - sendAnimatePacket(player, headBlock, 5, 1); + sendAnimatePacket(playerConn, headBlock, 5, 1); break; case PIGLIN_HEAD: - sendAnimatePacket(player, headBlock, 6, 1); + sendAnimatePacket(playerConn, headBlock, 6, 1); break; case PIGLIN_WALL_HEAD: - sendAnimatePacket(player, headBlock, 6, 1); + sendAnimatePacket(playerConn, headBlock, 6, 1); break; default: break; @@ -173,7 +167,7 @@ public boolean isHead(Material material) { } // animate or deanimate bedrock animations for vanilla skulls. - public void sendAnimatePacket(FloodgatePlayer player, Block head, int headType, int animationStatus) { + public void sendAnimatePacket(Connection playerConn, Block head, int headType, int animationStatus) { NbtMapBuilder builder = NbtMap.builder(); builder.putByte("DoingAnimation", (byte) animationStatus); builder.putInt("MouthTickCount", animationStatus); @@ -246,20 +240,6 @@ public void sendAnimatePacket(FloodgatePlayer player, Block head, int headType, headAnimationPacket.setBlockPosition(Vector3i.from(head.getX(), head.getY(), head.getZ())); headAnimationPacket.setData(builder.build()); GeyserImpl geyserInstance = (GeyserImpl) Geyser.api(); - geyserInstance.connectionByUuid(player.getCorrectUniqueId()).sendUpstreamPacket((BedrockPacket) headAnimationPacket); - - // When I was testing sending packet through floodgate api but obviously this is not how you do it. You have to use geyser api. - -// ByteArrayOutputStream bos = new ByteArrayOutputStream(); -// ObjectOutputStream oos = new ObjectOutputStream(bos); - //oos.writeObject(builder.build().toString()); - -// Gson gson = new Gson(); -// String PacketdataString = "{'DoingAnimation':"+animationStatus+",'MouthTickCount':"+animationStatus+",'Rotation':"+rotationDegree+",'SkullType':"+headType+",'id':'Skull','isMovable':"+1+",'x':"+head.getX()+",'y':"+head.getY()+",'z':"+head.getZ()+"}"; -// JsonElement PacketdataJson = gson.fromJson(PacketdataString,JsonElement.class); - //String HeadPacketString = "BlockEntityDataPacket(blockPosition=("+head.getX()+","+head.getY()+","+head.getZ()+"),data="+PacketdataJson+")"; - //plugin.getLogger().info(headAnimationPacket.toString()); - //FloodgateApi.getInstance().unsafe().sendPacket(player, 0x38, headAnimationPacket.toString().getBytes()); - + geyserInstance.connectionByUuid(playerConn.javaUuid()).sendUpstreamPacket((BedrockPacket) headAnimationPacket); } } \ No newline at end of file diff --git a/src/main/java/com/tbyt/BedrockEvents.java b/src/main/java/com/tbyt/BedrockEvents.java new file mode 100644 index 0000000..68ae300 --- /dev/null +++ b/src/main/java/com/tbyt/BedrockEvents.java @@ -0,0 +1,32 @@ +package com.tbyt; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitScheduler; +import org.geysermc.geyser.api.GeyserApi; +import org.geysermc.geyser.api.event.EventRegistrar; +import org.geysermc.geyser.api.event.bedrock.SessionJoinEvent; + +public class BedrockEvents implements EventRegistrar { + + public int animateHeadBlockDistance = 0; + private final Plugin plugin; + + public BedrockEvents(int animateHeadBlockDistance, Plugin plugin) { + this.animateHeadBlockDistance = animateHeadBlockDistance; + this.plugin = plugin; + GeyserApi.api().eventBus().subscribe(this, SessionJoinEvent.class, this::onGeyserPlayerJoin); + } + + public void onGeyserPlayerJoin(SessionJoinEvent event) { + AnimateHeadsForGeyser animateHeadsForGeyser = new AnimateHeadsForGeyser(plugin, event.connection(), animateHeadBlockDistance); + Bukkit.getPluginManager().registerEvents(animateHeadsForGeyser, plugin); + BukkitScheduler scheduler = plugin.getServer().getScheduler(); + scheduler.scheduleSyncRepeatingTask(plugin, new Runnable() { + @Override + public void run() { + animateHeadsForGeyser.animateForBedrockPlayer(); + } + }, 0L, 4L); + } +} diff --git a/src/main/java/com/tbyt/BedrockParity.java b/src/main/java/com/tbyt/BedrockParity.java index 4e7bc59..df65904 100644 --- a/src/main/java/com/tbyt/BedrockParity.java +++ b/src/main/java/com/tbyt/BedrockParity.java @@ -3,58 +3,45 @@ import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitScheduler; import org.geysermc.floodgate.api.FloodgateApi; -import org.geysermc.floodgate.api.player.FloodgatePlayer; - import java.util.UUID; import java.util.function.Predicate; public class BedrockParity extends JavaPlugin { private Predicate playerChecker; - @Override - public void onEnable() { - FileConfiguration config = getConfig(); - config.addDefault("sweeping-edge-book-anvil-fix", true); - config.addDefault("animate-heads-for-bedrock", true); - config.options().copyDefaults(true); - saveDefaultConfig(); + + @Override + public void onEnable() { + FileConfiguration config = getConfig(); + config.addDefault("sweeping-edge-book-anvil-fix", true); + config.addDefault("animate-heads-for-bedrock", true); + config.options().copyDefaults(true); + saveDefaultConfig(); try { Class.forName("org.geysermc.floodgate.api.FloodgateApi"); playerChecker = uuid -> FloodgateApi.getInstance().isFloodgatePlayer(uuid); } catch (ClassNotFoundException e) { getLogger().warning("Could not find Floodgate; Bedrock Parity is disabled."); } - if (playerChecker != null) { - if(this.getConfig().getBoolean("sweeping-edge-book-anvil-fix")) - { + if (this.getConfig().getBoolean("sweeping-edge-book-anvil-fix")) { Bukkit.getPluginManager().registerEvents(new SweepingEdgeFix(this), this); getLogger().info("Sweeping Edge Book Fix in Anvil is enabled."); - } - else + } else getLogger().info("Sweeping Edge Book Fix in Anvil is manually disabled."); - if(this.getConfig().getInt("animate-head-blocks-distance")!=0&&Bukkit.getPluginManager().getPlugin("Geyser-Spigot")!=null) - { - getLogger().info("Animating Dragon and Piglin Heads is enabled."); - int animateHeadBlockDistance = this.getConfig().getInt("animate-head-blocks-distance"); - AnimateHeadsForGeyser animateHeadsForGeyser = new AnimateHeadsForGeyser(this, animateHeadBlockDistance); - Bukkit.getPluginManager().registerEvents(animateHeadsForGeyser, this); - BukkitScheduler scheduler = getServer().getScheduler(); - scheduler.scheduleSyncRepeatingTask(this, new Runnable() { - @Override - public void run() { - //Player player : Bukkit.getOnlinePlayers() - for (FloodgatePlayer player : FloodgateApi.getInstance().getPlayers()) { - // Update every 4 ticks - animateHeadsForGeyser.animateForBedrockPlayer(player); - } - } - }, 0L, 4L); - } - else - getLogger().info("Animating Heads for Bedrock Players is manually disabled, or Geyser-Spigot could not be found."); -// getLogger().info("Animating Heads for Bedrock Players is disabled in BedrockParity because Geyser natively supports it Minecraft Java 1.20.2 and up."); + if (Bukkit.getUnsafe().getDataVersion() < 3466) { + if (Bukkit.getPluginManager().getPlugin("Geyser-Spigot") != null) { + int animateHeadBlockDistance = this.getConfig().getInt("animate-head-blocks-distance"); + if (animateHeadBlockDistance != 0) { + new BedrockEvents(animateHeadBlockDistance, this); + getLogger().info("Animating Dragon and Piglin Heads is enabled."); + + } else + getLogger().info("Animating Heads for Bedrock Players is manually disabled in config.yml"); + } else + getLogger().info("Geyser-Spigot could not be found. Animating Heads for Bedrock Players is disabled."); + } else + getLogger().info("Animating Heads for Bedrock Players is disabled because Geyser natively supports it Minecraft Java v1.20.2 and up."); } } }