Last active
January 29, 2024 12:40
-
-
Save HeathLoganCampbell/3e5c0a482b509f8d490cd0fb9ebb57e6 to your computer and use it in GitHub Desktop.
Disguise items to players via packet, basically have under the hood item seperate for what each player sees. this means you can customize each item for each viewer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.skyblock.realm.customitems; | |
import com.comphenix.protocol.PacketType; | |
import com.comphenix.protocol.ProtocolLibrary; | |
import com.comphenix.protocol.ProtocolManager; | |
import com.comphenix.protocol.events.ListenerPriority; | |
import com.comphenix.protocol.events.PacketAdapter; | |
import com.comphenix.protocol.events.PacketContainer; | |
import com.comphenix.protocol.events.PacketEvent; | |
import com.comphenix.protocol.reflect.StructureModifier; | |
import com.comphenix.protocol.utility.MinecraftReflection; | |
import com.comphenix.protocol.wrappers.WrappedDataValue; | |
import com.comphenix.protocol.wrappers.WrappedDataWatcher; | |
import com.comphenix.protocol.wrappers.WrappedWatchableObject; | |
import com.comphenix.protocol.wrappers.nbt.NbtCompound; | |
import com.comphenix.protocol.wrappers.nbt.NbtFactory; | |
import com.comphenix.protocol.wrappers.nbt.NbtWrapper; | |
import com.google.common.collect.Lists; | |
import de.tr7zw.changeme.nbtapi.NBTItem; | |
import net.minecraft.server.level.EntityPlayer; | |
import net.minecraft.server.level.WorldServer; | |
import net.minecraft.world.entity.projectile.EntityFishingHook; | |
import org.bukkit.*; | |
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; | |
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; | |
import org.bukkit.entity.*; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.block.Action; | |
import org.bukkit.event.entity.CreatureSpawnEvent; | |
import org.bukkit.event.player.PlayerCommandPreprocessEvent; | |
import org.bukkit.event.player.PlayerGameModeChangeEvent; | |
import org.bukkit.event.player.PlayerInteractEvent; | |
import org.bukkit.event.player.PlayerToggleSneakEvent; | |
import org.bukkit.inventory.ItemStack; | |
import org.bukkit.inventory.meta.ItemMeta; | |
import org.bukkit.plugin.java.JavaPlugin; | |
import org.bukkit.util.Vector; | |
import java.lang.reflect.InvocationTargetException; | |
import java.time.LocalDate; | |
import java.time.LocalTime; | |
import java.util.*; | |
public class RealmCustomItemsPlugin extends JavaPlugin | |
{ | |
// Deep sea fishing? | |
// Net fishing? | |
// Lava fishing | |
// spear fishing | |
private static final WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.getItemStackSerializer(false); | |
public static Material UNDER_LAYING_MATERIAL = Material.FISHING_ROD; | |
public static Material DISPLAY_MATERIAL = Material.FISHING_ROD; | |
private void replaceItem(ItemStack itemStack) | |
{ | |
if(itemStack.getType() != UNDER_LAYING_MATERIAL) return; | |
NbtWrapper<?> wrapper = NbtFactory.fromItemTag(itemStack); | |
NbtCompound compound = NbtFactory.asCompound(wrapper); | |
if(!compound.containsKey("custom_item_id")) return; | |
int customItemId = compound.getInteger("custom_item_id"); | |
if(customItemId == 1) | |
{ | |
itemStack.setType(DISPLAY_MATERIAL); | |
ItemMeta itemMeta = itemStack.getItemMeta(); | |
itemMeta.setDisplayName(ChatColor.GREEN + "Fishing Rod"); | |
ArrayList<String> lines = new ArrayList<>(); | |
lines.add(CC.gray + "Your run of the mill fishing rod"); | |
lines.add(CC.gray + "used to catch a meal for one."); | |
lines.add(""); | |
lines.add(CC.bGray + "COMMON"); | |
itemMeta.setLore(lines); | |
itemStack.setItemMeta(itemMeta); | |
} | |
} | |
private Entity getEntityById(World world, int entityId) | |
{ | |
for (Entity entity : world.getEntities()) { | |
if (entity.getEntityId() == entityId) { | |
return entity; | |
} | |
} | |
return null; | |
} | |
private void spawnEntity(Location location, Vector vector, EntityType type, int shooterId) { | |
int entityId = 10000; | |
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); | |
packet.getIntegers().write(0, entityId); | |
packet.getUUIDs().write(0, UUID.randomUUID()); | |
packet.getEntityTypeModifier().write(0, type); | |
packet.getDoubles() | |
.write(0, location.getX()) | |
.write(1, location.getY()) | |
.write(2, location.getZ()); | |
packet.getIntegers() | |
.write(1, convertVelocity(vector.getX())) | |
.write(2, convertVelocity(vector.getY())) | |
.write(3, convertVelocity(vector.getZ())) | |
.write(4, shooterId); | |
for(Player player : Bukkit.getOnlinePlayers()) { | |
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | |
} | |
WrappedDataWatcher.Serializer intType = WrappedDataWatcher.Registry.get(Integer.class); | |
int fishingHookEntityId = 10000; | |
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); | |
PacketContainer metadataPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_METADATA); | |
metadataPacket.getIntegers().write(0, fishingHookEntityId); | |
for(Player player : Bukkit.getOnlinePlayers()) { | |
int targetEntityId = player.getEntityId(); // The entity ID of the entity to attach the fishing hook to | |
List<WrappedDataValue> values = Lists.newArrayList( | |
new WrappedDataValue(0, intType, -1)); | |
metadataPacket.getDataValueCollectionModifier().write(0, values); | |
protocolManager.sendServerPacket(player, metadataPacket); | |
} | |
} | |
private int convertVelocity(double velocity) { | |
return (int) (clamp(velocity, -3.9, 3.9) * 8000); | |
} | |
public static double clamp(double targetNum, double min, double max) { | |
// Makes sure a number is within a range | |
return Math.max(min, Math.min(targetNum, max)); | |
} | |
// RealmsTextures | |
// Sea Horse | |
///https://mcmodels.net/products/9164/more-fish | |
@Override | |
public void onEnable() { | |
// Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); | |
Bukkit.getPluginManager().registerEvents(new Listener() { | |
@EventHandler | |
public void onGameModeChange(PlayerGameModeChangeEvent e) | |
{ | |
Player player = e.getPlayer(); | |
Bukkit.getScheduler().scheduleSyncDelayedTask(RealmCustomItemsPlugin.this, () -> { | |
player.updateInventory(); | |
}, 1L); | |
} | |
@EventHandler | |
public void onPaper(PlayerInteractEvent e) | |
{ | |
if (!e.getAction().equals(Action.RIGHT_CLICK_AIR)) { | |
return; | |
} | |
if(!e.getItem().getType().equals(UNDER_LAYING_MATERIAL)) | |
{ | |
return; | |
} | |
NBTItem nbte = new NBTItem(e.getItem()); | |
if (!nbte.hasTag("custom_item_id")) | |
{ | |
return; | |
} | |
Integer customItemId = nbte.getInteger("custom_item_id"); | |
if(customItemId == 1) | |
{ | |
// Vector vec = e.getPlayer().getLocation().getDirection().multiply(1.5); | |
// e.getPlayer().launchProjectile(FishHook.class, vec); | |
} | |
} | |
private static int ENTITY_ID = 100000; | |
@EventHandler | |
public void onShift(PlayerToggleSneakEvent e) | |
{ | |
// Location location = e.getPlayer().getLocation(); | |
// spawnEntity(location, new Vector(0, 1, 0), EntityType.FISHING_HOOK, e.getPlayer().getEntityId()); | |
} | |
@EventHandler | |
public void onCommand(PlayerCommandPreprocessEvent e) | |
{ | |
if (e.getMessage().toLowerCase().contains("yeet")) { | |
int customItemId = 1; | |
ItemStack itemStack = new ItemStack(UNDER_LAYING_MATERIAL); | |
ItemMeta itemMeta = itemStack.getItemMeta(); | |
ArrayList<String> lines = new ArrayList<>(); | |
lines.add("Custom Item Id: " + customItemId); | |
itemMeta.setLore(lines); | |
itemStack.setItemMeta(itemMeta); | |
NBTItem nbte = new NBTItem(itemStack); | |
nbte.setInteger("custom_item_id", customItemId); | |
ItemStack item = nbte.getItem(); | |
e.getPlayer().getInventory().addItem(item); | |
} | |
} | |
}, this); | |
ProtocolLibrary.getProtocolManager().addPacketListener( | |
new PacketAdapter(this, ListenerPriority.NORMAL, PacketType.Play.Server.WINDOW_ITEMS, PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS, PacketType.Play.Server.SPAWN_ENTITY, PacketType.Play.Server.ENTITY_METADATA) { | |
@Override | |
public void onPacketSending(PacketEvent event) { | |
PacketContainer packet = event.getPacket(); | |
if(event.getPlayer().getGameMode() == GameMode.CREATIVE) return; | |
if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) | |
{ | |
ItemStack itemStack = packet.getItemModifier().read(0); | |
if (itemStack != null && itemStack.getType() != Material.AIR) { | |
replaceItem(itemStack); | |
} | |
} | |
if (event.getPacketType() == PacketType.Play.Server.WINDOW_ITEMS) { | |
List<ItemStack> itemStacks = packet.getItemListModifier().read(0); | |
ItemStack carrierItem = packet.getItemModifier().read(0); | |
if (carrierItem != null && carrierItem.getType() != Material.AIR) { | |
replaceItem(carrierItem); | |
} | |
for (ItemStack itemStack: itemStacks) { | |
if (itemStack != null && itemStack.getType() != Material.AIR) { | |
replaceItem(itemStack); | |
} | |
} | |
} | |
if(event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) | |
{ | |
int entityId = packet.getIntegers().read(0); | |
Entity entity = getEntityById(event.getPlayer().getWorld(), entityId); | |
if (entity instanceof Item) { | |
Item item = (Item) entity; | |
ItemStack itemStack = item.getItemStack(); | |
if (itemStack.getType() == UNDER_LAYING_MATERIAL) | |
{ | |
packet.getDataValueCollectionModifier() | |
.write(0, List.of( | |
// https://wiki.vg/Entity_metadata#Item_Entity | |
new WrappedDataValue(8, serializer, MinecraftReflection.getMinecraftItemStack(new ItemStack(DISPLAY_MATERIAL))) | |
)); | |
} | |
} | |
} | |
event.setPacket(packet); | |
} | |
} | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<repositories> | |
<repository> | |
<id>spigot-repo</id> | |
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> | |
</repository> | |
<repository> | |
<id>dmulloy2-repo</id> | |
<url>https://repo.dmulloy2.net/repository/public/</url> | |
</repository> | |
<repository> | |
<id>aikar</id> | |
<url>https://repo.aikar.co/content/groups/aikar/</url> | |
</repository> | |
<repository> | |
<id>codemc-repo</id> | |
<url>https://repo.codemc.io/repository/maven-public/</url> | |
</repository> | |
</repositories> | |
<dependencies> | |
<dependency> | |
<groupId>org.spigotmc</groupId> | |
<artifactId>spigot-api</artifactId> | |
<version>1.20.2-R0.1-SNAPSHOT</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.spigotmc</groupId> | |
<artifactId>spigot</artifactId> | |
<version>1.20.2-R0.1-SNAPSHOT</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.projectlombok</groupId> | |
<artifactId>lombok</artifactId> | |
<version>1.18.30</version> | |
<scope>compile</scope> | |
</dependency> | |
<dependency> | |
<groupId>com.comphenix.protocol</groupId> | |
<artifactId>ProtocolLib</artifactId> | |
<version>5.1.0</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>de.tr7zw</groupId> | |
<artifactId>item-nbt-api</artifactId> | |
<version>2.12.2</version> | |
</dependency> | |
</dependencies> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment