9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-26 02:19:25 +00:00

Added packets with hats

This commit is contained in:
HeroBrineGoat
2021-11-12 13:30:34 -05:00
parent 47c5514e28
commit ce94d962a6
15 changed files with 288 additions and 24 deletions

View File

@@ -46,5 +46,10 @@
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$MAVEN_REPOSITORY$/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven7" />
<option name="name" value="maven7" />
<option name="url" value="https://repo.dmulloy2.net/repository/public/" />
</remote-repository>
</component>
</project>

View File

@@ -9,12 +9,13 @@ version '1.0.0'
repositories {
mavenCentral()
mavenLocal()
maven { url 'https://papermc.io/repo/repository/maven-public/' }
maven { url = 'https://papermc.io/repo/repository/maven-public/' }
maven { url = 'https://repo.mattstudios.me/artifactory/public/' }
maven { url = 'https://jitpack.io' }
maven { url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
maven { url = 'https://repo.leonardobishop.com/releases/' }
maven { url = 'https://jitpack.io' }
maven { url = 'https://repo.dmulloy2.net/repository/public/' }
}
dependencies {
@@ -23,6 +24,7 @@ dependencies {
compileOnly 'io.papermc.paper:paper:1.17.1-R0.1-SNAPSHOT'
compileOnly 'org.jetbrains:annotations:22.0.0'
compileOnly 'net.kyori:adventure-api:4.9.3'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.0'
implementation 'net.kyori:adventure-text-minimessage:4.2.0-SNAPSHOT'
implementation 'net.kyori:adventure-platform-bukkit:4.0.0'
implementation 'dev.triumphteam:triumph-gui:3.0.3'

View File

@@ -1,7 +1,11 @@
package io.github.fisher2911.hmccosmetics;
import com.comphenix.protocol.ProtocolLib;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
import io.github.fisher2911.hmccosmetics.listener.JoinListener;
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages;
@@ -13,6 +17,7 @@ import java.util.List;
public class HMCCosmetics extends JavaPlugin {
private ProtocolManager protocolManager;
private UserManager userManager;
private MessageHandler messageHandler;
private CosmeticsMenu cosmeticsMenu;
@@ -20,6 +25,7 @@ public class HMCCosmetics extends JavaPlugin {
@Override
public void onEnable() {
protocolManager = ProtocolLibrary.getProtocolManager();
this.messageHandler = new MessageHandler(this);
this.userManager = new UserManager(this);
this.cosmeticsMenu = new CosmeticsMenu(this);
@@ -39,7 +45,8 @@ public class HMCCosmetics extends JavaPlugin {
}
private void registerListeners() {
List.of(new JoinListener(this)).
List.of(new JoinListener(this),
new ClickListener(this)).
forEach(listener ->
this.getServer().getPluginManager().registerEvents(listener, this)
);
@@ -69,4 +76,9 @@ public class HMCCosmetics extends JavaPlugin {
public CosmeticsMenu getCosmeticsMenu() {
return cosmeticsMenu;
}
public ProtocolManager getProtocolManager() {
return protocolManager;
}
}

View File

@@ -76,8 +76,6 @@ public class CosmeticsCommand extends CommandBase {
case BACKPACK -> user.getPlayerArmor().getBackpack();
};
player.sendMessage("Opening dye menu");
this.cosmeticsMenu.openDyeSelectorGui(user, armorItem);
}

View File

@@ -4,6 +4,7 @@ import dev.triumphteam.gui.guis.GuiItem;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.message.Adventure;
import io.github.fisher2911.hmccosmetics.util.Keys;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import io.github.fisher2911.hmccosmetics.util.Utils;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
@@ -193,6 +194,8 @@ public class ItemSerializer implements TypeSerializer<GuiItem> {
final String openMenu = openMenuNode.getString(
Utils.replaceIfNull(OPEN_MENU, ""));
Keys.setKey(itemStack);
try {
final ArmorItem.Type cosmeticType = ArmorItem.Type.valueOf(
Utils.replaceIfNull(

View File

@@ -128,17 +128,15 @@ public class CosmeticGui {
switch (type) {
case HAT -> {
final boolean set = user.setOrUnsetHat(armorItem, this.messageHandler);
final boolean set = user.setOrUnsetHat(armorItem, this.messageHandler, this.plugin.getUserManager());
if (set) {
actionIfSet.execute(event);
player.sendMessage("Set");
}
}
case BACKPACK -> {
final boolean set = user.setOrUnsetBackpack(armorItem, this.messageHandler);
if (set) {
actionIfSet.execute(event);
player.sendMessage("Set");
}
}
}

View File

@@ -59,10 +59,8 @@ public class CosmeticsMenu {
final CosmeticGui gui = this.guiMap.get(DYE_MENU);
if (gui instanceof final DyeSelectorGui dyeSelectorGui) {
player.sendMessage("Is Dye selector");
dyeSelectorGui.getGui(user, armorItem).open(player);
} else {
player.sendMessage("Not dye selector");
player.sendMessage(gui.getClass().toString());
}
}

View File

@@ -68,12 +68,10 @@ public class DyeSelectorGui extends CosmeticGui{
};
if (itemStack == null) {
event.getWhoClicked().sendMessage("ItemStack null");
return;
}
if (!armorItem.isDyeable()) {
event.getWhoClicked().sendMessage("Not dyeable");
return;
}
@@ -83,7 +81,6 @@ public class DyeSelectorGui extends CosmeticGui{
final GuiItem guiItem = this.guiItemMap.get(event.getSlot());
if (!(guiItem instanceof final ColorItem colorItem)) {
event.getWhoClicked().sendMessage("Not color item");
return;
}
@@ -102,7 +99,7 @@ public class DyeSelectorGui extends CosmeticGui{
);
switch (type) {
case HAT -> user.setHat(newArmorItem);
case HAT -> user.setHat(newArmorItem, plugin.getUserManager());
case BACKPACK -> user.setBackpack(newArmorItem);
}
});

View File

@@ -0,0 +1,45 @@
package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.PlayerInventory;
import java.util.Optional;
public class ClickListener implements Listener {
private final HMCCosmetics plugin;
private final UserManager userManager;
public ClickListener(final HMCCosmetics plugin) {
this.plugin = plugin;
this.userManager = this.plugin.getUserManager();
}
@EventHandler
public void onHelmetClick(final InventoryClickEvent event) {
final HumanEntity player = event.getWhoClicked();
final Optional<User> optionalUser = this.userManager.get(player.getUniqueId());
if (optionalUser.isEmpty()) {
return;
}
if (event.getClickedInventory() instanceof final PlayerInventory inventory) {
final User user = optionalUser.get();
if (event.getSlot() == 39) {
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {
this.userManager.updateHat(user);
}, 1);
}
}
}
}

View File

@@ -2,6 +2,8 @@ package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

View File

@@ -45,7 +45,9 @@ public class User {
}
// return true if backpack was set
public boolean setOrUnsetBackpack(final ArmorItem backpack, final MessageHandler messageHandler) {
public boolean setOrUnsetBackpack(
final ArmorItem backpack,
final MessageHandler messageHandler) {
final Player player = this.getPlayer();
@@ -80,14 +82,17 @@ public class User {
}
public void setHat(final ArmorItem hat) {
public void setHat(final ArmorItem hat, final UserManager userManager) {
this.playerArmor.setHat(hat);
this.getPlayer().getEquipment().setHelmet(this.playerArmor.getHat().getItemStack());
this.lastSetItem = hat;
userManager.updateHat(this);
}
// return true if hat was set
public boolean setOrUnsetHat(final ArmorItem hat, final MessageHandler messageHandler) {
public boolean setOrUnsetHat(
final ArmorItem hat,
final MessageHandler messageHandler,
final UserManager userManager) {
final Player player = this.getPlayer();
@@ -102,16 +107,18 @@ public class User {
new ArrayList<>(),
"",
ArmorItem.Type.HAT
));
),
userManager);
messageHandler.sendMessage(
player,
Messages.REMOVED_HAT
);
return false;
}
this.setHat(hat);
this.setHat(hat, userManager);
messageHandler.sendMessage(
player,
Messages.SET_HAT
@@ -127,7 +134,6 @@ public class User {
}
// teleports armor stand to the correct position
// todo change to packets
public void updateArmorStand() {
final ArmorItem backpackArmorItem = this.playerArmor.getBackpack();
if (backpackArmorItem == null ) {

View File

@@ -1,17 +1,42 @@
package io.github.fisher2911.hmccosmetics.user;
import com.comphenix.protocol.PacketType;
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.events.PacketListener;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import dev.triumphteam.gui.guis.GuiItem;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.message.Placeholder;
import io.github.fisher2911.hmccosmetics.util.Keys;
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
import net.minecraft.network.protocol.game.PacketPlayOutEntityEquipment;
import net.minecraft.world.entity.EnumItemSlot;
import net.minecraft.world.level.levelgen.HeightMap;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@@ -26,17 +51,37 @@ public class UserManager {
public UserManager(final HMCCosmetics plugin) {
this.plugin = plugin;
this.registerPacketListener();
}
public void add(final Player player) {
final UUID uuid = player.getUniqueId();
this.userMap.put(uuid, new User(uuid, PlayerArmor.empty()));
this.userMap.put(uuid, new User(uuid, new PlayerArmor(
new ArmorItem(
new ItemStack(Material.AIR),
"",
new ArrayList<>(),
"",
ArmorItem.Type.HAT
),
new ArmorItem(
new ItemStack(Material.AIR),
"",
new ArrayList<>(),
"",
ArmorItem.Type.BACKPACK
)
)));
}
public Optional<User> get(final UUID uuid) {
return Optional.ofNullable(this.userMap.get(uuid));
}
public void updateHat(final User user) {
this.setFakeHelmet(user);
}
public void remove(final UUID uuid) {
this.get(uuid).ifPresent(User::detach);
this.userMap.remove(uuid);
@@ -45,14 +90,94 @@ public class UserManager {
public void startTeleportTask() {
this.teleportTask = Bukkit.getScheduler().runTaskTimer(
this.plugin,
() -> this.userMap.values().forEach(
User::updateArmorStand
),
() -> this.userMap.values().forEach(User::updateArmorStand),
1,
1
);
}
private void registerPacketListener() {
final ProtocolManager protocolManager = this.plugin.getProtocolManager();
protocolManager.addPacketListener(new PacketAdapter(this.plugin,
ListenerPriority.NORMAL,
PacketType.Play.Server.ENTITY_EQUIPMENT) {
@Override
public void onPacketReceiving(PacketEvent event) {
}
@Override
public void onPacketSending(final PacketEvent event) {
if (event.getPacketType() == PacketType.Play.Server.ENTITY_EQUIPMENT) {
final int id = event.getPacket().getIntegers().read(0);
for (final var entry : event.getPacket().getSlotStackPairLists().getValues().get(0)) {
if (entry.getFirst() != EnumWrappers.ItemSlot.HEAD) {
continue;
}
for (final Player p : Bukkit.getOnlinePlayers()) {
if (p.getEntityId() != id) {
continue;
}
final User user = userMap.get(p.getUniqueId());
if (user == null) {
break;
}
final ItemStack hat = user.getPlayerArmor().getHat().getItemStack();
final ItemStack second = entry.getSecond();
if (hat != null && hat
.getType() != Material.AIR &&
second != null &&
!Keys.hasKey(second)) {
event.setCancelled(true);
}
}
}
}
}
});
}
public void setFakeHelmet(final User user) {
final ItemStack hat = user.getPlayerArmor().getHat().getItemStack();
final Player player = user.getPlayer();
if (player == null || hat == null) {
return;
}
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList = new ArrayList<>();
final Map<String, String> placeholders = Map.of(Placeholder.ALLOWED, "true",
Placeholder.ENABLED, "true");
equipmentList.add(new Pair<>(EnumWrappers.ItemSlot.HEAD,
ItemBuilder.from(hat).
namePlaceholders(placeholders).
lorePlaceholders(placeholders).
build()
));
final PacketContainer fake = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
fake.getIntegers().write(0, player.getEntityId());
fake.getSlotStackPairLists().write(0, equipmentList);
for (final Player p : Bukkit.getOnlinePlayers()) {
try {
this.plugin.getProtocolManager().sendServerPacket(p, fake);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
public void removeAll() {
for (final var user : this.userMap.values()) {
user.detach();

View File

@@ -0,0 +1,41 @@
package io.github.fisher2911.hmccosmetics.util;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
public class Keys {
static HMCCosmetics plugin;
static {
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
}
public static final NamespacedKey ITEM_KEY = new NamespacedKey(plugin, "cosmetic");
public static void setKey(final ItemStack itemStack) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return;
}
itemMeta.getPersistentDataContainer().set(ITEM_KEY, PersistentDataType.BYTE, (byte) 1);
itemStack.setItemMeta(itemMeta);
}
public static boolean hasKey(final ItemStack itemStack) {
final ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) {
return false;
}
return itemMeta.getPersistentDataContainer().has(ITEM_KEY, PersistentDataType.BYTE);
}
}

View File

@@ -73,11 +73,17 @@ public class ItemBuilder {
*/
public ItemBuilder name(final String name) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setDisplayName(name);
return this;
}
public ItemBuilder name(final Component name) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.displayName(name);
return this;
}
@@ -89,6 +95,9 @@ public class ItemBuilder {
*/
public ItemBuilder namePlaceholders(final Map<String, String> placeholders) {
if (this.itemMeta == null) {
return this;
}
final String name = StringUtils.
applyPlaceholders(this.itemMeta.getDisplayName(), placeholders);
this.itemMeta.displayName(
@@ -103,6 +112,9 @@ public class ItemBuilder {
*/
public ItemBuilder lore(final List<String> lore) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setLore(lore);
return this;
}
@@ -115,6 +127,9 @@ public class ItemBuilder {
public ItemBuilder lorePlaceholders(final Map<String, String> placeholders) {
if (this.itemMeta == null) {
return this;
}
final List<String> lore = new ArrayList<>();
final List<String> previousLore = this.itemMeta.getLore();
@@ -139,11 +154,17 @@ public class ItemBuilder {
*/
public ItemBuilder unbreakable(final boolean unbreakable) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setUnbreakable(unbreakable);
return this;
}
public ItemBuilder glow(final boolean glow) {
if (this.itemMeta == null) {
return this;
}
if (glow) {
this.itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
this.itemMeta.addEnchant(Enchantment.LUCK, 1, true);
@@ -158,6 +179,9 @@ public class ItemBuilder {
*/
public ItemBuilder enchants(final Map<Enchantment, Integer> enchantments, boolean ignoreLeveLRestrictions) {
if (this.itemMeta == null) {
return this;
}
enchantments.forEach((enchantment, level) -> this.itemMeta.addEnchant(enchantment, level, ignoreLeveLRestrictions));
return this;
}
@@ -168,6 +192,9 @@ public class ItemBuilder {
*/
public ItemBuilder itemFlags(final Set<ItemFlag> itemFlags) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.addItemFlags(itemFlags.toArray(new ItemFlag[0]));
return this;
}
@@ -178,6 +205,9 @@ public class ItemBuilder {
*/
public ItemBuilder modelData(final int modelData) {
if (this.itemMeta == null) {
return this;
}
this.itemMeta.setCustomModelData(modelData);
return this;
}

View File

@@ -2,6 +2,8 @@ name: HMCCosmetics
main: io.github.fisher2911.hmccosmetics.HMCCosmetics
version: 1.0.0
api-version: 1.17
depend:
- ProtocolLib
permissions:
hmccosmetics.cmd.default:
default: op