Skip to content

Commit

Permalink
ReIntroduce Spigot compatibility and optimize checks.
Browse files Browse the repository at this point in the history
  • Loading branch information
MrBsng committed Apr 29, 2024
1 parent 67b62a2 commit 097d3c7
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 91 deletions.
61 changes: 24 additions & 37 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,50 +41,37 @@
<name>Opencollab Repository</name>
<url>https://repo.opencollab.dev/main</url>
</repository>
<!-- <repository>
<id>opencollab-repository-maven-snapshots</id>
<name>Opencollab Repository</name>
<url>https://repo.opencollab.dev/maven-snapshots</url>
</repository> -->
<!-- <repository>
<id>opencollab-release-repo</id>
<url>https://repo.opencollab.dev/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> -->
<repository>
<id>papermc-repo</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<repository>
<id>opencollab-releases</id>
<url>https://repo.opencollab.dev/maven-releases/</url>
</repository>
<repository>
<id>opencollab-snapshots</id>
<url>https://repo.opencollab.dev/maven-snapshots/</url>
</repository>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>

<dependencies>
<!-- <dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.11.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency> -->
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.geyser</groupId>
<artifactId>core</artifactId>
<version>2.2.0-SNAPSHOT</version>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>com.github.GeyserMC</groupId>
<artifactId>MCAuthLib</artifactId>
</exclusion>
</exclusions>
<groupId>org.geysermc.geyser</groupId>
<artifactId>core</artifactId>
<version>2.2.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.github.GeyserMC</groupId>
<artifactId>MCAuthLib</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.geysermc.floodgate</groupId>
Expand Down
77 changes: 49 additions & 28 deletions src/main/java/com/tbyt/AnimateHeadsForGeyser.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
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;
Expand All @@ -11,18 +17,20 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.plugin.Plugin;
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.destroystokyo.paper.event.player.PlayerPostRespawnEvent;
//import com.google.gson.Gson;
//import com.google.gson.JsonElement;

/*
* Made by TBYT
Expand Down Expand Up @@ -51,32 +59,32 @@ public void geyserPlayerDimensionSwitch(PlayerChangedWorldEvent event)
}

@EventHandler
public void geyserPlayerDeath(PlayerPostRespawnEvent event)
public void geyserPlayerDeath(PlayerRespawnEvent event)
{
if (!FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId()))
return;
headsToAnimate = new ArrayList<Location>();
animatedHeads = new ArrayList<Location>();
}

public void animateForGeyserPlayer(Connection playerConn) {
Player player = null;
public void animateForBedrockPlayer(FloodgatePlayer player){
Player BukkitPlayer = null;
try {
player = Bukkit.getPlayer(playerConn.javaUuid());
BukkitPlayer = Bukkit.getPlayer(player.getCorrectUniqueId());
}
catch(IllegalArgumentException e)
{
return;
//may be null in the very first milliseconds of connecting to the server.
}
if(player==null)
if(BukkitPlayer==null)
return;

// this for loop is if the head is broken and not at the location anymore or not powered.
ArrayList<Location> headsToRemove = new ArrayList<Location>();
for (Location activeHead : headsToAnimate) {
Material currentMaterial = activeHead.getBlock().getType();
if (!IsHead(currentMaterial)) {
if (!isHead(currentMaterial)) {
headsToRemove.add(activeHead);
continue;
}
Expand All @@ -87,16 +95,16 @@ public void animateForGeyserPlayer(Connection playerConn) {
// send deanimate packet
switch (currentMaterial) {
case DRAGON_HEAD:
sendAnimatePacket(playerConn, activeHead.getBlock(), 5, 0);
sendAnimatePacket(player, activeHead.getBlock(), 5, 0);
break;
case DRAGON_WALL_HEAD:
sendAnimatePacket(playerConn, activeHead.getBlock(), 5, 0);
sendAnimatePacket(player, activeHead.getBlock(), 5, 0);
break;
case PIGLIN_HEAD:
sendAnimatePacket(playerConn, activeHead.getBlock(), 6, 0);
sendAnimatePacket(player, activeHead.getBlock(), 6, 0);
break;
case PIGLIN_WALL_HEAD:
sendAnimatePacket(playerConn, activeHead.getBlock(), 6, 0);
sendAnimatePacket(player, activeHead.getBlock(), 6, 0);
break;
default:
break;
Expand All @@ -106,14 +114,14 @@ public void animateForGeyserPlayer(Connection playerConn) {
headsToAnimate.removeAll(headsToRemove);
animatedHeads.removeAll(headsToRemove);
// locate new heads by giving the player a radius.
Location PlayerLoc = player.getLocation();
Location PlayerLoc = BukkitPlayer.getLocation();
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
for (int y = -radius; y <= radius; y++) {
Block headBlock = PlayerLoc.clone().add(x, y, z).getBlock();
Material materialOfBlock = headBlock.getType();
// if Block is actually a dragon or piglin head block.
if (IsHead(materialOfBlock)) {
if (isHead(materialOfBlock)) {
if (headBlock.isBlockPowered() || headBlock.isBlockIndirectlyPowered()) {
if (!headsToAnimate.contains(headBlock.getLocation()))
headsToAnimate.add(headBlock.getLocation());
Expand All @@ -132,24 +140,24 @@ public void animateForGeyserPlayer(Connection playerConn) {
Material materialOfBlock = headBlock.getType();
switch (materialOfBlock) {
case DRAGON_HEAD:
sendAnimatePacket(playerConn, headBlock, 5, 1);
sendAnimatePacket(player, headBlock, 5, 1);
break;
case DRAGON_WALL_HEAD:
sendAnimatePacket(playerConn, headBlock, 5, 1);
sendAnimatePacket(player, headBlock, 5, 1);
break;
case PIGLIN_HEAD:
sendAnimatePacket(playerConn, headBlock, 6, 1);
sendAnimatePacket(player, headBlock, 6, 1);
break;
case PIGLIN_WALL_HEAD:
sendAnimatePacket(playerConn, headBlock, 6, 1);
sendAnimatePacket(player, headBlock, 6, 1);
break;
default:
break;
}
}
}

public boolean IsHead(Material material) {
public boolean isHead(Material material) {
switch (material) {
case DRAGON_HEAD:
return true;
Expand All @@ -165,14 +173,14 @@ public boolean IsHead(Material material) {
}

// animate or deanimate bedrock animations for vanilla skulls.
public void sendAnimatePacket(Connection playerConn, Block head, int headType, int animationStatus) {
public void sendAnimatePacket(FloodgatePlayer player, Block head, int headType, int animationStatus) {
NbtMapBuilder builder = NbtMap.builder();
builder.putByte("DoingAnimation", (byte) animationStatus);
builder.putInt("MouthTickCount", animationStatus);
// if head is not on a Wall.
float rotationDegree = 0.0f;
if (head.getBlockData() instanceof Rotatable) {
Rotatable HeadRotation = (Rotatable) head.getBlockData();
float rotationDegree = 0.0f;

switch (HeadRotation.getRotation()) {
case EAST:
Expand Down Expand Up @@ -226,19 +234,32 @@ public void sendAnimatePacket(Connection playerConn, Block head, int headType, i
default:
break;
}
builder.put("Rotation", rotationDegree);
} else
builder.put("Rotation", 0f);
}
builder.put("Rotation", rotationDegree);
builder.putByte("SkullType", (byte) headType);
builder.putString("id", "Skull");
builder.putByte("isMovable", (byte) 1);
builder.putInt("X", head.getX());
builder.putInt("Y", head.getY());
builder.putInt("Z", head.getZ());
BlockEntityDataPacket HeadAnimationPacket = new BlockEntityDataPacket();
HeadAnimationPacket.setBlockPosition(Vector3i.from(head.getX(), head.getY(), head.getZ()));
HeadAnimationPacket.setData(builder.build());
BlockEntityDataPacket headAnimationPacket = new BlockEntityDataPacket();
headAnimationPacket.setBlockPosition(Vector3i.from(head.getX(), head.getY(), head.getZ()));
headAnimationPacket.setData(builder.build());
GeyserImpl geyserInstance = (GeyserImpl) Geyser.api();
geyserInstance.connectionByUuid(playerConn.javaUuid()).sendUpstreamPacket((BedrockPacket) HeadAnimationPacket);
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());

}
}
44 changes: 18 additions & 26 deletions src/main/java/com/tbyt/BedrockParity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.geysermc.api.connection.Connection;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.player.FloodgatePlayer;

import java.util.UUID;
import java.util.function.Predicate;
import org.geysermc.api.Geyser;
import org.geysermc.geyser.GeyserImpl;

public class BedrockParity extends JavaPlugin {
private Predicate<UUID> playerChecker;
Expand All @@ -20,19 +19,11 @@ public void onEnable() {
config.addDefault("animate-heads-for-bedrock", true);
config.options().copyDefaults(true);
saveDefaultConfig();

//Predicate<UUID> playerChecker;
try {
Class.forName("org.geysermc.floodgate.api.FloodgateApi");
playerChecker = uuid -> FloodgateApi.getInstance().isFloodgatePlayer(uuid);
} catch (ClassNotFoundException e) {
try {
Class.forName("org.geysermc.geyser.GeyserImpl");
playerChecker = uuid -> GeyserImpl.getInstance().connectionByUuid(uuid) != null;
} catch (ClassNotFoundException e2) {
getLogger().warning("Could not find Geyser or Floodgate; Bedrock Parity is disabled.");
playerChecker = null;
}
getLogger().warning("Could not find Floodgate; Bedrock Parity is disabled.");
}

if (playerChecker != null) {
Expand All @@ -43,26 +34,27 @@ public void onEnable() {
}
else
getLogger().info("Sweeping Edge Book Fix in Anvil is manually disabled.");
if(this.getConfig().getInt("animate-head-blocks-distance")!=0)
if(this.getConfig().getInt("animate-head-blocks-distance")!=0&&Bukkit.getPluginManager().getPlugin("Geyser-Spigot")!=null)
{
getLogger().info("Animating Heads for Bedrock Players is enabled.");
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 (Connection playerConn : Geyser.api().onlineConnections()) {
// Update every 4 ticks
animateHeadsForGeyser.animateForGeyserPlayer(playerConn);
}
}
}, 0L, 4L);
}
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.");
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.");
}
}
}

0 comments on commit 097d3c7

Please sign in to comment.