mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-22 16:39:21 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8b7430998 | ||
|
|
42de76d84d | ||
|
|
5102fd77b7 | ||
|
|
9c66d4ee81 | ||
|
|
7ade2d9227 | ||
|
|
7b43b42740 | ||
|
|
25f050f387 | ||
|
|
05c13e8990 | ||
|
|
34b02574b2 | ||
|
|
f81d350a2e | ||
|
|
be86314daf | ||
|
|
345f903113 | ||
|
|
3cf265f231 | ||
|
|
d26e7df2ca | ||
|
|
e5dc3f6774 | ||
|
|
fdc9893a60 | ||
|
|
e8694076b8 | ||
|
|
1acf536080 | ||
|
|
9d3ad0b54b | ||
|
|
0b2ade1598 | ||
|
|
83651b7250 | ||
|
|
6818c09a69 | ||
|
|
dc72b677de | ||
|
|
5ff1a63eaa | ||
|
|
8300a86225 | ||
|
|
9e8084194a | ||
|
|
c0ea4d5a5b | ||
|
|
5a963391f8 | ||
|
|
6c4586a6b9 | ||
|
|
4cc0a6f968 | ||
|
|
ab8656ad1a | ||
|
|
ca5e0f96c2 | ||
|
|
5cddd24097 | ||
|
|
656e539ae3 | ||
|
|
862b7c9ee6 | ||
|
|
c632174de8 | ||
|
|
1e96303765 | ||
|
|
1a6d587ee0 | ||
|
|
adcb6de5e4 | ||
|
|
c36e263a95 | ||
|
|
de1e5bf100 | ||
|
|
ea25dcf208 | ||
|
|
e3c73d0bfe | ||
|
|
91b24bfa82 | ||
|
|
28bf5ba2b6 | ||
|
|
0249d6abdb | ||
|
|
cb32f635d0 | ||
|
|
3bfdde4281 | ||
|
|
8daa2709f3 |
@@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "com.hibiscusmc"
|
||||
version = "2.7.3-DEV"
|
||||
version = "2.7.3"
|
||||
|
||||
allprojects {
|
||||
apply(plugin = "java")
|
||||
@@ -75,26 +75,26 @@ allprojects {
|
||||
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
//compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
|
||||
compileOnly("me.clip:placeholderapi:2.11.3")
|
||||
compileOnly("io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT")
|
||||
compileOnly("org.jetbrains:annotations:24.1.0")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0-SNAPSHOT")
|
||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
|
||||
compileOnly("it.unimi.dsi:fastutil:8.5.11")
|
||||
compileOnly("org.projectlombok:lombok:1.18.2")
|
||||
compileOnly("me.lojosho:HibiscusCommons:0.2.2")
|
||||
compileOnly("it.unimi.dsi:fastutil:8.5.13")
|
||||
compileOnly("org.projectlombok:lombok:1.18.34")
|
||||
compileOnly("me.lojosho:HibiscusCommons:0.4.1")
|
||||
|
||||
// Handled by Spigot Library Loader
|
||||
compileOnly("net.kyori:adventure-api:4.15.0")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:4.15.0")
|
||||
compileOnly("net.kyori:adventure-platform-bukkit:4.3.2")
|
||||
compileOnly("net.kyori:adventure-api:4.17.0")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:4.17.0")
|
||||
compileOnly("net.kyori:adventure-platform-bukkit:4.3.3")
|
||||
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.28")
|
||||
testCompileOnly("org.projectlombok:lombok:1.18.28")
|
||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.28")
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.34")
|
||||
testCompileOnly("org.projectlombok:lombok:1.18.34")
|
||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.34")
|
||||
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.7") {
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.10") {
|
||||
exclude("net.kyori") // Already have adventure API
|
||||
}
|
||||
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
|
||||
@@ -110,7 +110,7 @@ tasks {
|
||||
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(17)
|
||||
options.release.set(21)
|
||||
}
|
||||
|
||||
javadoc {
|
||||
@@ -123,7 +123,7 @@ tasks {
|
||||
}
|
||||
|
||||
runServer {
|
||||
minecraftVersion("1.20.4")
|
||||
minecraftVersion("1.20.6")
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
@@ -156,7 +156,7 @@ tasks {
|
||||
bukkit {
|
||||
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
|
||||
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
|
||||
apiVersion = "1.18"
|
||||
apiVersion = "1.19"
|
||||
authors = listOf("LoJoSho")
|
||||
depend = listOf("HibiscusCommons", "ProtocolLib")
|
||||
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
||||
@@ -257,6 +257,6 @@ bukkit {
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21
|
||||
))
|
||||
}
|
||||
|
||||
@@ -65,12 +65,8 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
|
||||
if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
|
||||
|
||||
// Emote folder setup
|
||||
File emoteFile = new File(getDataFolder().getPath() + "/emotes");
|
||||
if (!emoteFile.exists()) emoteFile.mkdir();
|
||||
|
||||
// Player Animator
|
||||
if (!HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R2") && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R3")) PlayerAnimatorImpl.initialize(this); // PlayerAnimator does not support 1.20.2 yet
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) PlayerAnimatorImpl.initialize(this); // PlayerAnimator does not support 1.20.2 yet
|
||||
|
||||
// Configuration Sync
|
||||
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
|
||||
@@ -229,7 +225,7 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.isEmotesEnabled() && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R2") && !HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R3")) EmoteManager.loadEmotes(); // PlayerAnimator does not support 1.20.2 yet
|
||||
if (Settings.isEmotesEnabled() && (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1"))) EmoteManager.loadEmotes(); // PlayerAnimator does not support 1.20.2 yet
|
||||
|
||||
getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
|
||||
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a cosmetic type not registered with HMCC default cosmetics is attempted to be registered. So if someone puts "test" in the config slot, and it's not a default cosmetic, this event will be called.
|
||||
*/
|
||||
public class CosmeticTypeRegisterEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final String id;
|
||||
private final ConfigurationNode config;
|
||||
|
||||
public CosmeticTypeRegisterEvent(String id, ConfigurationNode config) {
|
||||
this.id = id;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the cosmetic trying to be registered. For example, "beanie" or "test"
|
||||
* @return The id. This is the key in the cosmetic config
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will already be in the nested node below the id in the config.
|
||||
* @return The cosmetic config node in the cosmetic config that was attempted to get registered
|
||||
*/
|
||||
public ConfigurationNode getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@@ -48,14 +49,11 @@ public class Settings {
|
||||
private static final String COSMETIC_DISABLED_WORLDS_PATH = "disabled-worlds";
|
||||
private static final String COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH = "entity-cooldown-teleport-packet";
|
||||
private static final String COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH = "backpack-force-riding-packet";
|
||||
private static final String COSMETIC_FORCE_OFFHAND_COSMETIC_SHOW_PATH = "offhand-always-show";
|
||||
private static final String COSMETIC_ADD_ENCHANTS_HELMET_PATH = "helmet-add-enchantments";
|
||||
private static final String COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH = "chest-add-enchantments";
|
||||
private static final String COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH = "leggings-add-enchantments";
|
||||
private static final String COSMETIC_ADD_ENCHANTS_BOOTS_PATH = "boots-add-enchantments";
|
||||
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
|
||||
private static final String COSMETIC_BALLOON_HEAD_FORWARD_PATH = "balloon-head-forward";
|
||||
private static final String MENU_SETTINGS_PATH = "menu-settings";
|
||||
private static final String MENU_CLICK_COOLDOWN_PATH = "click-cooldown";
|
||||
private static final String MENU_CLICK_COOLDOWN_TIME_PATH = "time";
|
||||
private static final String COSMETIC_TYPE_SETTINGS_PATH = "cosmetic-type";
|
||||
private static final String EQUIP_CLICK_TYPE = "equip-click";
|
||||
private static final String UNEQUIP_CLICK_TYPE = "unequip-click";
|
||||
@@ -69,6 +67,7 @@ public class Settings {
|
||||
private static final String EQUIPABLE_COSMETIC_COLOR_PATH = "equipable-cosmetic-color";
|
||||
private static final String LOCKED_COSMETIC_COLOR_PATH = "locked-cosmetic-color";
|
||||
private static final String ENABLED_PATH = "enabled";
|
||||
private static final String SLOT_OPTIONS_PATH = "slot-options";
|
||||
|
||||
@Getter
|
||||
private static String defaultMenu;
|
||||
@@ -94,14 +93,7 @@ public class Settings {
|
||||
private static boolean worldGuardMoveCheck;
|
||||
@Getter
|
||||
private static boolean cosmeticEmoteBlockCheck;
|
||||
@Getter
|
||||
private static boolean addHelmetEnchants;
|
||||
@Getter
|
||||
private static boolean addChestplateEnchants;
|
||||
@Getter
|
||||
private static boolean addLeggingEnchants;
|
||||
@Getter
|
||||
private static boolean addBootsEnchants;
|
||||
private static final HashMap<EquipmentSlot, SlotOptionConfig> slotOptions = new HashMap<>();
|
||||
@Getter
|
||||
private static boolean emoteAirCheck;
|
||||
@Getter
|
||||
@@ -113,8 +105,6 @@ public class Settings {
|
||||
@Getter
|
||||
private static boolean backpackForceRidingEnabled;
|
||||
@Getter
|
||||
private static boolean cosmeticForceOffhandCosmeticShow;
|
||||
@Getter
|
||||
private static boolean emotesEnabled;
|
||||
@Getter
|
||||
private static boolean disabledGamemodesEnabled;
|
||||
@@ -131,6 +121,10 @@ public class Settings {
|
||||
@Getter
|
||||
private static int packetEntityTeleportCooldown;
|
||||
@Getter
|
||||
private static Long defaultMenuCooldown;
|
||||
@Getter
|
||||
private static boolean menuClickCooldown;
|
||||
@Getter
|
||||
private static double emoteDistance;
|
||||
@Getter
|
||||
private static Vector balloonOffset;
|
||||
@@ -202,20 +196,31 @@ public class Settings {
|
||||
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
|
||||
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
|
||||
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
|
||||
addHelmetEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_HELMET_PATH).getBoolean(false);
|
||||
addChestplateEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_CHESTPLATE_PATH).getBoolean(false);
|
||||
addLeggingEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_LEGGINGS_PATH).getBoolean(false);
|
||||
addBootsEnchants = cosmeticSettings.node(COSMETIC_ADD_ENCHANTS_BOOTS_PATH).getBoolean(false);
|
||||
|
||||
cosmeticSettings.node(SLOT_OPTIONS_PATH).childrenMap().forEach((key, value) -> {
|
||||
EquipmentSlot slot = convertConfigToEquipment(key.toString().toLowerCase());
|
||||
if (slot == null) {
|
||||
MessagesUtil.sendDebugMessages("Invalid slot option: " + key, Level.WARNING);
|
||||
return;
|
||||
}
|
||||
boolean addEnchantments = value.node("add-enchantments").getBoolean(false);
|
||||
boolean requireEmpty = value.node("require-empty").getBoolean(false);
|
||||
slotOptions.put(slot, new SlotOptionConfig(slot, addEnchantments, requireEmpty));
|
||||
});
|
||||
|
||||
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
|
||||
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
|
||||
emoteCameraEnabled = cosmeticSettings.node(COSMETIC_EMOTE_CAMERA_PATH).getBoolean(true);
|
||||
emoteMoveCheck = cosmeticSettings.node(COSMETIC_EMOTE_MOVE_CHECK_PATH).getBoolean(false);
|
||||
packetEntityTeleportCooldown = cosmeticSettings.node(COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH).getInt(-1);
|
||||
cosmeticForceOffhandCosmeticShow = cosmeticSettings.node(COSMETIC_FORCE_OFFHAND_COSMETIC_SHOW_PATH).getBoolean(false);
|
||||
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false);
|
||||
|
||||
ConfigurationNode menuSettings = source.node(MENU_SETTINGS_PATH);
|
||||
|
||||
ConfigurationNode clickCooldownSettings = menuSettings.node(MENU_CLICK_COOLDOWN_PATH);
|
||||
menuClickCooldown = clickCooldownSettings.node(ENABLED_PATH).getBoolean(true);
|
||||
defaultMenuCooldown = clickCooldownSettings.node(MENU_CLICK_COOLDOWN_TIME_PATH).getLong(1000L);
|
||||
|
||||
ConfigurationNode shadingSettings = menuSettings.node(SHADING_PATH);
|
||||
defaultShading = shadingSettings.node(ENABLED_PATH).getBoolean();
|
||||
firstRowShift = shadingSettings.node(FIRST_ROW_SHIFT_PATH).getString();
|
||||
@@ -257,24 +262,9 @@ public class Settings {
|
||||
return new Vector(config.node("x").getDouble(), config.node("y").getDouble(), config.node("z").getDouble());
|
||||
}
|
||||
|
||||
public static boolean getShouldAddEnchants(EquipmentSlot slot) {
|
||||
switch (slot) {
|
||||
case HEAD -> {
|
||||
return addHelmetEnchants;
|
||||
}
|
||||
case CHEST -> {
|
||||
return addChestplateEnchants;
|
||||
}
|
||||
case LEGS -> {
|
||||
return addLeggingEnchants;
|
||||
}
|
||||
case FEET -> {
|
||||
return addBootsEnchants;
|
||||
}
|
||||
default -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static SlotOptionConfig getSlotOption(EquipmentSlot slot) {
|
||||
if (!slotOptions.containsKey(slot)) slotOptions.put(slot, new SlotOptionConfig(slot, false, false));
|
||||
return slotOptions.get(slot);
|
||||
}
|
||||
|
||||
public static void setDebugMode(boolean newSetting) {
|
||||
@@ -286,4 +276,16 @@ public class Settings {
|
||||
|
||||
plugin.saveConfig();
|
||||
}
|
||||
|
||||
private static EquipmentSlot convertConfigToEquipment(String slot) {
|
||||
return switch (slot) {
|
||||
case "helmet" -> EquipmentSlot.HEAD;
|
||||
case "chestplate" -> EquipmentSlot.CHEST;
|
||||
case "leggings" -> EquipmentSlot.LEGS;
|
||||
case "boots" -> EquipmentSlot.FEET;
|
||||
case "offhand" -> EquipmentSlot.OFF_HAND;
|
||||
case "mainhand" -> EquipmentSlot.HAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.hibiscusmc.hmccosmetics.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
public class SlotOptionConfig {
|
||||
|
||||
@Getter
|
||||
private final EquipmentSlot slot;
|
||||
@Getter
|
||||
private final boolean addEnchantments;
|
||||
@Getter
|
||||
private final boolean requireEmpty;
|
||||
|
||||
public SlotOptionConfig(EquipmentSlot slot, boolean addEnchantments, boolean requireEmpty) {
|
||||
this.slot = slot;
|
||||
this.addEnchantments = addEnchantments;
|
||||
this.requireEmpty = requireEmpty;
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ public enum CosmeticSlot {
|
||||
OFFHAND,
|
||||
BACKPACK,
|
||||
BALLOON,
|
||||
EMOTE
|
||||
EMOTE,
|
||||
CUSTOM
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.CosmeticTypeRegisterEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
@@ -105,12 +106,13 @@ public class Cosmetics {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because " + slotNode.getString() + " is not a valid slot!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
switch (CosmeticSlot.valueOf(cosmeticConfig.node("slot").getString())) {
|
||||
switch (CosmeticSlot.valueOf(slotNode.getString())) {
|
||||
case BALLOON -> new CosmeticBalloonType(id, cosmeticConfig);
|
||||
case BACKPACK -> new CosmeticBackpackType(id, cosmeticConfig);
|
||||
case MAINHAND -> new CosmeticMainhandType(id, cosmeticConfig);
|
||||
case EMOTE -> new CosmeticEmoteType(id, cosmeticConfig);
|
||||
default -> new CosmeticArmorType(id, cosmeticConfig);
|
||||
case HELMET, CHESTPLATE, LEGGINGS, BOOTS, OFFHAND -> new CosmeticArmorType(id, cosmeticConfig);
|
||||
default -> new CosmeticTypeRegisterEvent(id, cosmeticConfig).callEvent();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (Settings.isDebugMode()) e.printStackTrace();
|
||||
|
||||
@@ -30,9 +30,9 @@ public class CosmeticArmorType extends Cosmetic {
|
||||
if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) return;
|
||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||
if (entity == null) return;
|
||||
if (!Settings.isCosmeticForceOffhandCosmeticShow()
|
||||
&& equipSlot.equals(EquipmentSlot.OFF_HAND)
|
||||
&& ((user.getEntity() instanceof Player) && !user.getPlayer().getInventory().getItemInOffHand().getType().isAir())) return;
|
||||
if (Settings.getSlotOption(equipSlot).isRequireEmpty() && entity instanceof HumanEntity humanEntity) {
|
||||
if (!humanEntity.getInventory().getItem(equipSlot).getType().isAir()) return;
|
||||
}
|
||||
ItemStack item = getItem(user);
|
||||
if (item == null) return;
|
||||
PacketManager.equipmentSlotUpdate(entity.getEntityId(), equipSlot, item, HMCCPacketManager.getViewers(entity.getLocation()));
|
||||
@@ -44,7 +44,7 @@ public class CosmeticArmorType extends Cosmetic {
|
||||
|
||||
public ItemStack getItem(@NotNull CosmeticUser user, ItemStack cosmeticItem) {
|
||||
if (!(user.getEntity() instanceof HumanEntity humanEntity)) return null;
|
||||
if (Settings.getShouldAddEnchants(equipSlot)) {
|
||||
if (Settings.getSlotOption(equipSlot).isAddEnchantments()) {
|
||||
ItemStack equippedItem = humanEntity.getInventory().getItem(equipSlot);
|
||||
cosmeticItem.addUnsafeEnchantments(equippedItem.getEnchantments());
|
||||
}
|
||||
|
||||
@@ -49,7 +49,11 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
Location loc = entity.getLocation().clone().add(0, 2, 0);
|
||||
|
||||
if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
|
||||
// This needs to be moved to purely packet based, there are far to many plugin doing dumb stuff that prevents spawning armorstands ignoring our spawn reason.
|
||||
if (user.isHidden()) {
|
||||
// Sometimes the backpack is not despawned when the player is hidden (weird ass logic happening somewhere)
|
||||
user.despawnBackpack();
|
||||
return;
|
||||
}
|
||||
List<Player> outsideViewers = user.getUserBackpackManager().getEntityManager().refreshViewers(loc);
|
||||
|
||||
user.getUserBackpackManager().getEntityManager().teleport(loc);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.database;
|
||||
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
|
||||
import com.hibiscusmc.hmccosmetics.database.types.Data;
|
||||
import com.hibiscusmc.hmccosmetics.database.types.MySQLData;
|
||||
import com.hibiscusmc.hmccosmetics.database.types.NoneData;
|
||||
import com.hibiscusmc.hmccosmetics.database.types.SQLiteData;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
@@ -11,6 +12,7 @@ import lombok.Getter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Database {
|
||||
|
||||
@@ -18,18 +20,25 @@ public class Database {
|
||||
private static Data data;
|
||||
private static final MySQLData MYSQL_DATA = new MySQLData();
|
||||
private static final SQLiteData SQLITE_DATA = new SQLiteData();
|
||||
private static final NoneData NONE_DATA = new NoneData();
|
||||
|
||||
public Database() {
|
||||
String databaseType = DatabaseSettings.getDatabaseType();
|
||||
data = SQLITE_DATA; // default
|
||||
if (databaseType.equalsIgnoreCase("MySQL")) {
|
||||
data = MYSQL_DATA;
|
||||
data = SQLITE_DATA; // default to SQLite, then check if it's anything different
|
||||
switch (databaseType.toLowerCase()) {
|
||||
case "mysql":
|
||||
data = MYSQL_DATA;
|
||||
break;
|
||||
case "sqlite":
|
||||
// already the default
|
||||
break;
|
||||
case "none":
|
||||
data = NONE_DATA;
|
||||
MessagesUtil.sendDebugMessages("Database is set to none. Data will not be saved.", Level.WARNING);
|
||||
break;
|
||||
default:
|
||||
MessagesUtil.sendDebugMessages("Invalid database type. Defaulting to SQLite.", Level.WARNING);
|
||||
}
|
||||
/* SQLite is the default database. Might change in the future, so keep code here in case.
|
||||
if (databaseType.equalsIgnoreCase("sqlite")) {
|
||||
data = SQLITE_DATA;
|
||||
}
|
||||
*/
|
||||
MessagesUtil.sendDebugMessages("Database is " + data);
|
||||
|
||||
setup();
|
||||
|
||||
@@ -103,7 +103,7 @@ public abstract class Data {
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
// Handle gamemode check
|
||||
if (user.getPlayer() != null && Settings.getDisabledGamemodes().contains(user.getPlayer().getGameMode().toString())) {
|
||||
if (user.getPlayer() != null && Settings.isDisabledGamemodesEnabled() && Settings.getDisabledGamemodes().contains(user.getPlayer().getGameMode().toString())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to gamemode");
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
|
||||
return;
|
||||
@@ -115,7 +115,7 @@ public abstract class Data {
|
||||
}
|
||||
}
|
||||
// Handle world check
|
||||
if (Settings.getDisabledWorlds().contains(user.getPlayer().getWorld().getName())) {
|
||||
if (user.getPlayer() != null && Settings.getDisabledWorlds().contains(user.getPlayer().getWorld().getName())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to world");
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MySQLData extends SQLData {
|
||||
|
||||
@@ -132,7 +133,14 @@ public class MySQLData extends SQLData {
|
||||
public PreparedStatement preparedStatement(String query) {
|
||||
PreparedStatement ps = null;
|
||||
|
||||
if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
|
||||
if (!isConnectionOpen()) {
|
||||
MessagesUtil.sendDebugMessages("The MySQL database connection is not open (Could the database been idle for to long?). Reconnecting...", Level.WARNING);
|
||||
try {
|
||||
openConnection();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (connection == null) throw new NullPointerException("Connection is null");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.hibiscusmc.hmccosmetics.database.types;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class NoneData extends Data {
|
||||
@Override
|
||||
public void setup() {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(CosmeticUser user) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CosmeticUser get(UUID uniqueId) {
|
||||
return new CosmeticUser(uniqueId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(UUID uniqueId) {
|
||||
// Nothing
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ public class Menu {
|
||||
@Getter
|
||||
private final int rows;
|
||||
@Getter
|
||||
private final Long cooldown;
|
||||
@Getter
|
||||
private final ConfigurationNode config;
|
||||
@Getter
|
||||
private final String permissionNode;
|
||||
@@ -55,6 +57,7 @@ public class Menu {
|
||||
|
||||
title = config.node("title").getString("chest");
|
||||
rows = config.node("rows").getInt(1);
|
||||
cooldown = config.node("click-cooldown").getLong(Settings.getDefaultMenuCooldown());
|
||||
permissionNode = config.node("permission").getString("");
|
||||
refreshRate = config.node("refresh-rate").getInt(-1);
|
||||
shading = config.node("shading").getBoolean(Settings.isDefaultShading());
|
||||
@@ -90,7 +93,8 @@ public class Menu {
|
||||
try {
|
||||
item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config.node("item"));
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
MessagesUtil.sendDebugMessages("Unable to get valid item for " + config.key().toString() + " " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item == null) {
|
||||
@@ -244,13 +248,24 @@ public class Menu {
|
||||
if (modifiedItem.getType().isAir()) continue;
|
||||
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
|
||||
guiItem.setAction(event -> {
|
||||
MessagesUtil.sendDebugMessages("Selected slot " + slot);
|
||||
UUID uuid = user.getUniqueId();
|
||||
if (Settings.isMenuClickCooldown()) {
|
||||
Long userCooldown = Menus.getCooldown(uuid);
|
||||
if (userCooldown != 0 && (System.currentTimeMillis() - Menus.getCooldown(uuid) <= getCooldown())) {
|
||||
MessagesUtil.sendDebugMessages("Cooldown for " + user.getUniqueId() + " System time: " + System.currentTimeMillis() + " Cooldown: " + Menus.getCooldown(user.getUniqueId()) + " Difference: " + (System.currentTimeMillis() - Menus.getCooldown(user.getUniqueId())));
|
||||
MessagesUtil.sendMessage(user.getPlayer(), "on-click-cooldown");
|
||||
return;
|
||||
} else {
|
||||
Menus.addCooldown(user.getUniqueId(), System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
MessagesUtil.sendDebugMessages("Updated Menu Item in slot number " + slot);
|
||||
final ClickType clickType = event.getClick();
|
||||
if (type != null) type.run(user, item.itemConfig(), clickType);
|
||||
updateMenu(user, gui);
|
||||
});
|
||||
|
||||
MessagesUtil.sendDebugMessages("Added " + slot + " as " + guiItem + " in the menu");
|
||||
MessagesUtil.sendDebugMessages("Set an item in slot " + slot + " in the menu of " + getId());
|
||||
gui.updateItem(slot, guiItem);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -13,16 +13,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Menus {
|
||||
|
||||
private static final HashMap<String, Menu> MENUS = new HashMap<>();
|
||||
private static final HashMap<UUID, Long> COOLDOWNS = new HashMap<>();
|
||||
|
||||
public static void addMenu(Menu menu) {
|
||||
MENUS.put(menu.getId().toUpperCase(), menu);
|
||||
@@ -63,8 +61,21 @@ public class Menus {
|
||||
return MENUS.values();
|
||||
}
|
||||
|
||||
public static void addCooldown(UUID uuid, long time) {
|
||||
COOLDOWNS.put(uuid, time);
|
||||
}
|
||||
|
||||
public static Long getCooldown(UUID uuid) {
|
||||
return COOLDOWNS.getOrDefault(uuid, 0L);
|
||||
}
|
||||
|
||||
public static void removeCooldown(UUID uuid) {
|
||||
COOLDOWNS.remove(uuid);
|
||||
}
|
||||
|
||||
public static void setup() {
|
||||
MENUS.clear();
|
||||
COOLDOWNS.clear();
|
||||
|
||||
File cosmeticFolder = new File(HMCCosmeticsPlugin.getInstance().getDataFolder() + "/menus");
|
||||
if (!cosmeticFolder.exists()) cosmeticFolder.mkdir();
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.hibiscusmc.hmccosmetics.gui.action;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.actions.*;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -8,18 +8,16 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.hibiscuscommons.util.ColorBuilder;
|
||||
import me.lojosho.hibiscuscommons.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DyeMenu {
|
||||
|
||||
public static void openMenu(@NotNull CosmeticUser user, Cosmetic cosmetic) {
|
||||
@@ -42,9 +40,19 @@ public class DyeMenu {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) return;
|
||||
|
||||
Color color = meta instanceof LeatherArmorMeta leatherMeta ? leatherMeta.getColor() :
|
||||
meta instanceof PotionMeta potionMeta ? potionMeta.getColor() :
|
||||
meta instanceof MapMeta mapMeta ? mapMeta.getColor() : null;
|
||||
Color color = null;
|
||||
if (meta instanceof LeatherArmorMeta leatherMeta) {
|
||||
color = leatherMeta.getColor();
|
||||
} else if (meta instanceof PotionMeta potionMeta) {
|
||||
color = potionMeta.getColor();
|
||||
} else if (meta instanceof MapMeta mapMeta) {
|
||||
color = mapMeta.getColor();
|
||||
} else if (meta instanceof FireworkEffectMeta fireworkEffectMeta) {
|
||||
FireworkEffect effect = fireworkEffectMeta.getEffect();
|
||||
if (effect != null) {
|
||||
color = effect.getColors().stream().findFirst().isPresent() ? effect.getColors().stream().findFirst().get() : null;
|
||||
}
|
||||
}
|
||||
if (color == null) return;
|
||||
|
||||
addCosmetic(user, cosmetic, color);
|
||||
|
||||
@@ -140,9 +140,9 @@ public class TypeCosmetic extends Type {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
if (user.hasCosmeticInSlot(cosmetic) && !config.node("equipped-item").virtual()) {
|
||||
if (user.hasCosmeticInSlot(cosmetic) && (!config.node("equipped-item").virtual() || !config.node("locked-equipped-item").virtual())) {
|
||||
MessagesUtil.sendDebugMessages("GUI Equipped Item");
|
||||
ConfigurationNode equippedItem = config.node("equipped-item");
|
||||
ConfigurationNode equippedItem = config.node(user.canEquipCosmetic(cosmetic, true) && !config.node("equipped-item").virtual() ? "equipped-item" : "locked-equipped-item");
|
||||
try {
|
||||
if (equippedItem.node("material").virtual()) equippedItem.node("material").set(config.node("item", "material").getString());
|
||||
} catch (SerializationException e) {
|
||||
|
||||
@@ -167,6 +167,8 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
|
||||
} else {
|
||||
return TranslationUtil.getTranslation("amount-cosmetic", String.valueOf(Cosmetics.values().size()));
|
||||
}
|
||||
case "hidden":
|
||||
return TranslationUtil.getTranslation("hidden", String.valueOf(user.isHidden()));
|
||||
case "wardrobe-enabled":
|
||||
return TranslationUtil.getTranslation("in-wardrobe", String.valueOf(user.isInWardrobe()));
|
||||
}
|
||||
|
||||
@@ -39,10 +39,9 @@ public class WGListener implements Listener {
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
|
||||
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
return;
|
||||
} else {
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
}
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
return;
|
||||
}
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
|
||||
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
||||
import com.destroystokyo.paper.event.player.PlayerPostRespawnEvent;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
@@ -17,6 +18,14 @@ public class PaperPlayerGameListener implements Listener {
|
||||
user.updateCosmetic(slotTypeToCosmeticType(event.getSlotType()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerRespawn(PlayerPostRespawnEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
if (user.isInWardrobe()) return;
|
||||
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) user.respawnBackpack();
|
||||
}
|
||||
|
||||
private CosmeticSlot slotTypeToCosmeticType(PlayerArmorChangeEvent.SlotType slotType) {
|
||||
return switch (slotType) {
|
||||
case HEAD -> CosmeticSlot.HELMET;
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
@@ -65,6 +66,7 @@ public class PlayerConnectionListener implements Listener {
|
||||
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.CONNECTION);
|
||||
event.getPlayer().setInvisible(false);
|
||||
}
|
||||
Menus.removeCooldown(event.getPlayer().getUniqueId()); // Removes any menu cooldowns a player might have
|
||||
Database.save(user);
|
||||
user.destroy();
|
||||
CosmeticUsers.removeUser(user.getUniqueId());
|
||||
|
||||
@@ -27,9 +27,7 @@ import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import me.lojosho.hibiscuscommons.api.events.HibiscusHookReload;
|
||||
import me.lojosho.hibiscuscommons.api.events.HibiscusPlayerUnVanishEvent;
|
||||
import me.lojosho.hibiscuscommons.api.events.HibiscusPlayerVanishEvent;
|
||||
import me.lojosho.hibiscuscommons.api.events.*;
|
||||
import me.lojosho.hibiscuscommons.hooks.items.HookItemAdder;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -209,7 +207,7 @@ public class PlayerGameListener implements Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerLook(PlayerMoveEvent event) {
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
@@ -287,6 +285,7 @@ public class PlayerGameListener implements Listener {
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
if (user.getEntity() == null) return; // Player has likely logged off
|
||||
user.updateCosmetic(CosmeticSlot.OFFHAND);
|
||||
List<Player> viewers = HMCCPacketManager.getViewers(user.getEntity().getLocation());
|
||||
if (viewers.isEmpty()) return;
|
||||
@@ -325,11 +324,12 @@ public class PlayerGameListener implements Listener {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
|
||||
event.getPlayer().getInventory().setItem(event.getPreviousSlot(), event.getPlayer().getInventory().getItem(event.getPreviousSlot()));
|
||||
//NMSHandlers.getHandler().slotUpdate(event.getPlayer(), event.getPreviousSlot());
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
user.updateCosmetic(CosmeticSlot.MAINHAND);
|
||||
}, 2);
|
||||
if (user.hasCosmeticInSlot(CosmeticSlot.MAINHAND)) {
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
user.updateCosmetic(CosmeticSlot.MAINHAND);
|
||||
}, 2);
|
||||
}
|
||||
|
||||
// #84, Riptides mess with backpacks
|
||||
ItemStack currentItem = event.getPlayer().getInventory().getItem(event.getNewSlot());
|
||||
@@ -440,6 +440,21 @@ public class PlayerGameListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// These emote mostly handles emotes from other plugins, such as ItemsAdder
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerPlayEmote(HibiscusPlayerEmotePlayEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerEndEmote(HibiscusPlayerEmoteEndEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.EMOTE);
|
||||
}
|
||||
|
||||
private void registerInventoryClickListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
|
||||
@Override
|
||||
@@ -486,6 +501,10 @@ public class PlayerGameListener implements Listener {
|
||||
if (!user.isInWardrobe()) {
|
||||
for (Cosmetic cosmetic : user.getCosmetics()) {
|
||||
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
|
||||
boolean requireEmpty = Settings.getSlotOption(cosmeticArmorType.getEquipSlot()).isRequireEmpty();
|
||||
boolean isAir = user.getPlayer().getInventory().getItem(cosmeticArmorType.getEquipSlot()).getType().isAir();
|
||||
MessagesUtil.sendDebugMessages("Menu Fired (Checks) - " + cosmeticArmorType.getId() + " - " + requireEmpty + " - " + isAir);
|
||||
if (requireEmpty && !isAir) continue;
|
||||
items.put(HMCCInventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
|
||||
}
|
||||
}
|
||||
@@ -536,9 +555,14 @@ public class PlayerGameListener implements Listener {
|
||||
|
||||
int slot = event.getPacket().getIntegers().read(2);
|
||||
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
|
||||
if (slot == 45 && user.hasCosmeticInSlot(CosmeticSlot.OFFHAND) && player.getInventory().getItemInOffHand().getType().isAir()) {
|
||||
event.getPacket().getItemModifier().write(0, user.getUserCosmeticItem(CosmeticSlot.OFFHAND));
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slot);
|
||||
EquipmentSlot equipmentSlot = HMCCInventoryUtils.getPacketArmorSlot(slot);
|
||||
if (cosmeticSlot == null || equipmentSlot == null) return;
|
||||
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
|
||||
if (Settings.getSlotOption(equipmentSlot).isRequireEmpty()) {
|
||||
if (!player.getInventory().getItem(equipmentSlot).getType().isAir()) return;
|
||||
}
|
||||
event.getPacket().getItemModifier().write(0, user.getUserCosmeticItem(cosmeticSlot));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -563,20 +587,17 @@ public class PlayerGameListener implements Listener {
|
||||
if (user.getPlayer() == event.getPlayer()) continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
|
||||
armor.set(i, new Pair<>(pair.getFirst(), user.getPlayer().getInventory().getItemInMainHand()));
|
||||
}
|
||||
case OFFHAND -> {
|
||||
if (Settings.isCosmeticForceOffhandCosmeticShow() && user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) {
|
||||
ItemStack item = user.getUserCosmeticItem(CosmeticSlot.OFFHAND);
|
||||
if (item == null) continue;
|
||||
Pair<EnumWrappers.ItemSlot, ItemStack> offhandPair = new Pair<>(EnumWrappers.ItemSlot.OFFHAND, item);
|
||||
armor.set(i, offhandPair);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(HMCCInventoryUtils.getItemSlotToCosmeticSlot(pair.getFirst()));
|
||||
EquipmentSlot slot = HMCCInventoryUtils.getEquipmentSlot(pair.getFirst());
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.getItemSlotToCosmeticSlot(pair.getFirst());
|
||||
if (slot == null || cosmeticSlot == null) continue;
|
||||
if (Settings.getSlotOption(slot).isRequireEmpty()
|
||||
&& !user.getPlayer().getInventory().getItem(slot).getType().isAir()) continue;
|
||||
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(cosmeticSlot);
|
||||
if (cosmeticArmor == null) continue;
|
||||
ItemStack item = user.getUserCosmeticItem(cosmeticArmor);
|
||||
if (item == null) continue;
|
||||
Pair<EnumWrappers.ItemSlot, ItemStack> armorPair = new Pair<>(HMCCInventoryUtils.itemBukkitSlot(cosmeticArmor.getEquipSlot()), item);
|
||||
Pair<EnumWrappers.ItemSlot, ItemStack> armorPair = new Pair<>(HMCCInventoryUtils.itemBukkitSlot(slot), item);
|
||||
armor.set(i, armorPair);
|
||||
}
|
||||
}
|
||||
@@ -623,7 +644,8 @@ public class PlayerGameListener implements Listener {
|
||||
}
|
||||
if (!user.isInWardrobe()) return;
|
||||
if (!user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
|
||||
Menu menu = Menus.getDefaultMenu();
|
||||
|
||||
Menu menu = user.getWardrobeManager().getLastOpenMenu();
|
||||
if (menu == null) return;
|
||||
menu.openMenu(user);
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticMainhandType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
@@ -27,8 +28,10 @@ import me.lojosho.hibiscuscommons.util.InventoryUtils;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -68,7 +71,7 @@ public class CosmeticUser {
|
||||
Runnable run = () -> {
|
||||
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
|
||||
updateCosmetic();
|
||||
if (isHidden() && !getUserEmoteManager().isPlayingEmote()) MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
|
||||
if (isHidden() && !getUserEmoteManager().isPlayingEmote() && !getCosmetics().isEmpty()) MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
|
||||
};
|
||||
|
||||
int tickPeriod = Settings.getTickPeriod();
|
||||
@@ -195,13 +198,17 @@ public class CosmeticUser {
|
||||
for (Cosmetic cosmetic : getCosmetics()) {
|
||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||
if (getUserEmoteManager().isPlayingEmote() || isInWardrobe()) return;
|
||||
if (!Settings.isCosmeticForceOffhandCosmeticShow()
|
||||
&& armorType.getEquipSlot().equals(EquipmentSlot.OFF_HAND)
|
||||
&& !getPlayer().getInventory().getItemInOffHand().getType().isAir()) continue;
|
||||
if (!(getEntity() instanceof HumanEntity humanEntity)) return;
|
||||
|
||||
boolean requireEmpty = Settings.getSlotOption(armorType.getEquipSlot()).isRequireEmpty();
|
||||
boolean isAir = humanEntity.getInventory().getItem(armorType.getEquipSlot()).getType().isAir();
|
||||
MessagesUtil.sendDebugMessages("updateCosmetic (All) - " + armorType.getId() + " - " + requireEmpty + " - " + isAir);
|
||||
if (requireEmpty && !isAir) continue;
|
||||
|
||||
items.put(HMCCInventoryUtils.getEquipmentSlot(armorType.getSlot()), armorType.getItem(this));
|
||||
continue;
|
||||
} else {
|
||||
updateCosmetic(cosmetic.getSlot());
|
||||
}
|
||||
updateCosmetic(cosmetic.getSlot());
|
||||
}
|
||||
if (items.isEmpty() || getEntity() == null) return;
|
||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), items, HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
|
||||
@@ -289,6 +296,15 @@ public class CosmeticUser {
|
||||
potionMeta.setColor(color);
|
||||
} else if (itemMeta instanceof MapMeta mapMeta) {
|
||||
mapMeta.setColor(color);
|
||||
} else if (itemMeta instanceof FireworkEffectMeta fireworkMeta) {
|
||||
fireworkMeta.setEffect(
|
||||
FireworkEffect.builder()
|
||||
.with(FireworkEffect.Type.BALL)
|
||||
.withColor(color)
|
||||
.trail(false)
|
||||
.flicker(false)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
itemMeta.getPersistentDataContainer().set(HMCCInventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
|
||||
@@ -347,6 +363,7 @@ public class CosmeticUser {
|
||||
if (!getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
|
||||
|
||||
getWardrobeManager().setWardrobeStatus(UserWardrobeManager.WardrobeStatus.STOPPING);
|
||||
getWardrobeManager().setLastOpenMenu(Menus.getDefaultMenu());
|
||||
|
||||
if (WardrobeSettings.isEnabledTransition() && !ejected) {
|
||||
MessagesUtil.sendTitle(
|
||||
|
||||
@@ -10,10 +10,12 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
@@ -64,6 +66,9 @@ public class UserWardrobeManager {
|
||||
private boolean active;
|
||||
@Getter
|
||||
private WardrobeStatus wardrobeStatus;
|
||||
@Getter
|
||||
@Setter
|
||||
private Menu lastOpenMenu;
|
||||
|
||||
public UserWardrobeManager(CosmeticUser user, Wardrobe wardrobe) {
|
||||
NPC_ID = me.lojosho.hibiscuscommons.util.ServerUtils.getNextEntityId();
|
||||
@@ -79,6 +84,7 @@ public class UserWardrobeManager {
|
||||
this.npcLocation = wardrobeLocation.getNpcLocation();
|
||||
|
||||
wardrobeStatus = WardrobeStatus.SETUP;
|
||||
this.lastOpenMenu = Menus.getDefaultMenu();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -158,7 +164,7 @@ public class UserWardrobeManager {
|
||||
|
||||
if (WardrobeSettings.isEnabledBossbar()) {
|
||||
float progress = WardrobeSettings.getBossbarProgress();
|
||||
Component message = MessagesUtil.processStringNoKey(WardrobeSettings.getBossbarMessage());
|
||||
Component message = MessagesUtil.processStringNoKey(player, WardrobeSettings.getBossbarMessage());
|
||||
|
||||
bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay());
|
||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
||||
@@ -253,7 +259,7 @@ public class UserWardrobeManager {
|
||||
player.teleport(Objects.requireNonNullElseGet(exitLocation, () -> player.getWorld().getSpawnLocation()), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
|
||||
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
for (EquipmentSlot slot : HMCCInventoryUtils.getPlayerArmorSlots()) {
|
||||
ItemStack item = player.getInventory().getItem(slot);
|
||||
items.put(slot, item);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HMCCInventoryUtils {
|
||||
|
||||
/**
|
||||
@@ -60,6 +63,7 @@ public class HMCCInventoryUtils {
|
||||
case FEET -> CosmeticSlot.BOOTS;
|
||||
case OFFHAND -> CosmeticSlot.OFFHAND;
|
||||
case MAINHAND -> CosmeticSlot.MAINHAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -153,6 +157,32 @@ public class HMCCInventoryUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static EquipmentSlot getEquipmentSlot(@NotNull EnumWrappers.ItemSlot slot) {
|
||||
switch (slot) {
|
||||
case HEAD -> {
|
||||
return EquipmentSlot.HEAD;
|
||||
}
|
||||
case CHEST -> {
|
||||
return EquipmentSlot.CHEST;
|
||||
}
|
||||
case LEGS -> {
|
||||
return EquipmentSlot.LEGS;
|
||||
}
|
||||
case FEET -> {
|
||||
return EquipmentSlot.FEET;
|
||||
}
|
||||
case OFFHAND -> {
|
||||
return EquipmentSlot.OFF_HAND;
|
||||
}
|
||||
case MAINHAND -> {
|
||||
return EquipmentSlot.HAND;
|
||||
}
|
||||
default -> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCosmeticItem(ItemStack itemStack) {
|
||||
if (itemStack == null) return false;
|
||||
itemStack = itemStack.clone();
|
||||
@@ -163,4 +193,12 @@ public class HMCCInventoryUtils {
|
||||
public static NamespacedKey getCosmeticKey() {
|
||||
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmetic");
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns all the slots a player can have on them. In 1.20.6+, the enum includes BODY, which is not a valid slot for a player.
|
||||
* @return A list of all the slots a player can have on them
|
||||
*/
|
||||
public static List<EquipmentSlot> getPlayerArmorSlots() {
|
||||
return Arrays.asList(EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET, EquipmentSlot.OFF_HAND, EquipmentSlot.HAND);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
List<Player> sendTo
|
||||
) {
|
||||
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
|
||||
for (EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
for (EquipmentSlot slot : HMCCInventoryUtils.getPlayerArmorSlots()) {
|
||||
ItemStack item = player.getInventory().getItem(slot);
|
||||
if (empty) item = new ItemStack(Material.AIR);
|
||||
items.put(slot, item);
|
||||
@@ -91,7 +91,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
CosmeticSlot cosmeticSlot,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
if (cosmeticSlot == CosmeticSlot.BACKPACK || cosmeticSlot == CosmeticSlot.BALLOON || cosmeticSlot == CosmeticSlot.EMOTE) return;
|
||||
if (cosmeticSlot == CosmeticSlot.BACKPACK || cosmeticSlot == CosmeticSlot.CUSTOM || cosmeticSlot == CosmeticSlot.BALLOON || cosmeticSlot == CosmeticSlot.EMOTE) return;
|
||||
|
||||
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
|
||||
}
|
||||
@@ -103,19 +103,12 @@ public class HMCCPacketManager extends PacketManager {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x21);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x10);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
} else {
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
// 0x21 = Invisible + Fire (Aka, burns to make it not take the light of the block its in, avoiding turning it black)
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x21));
|
||||
wrappedDataValueList.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x10));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
}
|
||||
// 0x21 = Invisible + Fire (Aka, burns to make it not take the light of the block its in, avoiding turning it black)
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x21));
|
||||
wrappedDataValueList.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x10));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
}
|
||||
|
||||
@@ -126,16 +119,10 @@ public class HMCCPacketManager extends PacketManager {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
} else {
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
}
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
}
|
||||
|
||||
@@ -146,19 +133,13 @@ public class HMCCPacketManager extends PacketManager {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, WrappedDataWatcher.Registry.get(Byte.class)), (byte) 0x20);
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(8, WrappedDataWatcher.Registry.get(Float.class)), 0f);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
} else {
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
wrappedDataValueList.add(new WrappedDataValue(8, WrappedDataWatcher.Registry.get(Float.class), 0f));
|
||||
//wrappedDataValueList.add(new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Integer.class), 21));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
}
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
wrappedDataValueList.add(new WrappedDataValue(8, WrappedDataWatcher.Registry.get(Float.class), 0f));
|
||||
//wrappedDataValueList.add(new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Integer.class), 21));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
}
|
||||
|
||||
@@ -267,7 +248,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final int entityId,
|
||||
final @NotNull List<Player> sendTo
|
||||
) {
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) {
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) {
|
||||
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setPlayerUUID(uuid);
|
||||
@@ -304,22 +285,13 @@ public class HMCCPacketManager extends PacketManager {
|
||||
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
|
||||
WrappedSignedProperty skinData = HMCCPlayerUtils.getSkin(skinnedPlayer);
|
||||
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
|
||||
// For sor some reason <1.19.2 handles it on the 0 field index, newer versions handles it on the 1
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
info.getHandle().getPlayerInfoDataLists().write(0, Collections.singletonList(new PlayerInfoData(
|
||||
wrappedGameProfile,
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.CREATIVE,
|
||||
WrappedChatComponent.fromText(name)
|
||||
)));
|
||||
} else {
|
||||
info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData(
|
||||
wrappedGameProfile,
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.CREATIVE,
|
||||
WrappedChatComponent.fromText(name)
|
||||
)));
|
||||
}
|
||||
|
||||
info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData(
|
||||
wrappedGameProfile,
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.CREATIVE,
|
||||
WrappedChatComponent.fromText(name)
|
||||
)));
|
||||
for (final Player p : sendTo) sendPacket(p, info.getHandle());
|
||||
}
|
||||
|
||||
@@ -347,20 +319,12 @@ public class HMCCPacketManager extends PacketManager {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, playerId);
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
wrapper.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get(Byte.class)), mask);
|
||||
packet.getWatchableCollectionModifier().write(0, wrapper.getWatchableObjects());
|
||||
} else {
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(17, WrappedDataWatcher.Registry.get(Byte.class), mask));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
}
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(17, WrappedDataWatcher.Registry.get(Byte.class), mask));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
|
||||
for (final Player p : sendTo) {
|
||||
sendPacket(p, packet);
|
||||
}
|
||||
for (final Player p : sendTo) sendPacket(p, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,21 +339,6 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final UUID uuid,
|
||||
final List<Player> sendTo
|
||||
) {
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
// Remove player is deprecated on 1.19.3+, but we still need to support 1.18.2
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
|
||||
|
||||
String name = "Mannequin-" + player.getEntityId();
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
info.setData(List.of(new PlayerInfoData(new WrappedGameProfile(uuid, player.getName()), 0, EnumWrappers.NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name))));
|
||||
for (final Player p : sendTo) sendPacket(p, info.getHandle());
|
||||
return;
|
||||
}
|
||||
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE);
|
||||
packet.getUUIDLists().write(0, List.of(uuid));
|
||||
for (final Player p : sendTo) sendPacket(p, packet);
|
||||
|
||||
@@ -6,7 +6,7 @@ config-version: 1
|
||||
default-menu: defaultmenu
|
||||
debug-mode: false
|
||||
database-settings:
|
||||
type: sqlite #MYSQL, SQLite
|
||||
type: sqlite # SQLite (Default), MYSQL, NONE
|
||||
mysql:
|
||||
database: database
|
||||
password: cherryBomb
|
||||
@@ -51,13 +51,26 @@ cosmetic-settings:
|
||||
# This is useful for servers with a lot of backpacks, as they are passengers, which means the client will update their position automatically within an area where the entity is located.
|
||||
entity-cooldown-teleport-packet: 500
|
||||
# This forces the offhand to always show the cosmetic. False means it will only show when the slot is empty.
|
||||
# There is a small visual blip for a tick when you put a new item in the offhand slot, hence why its disabled by default.
|
||||
offhand-always-show: false
|
||||
|
||||
helmet-add-enchantments: false # If the plugin should keep enchants on helmets. This is useful as some enchantments are client side only.
|
||||
chest-add-enchantments: false # If the plugin should keep enchants on chestplate. This is useful as some enchantments are client side only.
|
||||
leggings-add-enchantments: false # If the plugin should keep enchants on leggings. This is useful as some enchantments are client side only.
|
||||
boots-add-enchantments: false # If the plugin should keep enchants on boots. This is useful as some enchantments are client side only.
|
||||
slot-options:
|
||||
helmet:
|
||||
# If the plugin should keep enchants on helmets. This is useful as some enchantments are client side only.
|
||||
add-enchantments: false
|
||||
# Should the player slot be empty for the cosmetic to be applied? A cosmetic will be "hidden" if a player has an item equipped in the slot
|
||||
require-empty: false
|
||||
chestplate:
|
||||
add-enchantments: false
|
||||
require-empty: false
|
||||
leggings:
|
||||
add-enchantments: false
|
||||
require-empty: false
|
||||
boots:
|
||||
add-enchantments: false
|
||||
require-empty: false
|
||||
offhand:
|
||||
add-enchantments: false
|
||||
# There is a small visual blip for a tick when you put a new item in the offhand slot, hence why its enabled by default.
|
||||
require-empty: true
|
||||
|
||||
# This attempts to destroy cosmetics that get loose in the wild, such as through a player entering creative mode.
|
||||
# Most servers who don't use creative mode and have properly set up the plugin should have no need for this and can leave it disabled.
|
||||
@@ -76,6 +89,11 @@ cosmetic-settings:
|
||||
y: 3
|
||||
z: 0.5
|
||||
menu-settings:
|
||||
click-cooldown:
|
||||
enabled: true
|
||||
# This is the cooldown in miliseconds for the menu. This is useful for servers that have a lot of players.
|
||||
# (So if a user clicks the menu, it won't spam the server with requesting it to refresh itself)
|
||||
time: 1000
|
||||
shading:
|
||||
# Below is the shading mechanism behind cosmetic items. This is a bit complicated, but it allows for a lot of customization.
|
||||
# The shading is done through the title and by shifting textures around. This is done by offsets.
|
||||
|
||||
@@ -9,6 +9,7 @@ not-enough-args: "%prefix% <red>Improper amount of arguments"
|
||||
no-permission: "%prefix% <red>No Permission!"
|
||||
no-cosmetic-permission: "%prefix% <red>You do not have permission for this cosmetic!"
|
||||
no-cosmetic-slot: "%prefix% <red>There are no cosmetics in that slot!"
|
||||
on-click-cooldown: "%prefix% <red>You are on cooldown!"
|
||||
|
||||
opened-wardrobe: "%prefix% <gradient:#6D9DC5:#45CDE9>Opened wardrobe!"
|
||||
closed-wardrobe: "%prefix% <gradient:#6D9DC5:#45CDE9>Closed wardrobe!"
|
||||
|
||||
@@ -13,6 +13,9 @@ in-wardrobe:
|
||||
using-cosmetic:
|
||||
true: "true"
|
||||
false: "false"
|
||||
hidden:
|
||||
true: "true"
|
||||
false: "false"
|
||||
current-cosmetic:
|
||||
no-cosmetic: "No Cosmetic"
|
||||
none: "none"
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
51
gradlew
vendored
51
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright <EFBFBD> 2015-2021 the original authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
|
||||
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
|
||||
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
|
||||
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
@@ -205,6 +214,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
||||
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
Reference in New Issue
Block a user