9
0
mirror of https://github.com/HibiscusMC/HMCCosmetics.git synced 2025-12-29 11:59:21 +00:00

Merge branch 'dev'

This commit is contained in:
HeroBrineGoat
2022-01-16 15:52:37 -05:00
20 changed files with 397 additions and 149 deletions

View File

@@ -8,6 +8,7 @@ import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
import io.github.fisher2911.hmccosmetics.listener.HatRemoveFixListener;
import io.github.fisher2911.hmccosmetics.listener.JoinListener;
import io.github.fisher2911.hmccosmetics.listener.RespawnListener;
import io.github.fisher2911.hmccosmetics.listener.TeleportListener;
@@ -16,6 +17,7 @@ import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import me.mattstudios.mf.base.CommandManager;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Arrays;
@@ -31,6 +33,7 @@ public class HMCCosmetics extends JavaPlugin {
private MessageHandler messageHandler;
private CosmeticsMenu cosmeticsMenu;
private CommandManager commandManager;
private boolean papiEnabled;
@Override
public void onEnable() {
@@ -48,6 +51,8 @@ public class HMCCosmetics extends JavaPlugin {
this.registerListeners();
this.userManager.startTeleportTask();
this.papiEnabled = Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
}
@Override
@@ -61,7 +66,8 @@ public class HMCCosmetics extends JavaPlugin {
List.of(new JoinListener(this),
new ClickListener(this),
new TeleportListener(this),
new RespawnListener(this)).
new RespawnListener(this),
new HatRemoveFixListener(this)).
forEach(listener ->
this.getServer().getPluginManager().registerEvents(listener, this)
);
@@ -109,5 +115,9 @@ public class HMCCosmetics extends JavaPlugin {
public ProtocolManager getProtocolManager() {
return protocolManager;
}
public boolean isPapiEnabled() {
return papiEnabled;
}
}

View File

@@ -3,8 +3,6 @@ package io.github.fisher2911.hmccosmetics.command;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
import io.github.fisher2911.hmccosmetics.gui.DyeSelectorGui;
import io.github.fisher2911.hmccosmetics.message.Message;
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.message.Placeholder;
@@ -17,12 +15,9 @@ import me.mattstudios.mf.annotations.Permission;
import me.mattstudios.mf.annotations.SubCommand;
import me.mattstudios.mf.base.CommandBase;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@Command("cosmetics")

View File

@@ -5,6 +5,7 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ColorItem;
import io.github.fisher2911.hmccosmetics.gui.DyeSelectorGui;
import io.github.fisher2911.hmccosmetics.message.Adventure;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import org.bukkit.Color;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
@@ -81,10 +82,14 @@ public class DyeGuiSerializer implements TypeSerializer<DyeSelectorGui> {
guiItemMap.put(slot, new ColorItem(guiItem.getItemStack(), Color.fromRGB(red, green, blue)));
}
String title = titleNode.getString();
if (title == null) title = "";
return new DyeSelectorGui(
plugin,
Adventure.SERIALIZER.serialize(
Adventure.MINI_MESSAGE.parse(titleNode.getString())),
Adventure.MINI_MESSAGE.parse(title)),
rowsNode.getInt(),
guiItemMap);
}

View File

@@ -4,6 +4,8 @@ import dev.triumphteam.gui.guis.GuiItem;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.CosmeticGui;
import io.github.fisher2911.hmccosmetics.message.Adventure;
import io.github.fisher2911.hmccosmetics.papi.PAPIHook;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
@@ -43,7 +45,7 @@ public class GuiSerializer implements TypeSerializer<CosmeticGui> {
final ConfigurationNode rowsNode = this.nonVirtualNode(source, ROWS);
final ConfigurationNode itemsNode = source.node(ITEMS);
final var childrenMap = source.node(ITEMS).childrenMap();
final var childrenMap = itemsNode.childrenMap();
final Map<Integer, GuiItem> guiItemMap = new HashMap<>();
@@ -60,9 +62,13 @@ public class GuiSerializer implements TypeSerializer<CosmeticGui> {
guiItemMap.put(slot, guiItem);
}
String title = titleNode.getString();
if (title == null) title = "";
return new CosmeticGui(plugin,
Adventure.SERIALIZER.serialize(
Adventure.MINI_MESSAGE.parse(titleNode.getString())),
Adventure.MINI_MESSAGE.parse(title)),
rowsNode.getInt(),
guiItemMap);
}

View File

@@ -100,9 +100,6 @@ public class ItemSerializer implements TypeSerializer<GuiItem> {
Material.class, Material.AIR);
final int amount = amountNode.getInt();
final Component name = StringUtils.parse(nameNode.getString());
// Adventure.MINI_MESSAGE.parse(
// Utils.replaceIfNull(nameNode.getString(), "")
// );
final boolean unbreakable = unbreakableNode.getBoolean();
final boolean glowing = glowingNode.getBoolean();

View File

@@ -10,11 +10,13 @@ import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.message.Placeholder;
import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Locale;
@@ -27,6 +29,7 @@ public class CosmeticGui {
protected final MessageHandler messageHandler;
protected final String title;
protected final int rows;
protected final Map<Integer, ItemStack> itemStackMap;
protected final Map<Integer, GuiItem> guiItemMap;
protected Gui gui;
@@ -40,6 +43,8 @@ public class CosmeticGui {
this.title = title;
this.rows = rows;
this.guiItemMap = guiItemMap;
this.itemStackMap = new HashMap<>();
this.guiItemMap.forEach((key, value) -> itemStackMap.put(key, value.getItemStack()));
}
private void setItems(final User user) {
@@ -55,6 +60,14 @@ public class CosmeticGui {
final GuiItem guiItem = entry.getValue();
final ItemStack itemStack = this.itemStackMap.get(slot);
if (itemStack == null) continue;
guiItem.setItemStack(
ItemBuilder.from(itemStack.clone()).papiPlaceholders(player).build()
);
if (guiItem instanceof final ArmorItem armorItem) {
final Map<String, String> placeholders = new HashMap<>();
@@ -91,6 +104,7 @@ public class CosmeticGui {
armorItem.getItemStack(hasPermission)
).namePlaceholders(placeholders).
lorePlaceholders(placeholders).
papiPlaceholders(player).
build(),
event -> {
if (!hasPermission) {
@@ -152,7 +166,7 @@ public class CosmeticGui {
final User user = optionalUser.get();
this.gui = Gui.gui().
title(Adventure.MINI_MESSAGE.parse(this.title)).
title(Adventure.MINI_MESSAGE.parse(StringUtils.applyPapiPlaceholders(user.getPlayer(), this.title))).
rows(this.rows).
create();

View File

@@ -63,8 +63,6 @@ public class CosmeticsMenu {
if (gui instanceof final DyeSelectorGui dyeSelectorGui) {
dyeSelectorGui.getGui(user, armorItem).open(player);
} else {
player.sendMessage(gui.getClass().toString());
}
}

View File

@@ -1,23 +1,25 @@
package io.github.fisher2911.hmccosmetics.gui;
import dev.triumphteam.gui.builder.item.ItemBuilder;
import dev.triumphteam.gui.guis.Gui;
import dev.triumphteam.gui.guis.GuiItem;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class DyeSelectorGui extends CosmeticGui{
public class DyeSelectorGui extends CosmeticGui {
public DyeSelectorGui(
final HMCCosmetics plugin,
@@ -29,12 +31,25 @@ public class DyeSelectorGui extends CosmeticGui{
public Gui getGui(final User user, final ArmorItem armorItem) {
final Gui gui = Gui.gui().
title(Component.text(this.title)).
title(Component.text(StringUtils.applyPapiPlaceholders(user.getPlayer(), this.title))).
rows(rows).
create();
final Player player = user.getPlayer();
for (final var entry : this.guiItemMap.entrySet()) {
gui.setItem(entry.getKey(), entry.getValue());
final GuiItem guiItem = entry.getValue();
final ItemStack itemStack = this.itemStackMap.get(entry.getKey());
if (itemStack == null) continue;
guiItem.setItemStack(
ItemBuilder.from(itemStack.clone()).papiPlaceholders(player).build()
);
gui.setItem(entry.getKey(), guiItem);
}
gui.setDefaultClickAction(event -> {

View File

@@ -10,6 +10,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.PlayerInventory;
import org.spigotmc.event.entity.EntityMountEvent;
import java.util.Optional;

View File

@@ -0,0 +1,47 @@
package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.spigotmc.event.entity.EntityMountEvent;
public class HatRemoveFixListener implements Listener {
private final HMCCosmetics plugin;
private final UserManager userManager;
public HatRemoveFixListener(final HMCCosmetics plugin) {
this.plugin = plugin;
this.userManager = this.plugin.getUserManager();
}
@EventHandler
public void onInventoryClick(final InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof final Player player)) return;
this.fixHat(player);
}
@EventHandler
public void onInventoryDrag(final InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof final Player player)) return;
this.fixHat(player);
}
@EventHandler
public void test(final EntityMountEvent event) {
if (!(event.getEntity() instanceof final Player player)) return;
this.fixHat(player);
}
private void fixHat(final Player player) {
Bukkit.getScheduler().runTaskLater(
this.plugin,
() -> this.userManager.get(player.getUniqueId()).ifPresent(this.userManager::setFakeHelmet),
1);
}
}

View File

@@ -1,6 +1,7 @@
package io.github.fisher2911.hmccosmetics.message;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.papi.PAPIHook;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import io.github.fisher2911.hmccosmetics.util.Utils;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
@@ -40,22 +41,23 @@ public class MessageHandler {
}
/**
*
* @param sender receiver of message
* @param key message key
* @param sender receiver of message
* @param key message key
* @param placeholders placeholders
*/
public void sendMessage(final CommandSender sender, final Message key, final Map<String, String> placeholders) {
final String message = StringUtils.applyPlaceholders(this.getMessage(key), placeholders);
final Component component = Adventure.MINI_MESSAGE.parse(message);
this.adventure.sender(sender).sendMessage(component);
final String message = this.getPapiPlaceholders(
sender,
StringUtils.applyPlaceholders(this.getMessage(key), placeholders)
);
final Component component = Adventure.MINI_MESSAGE.parse(message);
this.adventure.sender(sender).sendMessage(component);
}
/**
*
* @param sender receiver of message
* @param key message key
* @param key message key
*/
public void sendMessage(final CommandSender sender, final Message key) {
@@ -63,22 +65,23 @@ public class MessageHandler {
}
/**
*
* @param player receiver of message
* @param key message key
* @param player receiver of message
* @param key message key
* @param placeholders placeholders
*/
public void sendActionBar(final Player player, final Message key, final Map<String, String> placeholders) {
final String message = StringUtils.applyPlaceholders(this.getMessage(key), placeholders);
final String message = this.getPapiPlaceholders(
player,
StringUtils.applyPlaceholders(this.getMessage(key), placeholders)
);
Component component = Adventure.MINI_MESSAGE.parse(message);
this.adventure.player(player).sendActionBar(component);
}
/**
*
* @param player receiver of message
* @param key message key
* @param key message key
*/
public void sendActionBar(final Player player, final Message key) {
@@ -86,22 +89,23 @@ public class MessageHandler {
}
/**
*
* @param player receiver of message
* @param key message key
* @param player receiver of message
* @param key message key
* @param placeholders placeholders
*/
public void sendTitle(final Player player, final Message key, final Map<String, String> placeholders) {
final String message = StringUtils.applyPlaceholders(this.getMessage(key), placeholders);
final String message = this.getPapiPlaceholders(
player,
StringUtils.applyPlaceholders(this.getMessage(key), placeholders)
);
Component component = Adventure.MINI_MESSAGE.parse(message);
this.adventure.player(player).showTitle(Title.title(component, Component.empty()));
}
/**
*
* @param player receiver of message
* @param key message key
* @param key message key
*/
public void sendTitle(final Player player, final Message key) {
@@ -109,7 +113,6 @@ public class MessageHandler {
}
/**
*
* @param key message key
* @return message, or empty string if message not found
*/
@@ -153,4 +156,12 @@ public class MessageHandler {
this.messageMap.put(key, new Message(key, message, messageType));
}
}
private String getPapiPlaceholders(final CommandSender sender, final String message) {
if (sender instanceof final Player player) {
return StringUtils.applyPapiPlaceholders(player, message);
}
return StringUtils.applyPapiPlaceholders(null, message);
}
}

View File

@@ -10,4 +10,5 @@ public class Placeholder {
public static final String PLAYER = "%player%";
public static final String ENABLED = "%enabled%";
public static final String ALLOWED = "%allowed%";
}

View File

@@ -0,0 +1,12 @@
package io.github.fisher2911.hmccosmetics.papi;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.entity.Player;
public class PAPIHook {
public static String parse(final Player player, final String string) {
return PlaceholderAPI.setPlaceholders(player, string);
}
}

View File

@@ -1,32 +1,46 @@
package io.github.fisher2911.hmccosmetics.user;
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.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.util.Keys;
import io.github.fisher2911.hmccosmetics.message.Placeholder;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class User {
private final UUID uuid;
private final PlayerArmor playerArmor;
private ArmorStand attached;
private ArmorItem lastSetItem;
public User(final UUID uuid, final PlayerArmor playerArmor) {
private boolean hasArmorStand;
private final int armorStandId;
public User(final UUID uuid, final PlayerArmor playerArmor, final int armorStandId) {
this.uuid = uuid;
this.playerArmor = playerArmor;
this.armorStandId = armorStandId;
}
public @Nullable Player getPlayer() {
@@ -41,6 +55,19 @@ public class User {
return playerArmor;
}
public void setPlayerArmor(final PlayerArmor playerArmor) {
this.playerArmor.setBackpack(playerArmor.getBackpack());
this.playerArmor.setHat(playerArmor.getHat());
}
public void removeAllCosmetics() {
this.setPlayerArmor(PlayerArmor.empty());
}
public int getArmorStandId() {
return armorStandId;
}
public void setBackpack(final ArmorItem backpack) {
this.playerArmor.setBackpack(backpack);
this.lastSetItem = backpack;
@@ -129,83 +156,140 @@ public class User {
return true;
}
public void detach() {
if (this.attached != null) {
this.attached.remove();
public void spawnArmorStand(final Player other) {
final Player player = this.getPlayer();
if (player == null) return;
final Location location = player.getLocation();
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
final PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
// Entity ID
packet.getIntegers().write(0, this.armorStandId);
// Entity Type
// packet.getIntegers().write(6, 78);
// Set yaw pitch
packet.getIntegers().write(4, (int) location.getPitch());
packet.getIntegers().write(5, (int) location.getYaw());
// Set location
packet.getDoubles().write(0, 0d);
packet.getDoubles().write(1, -5d);
packet.getDoubles().write(2, 0d);
// Set UUID
packet.getUUIDs().write(0, UUID.randomUUID());
packet.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND);
final PacketContainer ridingPacket = new PacketContainer(PacketType.Play.Server.MOUNT);
ridingPacket.
getIntegers().
write(0, player.getEntityId());
ridingPacket.getIntegerArrays().write(0, new int[]{this.armorStandId});
try {
protocolManager.sendServerPacket(other, packet);
protocolManager.sendServerPacket(other, ridingPacket);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
// teleports armor stand to the correct position
public void updateArmorStand() {
final ArmorItem backpackArmorItem = this.playerArmor.getBackpack();
if (backpackArmorItem == null) {
this.despawnAttached();
public void spawnArmorStand() {
if (this.hasArmorStand) {
this.updateArmorStand();
return;
}
final ItemStack backpackItem = backpackArmorItem.getItemStack();
for (final Player p : Bukkit.getOnlinePlayers()) {
this.spawnArmorStand(p);
}
if (backpackItem == null || backpackItem.getType() == Material.AIR) {
this.despawnAttached();
this.hasArmorStand = true;
}
public void updateArmorStand() {
if (!this.hasArmorStand) {
this.spawnArmorStand();
return;
}
final Player player = this.getPlayer();
if (player == null) {
this.despawnAttached();
return;
if (player == 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(this.playerArmor.getBackpack().getItemStack()).
namePlaceholders(placeholders).
lorePlaceholders(placeholders).
build()
));
final PacketContainer armorPacket = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
armorPacket.getIntegers().write(0, this.armorStandId);
armorPacket.getSlotStackPairLists().write(0, equipmentList);
final Location location = player.getLocation();
final PacketContainer metaContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
WrappedDataWatcher metaData = new WrappedDataWatcher();
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) (0x20));
metaData.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) (0x10));
final PacketContainer rotationPacket = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
rotationPacket.getIntegers().write(0, this.armorStandId);
rotationPacket.getBytes().write(0, (byte) (location.getYaw() * 256 / 360));
metaContainer.getIntegers().write(0, this.armorStandId);
metaContainer.getWatchableCollectionModifier().write(0, metaData.getWatchableObjects());
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
final PacketContainer teleportPacket = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
teleportPacket.getIntegers().write(0, this.armorStandId);
teleportPacket.getDoubles().
write(0, location.getX()).
write(1, location.getY()).
write(2, location.getZ());
teleportPacket.getBytes().
write(0, (byte) (location.getYaw() * 256.0F / 360.0F)).
write(1, (byte) (location.getPitch() * 256.0F / 360.0F));
for (final Player p : Bukkit.getOnlinePlayers()) {
try {
protocolManager.sendServerPacket(p, armorPacket);
protocolManager.sendServerPacket(p, metaContainer);
protocolManager.sendServerPacket(p, rotationPacket);
} catch (final InvocationTargetException exception) {
exception.printStackTrace();
}
}
if (this.attached == null) {
this.attached = player.getWorld().spawn(player.getLocation(),
ArmorStand.class,
armorStand -> {
armorStand.setVisible(false);
armorStand.setMarker(true);
armorStand.getPersistentDataContainer().set(
Keys.ARMOR_STAND_KEY,
PersistentDataType.BYTE,
(byte) 1
);
player.addPassenger(armorStand);
});
}
if (!player.getPassengers().contains(this.attached)) {
player.addPassenger(this.attached);
}
final EntityEquipment equipment = this.attached.getEquipment();
if (equipment == null) {
this.despawnAttached();
return;
}
if (!backpackItem.equals(equipment.getHelmet())) {
equipment.setHelmet(backpackItem);
}
this.attached.
setRotation(
player.getLocation().getYaw(),
player.getLocation().getPitch());
}
public void despawnAttached() {
if (this.attached == null) {
return;
final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
final PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getModifier().write(0, new IntArrayList(new int[]{this.armorStandId}));
for (final Player p : Bukkit.getOnlinePlayers()) {
try {
protocolManager.sendServerPacket(p, destroyPacket);
} catch (final InvocationTargetException exception) {
exception.printStackTrace();
}
}
final Player player = this.getPlayer();
if (player != null) {
player.removePassenger(this.attached);
}
this.attached.remove();
this.attached = null;
}
public ArmorItem getLastSetItem() {

View File

@@ -6,36 +6,23 @@ 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.EntityEquipment;
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;
@@ -43,9 +30,11 @@ import java.util.UUID;
public class UserManager {
private int currentArmorStandId = Integer.MAX_VALUE;
private final HMCCosmetics plugin;
private final Map<UUID, User> userMap = new HashMap<>();
private final Map<Integer, User> armorStandIdMap = new HashMap<>();
private BukkitTask teleportTask;
@@ -56,22 +45,14 @@ public class UserManager {
public void add(final Player player) {
final UUID uuid = player.getUniqueId();
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
)
)));
final int armorStandId = this.currentArmorStandId;
final User user = new User(
uuid,
PlayerArmor.empty(),
armorStandId);
this.userMap.put(uuid, user);
this.armorStandIdMap.put(armorStandId, user);
this.currentArmorStandId--;
}
public Optional<User> get(final UUID uuid) {
@@ -83,8 +64,15 @@ public class UserManager {
}
public void remove(final UUID uuid) {
this.get(uuid).ifPresent(User::detach);
this.userMap.remove(uuid);
final User user = this.userMap.remove(uuid);
if (user == null) return;
user.removeAllCosmetics();
this.setFakeHelmet(user);
user.despawnAttached();
this.armorStandIdMap.remove(user.getArmorStandId());
}
public void startTeleportTask() {
@@ -96,9 +84,16 @@ public class UserManager {
);
}
public void resendCosmetics(final Player player) {
for (final User user : this.userMap.values()) {
user.spawnArmorStand(player);
}
}
private void registerPacketListener() {
final ProtocolManager protocolManager = this.plugin.getProtocolManager();
protocolManager.addPacketListener(new PacketAdapter(this.plugin,
protocolManager.addPacketListener(new PacketAdapter(
this.plugin,
ListenerPriority.NORMAL,
PacketType.Play.Server.ENTITY_EQUIPMENT) {
@Override
@@ -129,7 +124,6 @@ public class UserManager {
final ItemStack hat = user.getPlayerArmor().getHat().getItemStack();
final ItemStack second = entry.getSecond();
if (hat != null && hat
.getType() != Material.AIR &&
second != null &&
@@ -145,13 +139,20 @@ public class UserManager {
public void setFakeHelmet(final User user) {
final ItemStack hat = user.getPlayerArmor().getHat().getItemStack();
ItemStack hat = user.getPlayerArmor().getHat().getItemStack();
final Player player = user.getPlayer();
if (player == null || hat == null) {
return;
}
if (hat.getType() == Material.AIR) {
final EntityEquipment equipment = player.getEquipment();
if (equipment != null) {
hat = equipment.getHelmet() == null ? hat : equipment.getHelmet();
}
}
final List<Pair<EnumWrappers.ItemSlot, ItemStack>> equipmentList = new ArrayList<>();
final Map<String, String> placeholders = Map.of(Placeholder.ALLOWED, "true",
@@ -180,7 +181,7 @@ public class UserManager {
public void removeAll() {
for (final var user : this.userMap.values()) {
user.detach();
user.despawnAttached();
}
this.userMap.clear();

View File

@@ -1,15 +1,25 @@
package io.github.fisher2911.hmccosmetics.util;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.message.Adventure;
import io.github.fisher2911.hmccosmetics.papi.PAPIHook;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class StringUtils {
private static final HMCCosmetics plugin;
static {
plugin = HMCCosmetics.getPlugin(HMCCosmetics.class);
}
/**
*
* @param message message being translated
* @param message message being translated
* @param placeholders placeholders applied
* @return message with placeholders applied
*/
@@ -21,9 +31,15 @@ public class StringUtils {
return message;
}
public static String applyPapiPlaceholders(@Nullable final Player player, final String message) {
if (plugin.isPapiEnabled()) {
return PAPIHook.parse(player, message);
}
return message;
}
/**
*
* @param parsed message to be parsed
* @return MiniMessage parsed string
*/

View File

@@ -3,9 +3,11 @@ package io.github.fisher2911.hmccosmetics.util.builder;
import io.github.fisher2911.hmccosmetics.message.Adventure;
import io.github.fisher2911.hmccosmetics.util.StringUtils;
import net.kyori.adventure.text.Component;
import net.minecraft.network.PacketListener;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -147,6 +149,38 @@ public class ItemBuilder {
return this;
}
public ItemBuilder papiPlaceholders(final Player player) {
this.lorePapiPlaceholders(player);
this.namePapiPlaceholders(player);
return this;
}
private void lorePapiPlaceholders(final Player player) {
if (this.itemMeta == null) return;
final List<String> newLore = new ArrayList<>();
final List<String> lore = this.itemMeta.getLore();
if (lore == null) return;
for (final String line : this.itemMeta.getLore()) {
newLore.add(StringUtils.applyPapiPlaceholders(player, line));
}
this.itemMeta.setLore(newLore);
}
private void namePapiPlaceholders(final Player player) {
if (this.itemMeta == null) return;
this.itemMeta.setDisplayName(
StringUtils.applyPapiPlaceholders(
player,
this.itemMeta.getDisplayName()
)
);
}
/**
* @param unbreakable whether the ItemStack is unbreakable
* @return this