mirror of
https://github.com/HibiscusMC/HibiscusCommons.git
synced 2025-12-20 07:29:15 +00:00
Merge pull request #15 from Boy0000/nms-packets
refactor: drop ProtocolLib, replace reflection usage
This commit is contained in:
@@ -11,7 +11,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "me.lojosho"
|
group = "me.lojosho"
|
||||||
version = "0.6.5${getGitCommitHash()}"
|
version = "0.7.0${getGitCommitHash()}"
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply(plugin = "java")
|
apply(plugin = "java")
|
||||||
@@ -33,7 +33,7 @@ allprojects {
|
|||||||
maven("https://repo.nexomc.com/snapshots/")
|
maven("https://repo.nexomc.com/snapshots/")
|
||||||
maven("https://repo.nexomc.com/releases/")
|
maven("https://repo.nexomc.com/releases/")
|
||||||
|
|
||||||
// Geary & Backup ProtocolLib repo
|
// Geary repo
|
||||||
maven("https://repo.mineinabyss.com/releases/")
|
maven("https://repo.mineinabyss.com/releases/")
|
||||||
maven("https://repo.mineinabyss.com/snapshots/")
|
maven("https://repo.mineinabyss.com/snapshots/")
|
||||||
|
|
||||||
@@ -55,9 +55,6 @@ allprojects {
|
|||||||
// PlaceholderAPI
|
// PlaceholderAPI
|
||||||
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||||
|
|
||||||
// ProtocolLib
|
|
||||||
maven("https://repo.dmulloy2.net/repository/public/")
|
|
||||||
|
|
||||||
// Oraxen
|
// Oraxen
|
||||||
maven("https://repo.oraxen.com/releases")
|
maven("https://repo.oraxen.com/releases")
|
||||||
|
|
||||||
@@ -83,7 +80,7 @@ allprojects {
|
|||||||
compileOnly("com.mojang:authlib:3.13.56")
|
compileOnly("com.mojang:authlib:3.13.56")
|
||||||
compileOnly("org.jetbrains:annotations:26.0.1")
|
compileOnly("org.jetbrains:annotations:26.0.1")
|
||||||
compileOnly("io.th0rgal:oraxen:1.182.0")
|
compileOnly("io.th0rgal:oraxen:1.182.0")
|
||||||
compileOnly("com.nexomc:nexo:1.0.0")
|
compileOnly("com.nexomc:nexo:1.4.0")
|
||||||
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.6.3-beta-14")
|
compileOnly("com.github.LoneDev6:API-ItemsAdder:3.6.3-beta-14")
|
||||||
compileOnly("com.mineinabyss:geary-papermc:0.31.0-dev.4")
|
compileOnly("com.mineinabyss:geary-papermc:0.31.0-dev.4")
|
||||||
compileOnly("it.unimi.dsi:fastutil:8.5.15")
|
compileOnly("it.unimi.dsi:fastutil:8.5.15")
|
||||||
@@ -98,7 +95,6 @@ allprojects {
|
|||||||
}
|
}
|
||||||
compileOnly("com.github.Xiao-MoMi:Custom-Fishing:2.3.3")
|
compileOnly("com.github.Xiao-MoMi:Custom-Fishing:2.3.3")
|
||||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
|
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
|
||||||
compileOnly("org.joml:joml:1.10.8")
|
compileOnly("org.joml:joml:1.10.8")
|
||||||
compileOnly("com.google.guava:guava:33.4.0-jre") // Sometimes just not included in compile time???
|
compileOnly("com.google.guava:guava:33.4.0-jre") // Sometimes just not included in compile time???
|
||||||
compileOnly("com.github.Gecolay.GSit:core:2.0.0")
|
compileOnly("com.github.Gecolay.GSit:core:2.0.0")
|
||||||
@@ -148,12 +144,11 @@ tasks {
|
|||||||
runServer {
|
runServer {
|
||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
dependsOn(jar)
|
dependsOn(jar)
|
||||||
minecraftVersion("1.21.5")
|
minecraftVersion("1.21.6")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
hangar("PlaceholderAPI", "2.11.6")
|
hangar("PlaceholderAPI", "2.11.6")
|
||||||
url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
|
url("https://download.luckperms.net/1593/bukkit/loader/LuckPerms-Bukkit-5.5.8.jar")
|
||||||
url("https://download.luckperms.net/1567/bukkit/loader/LuckPerms-Bukkit-5.4.150.jar")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +200,6 @@ bukkit {
|
|||||||
main = "me.lojosho.hibiscuscommons.HibiscusCommonsPlugin"
|
main = "me.lojosho.hibiscuscommons.HibiscusCommonsPlugin"
|
||||||
apiVersion = "1.20"
|
apiVersion = "1.20"
|
||||||
authors = listOf("LoJoSho")
|
authors = listOf("LoJoSho")
|
||||||
depend = listOf("ProtocolLib")
|
|
||||||
softDepend = listOf(
|
softDepend = listOf(
|
||||||
"ModelEngine",
|
"ModelEngine",
|
||||||
"Oraxen",
|
"Oraxen",
|
||||||
@@ -252,12 +246,6 @@ hangarPublish {
|
|||||||
|
|
||||||
val versions: List<String> = listOf("1.18.2-1.20.4")
|
val versions: List<String> = listOf("1.18.2-1.20.4")
|
||||||
platformVersions.set(versions)
|
platformVersions.set(versions)
|
||||||
|
|
||||||
dependencies {
|
|
||||||
hangar("ProtocolLib") {
|
|
||||||
required.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package me.lojosho.hibiscuscommons;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||||
|
import me.lojosho.hibiscuscommons.listener.PlayerConnectionEvent;
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
@@ -42,6 +43,8 @@ public final class HibiscusCommonsPlugin extends HibiscusPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getServer().getPluginManager().registerEvents(new PlayerConnectionEvent(), this);
|
||||||
|
|
||||||
// Plugin startup logic
|
// Plugin startup logic
|
||||||
Hooks.setup();
|
Hooks.setup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ package me.lojosho.hibiscuscommons;
|
|||||||
import com.jeff_media.updatechecker.UpdateCheckSource;
|
import com.jeff_media.updatechecker.UpdateCheckSource;
|
||||||
import com.jeff_media.updatechecker.UpdateChecker;
|
import com.jeff_media.updatechecker.UpdateChecker;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.DefaultPacketInterface;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.PacketInterface;
|
||||||
|
import me.lojosho.hibiscuscommons.plugins.SubPlugins;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@@ -20,6 +24,8 @@ public abstract class HibiscusPlugin extends JavaPlugin {
|
|||||||
private boolean onLatestVersion = true;
|
private boolean onLatestVersion = true;
|
||||||
@Getter
|
@Getter
|
||||||
private boolean disabled = false;
|
private boolean disabled = false;
|
||||||
|
@Getter @Setter
|
||||||
|
private PacketInterface packetInterface = new DefaultPacketInterface();
|
||||||
|
|
||||||
protected HibiscusPlugin() {
|
protected HibiscusPlugin() {
|
||||||
this(-1);
|
this(-1);
|
||||||
@@ -47,6 +53,8 @@ public abstract class HibiscusPlugin extends JavaPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubPlugins.addSubPlugin(this);
|
||||||
|
|
||||||
if (bstats > 0) {
|
if (bstats > 0) {
|
||||||
Metrics metrics = new Metrics(this, bstats);
|
Metrics metrics = new Metrics(this, bstats);
|
||||||
}
|
}
|
||||||
@@ -88,6 +96,7 @@ public abstract class HibiscusPlugin extends JavaPlugin {
|
|||||||
@Override
|
@Override
|
||||||
public final void onDisable() {
|
public final void onDisable() {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
|
SubPlugins.removeSubPlugin(this);
|
||||||
|
|
||||||
onEnd();
|
onEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.listener;
|
||||||
|
|
||||||
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
|
public class PlayerConnectionEvent implements Listener {
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOW)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
NMSHandlers.getHandler().getUtilHandler().handleChannelOpen(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +1,48 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms;
|
package me.lojosho.hibiscuscommons.nms;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Display;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.ItemDisplay;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface NMSPackets {
|
public interface NMSPackets {
|
||||||
|
|
||||||
static int POSITION_INTERPOLATION_DURATION = 2;
|
static int POSITION_INTERPOLATION_DURATION = 2;
|
||||||
|
static int SHARED_ENTITY_METADATA = 0;
|
||||||
|
|
||||||
void sendSlotUpdate(
|
void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo);
|
||||||
Player player,
|
|
||||||
int slot
|
void sendFakePlayerInfoPacket(final Player skinnedPlayer, final int entityId, final UUID uuid, final String npcName, final List<Player> sendTo);
|
||||||
);
|
|
||||||
|
void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo);
|
||||||
|
|
||||||
|
void sendMovePacket(final int entityId, final @NotNull Location from, final @NotNull Location to, final boolean onGround, @NotNull List<Player> sendTo);
|
||||||
|
|
||||||
|
void sendGamemodeChange(Player player, GameMode gameMode);
|
||||||
|
|
||||||
|
void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo);
|
||||||
|
|
||||||
|
void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo);
|
||||||
|
|
||||||
|
void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo);
|
||||||
|
|
||||||
|
void sendSlotUpdate(Player player, int slot);
|
||||||
|
|
||||||
|
default void sendLookAtPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void sendEquipmentSlotUpdate(
|
void sendEquipmentSlotUpdate(
|
||||||
int entityId,
|
int entityId,
|
||||||
@@ -58,8 +77,6 @@ public interface NMSPackets {
|
|||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
);
|
);
|
||||||
|
|
||||||
void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo);
|
|
||||||
|
|
||||||
void sendCameraPacket(int entityId, List<Player> sendTo);
|
void sendCameraPacket(int entityId, List<Player> sendTo);
|
||||||
|
|
||||||
void sendSpawnEntityPacket(int entityId, UUID uuid, EntityType entityType, Location location, List<Player> sendTo);
|
void sendSpawnEntityPacket(int entityId, UUID uuid, EntityType entityType, Location location, List<Player> sendTo);
|
||||||
@@ -77,4 +94,6 @@ public interface NMSPackets {
|
|||||||
List<Player> sendTo);
|
List<Player> sendTo);
|
||||||
|
|
||||||
void sendToastPacket(Player player, ItemStack icon, Component title, Component description);
|
void sendToastPacket(Player player, ItemStack icon, Component title, Component description);
|
||||||
|
|
||||||
|
Object createMountPacket(int entityId, int[] passengerIds);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,8 @@ public interface NMSUtils {
|
|||||||
|
|
||||||
ItemStack setColor(@NotNull ItemStack itemStack, Color color);
|
ItemStack setColor(@NotNull ItemStack itemStack, Color color);
|
||||||
|
|
||||||
|
default void handleChannelOpen(@NotNull Player player) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets;
|
||||||
|
|
||||||
|
public class DefaultPacketInterface implements PacketInterface {
|
||||||
|
// Overrides nothing
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets;
|
||||||
|
|
||||||
|
public enum PacketAction {
|
||||||
|
NOTHING,
|
||||||
|
CHANGED,
|
||||||
|
CANCELLED,
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets;
|
||||||
|
|
||||||
|
import me.lojosho.hibiscuscommons.packets.wrapper.*;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface PacketInterface {
|
||||||
|
|
||||||
|
default PacketAction writeContainerContent(@NotNull Player player, @NotNull ContainerContentWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction writeSlotContent(@NotNull Player player, @NotNull SlotContentWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction writeEquipmentContent(@NotNull Player player, @NotNull EntityEquipmentWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction writePassengerContent(@NotNull Player player, @NotNull PassengerWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction readInventoryClick(@NotNull Player player, @NotNull InventoryClickWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
// Override
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction readPlayerAction(@NotNull Player player, @NotNull PlayerActionWrapper wrapper) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
// Override
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction readPlayerArm(@NotNull Player player) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
// Override
|
||||||
|
}
|
||||||
|
|
||||||
|
default PacketAction readEntityHandle(@NotNull Player player) {
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
// Override
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class ContainerContentWrapper {
|
||||||
|
|
||||||
|
private Integer windowId;
|
||||||
|
private List<ItemStack> slotData;
|
||||||
|
|
||||||
|
public ContainerContentWrapper(@NotNull Integer windowId, @NotNull List<ItemStack> slotData) {
|
||||||
|
this.windowId = windowId;
|
||||||
|
this.slotData = slotData;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class EntityEquipmentWrapper {
|
||||||
|
|
||||||
|
private int entityId;
|
||||||
|
private Map<EquipmentSlot, ItemStack> armor;
|
||||||
|
|
||||||
|
public EntityEquipmentWrapper(int entityId, @NotNull Map<EquipmentSlot, ItemStack> armor) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
this.armor = armor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class InventoryClickWrapper {
|
||||||
|
|
||||||
|
private int clickType;
|
||||||
|
private int slotNumber;
|
||||||
|
|
||||||
|
public InventoryClickWrapper(@NotNull Integer clickType, @NotNull Integer slotNumber) {
|
||||||
|
this.clickType = clickType;
|
||||||
|
this.slotNumber = slotNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class PassengerWrapper {
|
||||||
|
|
||||||
|
private int owner;
|
||||||
|
private List<Integer> passengers;
|
||||||
|
|
||||||
|
public PassengerWrapper(@NotNull Integer owner, @NotNull List<Integer> passengers) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.passengers = passengers;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class PlayerActionWrapper {
|
||||||
|
|
||||||
|
private String actionType;
|
||||||
|
|
||||||
|
public PlayerActionWrapper(String actionType) {
|
||||||
|
this.actionType = actionType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.packets.wrapper;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@Setter @Getter
|
||||||
|
public class SlotContentWrapper {
|
||||||
|
|
||||||
|
private Integer windowId;
|
||||||
|
private int slot;
|
||||||
|
private ItemStack itemStack;
|
||||||
|
|
||||||
|
public SlotContentWrapper(Integer windowId, Integer slot, @NotNull ItemStack itemStack) {
|
||||||
|
this.windowId = windowId;
|
||||||
|
this.slot = slot;
|
||||||
|
this.itemStack = itemStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.plugins;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import me.lojosho.hibiscuscommons.HibiscusPlugin;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SubPlugins {
|
||||||
|
|
||||||
|
private static final List<HibiscusPlugin> SUB_PLUGINS = new ArrayList<>();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<HibiscusPlugin> getSubPlugins() {
|
||||||
|
return ImmutableList.copyOf(SUB_PLUGINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void addSubPlugin(@NotNull HibiscusPlugin plugin) {
|
||||||
|
SUB_PLUGINS.add(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void removeSubPlugin(@NotNull HibiscusPlugin plugin) {
|
||||||
|
SUB_PLUGINS.remove(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package me.lojosho.hibiscuscommons.util;
|
package me.lojosho.hibiscuscommons.util;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.profile.PlayerProfile;
|
||||||
|
import org.bukkit.profile.PlayerTextures;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -21,14 +21,8 @@ public class ServerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static WrappedSignedProperty getSkin(Player player) {
|
public static PlayerTextures getSkin(Player player) {
|
||||||
WrappedSignedProperty skinData = WrappedGameProfile.fromPlayer(player).getProperties()
|
return player.getPlayerProfile().getTextures();
|
||||||
.get("textures").stream().findAny().orElse(null);
|
|
||||||
|
|
||||||
if (skinData == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new WrappedSignedProperty("textures", skinData.getValue(), skinData.getSignature());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package me.lojosho.hibiscuscommons.util.packets;
|
package me.lojosho.hibiscuscommons.util.packets;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import me.lojosho.hibiscuscommons.util.MessagesUtil;
|
import me.lojosho.hibiscuscommons.util.MessagesUtil;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
@@ -34,14 +32,9 @@ public class PacketManager {
|
|||||||
|
|
||||||
public static void gamemodeChangePacket(
|
public static void gamemodeChangePacket(
|
||||||
Player player,
|
Player player,
|
||||||
int gamemode
|
GameMode gamemode
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
|
NMSHandlers.getHandler().getPacketHandler().sendGamemodeChange(player, gamemode);
|
||||||
packet.getGameStateIDs().write(0, 3);
|
|
||||||
// Tells what event this is. This is a change gamemode event.
|
|
||||||
packet.getFloat().write(0, (float) gamemode);
|
|
||||||
sendPacket(player, packet);
|
|
||||||
MessagesUtil.sendDebugMessages("Gamemode Change sent to " + player + " to be " + gamemode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ridingMountPacket(
|
public static void ridingMountPacket(
|
||||||
@@ -52,15 +45,12 @@ public class PacketManager {
|
|||||||
NMSHandlers.getHandler().getPacketHandler().sendMountPacket(mountId, new int[]{passengerId}, sendTo);
|
NMSHandlers.getHandler().getPacketHandler().sendMountPacket(mountId, new int[]{passengerId}, sendTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendLookPacket(
|
public static void sendRotateHeadPacket(
|
||||||
int entityId,
|
int entityId,
|
||||||
@NotNull Location location,
|
@NotNull Location location,
|
||||||
@NotNull List<Player> sendTo
|
@NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
|
NMSHandlers.getHandler().getPacketHandler().sendRotateHeadPacket(entityId, location, sendTo);
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getBytes().write(0, (byte) (location.getYaw() * 256.0F / 360.0F));
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendRotationPacket(
|
public static void sendRotationPacket(
|
||||||
@@ -69,29 +59,7 @@ public class PacketManager {
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
@NotNull List<Player> sendTo
|
@NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, location, onGround, sendTo);
|
||||||
float yaw = location.getYaw() * ROTATION_FACTOR;
|
|
||||||
float pitch = location.getPitch() * ROTATION_FACTOR;
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getBytes().write(0, (byte) yaw);
|
|
||||||
packet.getBytes().write(1, (byte) pitch);
|
|
||||||
|
|
||||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
|
||||||
packet.getBooleans().write(0, onGround);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendRotationPacket(
|
|
||||||
int entityId,
|
|
||||||
int yaw,
|
|
||||||
boolean onGround,
|
|
||||||
@NotNull List<Player> sendTo
|
|
||||||
) {
|
|
||||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
|
||||||
float yaw2 = yaw * ROTATION_FACTOR;
|
|
||||||
|
|
||||||
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, yaw2, onGround, sendTo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendRidingPacket(
|
public static void sendRidingPacket(
|
||||||
@@ -213,9 +181,4 @@ public class PacketManager {
|
|||||||
return players;
|
return players;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPacket(Player player, PacketContainer packet) {
|
|
||||||
if (player == null) return;
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, null,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,31 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_20_R3;
|
package me.lojosho.hibiscuscommons.nms.v1_20_R3;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
import net.minecraft.advancements.Advancement;
|
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.v1_20_R3.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntityType;
|
||||||
@@ -36,52 +37,113 @@ import org.bukkit.entity.EntityType;
|
|||||||
import org.bukkit.entity.ItemDisplay;
|
import org.bukkit.entity.ItemDisplay;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundTeleportEntityPacket> teleportConstructor;
|
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
@Override @SuppressWarnings("unchecked")
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
static {
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
try {
|
int index = entry.getKey();
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
Number value = entry.getValue();
|
||||||
passengerConstructor.setAccessible(true);
|
return switch (value) {
|
||||||
} catch (Exception e) {
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
e.printStackTrace();
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
}
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
try {
|
default ->
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
linkConstructor.setAccessible(true);
|
};
|
||||||
} catch (Exception e) {
|
}).collect(Collectors.toList());
|
||||||
e.printStackTrace();
|
|
||||||
}
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
try {
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
teleportConstructor = ClientboundTeleportEntityPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
}
|
||||||
teleportConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
@Override
|
||||||
e.printStackTrace();
|
public void sendFakePlayerInfoPacket(
|
||||||
}
|
final Player skinnedPlayer,
|
||||||
try {
|
final int entityId,
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final UUID uuid,
|
||||||
cameraConstructor.setAccessible(true);
|
final String npcName,
|
||||||
} catch (Exception e) {
|
final List<Player> sendTo
|
||||||
e.printStackTrace();
|
) {
|
||||||
}
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
try {
|
String name = npcName.substring(0, 15);
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
lookAtConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
e.printStackTrace();
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
}
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -177,28 +239,28 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
} catch (Exception e) {
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
e.printStackTrace();
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -212,47 +274,20 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
fakeNmsEntity.setRot((yaw * 256.0F / 360.0F), (pitch * 256.0F / 360.0F));
|
||||||
byteBuf.writeDouble(x);
|
fakeNmsEntity.setOnGround(onGround);
|
||||||
byteBuf.writeDouble(y);
|
|
||||||
byteBuf.writeDouble(z);
|
|
||||||
byteBuf.writeByte((byte) (yaw * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeByte((byte) (pitch * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
|
|
||||||
try {
|
ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity);
|
||||||
ClientboundTeleportEntityPacket packet = teleportConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -311,4 +346,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
public void sendToastPacket(Player player, ItemStack icon, Component title, Component description) {
|
public void sendToastPacket(Player player, ItemStack icon, Component title, Component description) {
|
||||||
throw new UnsupportedOperationException("Not implemented in this version.");
|
throw new UnsupportedOperationException("Not implemented in this version.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,37 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_20_R4;
|
package me.lojosho.hibiscuscommons.nms.v1_20_R4;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.advancements.Advancement;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
@@ -36,51 +44,113 @@ import org.bukkit.entity.ItemDisplay;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundTeleportEntityPacket> teleportConstructor;
|
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
@Override @SuppressWarnings("unchecked")
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
static {
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
try {
|
int index = entry.getKey();
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
Number value = entry.getValue();
|
||||||
passengerConstructor.setAccessible(true);
|
return switch (value) {
|
||||||
} catch (Exception e) {
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
e.printStackTrace();
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
}
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
try {
|
default ->
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
linkConstructor.setAccessible(true);
|
};
|
||||||
} catch (Exception e) {
|
}).collect(Collectors.toList());
|
||||||
e.printStackTrace();
|
|
||||||
}
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
try {
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
teleportConstructor = ClientboundTeleportEntityPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
}
|
||||||
teleportConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
@Override
|
||||||
e.printStackTrace();
|
public void sendFakePlayerInfoPacket(
|
||||||
}
|
final Player skinnedPlayer,
|
||||||
try {
|
final int entityId,
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final UUID uuid,
|
||||||
cameraConstructor.setAccessible(true);
|
final String npcName,
|
||||||
} catch (Exception e) {
|
final List<Player> sendTo
|
||||||
e.printStackTrace();
|
) {
|
||||||
}
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
try {
|
String name = npcName.substring(0, 15);
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
lookAtConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
e.printStackTrace();
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
}
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,28 +245,28 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
} catch (Exception e) {
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
e.printStackTrace();
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -210,47 +280,20 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
fakeNmsEntity.setRot((yaw * 256.0F / 360.0F), (pitch * 256.0F / 360.0F));
|
||||||
byteBuf.writeDouble(x);
|
fakeNmsEntity.setOnGround(onGround);
|
||||||
byteBuf.writeDouble(y);
|
|
||||||
byteBuf.writeDouble(z);
|
|
||||||
byteBuf.writeByte((byte) (yaw * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeByte((byte) (pitch * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
|
|
||||||
try {
|
ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity);
|
||||||
ClientboundTeleportEntityPacket packet = teleportConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -372,4 +415,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,37 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R1;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R1;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.mojang.datafixers.kinds.Const;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.advancements.Advancement;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
@@ -37,61 +44,114 @@ import org.bukkit.entity.ItemDisplay;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundTeleportEntityPacket> teleportConstructor;
|
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
|
||||||
static Constructor<ClientboundRotateHeadPacket> rotationConstructor;
|
|
||||||
static Constructor<ClientboundAddEntityPacket> spawnConstructor;
|
|
||||||
|
|
||||||
static {
|
@Override @SuppressWarnings("unchecked")
|
||||||
try {
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
passengerConstructor.setAccessible(true);
|
int index = entry.getKey();
|
||||||
} catch (Exception e) {
|
Number value = entry.getValue();
|
||||||
e.printStackTrace();
|
return switch (value) {
|
||||||
}
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
try {
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
linkConstructor.setAccessible(true);
|
default ->
|
||||||
} catch (Exception e) {
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
e.printStackTrace();
|
};
|
||||||
}
|
}).collect(Collectors.toList());
|
||||||
try {
|
|
||||||
teleportConstructor = ClientboundTeleportEntityPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
teleportConstructor.setAccessible(true);
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
|
||||||
cameraConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
|
||||||
lookAtConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
rotationConstructor = ClientboundRotateHeadPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
|
||||||
rotationConstructor.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakePlayerInfoPacket(
|
||||||
|
final Player skinnedPlayer,
|
||||||
|
final int entityId,
|
||||||
|
final UUID uuid,
|
||||||
|
final String npcName,
|
||||||
|
final List<Player> sendTo
|
||||||
|
) {
|
||||||
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
|
String name = npcName.substring(0, 15);
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendEquipmentSlotUpdate(
|
public void sendEquipmentSlotUpdate(
|
||||||
@@ -185,28 +245,28 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
} catch (Exception e) {
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
e.printStackTrace();
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -220,47 +280,20 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
fakeNmsEntity.setRot((yaw * 256.0F / 360.0F), (pitch * 256.0F / 360.0F));
|
||||||
byteBuf.writeDouble(x);
|
fakeNmsEntity.setOnGround(onGround);
|
||||||
byteBuf.writeDouble(y);
|
|
||||||
byteBuf.writeDouble(z);
|
|
||||||
byteBuf.writeByte((byte) (yaw * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeByte((byte) (pitch * 256.0F / 360.0F));
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
|
|
||||||
try {
|
ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity);
|
||||||
ClientboundTeleportEntityPacket packet = teleportConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -381,4 +414,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,38 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R2;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R2;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.advancements.Advancement;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.PositionMoveRotation;
|
import net.minecraft.world.entity.PositionMoveRotation;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.level.portal.TeleportTransition;
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
@@ -36,47 +43,115 @@ import org.bukkit.entity.Display;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.ItemDisplay;
|
import org.bukkit.entity.ItemDisplay;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
@Override @SuppressWarnings("unchecked")
|
||||||
static {
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
try {
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
int index = entry.getKey();
|
||||||
passengerConstructor.setAccessible(true);
|
Number value = entry.getValue();
|
||||||
} catch (Exception e) {
|
return switch (value) {
|
||||||
e.printStackTrace();
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
}
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
try {
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
default ->
|
||||||
linkConstructor.setAccessible(true);
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
} catch (Exception e) {
|
};
|
||||||
e.printStackTrace();
|
}).collect(Collectors.toList());
|
||||||
}
|
|
||||||
try {
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
cameraConstructor.setAccessible(true);
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
@Override
|
||||||
}
|
public void sendFakePlayerInfoPacket(
|
||||||
try {
|
final Player skinnedPlayer,
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final int entityId,
|
||||||
lookAtConstructor.setAccessible(true);
|
final UUID uuid,
|
||||||
} catch (Exception e) {
|
final String npcName,
|
||||||
e.printStackTrace();
|
final List<Player> sendTo
|
||||||
}
|
) {
|
||||||
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
|
String name = npcName.substring(0, 15);
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, player.listOrder, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -172,28 +247,28 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
} catch (Exception e) {
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
e.printStackTrace();
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -215,30 +290,12 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -360,4 +417,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,40 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R3;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R3;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.*;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.PositionMoveRotation;
|
import net.minecraft.world.entity.PositionMoveRotation;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.level.portal.TeleportTransition;
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
@@ -38,49 +45,116 @@ import org.bukkit.entity.Display;
|
|||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.ItemDisplay;
|
import org.bukkit.entity.ItemDisplay;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
|
||||||
|
|
||||||
static {
|
@Override @SuppressWarnings("unchecked")
|
||||||
try {
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
passengerConstructor.setAccessible(true);
|
int index = entry.getKey();
|
||||||
} catch (Exception e) {
|
Number value = entry.getValue();
|
||||||
e.printStackTrace();
|
return switch (value) {
|
||||||
}
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
try {
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
linkConstructor.setAccessible(true);
|
default ->
|
||||||
} catch (Exception e) {
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
e.printStackTrace();
|
};
|
||||||
}
|
}).collect(Collectors.toList());
|
||||||
try {
|
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
cameraConstructor.setAccessible(true);
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
} catch (Exception e) {
|
}
|
||||||
e.printStackTrace();
|
|
||||||
}
|
@Override
|
||||||
try {
|
public void sendFakePlayerInfoPacket(
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final Player skinnedPlayer,
|
||||||
lookAtConstructor.setAccessible(true);
|
final int entityId,
|
||||||
} catch (Exception e) {
|
final UUID uuid,
|
||||||
e.printStackTrace();
|
final String npcName,
|
||||||
}
|
final List<Player> sendTo
|
||||||
|
) {
|
||||||
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
|
String name = npcName.substring(0, 15);
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, true, player.listOrder, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,28 +250,29 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.setId(mountId);
|
||||||
} catch (Exception e) {
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
e.printStackTrace();
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
}
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -219,30 +294,12 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -398,4 +455,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,85 +1,162 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R4;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R4;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.AdventureComponent;
|
||||||
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.*;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.network.syncher.EntityDataSerializer;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
|
import net.minecraft.resources.RegistryOps;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.PositionMoveRotation;
|
import net.minecraft.world.entity.PositionMoveRotation;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.level.portal.TeleportTransition;
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
|
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
|
||||||
import org.bukkit.entity.Display;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.ItemDisplay;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
|
||||||
|
|
||||||
static {
|
@Override @SuppressWarnings("unchecked")
|
||||||
try {
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
passengerConstructor.setAccessible(true);
|
int index = entry.getKey();
|
||||||
} catch (Exception e) {
|
Number value = entry.getValue();
|
||||||
e.printStackTrace();
|
return switch (value) {
|
||||||
}
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
try {
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
linkConstructor.setAccessible(true);
|
default ->
|
||||||
} catch (Exception e) {
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
e.printStackTrace();
|
};
|
||||||
}
|
}).collect(Collectors.toList());
|
||||||
try {
|
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
cameraConstructor.setAccessible(true);
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
} catch (Exception e) {
|
}
|
||||||
e.printStackTrace();
|
|
||||||
}
|
@Override
|
||||||
try {
|
public void sendFakePlayerInfoPacket(
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final Player skinnedPlayer,
|
||||||
lookAtConstructor.setAccessible(true);
|
final int entityId,
|
||||||
} catch (Exception e) {
|
final UUID uuid,
|
||||||
e.printStackTrace();
|
final String npcName,
|
||||||
}
|
final List<Player> sendTo
|
||||||
|
) {
|
||||||
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
|
String name = npcName.substring(0, 15);
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, true, player.listOrder, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -175,28 +252,28 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
} catch (Exception e) {
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
e.printStackTrace();
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -211,21 +288,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), java.util.Set.of(), onGround);
|
ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Set.of(), onGround);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -234,14 +297,10 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -394,4 +453,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,5 +13,4 @@ public class NMSCommon {
|
|||||||
ServerPlayerConnection connection = serverPlayer.connection;
|
ServerPlayerConnection connection = serverPlayer.connection;
|
||||||
connection.send(packet);
|
connection.send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
package me.lojosho.hibiscuscommons.nms.v1_21_R5;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import lombok.Getter;
|
||||||
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.PacketAction;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.wrapper.*;
|
||||||
|
import me.lojosho.hibiscuscommons.plugins.SubPlugins;
|
||||||
|
import me.lojosho.hibiscuscommons.util.MessagesUtil;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.world.inventory.ClickType;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class NMSPacketChannel extends ChannelDuplexHandler {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
public NMSPacketChannel(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||||
|
if (!(msg instanceof Packet packet)) {
|
||||||
|
super.write(ctx, msg, promise);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (packet) {
|
||||||
|
case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket);
|
||||||
|
case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket);
|
||||||
|
case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket);
|
||||||
|
case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket);
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == null) return;
|
||||||
|
else super.write(ctx, msg, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handleMenuChange(@NotNull ClientboundContainerSetContentPacket packet) {
|
||||||
|
MessagesUtil.sendDebugMessages("Menu Initial ");
|
||||||
|
|
||||||
|
Integer windowId = packet.containerId();
|
||||||
|
NonNullList<ItemStack> slotData = NonNullList.create();
|
||||||
|
slotData.addAll(packet.items());
|
||||||
|
|
||||||
|
List<org.bukkit.inventory.ItemStack> bukkitItems = slotData.stream().map(CraftItemStack::asBukkitCopy).toList();
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
ContainerContentWrapper wrapper = new ContainerContentWrapper(windowId, bukkitItems);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().writeContainerContent(player, wrapper);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
if (action.get() == PacketAction.NOTHING) return packet;
|
||||||
|
List<ItemStack> nmsItems = wrapper.getSlotData().stream().map(CraftItemStack::asNMSCopy).toList();
|
||||||
|
return new ClientboundContainerSetContentPacket(0, packet.stateId(), nmsItems, packet.carriedItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handleSlotChange(@NotNull ClientboundContainerSetSlotPacket packet) {
|
||||||
|
MessagesUtil.sendDebugMessages("SetSlot Initial ");
|
||||||
|
|
||||||
|
final int windowId = packet.getContainerId();
|
||||||
|
final int slot = packet.getSlot();
|
||||||
|
final ItemStack item = packet.getItem();
|
||||||
|
|
||||||
|
org.bukkit.inventory.ItemStack bukkitItem = CraftItemStack.asBukkitCopy(item);
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
SlotContentWrapper wrapper = new SlotContentWrapper(windowId, slot, bukkitItem);
|
||||||
|
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().writeSlotContent(player, wrapper);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
if (action.get() == PacketAction.NOTHING) return packet;
|
||||||
|
|
||||||
|
final ItemStack nmsItem = CraftItemStack.asNMSCopy(wrapper.getItemStack());
|
||||||
|
|
||||||
|
return new ClientboundContainerSetSlotPacket(0, packet.getStateId(), wrapper.getSlot(), nmsItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handlePlayerEquipment(@NotNull ClientboundSetEquipmentPacket packet) {
|
||||||
|
final List<Pair<net.minecraft.world.entity.EquipmentSlot, ItemStack>> nmsArmor = packet.getSlots();
|
||||||
|
final int entity = packet.getEntity();
|
||||||
|
HashMap<EquipmentSlot, org.bukkit.inventory.ItemStack> bukkitArmor = new HashMap<>();
|
||||||
|
for (Pair<net.minecraft.world.entity.EquipmentSlot, ItemStack> piece : nmsArmor) {
|
||||||
|
EquipmentSlot slot = CraftEquipmentSlot.getSlot(piece.getFirst());
|
||||||
|
org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(piece.getSecond());
|
||||||
|
bukkitArmor.put(slot, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
EntityEquipmentWrapper wrapper = new EntityEquipmentWrapper(entity, bukkitArmor);
|
||||||
|
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().writeEquipmentContent(player, wrapper);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
if (action.get() == PacketAction.NOTHING) return packet;
|
||||||
|
|
||||||
|
|
||||||
|
List<Pair<net.minecraft.world.entity.EquipmentSlot, ItemStack>> newArmor = new ArrayList<>();
|
||||||
|
for (Map.Entry<EquipmentSlot, org.bukkit.inventory.ItemStack> entry : wrapper.getArmor().entrySet()) {
|
||||||
|
net.minecraft.world.entity.EquipmentSlot slot = CraftEquipmentSlot.getNMS(entry.getKey());
|
||||||
|
ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue());
|
||||||
|
newArmor.add(new Pair<>(slot, itemStack));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ClientboundSetEquipmentPacket(packet.getEntity(), newArmor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handlePassengerSet(@NotNull ClientboundSetPassengersPacket packet) {
|
||||||
|
int ownerId = packet.getVehicle();
|
||||||
|
List<Integer> passengers = Arrays.stream(packet.getPassengers()).boxed().collect(Collectors.toList());
|
||||||
|
MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId);
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
PassengerWrapper wrapper = new PassengerWrapper(ownerId, passengers);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().writePassengerContent(player, wrapper);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) {
|
||||||
|
action.set(pluginAction);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
if (action.get() == PacketAction.NOTHING) return packet;
|
||||||
|
return (Packet<?>) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengers.stream().mapToInt(Integer::intValue).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
if (!(msg instanceof Packet packet)) {
|
||||||
|
super.channelRead(ctx, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (packet) {
|
||||||
|
case ServerboundContainerClickPacket clickPacket -> msg = handleInventoryClick(clickPacket);
|
||||||
|
case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket);
|
||||||
|
case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket);
|
||||||
|
case ServerboundInteractPacket interactPacket -> msg = handleInteract(interactPacket);
|
||||||
|
default -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg == null) return;
|
||||||
|
else super.channelRead(ctx, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handleInventoryClick(@NotNull ServerboundContainerClickPacket packet) {
|
||||||
|
ClickType clickType = packet.clickType();
|
||||||
|
int slotClicked = packet.slotNum();
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().readInventoryClick(player, new InventoryClickWrapper(clickType.id(), slotClicked));
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
|
||||||
|
});
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handlePlayerAction(ServerboundPlayerActionPacket packet) {
|
||||||
|
ServerboundPlayerActionPacket.Action playerAction = packet.getAction();
|
||||||
|
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().readPlayerAction(player, new PlayerActionWrapper(playerAction.name()));
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
|
||||||
|
});
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handlePlayerArm(ServerboundSwingPacket packet) {
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().readPlayerArm(player);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
|
||||||
|
});
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> handleInteract(ServerboundInteractPacket packet) {
|
||||||
|
AtomicReference<PacketAction> action = new AtomicReference<>(PacketAction.NOTHING);
|
||||||
|
SubPlugins.getSubPlugins().forEach(plugin -> {
|
||||||
|
|
||||||
|
PacketAction pluginAction = plugin.getPacketInterface().readEntityHandle(player);
|
||||||
|
if (pluginAction != PacketAction.NOTHING) action.set(pluginAction);
|
||||||
|
|
||||||
|
});
|
||||||
|
if (action.get() == PacketAction.CANCELLED) return null;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,84 +1,165 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R5;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R5;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.advancements.*;
|
import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
|
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||||
import net.minecraft.network.protocol.Packet;
|
import net.minecraft.network.protocol.Packet;
|
||||||
import net.minecraft.network.protocol.game.*;
|
import net.minecraft.network.protocol.game.*;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
import net.minecraft.world.entity.PositionMoveRotation;
|
import net.minecraft.world.entity.PositionMoveRotation;
|
||||||
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.level.portal.TeleportTransition;
|
import net.minecraft.world.level.GameType;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
|
import org.bukkit.craftbukkit.scoreboard.CraftScoreboard;
|
||||||
import org.bukkit.entity.Display;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.ItemDisplay;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
import org.bukkit.inventory.meta.components.CustomModelDataComponent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.nms.NMSPackets {
|
||||||
|
|
||||||
static Constructor<ClientboundSetPassengersPacket> passengerConstructor;
|
private static ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
static Constructor<ClientboundSetEntityLinkPacket> linkConstructor;
|
private static Entity fakeNmsEntity = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
static Constructor<ClientboundSetCameraPacket> cameraConstructor;
|
|
||||||
static Constructor<ClientboundPlayerLookAtPacket> lookAtConstructor;
|
|
||||||
|
|
||||||
static {
|
@Override @SuppressWarnings("unchecked")
|
||||||
try {
|
public void sendSharedEntityData(int entityId, Map<Integer, Number> dataValues, List<Player> sendTo) {
|
||||||
passengerConstructor = ClientboundSetPassengersPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
List<SynchedEntityData.DataValue<?>> nmsDataValues = dataValues.entrySet().stream().map(entry -> {
|
||||||
passengerConstructor.setAccessible(true);
|
int index = entry.getKey();
|
||||||
} catch (Exception e) {
|
Number value = entry.getValue();
|
||||||
e.printStackTrace();
|
return switch (value) {
|
||||||
}
|
case Byte byteVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.BYTE, byteVal);
|
||||||
try {
|
case Float floatVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.FLOAT, floatVal);
|
||||||
linkConstructor = ClientboundSetEntityLinkPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
case Integer intVal -> new SynchedEntityData.DataValue<>(index, EntityDataSerializers.INT, intVal);
|
||||||
linkConstructor.setAccessible(true);
|
default ->
|
||||||
} catch (Exception e) {
|
throw new IllegalArgumentException("Unsupported data value type: " + value.getClass().getSimpleName());
|
||||||
e.printStackTrace();
|
};
|
||||||
}
|
}).collect(Collectors.toList());
|
||||||
try {
|
|
||||||
cameraConstructor = ClientboundSetCameraPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
ClientboundSetEntityDataPacket packet = new ClientboundSetEntityDataPacket(entityId, nmsDataValues);
|
||||||
cameraConstructor.setAccessible(true);
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
} catch (Exception e) {
|
}
|
||||||
e.printStackTrace();
|
|
||||||
}
|
@Override
|
||||||
try {
|
public void sendFakePlayerInfoPacket(
|
||||||
lookAtConstructor = ClientboundPlayerLookAtPacket.class.getDeclaredConstructor(FriendlyByteBuf.class);
|
final Player skinnedPlayer,
|
||||||
lookAtConstructor.setAccessible(true);
|
final int entityId,
|
||||||
} catch (Exception e) {
|
final UUID uuid,
|
||||||
e.printStackTrace();
|
final String npcName,
|
||||||
}
|
final List<Player> sendTo
|
||||||
|
) {
|
||||||
|
ServerPlayer player = ((CraftPlayer) skinnedPlayer).getHandle();
|
||||||
|
String name = npcName.substring(0, 15);
|
||||||
|
GameProfile profile = new GameProfile(uuid, name);
|
||||||
|
|
||||||
|
Component component = AdventureUtils.MINI_MESSAGE.deserialize(name);
|
||||||
|
net.minecraft.network.chat.Component nmsComponent = HibiscusCommonsPlugin.isOnPaper() ? PaperAdventure.asVanilla(component) : net.minecraft.network.chat.Component.literal(name);
|
||||||
|
|
||||||
|
ClientboundPlayerInfoUpdatePacket.Entry entry = new ClientboundPlayerInfoUpdatePacket.Entry(uuid, profile, false, 0, GameType.CREATIVE, nmsComponent, true, player.listOrder, player.getChatSession().asData());
|
||||||
|
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||||
|
ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(actions, entry);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendPlayerInfoRemovePacket(final UUID uuid, final List<Player> sendTo) {
|
||||||
|
ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(uuid));
|
||||||
|
for (Player player : sendTo) sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMovePacket(
|
||||||
|
final int entityId,
|
||||||
|
final @NotNull Location from,
|
||||||
|
final @NotNull Location to,
|
||||||
|
final boolean onGround,
|
||||||
|
@NotNull List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte dx = (byte) (to.getX() - from.getX());
|
||||||
|
byte dy = (byte) (to.getY() - from.getY());
|
||||||
|
byte dz = (byte) (to.getZ() - from.getZ());
|
||||||
|
|
||||||
|
ClientboundMoveEntityPacket.Pos packet = new ClientboundMoveEntityPacket.Pos(entityId, dx, dy, dz, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendGamemodeChange(Player player, GameMode gameMode) {
|
||||||
|
ClientboundGameEventPacket.Type type = ClientboundGameEventPacket.CHANGE_GAME_MODE;
|
||||||
|
float param = gameMode.ordinal();
|
||||||
|
|
||||||
|
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(type, param);
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendLookAtPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
fakeNmsEntity.getBukkitEntity().teleport(location);
|
||||||
|
ClientboundPlayerLookAtPacket packet = new ClientboundPlayerLookAtPacket(EntityAnchorArgument.Anchor.EYES, fakeNmsEntity, EntityAnchorArgument.Anchor.EYES);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotateHeadPacket(int entityId, Location location, List<Player> sendTo) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
byte headRot = (byte) (location.getYaw() * 256.0F / 360.0F);
|
||||||
|
|
||||||
|
ClientboundRotateHeadPacket packet = new ClientboundRotateHeadPacket(fakeNmsEntity, headRot);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
yaw = (byte) (yaw * ROTATION_FACTOR);
|
||||||
|
pitch = (byte) (pitch * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendRotationPacket(int entityId, Location location, boolean onGround, List<Player> sendTo) {
|
||||||
|
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||||
|
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||||
|
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||||
|
ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, yaw, pitch, onGround);
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,28 +255,29 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
public void sendMountPacket(int mountId, int[] passengerIds, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
byteBuf.writeVarInt(mountId);
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
byteBuf.writeVarIntArray(passengerIds);
|
passenger.setId(id);
|
||||||
try {
|
return passenger;
|
||||||
ClientboundSetPassengersPacket packet = passengerConstructor.newInstance(byteBuf);
|
}).toList();
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
fakeNmsEntity.setId(mountId);
|
||||||
} catch (Exception e) {
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
e.printStackTrace();
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
}
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
public void sendLeashPacket(int leashEntity, int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
// Fake entities just to avoid reflection
|
||||||
byteBuf.writeInt(leashEntity);
|
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||||
byteBuf.writeInt(entityId);
|
Entity entity1 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
try {
|
Entity entity2 = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
ClientboundSetEntityLinkPacket packet = linkConstructor.newInstance(byteBuf);
|
entity1.setId(leashEntity);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
entity2.setId(entityId);
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
ClientboundSetEntityLinkPacket packet = new ClientboundSetEntityLinkPacket(entity1, entity2);
|
||||||
}
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -210,21 +292,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), java.util.Set.of(), onGround);
|
ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Set.of(), onGround);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRotationPacket(int entityId, float yaw, boolean onGround, List<Player> sendTo) {
|
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
byteBuf.writeFloat(yaw);
|
|
||||||
byteBuf.writeBoolean(onGround);
|
|
||||||
try {
|
|
||||||
ClientboundPlayerLookAtPacket packet = lookAtConstructor.newInstance(byteBuf);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -233,14 +301,10 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
public void sendCameraPacket(int entityId, List<Player> sendTo) {
|
||||||
FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer());
|
fakeNmsEntity.setId(entityId);
|
||||||
byteBuf.writeVarInt(entityId);
|
|
||||||
try {
|
ClientboundSetCameraPacket packet = new ClientboundSetCameraPacket(fakeNmsEntity);
|
||||||
ClientboundSetCameraPacket packet = cameraConstructor.newInstance(byteBuf);
|
for (Player p : sendTo) sendPacket(p, packet);
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -393,4 +457,18 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons.
|
|||||||
sendPacket(player, removePacket);
|
sendPacket(player, removePacket);
|
||||||
}, 2L);
|
}, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createMountPacket(int entityId, int[] passengerIds) {
|
||||||
|
fakeNmsEntity.setId(entityId);
|
||||||
|
List<Entity> passengers = Arrays.stream(passengerIds).mapToObj(id -> {
|
||||||
|
Entity passenger = new ArmorStand(net.minecraft.world.entity.EntityType.ARMOR_STAND, level);
|
||||||
|
passenger.setId(id);
|
||||||
|
return passenger;
|
||||||
|
}).toList();
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.copyOf(passengers);
|
||||||
|
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity);
|
||||||
|
fakeNmsEntity.passengers = ImmutableList.of();
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
package me.lojosho.hibiscuscommons.nms.v1_21_R5;
|
package me.lojosho.hibiscuscommons.nms.v1_21_R5;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
import net.minecraft.core.component.DataComponents;
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.network.Connection;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.item.component.DyedItemColor;
|
import net.minecraft.world.item.component.DyedItemColor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -51,4 +56,16 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleChannelOpen(@NotNull Player player) {
|
||||||
|
Channel channel = ((CraftPlayer) player).getHandle().connection.connection.channel;
|
||||||
|
ChannelPipeline pipeline = channel.pipeline();
|
||||||
|
|
||||||
|
NMSPacketChannel channelHandler = new NMSPacketChannel(player);
|
||||||
|
for (String key : pipeline.toMap().keySet()) {
|
||||||
|
if (!(pipeline.get(key) instanceof Connection)) continue;
|
||||||
|
pipeline.addBefore(key, "hibiscus_channel_handler", channelHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user