diff --git a/src/main/java/IDEAS b/src/main/java/IDEAS new file mode 100644 index 0000000..65baf92 --- /dev/null +++ b/src/main/java/IDEAS @@ -0,0 +1,100 @@ +A teleportation plugin that allows players to easily and quickly travel to different locations on the server. +A rewards system that gives players rewards for reaching certain milestones, such as reaching a certain level or completing specific tasks. +A custom enchantments plugin that allows players to add unique enchantments to their gear. +A custom crafting system that adds new recipes and allows players to create unique items. +A minigame plugin that adds fun, engaging minigames for players to enjoy. +A player-run economy plugin that allows players to trade and sell items with one another. +A chat enhancement plugin that adds fun emotes, chat formatting options, and other features to improve the chat experience. +A pet plugin that allows players to tame and care for their own pets. +A player-run shop plugin that allows players to create their own shops and sell items to other players. +A dungeon generator plugin that randomly generates challenging dungeon experiences for players to explore. +A chat enhancement plugin that allows players to use custom emotes and chat formatting. +A teleportation plugin that allows players to set and teleport to waypoints. +A death tracker plugin that keeps track of how many times a player has died and displays it in chat. +A farming plugin that makes it easier for players to plant and grow crops. +A minigame plugin that adds new games for players to play, such as parkour challenges or capture the flag. +A voting plugin that allows players to vote on different options, such as which game mode to play next or which map to use. +A recipe book plugin that allows players to access a comprehensive list of all the crafting recipes in the game. +An economy plugin that adds a virtual currency and trading system to the game, allowing players to buy and sell items with one another. +A permissions plugin that allows server administrators to manage player permissions and control who can do what on the server. +A game mode plugin that adds new game modes, such as creative mode or adventure mode, for players to choose from. +A dungeon generation plugin that automatically generates new dungeon structures for players to explore and conquer. +A parkour plugin that adds new parkour maps and challenges for players to complete. +A mob spawning control plugin that allows players to customize mob spawning behavior on the server. +A music plugin that allows players to play music in-game using note blocks. +A custom crafting plugin that allows players to create their own custom crafting recipes. +A loot table editor plugin that allows players to customize the loot that mobs drop when they are killed. +A scoreboard plugin that allows players to create and customize their own in-game scoreboard. +A grief prevention plugin that allows players to protect their builds from being destroyed by other players. +A teleport request plugin that allows players to request teleportations to other players and requires the other player to accept the request before the teleportation occurs. +A weather control plugin that allows players to change the weather on the server, such as making it rain or clearing up the skies. +A plugin that adds new types of blocks, items, or mobs to the game. +A plugin that allows players to create and customize their own in-game homes or shops. +A plugin that introduces a new type of game mechanic, such as a crafting system or a trading system. +A plugin that adds new mini-games or challenges for players to complete. +A plugin that allows players to use custom skins or textures for their characters. +A plugin that introduces a new level of difficulty for players to experience, such as a "hardcore" mode. +A plugin that adds new, themed environments for players to explore, such as a jungle or a desert. +A plugin that allows players to create and manage their own in-game economy, with the ability to buy and sell items with each other. +A plugin that introduces new forms of transportation, such as minecart rail networks or boats. +A plugin that allows players to create and customize their own in-game maps, which can be shared with other players. +A plugin that allows players to create and customize their own in-game characters, including appearance, abilities, and stats. +A plugin that introduces new forms of combat, such as ranged weapons or magic spells. +A plugin that adds new dungeons or boss battles for players to challenge. +A plugin that allows players to create and join different factions or clans, and compete against each other in in-game events or challenges. +A plugin that adds new biomes or dimensions for players to explore, such as a Nether or a End-like dimension. +A plugin that introduces new environmental hazards or challenges, such as weather effects or dangerous mobs. +A plugin that allows players to create and customize their own in-game weapons, armor, or tools. +A plugin that adds new types of crops, food, or farming tools for players to use. +A plugin that allows players to create and customize their own in-game quests or objectives, which can be shared with other players. +A plugin that introduces new forms of transportation, such as flying mounts or teleportation spells. +A plugin that adds new forms of currency, such as virtual coins or tokens, which players can earn and spend in-game. +A plugin that introduces new forms of resource gathering or processing, such as mining, smelting, or crafting. +A plugin that allows players to create and customize their own in-game shops or markets, where they can buy and sell items with each other. +A plugin that adds new challenges or events for players to participate in, such as races, tournaments, or scavenger hunts. +A plugin that allows players to create and customize their own in-game pets or companions, which can provide various benefits or abilities. +A plugin that adds new environmental effects, such as day/night cycles or changing seasons. +A plugin that allows players to create and customize their own in-game vehicles, such as cars, planes, or boats. +A plugin that introduces new forms of player-versus-player (PvP) combat, such as team battles or capture the flag. +A plugin that allows players to create and customize their own in-game skills or abilities, which can be leveled up and improved over time. +A plugin that adds new types of terrain or structures for players to explore, such as caves, ruins, or abandoned buildings. +A player teleportation plugin +A plugin that adds custom crafting recipes +A plugin that adds new types of enemies and boss battles +A plugin that allows players to create and join guilds +A plugin that adds new types of weapons and armor +A plugin that allows players to create and customize their own houses +A plugin that adds a quest and adventure system +A plugin that adds new types of biomes and dimensions +A plugin that allows players to ride and breed different types of horses +A plugin that adds new types of crops and plants for players to farm +A plugin that allows players to fish and cook different types of food +A plugin that adds new types of pets and companions for players to tame +A plugin that allows players to create and customize their own NPC characters +A plugin that adds new types of weather and environmental effects +A plugin that allows players to craft and use magic spells +A plugin that adds new types of transportation, such as minecarts or boats +A plugin that allows players to build and customize their own vehicles +A plugin that adds new types of trades and professions for players to pursue +A plugin that allows players to play mini-games and challenges with other players +A plugin that adds new types of items and resources for players to collect and use. +A plugin that adds a new type of energy system for players to manage and use +A plugin that allows players to build and customize their own multi-block structures +A plugin that adds new types of dimensions, each with their own unique features and challenges +A plugin that allows players to build and customize their own custom weapons and armor +A plugin that adds new types of resources, such as ores, gems, and fluids, that players can extract and use +A plugin that allows players to create and customize their own custom enchantments and potion effects +A plugin that adds new types of machines and technology for players to build and use +A plugin that allows players to create and customize their own custom items and blocks +A plugin that adds new types of hazards and challenges, such as natural disasters or enemy attacks, for players to face +A plugin that allows players to build and customize their own transportation networks, such as railways or highways +A plugin that adds new types of terrain and landscape features, such as caves, ravines, and mountains +A plugin that allows players to create and customize their own custom game modes and rules +A plugin that adds new types of interactive objects and mechanisms for players to use and explore +A plugin that allows players to build and customize their own custom AI entities, such as guards or pets +A plugin that adds new types of environmental effects and physics, such as dynamic lighting or water simulation +A plugin that allows players to create and customize their own custom dimension and world generation settings +A plugin that adds new types of resources and materials for players to collect and use in their builds +A plugin that allows players to create and customize their own custom multiplayer game modes and rules +A plugin that adds new types of challenges and rewards for players to earn and unlock +A plugin that allows players to create and customize their own custom adventure maps and scenarios. \ No newline at end of file diff --git a/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java b/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java index 9cd36fe..0497b85 100644 --- a/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java +++ b/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java @@ -1,5 +1,6 @@ package me.night.nullvalkyrie.commands; +import me.night.nullvalkyrie.entities.npcs.NPCManager; import me.night.nullvalkyrie.entities.pets.ZombiePet; import org.bukkit.Material; import org.bukkit.command.CommandSender; @@ -33,6 +34,7 @@ public class BetaCommand extends Command { itemMeta2.setCustomModelData(1010101); item2.setItemMeta(itemMeta2); player.getInventory().addItem(item2); + NPCManager.createNPC(player, args[0]); } } diff --git a/src/main/java/me/night/nullvalkyrie/entities/holograms/PerPlayerHologram.java b/src/main/java/me/night/nullvalkyrie/entities/holograms/PerPlayerHologram.java index b4e2550..bf4d458 100644 --- a/src/main/java/me/night/nullvalkyrie/entities/holograms/PerPlayerHologram.java +++ b/src/main/java/me/night/nullvalkyrie/entities/holograms/PerPlayerHologram.java @@ -1,18 +1,16 @@ package me.night.nullvalkyrie.entities.holograms; +import me.night.nullvalkyrie.packets.protocol.PacketPlayOutEntityMetadata; +import me.night.nullvalkyrie.packets.protocol.PacketPlayOutSpawnEntity; import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.world.entity.decoration.ArmorStand; import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; import org.bukkit.entity.Player; -import java.util.List; import java.util.Optional; public class PerPlayerHologram { @@ -27,13 +25,10 @@ public class PerPlayerHologram { ServerPlayer p = ((CraftPlayer) player).getHandle(); ArmorStand stand = new ArmorStand(p.level, player.getLocation().getX(), y, player.getLocation().getZ()); stand.setInvisible(true); - ServerGamePacketListenerImpl connection = p.connection; - connection.send(new ClientboundAddEntityPacket(stand)); + new PacketPlayOutSpawnEntity(player, stand); SynchedEntityData watcher = stand.getEntityData(); - Optional optional = Optional.of(Component.nullToEmpty(line)); - watcher.set(new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT), optional); + watcher.set(new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT), Optional.of(Component.nullToEmpty(line))); watcher.set(new EntityDataAccessor<>(3, EntityDataSerializers.BOOLEAN), true); - List> list = watcher.getNonDefaultValues(); - connection.send(new ClientboundSetEntityDataPacket(stand.getBukkitEntity().getEntityId(), list)); + new PacketPlayOutEntityMetadata(player, stand, watcher.getNonDefaultValues()); } } diff --git a/src/main/java/me/night/nullvalkyrie/entities/npcs/NPCManager.java b/src/main/java/me/night/nullvalkyrie/entities/npcs/NPCManager.java index 8f9099e..38a62a5 100644 --- a/src/main/java/me/night/nullvalkyrie/entities/npcs/NPCManager.java +++ b/src/main/java/me/night/nullvalkyrie/entities/npcs/NPCManager.java @@ -3,8 +3,9 @@ package me.night.nullvalkyrie.entities.npcs; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.datafixers.util.Pair; -import me.night.nullvalkyrie.Main; import me.night.nullvalkyrie.database.NPCDataManager; +import me.night.nullvalkyrie.packets.protocol.PacketPlayOutEntityMetadata; +import me.night.nullvalkyrie.packets.protocol.PacketPlayOutSpawnEntity; import me.night.nullvalkyrie.util.*; import net.minecraft.network.protocol.game.*; import net.minecraft.network.syncher.*; @@ -35,6 +36,7 @@ public class NPCManager { return NPCs; } public static void createNPC(Player player, String name) { // name must be less than 16 characters including color codes + // TODO: npc not even spawning rn ServerPlayer sp = ((CraftPlayer) player).getHandle(); MinecraftServer server = sp.server; ServerLevel level = ((CraftWorld) player.getLocation().getWorld()).getHandle(); @@ -51,13 +53,11 @@ public class NPCManager { public static void addNPCPacket(ServerPlayer npc) { for (Player player : Bukkit.getOnlinePlayers()) { ServerGamePacketListenerImpl pc = ((CraftPlayer) player).getHandle().connection; - pc.send(new ClientboundAddPlayerPacket(npc)); + new PacketPlayOutSpawnEntity(player, npc); pc.send(new ClientboundRotateHeadPacket(npc, (byte) (npc.getBukkitYaw() * 256 / 360))); SynchedEntityData watcher = npc.getEntityData(); watcher.set(new EntityDataAccessor<>(17, EntityDataSerializers.BYTE), (byte) 127); - List> list = watcher.getNonDefaultValues(); - pc.send(new ClientboundSetEntityDataPacket(npc.getBukkitEntity().getEntityId(), list)); - Bukkit.getScheduler().runTaskLaterAsynchronously(Main.getPlugin(Main.class), () -> pc.send(new ClientboundPlayerInfoRemovePacket(List.of(npc.getUUID()))), 50); + new PacketPlayOutEntityMetadata(player, npc, watcher.getNonDefaultValues()); ItemStack netheriteAxe = new ItemStack(Material.NETHERITE_AXE); ItemStack anotherAxe = new ItemStack(Material.NETHERITE_INGOT); List> itemList = new ArrayList<>(); @@ -70,13 +70,11 @@ public class NPCManager { public static void addJoinPacket(Player player) { for (ServerPlayer npc : NPCs) { ServerGamePacketListenerImpl pc = ((CraftPlayer) player).getHandle().connection; - pc.send(new ClientboundAddPlayerPacket(npc)); + new PacketPlayOutSpawnEntity(player, npc); pc.send(new ClientboundRotateHeadPacket(npc, (byte) (npc.getBukkitYaw() * 256 / 360))); SynchedEntityData watcher = npc.getEntityData(); watcher.set(new EntityDataAccessor<>(17, EntityDataSerializers.BYTE), (byte) 127); - List> list = watcher.getNonDefaultValues(); - pc.send(new ClientboundSetEntityDataPacket(npc.getBukkitEntity().getEntityId(), list)); - Bukkit.getScheduler().runTaskLaterAsynchronously(Main.getPlugin(Main.class), () -> pc.send(new ClientboundPlayerInfoRemovePacket(List.of(npc.getUUID()))), 50); + new PacketPlayOutEntityMetadata(player, npc, watcher.getNonDefaultValues()); ItemStack netheriteAxe = new ItemStack(Material.NETHERITE_AXE); ItemStack anotherAxe = new ItemStack(Material.NETHERITE_INGOT); List> itemList = new ArrayList<>(); diff --git a/src/main/java/me/night/nullvalkyrie/events/listeners/CustomItemEvents.java b/src/main/java/me/night/nullvalkyrie/events/listeners/CustomItemEvents.java index e2d578c..ca04bf0 100644 --- a/src/main/java/me/night/nullvalkyrie/events/listeners/CustomItemEvents.java +++ b/src/main/java/me/night/nullvalkyrie/events/listeners/CustomItemEvents.java @@ -1,14 +1,10 @@ package me.night.nullvalkyrie.events.listeners; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.BlockPosition; import me.night.nullvalkyrie.entities.items.CustomItemManager; import me.night.nullvalkyrie.entities.items.Pickaxe; import me.night.nullvalkyrie.enums.Rarity; import me.night.nullvalkyrie.Main; +import me.night.nullvalkyrie.packets.protocol.PacketPlayOutBlockBreakAnimation; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.*; @@ -26,7 +22,6 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; -import java.lang.reflect.InvocationTargetException; import java.util.*; public class CustomItemEvents implements Listener { @@ -327,26 +322,10 @@ public class CustomItemEvents implements Listener { int blockStage = blockStages.getOrDefault(block.getLocation(), 0); blockStage = blockStage == 10 ? 0 : blockStage + 1; blockStages.put(block.getLocation(), blockStage); - sendBlockDamage(player, block); + new PacketPlayOutBlockBreakAnimation(player, block.getLocation(), blockStages.get(block.getLocation())); if (blockStage == 0) { blockStages.remove(block.getLocation()); block.breakNaturally(); } } - - final ProtocolManager manager = ProtocolLibrary.getProtocolManager(); - - public void sendBlockDamage(Player player, Block block) { - Location location = block.getLocation(); - int locationId = location.getBlockX() + location.getBlockY() + location.getBlockZ(); - PacketContainer packet = manager.createPacket(PacketType.Play.Server.BLOCK_BREAK_ANIMATION); - packet.getIntegers().write(0, locationId); // set entity ID to the location - packet.getBlockPositionModifier().write(0, new BlockPosition(location.toVector())); // set the block location - packet.getIntegers().write(1, blockStages.get(location)); // set the damage to blockStage - try { - manager.sendServerPacket(player, packet); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } } \ No newline at end of file diff --git a/src/main/java/me/night/nullvalkyrie/events/listeners/ServerEvents.java b/src/main/java/me/night/nullvalkyrie/events/listeners/ServerEvents.java index b1afd18..e6ee2f2 100644 --- a/src/main/java/me/night/nullvalkyrie/events/listeners/ServerEvents.java +++ b/src/main/java/me/night/nullvalkyrie/events/listeners/ServerEvents.java @@ -1,7 +1,7 @@ package me.night.nullvalkyrie.events.listeners; import me.night.nullvalkyrie.events.custom.InteractHologramEvent; -import me.night.nullvalkyrie.packets.PacketInjector; +import me.night.nullvalkyrie.packets.handle.PacketInjector; import me.night.nullvalkyrie.util.Util; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/src/main/java/me/night/nullvalkyrie/packets/PacketHandler.java b/src/main/java/me/night/nullvalkyrie/packets/handle/PacketHandler.java similarity index 92% rename from src/main/java/me/night/nullvalkyrie/packets/PacketHandler.java rename to src/main/java/me/night/nullvalkyrie/packets/handle/PacketHandler.java index 0414829..2864884 100644 --- a/src/main/java/me/night/nullvalkyrie/packets/PacketHandler.java +++ b/src/main/java/me/night/nullvalkyrie/packets/handle/PacketHandler.java @@ -1,4 +1,4 @@ -package me.night.nullvalkyrie.packets; +package me.night.nullvalkyrie.packets.handle; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; @@ -24,8 +24,8 @@ public class PacketHandler extends ChannelDuplexHandler { } @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - super.write(ctx, msg, promise); + public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { + super.write(ctx, packet, promise); } @Override diff --git a/src/main/java/me/night/nullvalkyrie/packets/PacketInjector.java b/src/main/java/me/night/nullvalkyrie/packets/handle/PacketInjector.java similarity index 61% rename from src/main/java/me/night/nullvalkyrie/packets/PacketInjector.java rename to src/main/java/me/night/nullvalkyrie/packets/handle/PacketInjector.java index 4c66f18..0700008 100644 --- a/src/main/java/me/night/nullvalkyrie/packets/PacketInjector.java +++ b/src/main/java/me/night/nullvalkyrie/packets/handle/PacketInjector.java @@ -1,13 +1,12 @@ -package me.night.nullvalkyrie.packets; +package me.night.nullvalkyrie.packets.handle; import io.netty.channel.Channel; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; import org.bukkit.entity.Player; public class PacketInjector { public void addPlayer(Player p) { try { - Channel ch = ((CraftPlayer) p).getHandle().connection.getConnection().channel; + Channel ch = me.night.nullvalkyrie.packets.protocol.Channel.getChannel(p); if (ch.pipeline().get("PacketInjector") == null) { PacketHandler h = new PacketHandler(p); ch.pipeline().addBefore("packet_handler", "PacketInjector", h); @@ -19,7 +18,7 @@ public class PacketInjector { public void removePlayer(Player p) { try { - Channel ch = ((CraftPlayer) p).getHandle().connection.getConnection().channel; // NMS: 1.19.2 https://nms.screamingsandals.org/1.19.2/net/minecraft/server/network/ServerGamePacketListenerImpl.html PlayerConnection -> NetworkManager -> Channel + Channel ch = me.night.nullvalkyrie.packets.protocol.Channel.getChannel(p); if (ch.pipeline().get("PacketInjector") != null) { ch.pipeline().remove("PacketInjector"); } diff --git a/src/main/java/me/night/nullvalkyrie/packets/protocol/Channel.java b/src/main/java/me/night/nullvalkyrie/packets/protocol/Channel.java new file mode 100644 index 0000000..b771540 --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/packets/protocol/Channel.java @@ -0,0 +1,10 @@ +package me.night.nullvalkyrie.packets.protocol; + +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class Channel { + public static io.netty.channel.Channel getChannel(Player player) { + return ((CraftPlayer) player).getHandle().connection.getConnection().channel; // NMS: 1.19.2 https://nms.screamingsandals.org/1.19.2/net/minecraft/server/network/ServerGamePacketListenerImpl.html PlayerConnection -> NetworkManager -> Channel + } +} diff --git a/src/main/java/me/night/nullvalkyrie/packets/protocol/Packet.java b/src/main/java/me/night/nullvalkyrie/packets/protocol/Packet.java new file mode 100644 index 0000000..b3369db --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/packets/protocol/Packet.java @@ -0,0 +1,4 @@ +package me.night.nullvalkyrie.packets.protocol; + +public interface Packet { +} diff --git a/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutBlockBreakAnimation.java b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutBlockBreakAnimation.java new file mode 100644 index 0000000..e1d22fb --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutBlockBreakAnimation.java @@ -0,0 +1,14 @@ +package me.night.nullvalkyrie.packets.protocol; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class PacketPlayOutBlockBreakAnimation implements Packet { + public PacketPlayOutBlockBreakAnimation(Player player, Location x, int stage) { + ClientboundBlockDestructionPacket packet = new ClientboundBlockDestructionPacket(player.getEntityId(), new BlockPos(x.getBlockX(), x.getBlockY(), x.getBlockZ()), stage); + ((CraftPlayer) player).getHandle().connection.send(packet); + } +} diff --git a/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutEntityMetadata.java b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutEntityMetadata.java new file mode 100644 index 0000000..da8bda5 --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutEntityMetadata.java @@ -0,0 +1,15 @@ +package me.night.nullvalkyrie.packets.protocol; + +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.world.entity.Entity; +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import java.util.List; + +public class PacketPlayOutEntityMetadata implements Packet { + public PacketPlayOutEntityMetadata(Player player, Entity entity, List> list) { + ((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityDataPacket(entity.getBukkitEntity().getEntityId(), list)); + } +} diff --git a/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutSpawnEntity.java b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutSpawnEntity.java new file mode 100644 index 0000000..d79e3d4 --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/packets/protocol/PacketPlayOutSpawnEntity.java @@ -0,0 +1,13 @@ +package me.night.nullvalkyrie.packets.protocol; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.world.entity.Entity; +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class PacketPlayOutSpawnEntity implements Packet { + public PacketPlayOutSpawnEntity(Player player, Entity entity) { + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(entity); + ((CraftPlayer) player).getHandle().connection.send(packet); + } +}