mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-20 07:29:15 +00:00
Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e2b2edadd | ||
|
|
7e384fcd79 | ||
|
|
e88b84610e | ||
|
|
223ffa46eb | ||
|
|
f408108682 | ||
|
|
b9f9448367 | ||
|
|
c40aca9946 | ||
|
|
98d2692def | ||
|
|
ebbc80c465 | ||
|
|
775699d9ca | ||
|
|
b0ba5fc011 | ||
|
|
af01ff600b | ||
|
|
2e4619da02 | ||
|
|
b4bd08c249 | ||
|
|
19981b33d3 | ||
|
|
c7c4c0e583 | ||
|
|
935c157421 | ||
|
|
20a3a508c2 | ||
|
|
92b75c43ab | ||
|
|
a6ad2c19aa | ||
|
|
fe8b4c97ff | ||
|
|
8c119c78db | ||
|
|
ce33a72fc2 | ||
|
|
2a8f30636d | ||
|
|
4103c2c232 | ||
|
|
fb5c9d205c | ||
|
|
126d576303 | ||
|
|
c74b76837b | ||
|
|
d2c37f8273 | ||
|
|
dbadbda82f | ||
|
|
d66aa3b79c | ||
|
|
1c5cd7b467 | ||
|
|
10f8dda150 | ||
|
|
e76aa0783e | ||
|
|
0676125f07 | ||
|
|
7aef681149 | ||
|
|
d5ac55f266 | ||
|
|
c2b787c97c | ||
|
|
732c3de0d8 | ||
|
|
3843a28804 | ||
|
|
a63494ba9f | ||
|
|
c7e6a77eb8 | ||
|
|
075d2b3182 | ||
|
|
515de7d2c8 | ||
|
|
429287c9f3 | ||
|
|
fed13b8ee6 | ||
|
|
8011dda200 | ||
|
|
7abfb0edf1 | ||
|
|
1f8c772712 | ||
|
|
7d727bb68f | ||
|
|
007f27f109 | ||
|
|
e0e0d0c997 | ||
|
|
75a1458ae1 | ||
|
|
548b15d99d | ||
|
|
50f04373b7 | ||
|
|
27a6c1bd54 | ||
|
|
bb08fb108c | ||
|
|
3907bc5839 | ||
|
|
1ef7f4759f | ||
|
|
937f66e8c5 | ||
|
|
158f3afdec | ||
|
|
38bdc01e9f | ||
|
|
797992362a | ||
|
|
9716a079be | ||
|
|
dfe51ba5b8 | ||
|
|
f5e81446a6 | ||
|
|
c99a57a6bf | ||
|
|
79630263f2 | ||
|
|
478c4280c1 | ||
|
|
4fd439acc4 | ||
|
|
58c955a00f | ||
|
|
2f9325b2fb | ||
|
|
823270648b | ||
|
|
d5e988261b | ||
|
|
13303096ec | ||
|
|
3ee79e8443 | ||
|
|
7785556967 | ||
|
|
1296ca6e92 | ||
|
|
f56d5c9093 | ||
|
|
bae04fba3f | ||
|
|
cbe5404399 | ||
|
|
dc4098782a | ||
|
|
2eb0b26fb3 | ||
|
|
22159fa9f4 | ||
|
|
539c09801c | ||
|
|
bed5cd7bbb | ||
|
|
4a1a631557 | ||
|
|
ad282a9efe | ||
|
|
86ef4d0efa | ||
|
|
da09a542f1 | ||
|
|
62f32cc03d | ||
|
|
ff1addfd65 | ||
|
|
73f013bf1f | ||
|
|
204fee4456 | ||
|
|
e7ea62a4d2 | ||
|
|
42802e41b4 | ||
|
|
7e7d81d0f8 | ||
|
|
b07c3c9878 | ||
|
|
a19d564460 | ||
|
|
b3408143f0 | ||
|
|
3c1539285d | ||
|
|
a642d88af2 | ||
|
|
36d4009f5e |
@@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.hibiscusmc"
|
group = "com.hibiscusmc"
|
||||||
version = "2.7.8${getGitCommitHash()}"
|
version = "2.8.3${getGitCommitHash()}"
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
apply(plugin = "java")
|
apply(plugin = "java")
|
||||||
@@ -16,6 +16,7 @@ allprojects {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
|
||||||
// Paper Repo
|
// Paper Repo
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
@@ -24,8 +25,7 @@ allprojects {
|
|||||||
// Jitpack
|
// Jitpack
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
|
|
||||||
// ProtocolLib repo
|
// Geary
|
||||||
maven("https://repo.dmulloy2.net/repository/public/") //ProtocolLib Repo, constantly down
|
|
||||||
maven("https://repo.mineinabyss.com/releases/")
|
maven("https://repo.mineinabyss.com/releases/")
|
||||||
maven("https://repo.mineinabyss.com/snapshots/")
|
maven("https://repo.mineinabyss.com/snapshots/")
|
||||||
|
|
||||||
@@ -75,23 +75,31 @@ allprojects {
|
|||||||
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
|
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
|
||||||
compileOnly("com.mojang:authlib:1.5.25")
|
compileOnly("com.mojang:authlib:1.5.25")
|
||||||
//compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
//compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
||||||
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
||||||
compileOnly("org.jetbrains:annotations:24.1.0")
|
compileOnly("org.jetbrains:annotations:24.1.0")
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
|
||||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.6")
|
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.6")
|
||||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.12")
|
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.12") {
|
||||||
|
exclude(group = "org.bukkit")
|
||||||
|
exclude(group = "com.google.guava")
|
||||||
|
exclude(group = "com.google.code.gson")
|
||||||
|
exclude(group = "it.unimi.dsi")
|
||||||
|
exclude(group = "com.sk89q.jnbt")
|
||||||
|
exclude(group = "org.enginehub.lin-bus.format")
|
||||||
|
}
|
||||||
compileOnly("io.github.toxicity188:BetterHud-standard-api:1.12") //Standard api
|
compileOnly("io.github.toxicity188:BetterHud-standard-api:1.12") //Standard api
|
||||||
compileOnly("io.github.toxicity188:BetterHud-bukkit-api:1.12") //Platform api
|
compileOnly("io.github.toxicity188:BetterHud-bukkit-api:1.12") //Platform api
|
||||||
compileOnly("io.github.toxicity188:BetterCommand:1.3") //BetterCommand library
|
compileOnly("io.github.toxicity188:BetterCommand:1.3") //BetterCommand library
|
||||||
//compileOnly("it.unimi.dsi:fastutil:8.5.14")
|
//compileOnly("it.unimi.dsi:fastutil:8.5.14")
|
||||||
compileOnly("org.projectlombok:lombok:1.18.34")
|
compileOnly("org.projectlombok:lombok:1.18.34")
|
||||||
compileOnly("me.lojosho:HibiscusCommons:0.6.3-0f0baaf4")
|
compileOnly("me.lojosho:HibiscusCommons:0.8.1-d9fbae1d")
|
||||||
|
|
||||||
// Handled by Spigot Library Loader
|
// Handled by Spigot Library Loader ~ Deprecated as of Dec 16, 2025
|
||||||
compileOnly("net.kyori:adventure-api:4.19.0")
|
/*
|
||||||
compileOnly("net.kyori:adventure-text-minimessage:4.19.0")
|
compileOnly("net.kyori:adventure-api:4.24.0")
|
||||||
compileOnly("net.kyori:adventure-platform-bukkit:4.3.4")
|
compileOnly("net.kyori:adventure-text-minimessage:4.24.0")
|
||||||
|
compileOnly("net.kyori:adventure-platform-bukkit:4.4.1")
|
||||||
|
*/
|
||||||
|
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.36")
|
annotationProcessor("org.projectlombok:lombok:1.18.36")
|
||||||
testCompileOnly("org.projectlombok:lombok:1.18.36")
|
testCompileOnly("org.projectlombok:lombok:1.18.36")
|
||||||
@@ -101,7 +109,6 @@ allprojects {
|
|||||||
exclude("net.kyori") // Already have adventure API
|
exclude("net.kyori") // Already have adventure API
|
||||||
}
|
}
|
||||||
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
|
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
|
||||||
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.7")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
@@ -134,12 +141,14 @@ tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.21.4")
|
minecraftVersion("1.21.8")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
hangar("PlaceholderAPI", "2.11.6")
|
hangar("PlaceholderAPI", "2.11.6")
|
||||||
url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
|
hangar("Multiverse-Core", "5.3.4")
|
||||||
url("https://download.luckperms.net/1582/bukkit/loader/LuckPerms-Bukkit-5.4.165.jar")
|
url("https://download.luckperms.net/1604/bukkit/loader/LuckPerms-Bukkit-5.5.15.jar")
|
||||||
|
github("Test-Account666", "PlugManX", "2.4.1", "PlugManX-2.4.1.jar")
|
||||||
|
//github("gecolay", "GSit", "2.4.3", "GSit-2.4.3.jar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,8 +184,8 @@ bukkit {
|
|||||||
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
|
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
|
||||||
apiVersion = "1.20"
|
apiVersion = "1.20"
|
||||||
authors = listOf("LoJoSho")
|
authors = listOf("LoJoSho")
|
||||||
depend = listOf("HibiscusCommons", "ProtocolLib")
|
depend = listOf("HibiscusCommons")
|
||||||
softDepend = listOf("BetterHud", "ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
softDepend = listOf("Nexo", "BetterHud", "ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
||||||
version = "${project.version}"
|
version = "${project.version}"
|
||||||
loadBefore = listOf(
|
loadBefore = listOf(
|
||||||
"Cosmin" // Fixes an issue with Cosmin loading before and taking /cosmetic, when messing with what we do.
|
"Cosmin" // Fixes an issue with Cosmin loading before and taking /cosmetic, when messing with what we do.
|
||||||
|
|||||||
@@ -11,23 +11,26 @@ import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
|||||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenuProvider;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.special.impl.HMCColorDyeMenu;
|
||||||
import com.hibiscusmc.hmccosmetics.hooks.items.HookHMCCosmetics;
|
import com.hibiscusmc.hmccosmetics.hooks.items.HookHMCCosmetics;
|
||||||
import com.hibiscusmc.hmccosmetics.hooks.misc.HookBetterHud;
|
import com.hibiscusmc.hmccosmetics.hooks.misc.HookBetterHud;
|
||||||
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HMCPlaceholderExpansion;
|
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HMCPlaceholderExpansion;
|
||||||
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
|
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
|
||||||
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener;
|
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener;
|
||||||
import com.hibiscusmc.hmccosmetics.listener.PaperPlayerGameListener;
|
import com.hibiscusmc.hmccosmetics.listener.*;
|
||||||
import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener;
|
import com.hibiscusmc.hmccosmetics.packets.CosmeticPacketInterface;
|
||||||
import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
|
|
||||||
import com.hibiscusmc.hmccosmetics.listener.ServerListener;
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
|
import com.hibiscusmc.hmccosmetics.util.PlayerSearchManager;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
|
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
|
||||||
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||||
import me.lojosho.hibiscuscommons.HibiscusPlugin;
|
import me.lojosho.hibiscuscommons.HibiscusPlugin;
|
||||||
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
||||||
import me.lojosho.hibiscuscommons.config.serializer.LocationSerializer;
|
import me.lojosho.hibiscuscommons.config.serializer.LocationSerializer;
|
||||||
|
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||||
import me.lojosho.shaded.configupdater.common.config.CommentedConfiguration;
|
import me.lojosho.shaded.configupdater.common.config.CommentedConfiguration;
|
||||||
import me.lojosho.shaded.configurate.ConfigurateException;
|
import me.lojosho.shaded.configurate.ConfigurateException;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationOptions;
|
import me.lojosho.shaded.configurate.ConfigurationOptions;
|
||||||
@@ -47,6 +50,9 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
|||||||
private static HMCCosmeticsPlugin instance;
|
private static HMCCosmeticsPlugin instance;
|
||||||
private static YamlConfigurationLoader configLoader;
|
private static YamlConfigurationLoader configLoader;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private PlayerSearchManager playerSearchManager;
|
||||||
|
|
||||||
public HMCCosmeticsPlugin() {
|
public HMCCosmeticsPlugin() {
|
||||||
super(13873, 1879);
|
super(13873, 1879);
|
||||||
new HookHMCCosmetics();
|
new HookHMCCosmetics();
|
||||||
@@ -58,12 +64,20 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
|||||||
// Plugin startup logic
|
// Plugin startup logic
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
|
// Search Service
|
||||||
|
this.playerSearchManager = new PlayerSearchManager(this);
|
||||||
|
|
||||||
// File setup
|
// File setup
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
|
if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false);
|
||||||
if (!Path.of(getDataFolder().getPath(), "translations.yml").toFile().exists()) saveResource("translations.yml", false);
|
if (!Path.of(getDataFolder().getPath(), "translations.yml").toFile().exists()) saveResource("translations.yml", false);
|
||||||
if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
|
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);
|
if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) {
|
||||||
|
saveResource("menus/defaultmenu_hats.yml", false);
|
||||||
|
saveResource("menus/defaultmenu_balloons.yml", false);
|
||||||
|
saveResource("menus/defaultmenu_hands.yml", false);
|
||||||
|
saveResource("menus/defaultmenu_backpacks.yml", false);
|
||||||
|
}
|
||||||
|
|
||||||
// Configuration Sync
|
// Configuration Sync
|
||||||
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
|
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
|
||||||
@@ -83,6 +97,7 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
|||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
setup();
|
setup();
|
||||||
|
setPacketInterface(new CosmeticPacketInterface());
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
getServer().getPluginCommand("cosmetic").setExecutor(new CosmeticCommand());
|
getServer().getPluginCommand("cosmetic").setExecutor(new CosmeticCommand());
|
||||||
@@ -92,6 +107,8 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
|||||||
getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this);
|
getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this);
|
||||||
getServer().getPluginManager().registerEvents(new PlayerGameListener(), this);
|
getServer().getPluginManager().registerEvents(new PlayerGameListener(), this);
|
||||||
getServer().getPluginManager().registerEvents(new ServerListener(), this);
|
getServer().getPluginManager().registerEvents(new ServerListener(), this);
|
||||||
|
getServer().getPluginManager().registerEvents(new PlayerMovementListener(), this);
|
||||||
|
getServer().getPluginManager().registerEvents(playerSearchManager, this);
|
||||||
|
|
||||||
if (HibiscusCommonsPlugin.isOnPaper()) {
|
if (HibiscusCommonsPlugin.isOnPaper()) {
|
||||||
getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this);
|
getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this);
|
||||||
@@ -103,6 +120,15 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
|||||||
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheck()) {
|
if (Bukkit.getPluginManager().getPlugin("WorldGuard") != null && Settings.isWorldGuardMoveCheck()) {
|
||||||
getServer().getPluginManager().registerEvents(new WGListener(), this);
|
getServer().getPluginManager().registerEvents(new WGListener(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HMCColor
|
||||||
|
if (Hooks.isActiveHook("HMCColor")) {
|
||||||
|
try {
|
||||||
|
DyeMenuProvider.setDyeMenuProvider(new HMCColorDyeMenu());
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
getLogger().warning("Unable to set HMCColor as the dye menu. There is likely another plugin registering another dye menu.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUserProvider;
|
|||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
import me.lojosho.hibiscuscommons.nms.MinecraftVersion;
|
import me.lojosho.hibiscuscommons.nms.MinecraftVersion;
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -21,7 +20,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main API class for HMCCosmetics. This class provides methods to interact with the plugin.
|
* The main API class for HMCCosmetics. This class provides methods to interact with the plugin.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.api.events;
|
package com.hibiscusmc.hmccosmetics.api.events;
|
||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.hibiscusmc.hmccosmetics.database.Database;
|
|||||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenuProvider;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
@@ -309,13 +310,17 @@ public class CosmeticCommand implements CommandExecutor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String rawSlot = args[1];
|
final String rawSlot = args[1];
|
||||||
if (!CosmeticSlot.contains(rawSlot)) {
|
if (!CosmeticSlot.contains(rawSlot)) {
|
||||||
if (!silent) MessagesUtil.sendMessage(player, "invalid-slot");
|
if (!silent) MessagesUtil.sendMessage(player, "invalid-slot");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CosmeticSlot slot = CosmeticSlot.valueOf(rawSlot);
|
final CosmeticSlot slot = CosmeticSlot.valueOf(rawSlot); // This is checked above. While IDEs may say the slot might be null, it will not be.
|
||||||
Cosmetic cosmetic = user.getCosmetic(slot);
|
final Cosmetic cosmetic = user.getCosmetic(slot);
|
||||||
|
if (cosmetic == null) {
|
||||||
|
if (!silent) MessagesUtil.sendMessage(player, "invalid-slot");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (args.length >= 3) {
|
if (args.length >= 3) {
|
||||||
if (args[2].isEmpty()) {
|
if (args[2].isEmpty()) {
|
||||||
@@ -329,7 +334,11 @@ public class CosmeticCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
user.addCosmetic(cosmetic, color); // #FFFFFF
|
user.addCosmetic(cosmetic, color); // #FFFFFF
|
||||||
} else {
|
} else {
|
||||||
DyeMenu.openMenu(user, cosmetic);
|
if (DyeMenuProvider.hasMenuProvider()) {
|
||||||
|
DyeMenuProvider.openMenu(player, user, cosmetic);
|
||||||
|
} else {
|
||||||
|
if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ("setwardrobesetting") -> {
|
case ("setwardrobesetting") -> {
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ public class Settings {
|
|||||||
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
|
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
|
||||||
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
|
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
|
||||||
private static final String COSMETIC_DISABLED_WORLDS_PATH = "disabled-worlds";
|
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_BACKPACK_FORCE_RIDING_PACKET_PATH = "backpack-force-riding-packet";
|
||||||
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
|
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 COSMETIC_BALLOON_HEAD_FORWARD_PATH = "balloon-head-forward";
|
||||||
|
private static final String COSMETIC_OFFHAND_PREVENT_SWAPPING = "offhand-prevent-swapping";
|
||||||
private static final String MENU_SETTINGS_PATH = "menu-settings";
|
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_PATH = "click-cooldown";
|
||||||
private static final String MENU_CLICK_COOLDOWN_TIME_PATH = "time";
|
private static final String MENU_CLICK_COOLDOWN_TIME_PATH = "time";
|
||||||
@@ -101,6 +101,8 @@ public class Settings {
|
|||||||
@Getter
|
@Getter
|
||||||
private static boolean destroyLooseCosmetics;
|
private static boolean destroyLooseCosmetics;
|
||||||
@Getter
|
@Getter
|
||||||
|
private static boolean preventOffhandSwapping;
|
||||||
|
@Getter
|
||||||
private static boolean backpackForceRidingEnabled;
|
private static boolean backpackForceRidingEnabled;
|
||||||
@Getter
|
@Getter
|
||||||
private static boolean disabledGamemodesEnabled;
|
private static boolean disabledGamemodesEnabled;
|
||||||
@@ -117,14 +119,10 @@ public class Settings {
|
|||||||
@Getter
|
@Getter
|
||||||
private static int tickPeriod;
|
private static int tickPeriod;
|
||||||
@Getter
|
@Getter
|
||||||
private static int packetEntityTeleportCooldown;
|
|
||||||
@Getter
|
|
||||||
private static Long defaultMenuCooldown;
|
private static Long defaultMenuCooldown;
|
||||||
@Getter
|
@Getter
|
||||||
private static boolean menuClickCooldown;
|
private static boolean menuClickCooldown;
|
||||||
@Getter
|
@Getter
|
||||||
private static double emoteDistance;
|
|
||||||
@Getter
|
|
||||||
private static Vector balloonOffset;
|
private static Vector balloonOffset;
|
||||||
@Getter
|
@Getter
|
||||||
private static String cosmeticEquipClickType;
|
private static String cosmeticEquipClickType;
|
||||||
@@ -192,6 +190,7 @@ public class Settings {
|
|||||||
forceShowOnJoin = cosmeticSettings.node(FORCE_SHOW_COSMETICS_PATH).getBoolean(false);
|
forceShowOnJoin = cosmeticSettings.node(FORCE_SHOW_COSMETICS_PATH).getBoolean(false);
|
||||||
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
|
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
|
||||||
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
|
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
|
||||||
|
preventOffhandSwapping = cosmeticSettings.node(COSMETIC_OFFHAND_PREVENT_SWAPPING).getBoolean(false);
|
||||||
|
|
||||||
cosmeticSettings.node(SLOT_OPTIONS_PATH).childrenMap().forEach((key, value) -> {
|
cosmeticSettings.node(SLOT_OPTIONS_PATH).childrenMap().forEach((key, value) -> {
|
||||||
EquipmentSlot slot = convertConfigToEquipment(key.toString().toLowerCase());
|
EquipmentSlot slot = convertConfigToEquipment(key.toString().toLowerCase());
|
||||||
@@ -206,7 +205,6 @@ public class Settings {
|
|||||||
|
|
||||||
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
|
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
|
||||||
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
|
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
|
||||||
packetEntityTeleportCooldown = cosmeticSettings.node(COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH).getInt(-1);
|
|
||||||
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false);
|
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false);
|
||||||
backpackPreventDarkness = cosmeticSettings.node(BACKPACK_PREVENT_DARKNESS_PATH).getBoolean(true);
|
backpackPreventDarkness = cosmeticSettings.node(BACKPACK_PREVENT_DARKNESS_PATH).getBoolean(true);
|
||||||
|
|
||||||
@@ -228,9 +226,9 @@ public class Settings {
|
|||||||
lockedCosmeticColor = shadingSettings.node(LOCKED_COSMETIC_COLOR_PATH).getString();
|
lockedCosmeticColor = shadingSettings.node(LOCKED_COSMETIC_COLOR_PATH).getString();
|
||||||
|
|
||||||
ConfigurationNode cosmeticTypeSettings = menuSettings.node(COSMETIC_TYPE_SETTINGS_PATH);
|
ConfigurationNode cosmeticTypeSettings = menuSettings.node(COSMETIC_TYPE_SETTINGS_PATH);
|
||||||
cosmeticEquipClickType = cosmeticTypeSettings.node(EQUIP_CLICK_TYPE).getString("ALL");
|
cosmeticEquipClickType = cosmeticTypeSettings.node(EQUIP_CLICK_TYPE).getString("ANY");
|
||||||
cosmeticUnEquipClickType = cosmeticTypeSettings.node(UNEQUIP_CLICK_TYPE).getString("ALL");
|
cosmeticUnEquipClickType = cosmeticTypeSettings.node(UNEQUIP_CLICK_TYPE).getString("ANY");
|
||||||
cosmeticDyeClickType = cosmeticTypeSettings.node(DYE_CLICK_TYPE).getString("ALL");
|
cosmeticDyeClickType = cosmeticTypeSettings.node(DYE_CLICK_TYPE).getString("ANY");
|
||||||
|
|
||||||
final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET);
|
final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET);
|
||||||
balloonOffset = loadVector(balloonSection);
|
balloonOffset = loadVector(balloonSection);
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticUpdateBehavior;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
||||||
import net.kyori.adventure.text.Component;
|
import org.bukkit.ChatColor;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -26,13 +27,16 @@ public abstract class Cosmetic {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
UNDEFINED_DISPLAY_ITEM_STACK = new ItemStack(Material.BARRIER);
|
UNDEFINED_DISPLAY_ITEM_STACK = new ItemStack(Material.BARRIER);
|
||||||
UNDEFINED_DISPLAY_ITEM_STACK.editMeta(meta -> {
|
|
||||||
meta.displayName(Component.text("Undefined Item Display", NamedTextColor.RED));
|
ItemMeta meta = UNDEFINED_DISPLAY_ITEM_STACK.getItemMeta();
|
||||||
meta.lore(List.of(
|
if (meta != null) {
|
||||||
Component.text("Please check your configurations & console to", NamedTextColor.RED),
|
// Legacy methods for Spigot >:(
|
||||||
Component.text("ensure there are no errors.", NamedTextColor.RED)
|
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&cUndefined Item Display"));
|
||||||
));
|
meta.setLore(List.of(
|
||||||
});
|
ChatColor.translateAlternateColorCodes('&', "&cPlease check your configurations & console to"),
|
||||||
|
ChatColor.translateAlternateColorCodes('&', "&censure there are no errors.")));
|
||||||
|
}
|
||||||
|
UNDEFINED_DISPLAY_ITEM_STACK.setItemMeta(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Identifier of the cosmetic. */
|
/** Identifier of the cosmetic. */
|
||||||
@@ -54,8 +58,12 @@ public abstract class Cosmetic {
|
|||||||
/** Whether the cosmetic is dyeable or not. */
|
/** Whether the cosmetic is dyeable or not. */
|
||||||
private boolean dyeable;
|
private boolean dyeable;
|
||||||
|
|
||||||
|
/** The config for the cosmetic */
|
||||||
|
private ConfigurationNode config;
|
||||||
|
|
||||||
protected Cosmetic(@NotNull String id, @NotNull ConfigurationNode config) {
|
protected Cosmetic(@NotNull String id, @NotNull ConfigurationNode config) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
if (!config.node("permission").virtual()) {
|
if (!config.node("permission").virtual()) {
|
||||||
this.permission = config.node("permission").getString();
|
this.permission = config.node("permission").getString();
|
||||||
@@ -94,19 +102,24 @@ public abstract class Cosmetic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatched when an update is requested upon the cosmetic.
|
* Dispatched when an update is requested upon the cosmetic. Instead, you should use {@link CosmeticUser#updateCosmetic(CosmeticSlot)})}
|
||||||
* @param user the user to preform the update against
|
* @param user the user to preform the update against
|
||||||
*/
|
*/
|
||||||
public final void update(CosmeticUser user) {
|
@Deprecated(since = "2.8.2")
|
||||||
this.doUpdate(user);
|
public void update(CosmeticUser user) {
|
||||||
|
if(this instanceof CosmeticUpdateBehavior behavior) {
|
||||||
|
behavior.dispatchUpdate(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action preformed on the update.
|
* Action preformed on the update. Instead, you should use {@link CosmeticUser#updateCosmetic(CosmeticSlot)})}
|
||||||
* @param user the user to preform the update against
|
* @param user the user to preform the update against
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "2.8.2")
|
||||||
protected void doUpdate(final CosmeticUser user) {
|
protected void doUpdate(final CosmeticUser user) {
|
||||||
// NO-OP.
|
// #update should be the preferred way of interacting with this api now.
|
||||||
|
this.update(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -133,4 +146,14 @@ public abstract class Cosmetic {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* While cosmetics registered in HMCC are made through a configuration, cosmetics registered from other plugins
|
||||||
|
* may not and instead opt for {@link Cosmetic#Cosmetic(String, String, ItemStack, String, CosmeticSlot, boolean)}, which doesn't use a config.
|
||||||
|
* This should be used only for reference.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public @Nullable ConfigurationNode getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
|||||||
import com.google.common.collect.ImmutableCollection;
|
import com.google.common.collect.ImmutableCollection;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -54,7 +55,9 @@ public interface CosmeticHolder {
|
|||||||
|
|
||||||
boolean canEquipCosmetic(@NotNull Cosmetic cosmetic, boolean ignoreWardrobe);
|
boolean canEquipCosmetic(@NotNull Cosmetic cosmetic, boolean ignoreWardrobe);
|
||||||
|
|
||||||
void updateCosmetic(@NotNull CosmeticSlot slot);
|
boolean updateCosmetic(@NotNull CosmeticSlot slot);
|
||||||
|
|
||||||
|
boolean updateMovementCosmetic(@NotNull CosmeticSlot slot, final Location from, final Location to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just for backwards compatibility, ensures that the given viewer and the given cosmetic holder
|
* Just for backwards compatibility, ensures that the given viewer and the given cosmetic holder
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
|||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
@@ -24,8 +22,6 @@ public abstract class CosmeticProvider {
|
|||||||
Map.entry(CosmeticSlot.BOOTS, CosmeticArmorType::new),
|
Map.entry(CosmeticSlot.BOOTS, CosmeticArmorType::new),
|
||||||
Map.entry(CosmeticSlot.OFFHAND, CosmeticArmorType::new),
|
Map.entry(CosmeticSlot.OFFHAND, CosmeticArmorType::new),
|
||||||
|
|
||||||
Map.entry(CosmeticSlot.MAINHAND, CosmeticMainhandType::new),
|
|
||||||
|
|
||||||
Map.entry(CosmeticSlot.BACKPACK, CosmeticBackpackType::new),
|
Map.entry(CosmeticSlot.BACKPACK, CosmeticBackpackType::new),
|
||||||
|
|
||||||
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::new)
|
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::new)
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.cosmetic.behavior;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates cosmetics whenever a player moves.
|
||||||
|
*/
|
||||||
|
public interface CosmeticMovementBehavior {
|
||||||
|
void dispatchMove(
|
||||||
|
@NotNull final CosmeticUser user,
|
||||||
|
@NotNull final Location from,
|
||||||
|
@NotNull final Location to
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.cosmetic.behavior;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic updates that happen every tick or when manually requested to be dispatched.
|
||||||
|
*/
|
||||||
|
public interface CosmeticUpdateBehavior {
|
||||||
|
void dispatchUpdate(
|
||||||
|
@NotNull final CosmeticUser user
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
|
|||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticUpdateBehavior;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
@@ -15,8 +16,7 @@ import org.bukkit.inventory.EquipmentSlot;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class CosmeticArmorType extends Cosmetic {
|
public class CosmeticArmorType extends Cosmetic implements CosmeticUpdateBehavior {
|
||||||
|
|
||||||
private final EquipmentSlot equipSlot;
|
private final EquipmentSlot equipSlot;
|
||||||
|
|
||||||
public CosmeticArmorType(String id, ConfigurationNode config) {
|
public CosmeticArmorType(String id, ConfigurationNode config) {
|
||||||
@@ -31,7 +31,7 @@ public class CosmeticArmorType extends Cosmetic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
public void dispatchUpdate(@NotNull CosmeticUser user) {
|
||||||
if (user.isInWardrobe()) return;
|
if (user.isInWardrobe()) return;
|
||||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
@@ -48,9 +48,11 @@ public class CosmeticArmorType extends Cosmetic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getItem(@NotNull CosmeticUser user, ItemStack cosmeticItem) {
|
public ItemStack getItem(@NotNull CosmeticUser user, ItemStack cosmeticItem) {
|
||||||
if (!(user.getEntity() instanceof HumanEntity humanEntity)) return null;
|
Player player = user.getPlayer();
|
||||||
|
if (player == null) return null;
|
||||||
|
|
||||||
if (Settings.getSlotOption(equipSlot).isAddEnchantments()) {
|
if (Settings.getSlotOption(equipSlot).isAddEnchantments()) {
|
||||||
ItemStack equippedItem = humanEntity.getInventory().getItem(equipSlot);
|
ItemStack equippedItem = player.getInventory().getItem(equipSlot);
|
||||||
cosmeticItem.addUnsafeEnchantments(equippedItem.getEnchantments());
|
cosmeticItem.addUnsafeEnchantments(equippedItem.getEnchantments());
|
||||||
}
|
}
|
||||||
// Basically, if force offhand is off AND there is no item in an offhand slot, then the equipment packet to add the cosmetic
|
// Basically, if force offhand is off AND there is no item in an offhand slot, then the equipment packet to add the cosmetic
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
|
|||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticMovementBehavior;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticUpdateBehavior;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEntity;
|
import com.hibiscusmc.hmccosmetics.user.manager.UserEntity;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -22,11 +23,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class CosmeticBackpackType extends Cosmetic {
|
@Getter
|
||||||
|
public class CosmeticBackpackType extends Cosmetic implements CosmeticUpdateBehavior, CosmeticMovementBehavior {
|
||||||
@Getter
|
|
||||||
private int height = -1;
|
private int height = -1;
|
||||||
private ItemStack firstPersonBackpack;
|
private ItemStack firstPersonBackpack;
|
||||||
|
|
||||||
@@ -40,37 +39,45 @@ public class CosmeticBackpackType extends Cosmetic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
public void dispatchUpdate(@NotNull CosmeticUser user) {
|
||||||
Entity entity = user.getEntity();
|
Entity entity = user.getEntity();
|
||||||
if (entity == null) return;
|
if(entity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Location entityLocation = entity.getLocation();
|
Location entityLocation = entity.getLocation();
|
||||||
Location loc = entityLocation.clone().add(0, 2, 0);
|
Location loc = entityLocation.clone().add(0, 2, 0);
|
||||||
|
|
||||||
if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
|
|
||||||
if (user.isHidden()) {
|
|
||||||
// Sometimes the backpack is not despawned when the player is hidden (weird ass logic happening somewhere)
|
|
||||||
user.despawnBackpack();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserBackpackManager backpackManager = user.getUserBackpackManager();
|
UserBackpackManager backpackManager = user.getUserBackpackManager();
|
||||||
UserEntity entityManager = backpackManager.getEntityManager();
|
if(backpackManager == null) return;
|
||||||
int firstArmorStandId = backpackManager.getFirstArmorStandId();
|
|
||||||
|
|
||||||
List<Player> outsideViewers = entityManager.refreshViewers(loc);
|
UserEntity entityManager = backpackManager.getEntityManager();
|
||||||
|
if(entityManager == null) return;
|
||||||
|
|
||||||
entityManager.teleport(loc);
|
entityManager.teleport(loc);
|
||||||
entityManager.setRotation((int) loc.getYaw(), isFirstPersonCompadible());
|
entityManager.setRotation((int) loc.getYaw(), isFirstPersonCompadible());
|
||||||
|
|
||||||
HMCCPacketManager.sendEntitySpawnPacket(entityLocation, firstArmorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), outsideViewers);
|
int firstArmorStandId = backpackManager.getFirstArmorStandId();
|
||||||
HMCCPacketManager.sendArmorstandMetadata(firstArmorStandId, outsideViewers);
|
|
||||||
PacketManager.equipmentSlotUpdate(firstArmorStandId, EquipmentSlot.HEAD, user.getUserCosmeticItem(this, getItem()), outsideViewers);
|
List<Player> newViewers = entityManager.refreshViewers(loc);
|
||||||
|
|
||||||
|
if(!newViewers.isEmpty()) {
|
||||||
|
HMCCPacketManager.spawnInvisibleArmorstand(firstArmorStandId, entityLocation, UUID.randomUUID(), newViewers);
|
||||||
|
PacketManager.equipmentSlotUpdate(firstArmorStandId, EquipmentSlot.HEAD, user.getUserCosmeticItem(this, getItem()), newViewers);
|
||||||
|
|
||||||
|
if (user.getPlayer() != null) {
|
||||||
|
AttributeInstance scaleAttribute = user.getPlayer().getAttribute(Attribute.SCALE);
|
||||||
|
if (scaleAttribute != null) {
|
||||||
|
HMCCPacketManager.sendEntityScalePacket(user.getUserBackpackManager().getFirstArmorStandId(), scaleAttribute.getValue(), newViewers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If true, it will send the riding packet to all players. If false, it will send the riding packet only to new players
|
// If true, it will send the riding packet to all players. If false, it will send the riding packet only to new players
|
||||||
if (Settings.isBackpackForceRidingEnabled()) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, entityManager.getViewers());
|
if (Settings.isBackpackForceRidingEnabled()) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, entityManager.getViewers());
|
||||||
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, outsideViewers);
|
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, newViewers);
|
||||||
|
|
||||||
if (!user.isInWardrobe() && isFirstPersonCompadible() && user.getPlayer() != null) {
|
if (isFirstPersonCompadible() && !user.isInWardrobe() && user.getPlayer() != null) {
|
||||||
List<Player> owner = List.of(user.getPlayer());
|
List<Player> owner = List.of(user.getPlayer());
|
||||||
|
|
||||||
ArrayList<Integer> particleCloud = backpackManager.getAreaEffectEntityId();
|
ArrayList<Integer> particleCloud = backpackManager.getAreaEffectEntityId();
|
||||||
@@ -83,21 +90,36 @@ public class CosmeticBackpackType extends Cosmetic {
|
|||||||
}
|
}
|
||||||
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), firstArmorStandId, owner);
|
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), firstArmorStandId, owner);
|
||||||
if (!user.isHidden()) {
|
if (!user.isHidden()) {
|
||||||
//if (loc.getPitch() < -70) NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, new ItemStack(Material.AIR), owner);
|
|
||||||
//else NMSHandlers.getHandler().equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, firstPersonBackpack, owner);
|
|
||||||
PacketManager.equipmentSlotUpdate(firstArmorStandId, EquipmentSlot.HEAD, user.getUserCosmeticItem(this, firstPersonBackpack), owner);
|
PacketManager.equipmentSlotUpdate(firstArmorStandId, EquipmentSlot.HEAD, user.getUserCosmeticItem(this, firstPersonBackpack), owner);
|
||||||
}
|
}
|
||||||
//MessagesUtil.sendDebugMessages("First Person Backpack Update[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.INFO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backpackManager.showBackpack();
|
backpackManager.showBackpack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispatchMove(@NotNull CosmeticUser user, @NotNull Location from, @NotNull Location to) {
|
||||||
|
@SuppressWarnings("DuplicatedCode") // thanks.
|
||||||
|
Entity entity = user.getEntity();
|
||||||
|
if(entity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Location entityLocation = entity.getLocation();
|
||||||
|
Location loc = entityLocation.clone().add(0, 2, 0);
|
||||||
|
|
||||||
|
UserBackpackManager backpackManager = user.getUserBackpackManager();
|
||||||
|
if(backpackManager == null) return;
|
||||||
|
|
||||||
|
UserEntity entityManager = backpackManager.getEntityManager();
|
||||||
|
if(entityManager == null) return;
|
||||||
|
|
||||||
|
entityManager.teleport(loc);
|
||||||
|
entityManager.setRotation((int) loc.getYaw(), isFirstPersonCompadible());
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isFirstPersonCompadible() {
|
public boolean isFirstPersonCompadible() {
|
||||||
return firstPersonBackpack != null;
|
return firstPersonBackpack != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getFirstPersonBackpack() {
|
|
||||||
return firstPersonBackpack;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.hibiscusmc.hmccosmetics.cosmetic.types;
|
|||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticMovementBehavior;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticUpdateBehavior;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
|
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
@@ -18,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CosmeticBalloonType extends Cosmetic {
|
public class CosmeticBalloonType extends Cosmetic implements CosmeticUpdateBehavior, CosmeticMovementBehavior {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final String modelName;
|
private final String modelName;
|
||||||
@@ -54,7 +56,7 @@ public class CosmeticBalloonType extends Cosmetic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
public void dispatchUpdate(@NotNull CosmeticUser user) {
|
||||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||||
UserBalloonManager userBalloonManager = user.getBalloonManager();
|
UserBalloonManager userBalloonManager = user.getBalloonManager();
|
||||||
|
|
||||||
@@ -66,6 +68,29 @@ public class CosmeticBalloonType extends Cosmetic {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Location newLocation = entity.getLocation();
|
||||||
|
newLocation = newLocation.clone().add(getBalloonOffset());
|
||||||
|
if (Settings.isBalloonHeadForward()) newLocation.setPitch(0);
|
||||||
|
|
||||||
|
if (!user.isHidden() && showLead) {
|
||||||
|
List<Player> sendTo = userBalloonManager.getPufferfish().refreshViewers(newLocation);
|
||||||
|
if (sendTo.isEmpty()) return;
|
||||||
|
user.getBalloonManager().getPufferfish().spawnPufferfish(newLocation, sendTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispatchMove(@NotNull CosmeticUser user, @NotNull Location from, @NotNull Location to) {
|
||||||
|
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||||
|
UserBalloonManager userBalloonManager = user.getBalloonManager();
|
||||||
|
|
||||||
|
if (entity == null || userBalloonManager == null) return;
|
||||||
|
if (user.isInWardrobe()) return;
|
||||||
|
|
||||||
|
if (!userBalloonManager.getModelEntity().isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Location newLocation = entity.getLocation();
|
Location newLocation = entity.getLocation();
|
||||||
Location currentLocation = user.getBalloonManager().getLocation();
|
Location currentLocation = user.getBalloonManager().getLocation();
|
||||||
newLocation = newLocation.clone().add(getBalloonOffset());
|
newLocation = newLocation.clone().add(getBalloonOffset());
|
||||||
@@ -90,15 +115,6 @@ public class CosmeticBalloonType extends Cosmetic {
|
|||||||
|
|
||||||
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
|
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
|
||||||
HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
|
HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
|
||||||
if (user.isHidden()) {
|
|
||||||
userBalloonManager.getPufferfish().hidePufferfish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!user.isHidden() && showLead) {
|
|
||||||
List<Player> sendTo = userBalloonManager.getPufferfish().refreshViewers(newLocation);
|
|
||||||
if (sendTo.isEmpty()) return;
|
|
||||||
user.getBalloonManager().getPufferfish().spawnPufferfish(newLocation, sendTo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDyeablePart(String name) {
|
public boolean isDyeablePart(String name) {
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.cosmetic.types;
|
|
||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class CosmeticMainhandType extends Cosmetic {
|
|
||||||
|
|
||||||
public CosmeticMainhandType(String id, ConfigurationNode config) {
|
|
||||||
super(id, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
|
||||||
Player player = user.getPlayer();
|
|
||||||
|
|
||||||
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), HMCCPacketManager.getViewers(player.getLocation()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.database.types;
|
package com.hibiscusmc.hmccosmetics.database.types;
|
||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
@@ -9,7 +8,6 @@ import com.hibiscusmc.hmccosmetics.database.UserData;
|
|||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import org.apache.commons.lang3.EnumUtils;
|
import org.apache.commons.lang3.EnumUtils;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -87,7 +85,7 @@ public abstract class Data {
|
|||||||
|
|
||||||
private boolean shouldHiddenSave(CosmeticUser.HiddenReason reason) {
|
private boolean shouldHiddenSave(CosmeticUser.HiddenReason reason) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case EMOTE, NONE, GAMEMODE, WORLD, DISABLED -> {
|
case EMOTE, NONE, GAMEMODE, WORLD, DISABLED, POTION -> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ public class MySQLData extends SQLData {
|
|||||||
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
|
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
|
||||||
try {
|
try {
|
||||||
openConnection();
|
openConnection();
|
||||||
if (connection == null) throw new NullPointerException("Connection is null");
|
if (connection == null) throw new IllegalStateException("Connection is null");
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS `COSMETICDATABASE` " +
|
try (PreparedStatement preparedStatement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS `COSMETICDATABASE` " +
|
||||||
"(UUID varchar(36) PRIMARY KEY, " +
|
"(UUID varchar(36) PRIMARY KEY, " +
|
||||||
"COSMETICS MEDIUMTEXT " +
|
"COSMETICS MEDIUMTEXT " +
|
||||||
");")) {
|
");")) {
|
||||||
preparedStatement.execute();
|
preparedStatement.execute();
|
||||||
}
|
}
|
||||||
} catch (SQLException | NullPointerException e) {
|
} catch (SQLException | IllegalStateException e) {
|
||||||
plugin.getLogger().severe("");
|
plugin.getLogger().severe("");
|
||||||
plugin.getLogger().severe("");
|
plugin.getLogger().severe("");
|
||||||
plugin.getLogger().severe("MySQL DATABASE CAN NOT BE REACHED.");
|
plugin.getLogger().severe("MySQL DATABASE CAN NOT BE REACHED.");
|
||||||
@@ -72,16 +72,10 @@ public class MySQLData extends SQLData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void openConnection() throws SQLException {
|
private void openConnection() throws SQLException {
|
||||||
// Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
|
|
||||||
// ...
|
|
||||||
// });
|
|
||||||
// connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
|
|
||||||
|
|
||||||
// Connection isn't null AND Connection isn't closed :: return
|
// Connection isn't null AND Connection isn't closed :: return
|
||||||
try {
|
try {
|
||||||
if (isConnectionOpen()) {
|
if (isConnectionOpen()) return;
|
||||||
return;
|
if (connection != null) close(); // Close connection if still active
|
||||||
} else if (connection != null) close(); // Close connection if still active
|
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
e.printStackTrace(); // If isConnectionOpen() throws error
|
e.printStackTrace(); // If isConnectionOpen() throws error
|
||||||
}
|
}
|
||||||
@@ -90,17 +84,15 @@ public class MySQLData extends SQLData {
|
|||||||
try {
|
try {
|
||||||
Class.forName("com.mysql.jdbc.Driver");
|
Class.forName("com.mysql.jdbc.Driver");
|
||||||
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, setupProperties());
|
connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, setupProperties());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException | ClassNotFoundException e) {
|
||||||
System.out.println(e.getMessage());
|
System.out.println(e.getMessage());
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||||
try {
|
try {
|
||||||
if (connection == null) throw new NullPointerException("Connection is null");
|
if (connection == null) throw new IllegalStateException("Connection is null");
|
||||||
connection.close();
|
connection.close();
|
||||||
} catch (SQLException | NullPointerException e) {
|
} catch (SQLException | NullPointerException e) {
|
||||||
System.out.println(e.getMessage());
|
System.out.println(e.getMessage());
|
||||||
@@ -111,13 +103,12 @@ public class MySQLData extends SQLData {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private Properties setupProperties() {
|
private Properties setupProperties() {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.put("user", user);
|
props.setProperty("user", user);
|
||||||
props.put("password", password);
|
props.setProperty("password", password);
|
||||||
props.put("autoReconnect", "true");
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConnectionOpen() throws RuntimeException {
|
private boolean isConnectionOpen() {
|
||||||
try {
|
try {
|
||||||
return connection != null && !connection.isClosed();
|
return connection != null && !connection.isClosed();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -139,9 +130,9 @@ public class MySQLData extends SQLData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (connection == null) throw new NullPointerException("Connection is null");
|
if (connection == null) throw new IllegalStateException("Connection is null");
|
||||||
ps = connection.prepareStatement(query);
|
ps = connection.prepareStatement(query);
|
||||||
} catch (SQLException | NullPointerException e) {
|
} catch (SQLException | IllegalStateException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
|||||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|||||||
@@ -60,11 +60,6 @@ public class SQLiteData extends SQLData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void openConnection() throws SQLException {
|
private void openConnection() throws SQLException {
|
||||||
// Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
|
|
||||||
// ...
|
|
||||||
// });
|
|
||||||
// connection = DriverManager.getConnection("jdbc:mysql://" + DatabaseSettings.getHost() + ":" + DatabaseSettings.getPort() + "/" + DatabaseSettings.getDatabase(), setupProperties());
|
|
||||||
|
|
||||||
if (connection != null && !connection.isClosed()) return;
|
if (connection != null && !connection.isClosed()) return;
|
||||||
|
|
||||||
// Close Connection if still active
|
// Close Connection if still active
|
||||||
@@ -84,9 +79,12 @@ public class SQLiteData extends SQLData {
|
|||||||
@Override
|
@Override
|
||||||
public PreparedStatement preparedStatement(String query) {
|
public PreparedStatement preparedStatement(String query) {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
if (!isConnectionOpen()) MessagesUtil.sendDebugMessages("Connection is not open");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (!isConnectionOpen()) {
|
||||||
|
MessagesUtil.sendDebugMessages("Connection is not open");
|
||||||
|
openConnection();
|
||||||
|
}
|
||||||
ps = connection.prepareStatement(query);
|
ps = connection.prepareStatement(query);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -14,21 +14,18 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
|||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import dev.triumphteam.gui.builder.item.ItemBuilder;
|
import dev.triumphteam.gui.builder.item.ItemBuilder;
|
||||||
import dev.triumphteam.gui.components.GuiType;
|
import dev.triumphteam.gui.components.GuiType;
|
||||||
import dev.triumphteam.gui.components.InventoryProvider;
|
|
||||||
import dev.triumphteam.gui.guis.Gui;
|
import dev.triumphteam.gui.guis.Gui;
|
||||||
import dev.triumphteam.gui.guis.GuiItem;
|
import dev.triumphteam.gui.guis.GuiItem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
||||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||||
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import me.lojosho.hibiscuscommons.util.StringUtils;
|
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.inventory.ClickType;
|
import org.bukkit.event.inventory.ClickType;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -185,18 +182,25 @@ public class Menu {
|
|||||||
if (taskid.get() != -1) Bukkit.getScheduler().cancelTask(taskid.get());
|
if (taskid.get() != -1) Bukkit.getScheduler().cancelTask(taskid.get());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Runnable openGuiTask = () -> {
|
||||||
|
gui.open(viewer);
|
||||||
|
updateMenu(viewer, cosmeticHolder, gui); // fixes shading? I know I do this twice but it's easier than writing a whole new class to deal with this shit
|
||||||
|
};
|
||||||
|
|
||||||
// API
|
// API
|
||||||
if (cosmeticHolder instanceof CosmeticUser user) {
|
if (cosmeticHolder instanceof CosmeticUser user) {
|
||||||
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
||||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(event));
|
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||||
if (event.isCancelled()) return;
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
openGuiTask.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Internal
|
// Internal
|
||||||
|
else {
|
||||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), openGuiTask);
|
||||||
gui.open(viewer);
|
}
|
||||||
updateMenu(viewer, cosmeticHolder, gui); // fixes shading? I know I do this twice but it's easier than writing a whole new class to deal with this shit
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMenu(Player viewer, CosmeticHolder cosmeticHolder, Gui gui) {
|
private void updateMenu(Player viewer, CosmeticHolder cosmeticHolder, Gui gui) {
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package com.hibiscusmc.hmccosmetics.gui;
|
|||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
|
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
|
||||||
import me.lojosho.shaded.configurate.ConfigurateException;
|
import me.lojosho.shaded.configurate.ConfigurateException;
|
||||||
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
|
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class Actions {
|
public class Actions {
|
||||||
@@ -30,7 +31,6 @@ public class Actions {
|
|||||||
private static final ActionCosmeticHide ACTION_HIDE = new ActionCosmeticHide();
|
private static final ActionCosmeticHide ACTION_HIDE = new ActionCosmeticHide();
|
||||||
private static final ActionCosmeticToggle ACTION_TOGGLE = new ActionCosmeticToggle();
|
private static final ActionCosmeticToggle ACTION_TOGGLE = new ActionCosmeticToggle();
|
||||||
|
|
||||||
|
|
||||||
public static Action getAction(@NotNull String id) {
|
public static Action getAction(@NotNull String id) {
|
||||||
return actions.get(id.toUpperCase());
|
return actions.get(id.toUpperCase());
|
||||||
}
|
}
|
||||||
@@ -45,13 +45,13 @@ public class Actions {
|
|||||||
|
|
||||||
public static void runActions(Player viewer, CosmeticHolder cosmeticHolder, @NotNull List<String> raw) {
|
public static void runActions(Player viewer, CosmeticHolder cosmeticHolder, @NotNull List<String> raw) {
|
||||||
for (String a : raw) {
|
for (String a : raw) {
|
||||||
String id = StringUtils.substringBetween(a, "[", "]").toUpperCase();
|
String id = StringUtils.substringBetween(a, "[", "]");
|
||||||
String message = StringUtils.substringAfter(a, "] ");
|
String message = StringUtils.substringAfter(a, "] ");
|
||||||
MessagesUtil.sendDebugMessages("ID is " + id + " // Raw Data is " + message);
|
MessagesUtil.sendDebugMessages("ID is " + id + " // Raw Data is " + message);
|
||||||
if (isAction(id)) {
|
if (id != null && isAction(id.toUpperCase())) {
|
||||||
getAction(id).run(viewer, cosmeticHolder, message);
|
getAction(id).run(viewer, cosmeticHolder, message);
|
||||||
} else {
|
} else {
|
||||||
MessagesUtil.sendDebugMessages("Possible ids: " + actions.keySet());
|
MessagesUtil.sendDebugMessages("Invalid Action ID (" + id + ") used in menus (Full raw: '" + a + "'). Make sure all actions are properly typed out. Here are all possible actions: " + actions.keySet(), Level.WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,67 +1,20 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.gui.special;
|
package com.hibiscusmc.hmccosmetics.gui.special;
|
||||||
|
|
||||||
import com.hibiscusmc.hmccolor.HMCColorApi;
|
|
||||||
import com.hibiscusmc.hmccolor.shaded.gui.guis.Gui;
|
|
||||||
import com.hibiscusmc.hmccolor.shaded.gui.guis.GuiItem;
|
|
||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
|
||||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
|
||||||
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
|
||||||
import me.lojosho.hibiscuscommons.util.StringUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class DyeMenu {
|
public interface DyeMenu {
|
||||||
public static void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, Cosmetic cosmetic) {
|
|
||||||
if (!Hooks.isActiveHook("HMCColor")) {
|
|
||||||
addCosmetic(viewer, cosmeticHolder, cosmetic, null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ItemStack originalItem = cosmetic.getItem();
|
|
||||||
if (originalItem == null || !cosmetic.isDyeable()) return;
|
|
||||||
|
|
||||||
Gui gui = HMCColorApi.createColorMenu(viewer);
|
/**
|
||||||
gui.updateTitle(AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(viewer, StringUtils.parseStringToString(Settings.getDyeMenuName()))));
|
* Overrideable method that is called when a player wishing to dye a menu.
|
||||||
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
|
* After the method is called, the menu plugin itself is supposed to handle everything else, including adding the cosmetic to the CosmeticHolder
|
||||||
gui.setDefaultTopClickAction(event -> {
|
*
|
||||||
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {
|
* @param viewer The player that is viewing the menu
|
||||||
ItemStack item = event.getInventory().getItem(Settings.getDyeMenuOutputSlot());
|
* @param cosmeticHolder The CosmeticHolder that is being dyed (Can be different from the viewer)
|
||||||
if (item == null) return;
|
* @param cosmetic (The cosmetic that is wished to be dyed)
|
||||||
|
*/
|
||||||
|
void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull Cosmetic cosmetic);
|
||||||
|
|
||||||
Color color = NMSHandlers.getHandler().getUtilHandler().getColor(item);
|
|
||||||
if (color == null) return;
|
|
||||||
|
|
||||||
addCosmetic(viewer, cosmeticHolder, cosmetic, color);
|
|
||||||
event.setCancelled(true);
|
|
||||||
} else event.setCancelled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
gui.setPlayerInventoryAction(event -> event.setCancelled(true));
|
|
||||||
gui.setCloseGuiAction(event -> {});
|
|
||||||
gui.open(viewer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void openMenu(@NotNull CosmeticUser user, Cosmetic cosmetic) {
|
|
||||||
Player player = user.getPlayer();
|
|
||||||
if (player == null) return;
|
|
||||||
openMenu(player, user, cosmetic);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addCosmetic(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull Cosmetic cosmetic, @Nullable Color color) {
|
|
||||||
cosmeticHolder.addCosmetic(cosmetic, color);
|
|
||||||
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
|
||||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
|
||||||
viewer.closeInventory();
|
|
||||||
cosmeticHolder.updateCosmetic(cosmetic.getSlot());
|
|
||||||
}, 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.gui.special;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class DyeMenuProvider {
|
||||||
|
|
||||||
|
private static DyeMenu instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the provider of the DyeMenu. Check {@link DyeMenuProvider#hasMenuProvider()} before attempting to set this,
|
||||||
|
* it is locked once a dye menu has been set!
|
||||||
|
* @param dyeMenu The dye menu implementation that wishes to be the provider.
|
||||||
|
* @throws IllegalStateException IllegalStateException will be thrown if a dye menu provider already is set by another plugin.
|
||||||
|
*/
|
||||||
|
public static void setDyeMenuProvider(@NotNull DyeMenu dyeMenu) throws IllegalStateException {
|
||||||
|
if (instance != null) {
|
||||||
|
throw new IllegalStateException("DyeMenu Implementation has already been set by another plugin.");
|
||||||
|
}
|
||||||
|
instance = dyeMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when wishing to dye a cosmetic to hand it off to the dye menu implementation
|
||||||
|
* @param viewer The viewer of the menu
|
||||||
|
* @param cosmeticHolder The cosmetic holder that the player viewer wishing to modify (could be themselves or another CosmeticHolder)
|
||||||
|
* @param cosmetic The cosmetic the user wishes to dye
|
||||||
|
* @throws IllegalStateException IllegalStateException will be thrown if the dye menu instance is null (Check {@link DyeMenuProvider#hasMenuProvider()} before calling)
|
||||||
|
*/
|
||||||
|
public static void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull Cosmetic cosmetic) throws IllegalStateException {
|
||||||
|
if (instance == null) {
|
||||||
|
throw new IllegalStateException("Unable to open a dye menu without instance of it.");
|
||||||
|
}
|
||||||
|
instance.openMenu(viewer, cosmeticHolder, cosmetic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does HMCC have a dye menu provider already set?
|
||||||
|
* @return True if it is already set and locked; false if none have been set.
|
||||||
|
*/
|
||||||
|
public static boolean hasMenuProvider() {
|
||||||
|
return instance != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.gui.special.impl;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccolor.HMCColorApi;
|
||||||
|
import com.hibiscusmc.hmccolor.shaded.gui.guis.Gui;
|
||||||
|
import com.hibiscusmc.hmccolor.shaded.gui.guis.GuiItem;
|
||||||
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
||||||
|
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||||
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class HMCColorDyeMenu implements DyeMenu {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull Cosmetic cosmetic) {
|
||||||
|
ItemStack originalItem = cosmetic.getItem();
|
||||||
|
if (originalItem == null || !cosmetic.isDyeable()) return;
|
||||||
|
|
||||||
|
Gui gui = HMCColorApi.createColorMenu(viewer);
|
||||||
|
gui.updateTitle(AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(viewer, Settings.getDyeMenuName())));
|
||||||
|
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
|
||||||
|
gui.setDefaultTopClickAction(event -> {
|
||||||
|
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {
|
||||||
|
ItemStack item = event.getInventory().getItem(Settings.getDyeMenuOutputSlot());
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
|
Color color = NMSHandlers.getHandler().getUtilHandler().getColor(item);
|
||||||
|
if (color == null) return;
|
||||||
|
|
||||||
|
addCosmetic(viewer, cosmeticHolder, cosmetic, color);
|
||||||
|
event.setCancelled(true);
|
||||||
|
} else event.setCancelled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
gui.setPlayerInventoryAction(event -> event.setCancelled(true));
|
||||||
|
gui.setCloseGuiAction(event -> {});
|
||||||
|
gui.open(viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCosmetic(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||||
|
cosmeticHolder.addCosmetic(cosmetic, color);
|
||||||
|
viewer.setItemOnCursor(new ItemStack(Material.AIR));
|
||||||
|
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||||
|
viewer.closeInventory();
|
||||||
|
cosmeticHolder.updateCosmetic(cosmetic.getSlot());
|
||||||
|
}, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
|||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
|
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenuProvider;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
@@ -66,14 +67,11 @@ public class TypeCosmetic extends Type {
|
|||||||
|
|
||||||
MessagesUtil.sendDebugMessages("Required click type: " + requiredClick);
|
MessagesUtil.sendDebugMessages("Required click type: " + requiredClick);
|
||||||
MessagesUtil.sendDebugMessages("Click type: " + clickType.name());
|
MessagesUtil.sendDebugMessages("Click type: " + clickType.name());
|
||||||
boolean isRequiredClick = requiredClick.equalsIgnoreCase("ANY") || requiredClick.equalsIgnoreCase(clickType.name());
|
|
||||||
boolean isDyeClick = dyeClick.equalsIgnoreCase("ANY") || dyeClick.equalsIgnoreCase(clickType.name());
|
|
||||||
if (!isRequiredClick && !isDyeClick) {
|
|
||||||
MessagesUtil.sendMessage(viewer.getPlayer(), "invalid-click-type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isRequiredClick && isDyeClick) isUnEquippingCosmetic = false;
|
final boolean isRequiredClick = requiredClick.equalsIgnoreCase("ANY") || requiredClick.equalsIgnoreCase(clickType.name());
|
||||||
|
final boolean isDyeClick = dyeClick.equalsIgnoreCase("ANY") || dyeClick.equalsIgnoreCase(clickType.name());
|
||||||
|
|
||||||
|
if (!isRequiredClick) isUnEquippingCosmetic = false;
|
||||||
|
|
||||||
List<String> actionStrings = new ArrayList<>();
|
List<String> actionStrings = new ArrayList<>();
|
||||||
ConfigurationNode actionConfig = config.node("actions");
|
ConfigurationNode actionConfig = config.node("actions");
|
||||||
@@ -105,9 +103,11 @@ public class TypeCosmetic extends Type {
|
|||||||
} else {
|
} else {
|
||||||
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
|
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
|
||||||
MessagesUtil.sendDebugMessages("on-equip");
|
MessagesUtil.sendDebugMessages("on-equip");
|
||||||
|
MessagesUtil.sendDebugMessages("Preparing for on-equip with the following checks:");
|
||||||
|
MessagesUtil.sendDebugMessages("CosmeticDyeable? " + cosmetic.isDyeable() + " / isDyeClick? " + isDyeClick + " / isHMCColorActive? " + Hooks.isActiveHook("HMCColor"));
|
||||||
// TODO: Redo this
|
// TODO: Redo this
|
||||||
if (cosmetic.isDyeable() && isDyeClick && Hooks.isActiveHook("HMCColor")) {
|
if (cosmetic.isDyeable() && isDyeClick && DyeMenuProvider.hasMenuProvider()) {
|
||||||
DyeMenu.openMenu(viewer, cosmeticHolder, cosmetic);
|
DyeMenuProvider.openMenu(viewer, cosmeticHolder, cosmetic);
|
||||||
} else if (isRequiredClick) {
|
} else if (isRequiredClick) {
|
||||||
cosmeticHolder.addCosmetic(cosmetic);
|
cosmeticHolder.addCosmetic(cosmetic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
|||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
|
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||||
import org.apache.commons.lang3.EnumUtils;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@@ -74,29 +73,20 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
|
|||||||
if (placeholderArgs.size() >= 2) {
|
if (placeholderArgs.size() >= 2) {
|
||||||
CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase());
|
CosmeticSlot slot = CosmeticSlot.valueOf(placeholderArgs.get(1).toUpperCase());
|
||||||
if (slot == null) return null;
|
if (slot == null) return null;
|
||||||
if (user.getCosmetic(slot) == null) return TranslationUtil.getTranslation("current-cosmetic", "no-cosmetic");
|
Cosmetic cosmetic = user.getCosmetic(slot);
|
||||||
|
if (cosmetic == null) return TranslationUtil.getTranslation("current-cosmetic", "no-cosmetic");
|
||||||
if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId();
|
if (placeholderArgs.size() == 2) return user.getCosmetic(slot).getId();
|
||||||
|
|
||||||
String output;
|
String output;
|
||||||
switch (placeholderArgs.get(2).toLowerCase()) {
|
switch (placeholderArgs.get(2).toLowerCase()) {
|
||||||
case "material" -> {
|
case "material" -> output = getMaterialName(cosmetic);
|
||||||
output = getMaterialName(user.getCosmetic(slot));
|
case "custommodeldata" -> output = getModelData(cosmetic);
|
||||||
}
|
case "itemmodel" -> output = getItemModel(cosmetic);
|
||||||
case "custommodeldata" -> {
|
case "itemname" -> output = getItemName(cosmetic);
|
||||||
output = getModelData(user.getCosmetic(slot));
|
case "name" -> output = getDisplayName(cosmetic);
|
||||||
}
|
case "lore" -> output = getItemLore(cosmetic);
|
||||||
case "name" -> {
|
case "permission" -> output = user.getCosmetic(slot).getPermission();
|
||||||
output = getItemName(user.getCosmetic(slot));
|
default -> output = user.getCosmetic(slot).getId();
|
||||||
}
|
|
||||||
case "lore" -> {
|
|
||||||
output = getItemLore(user.getCosmetic(slot));
|
|
||||||
}
|
|
||||||
case "permission" -> {
|
|
||||||
output = user.getCosmetic(slot).getPermission();
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
output = user.getCosmetic(slot).getId();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (output == null) output = "none";
|
if (output == null) output = "none";
|
||||||
return TranslationUtil.getTranslation("current-cosmetic", output);
|
return TranslationUtil.getTranslation("current-cosmetic", output);
|
||||||
@@ -218,13 +208,55 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
|
|||||||
return String.valueOf(itemMeta.getCustomModelData());
|
return String.valueOf(itemMeta.getCustomModelData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cosmetic items item model
|
||||||
|
* @param cosmetic The cosmetic to get its item model
|
||||||
|
* @return The cosmetic items item model
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getItemModel(@NotNull Cosmetic cosmetic) {
|
||||||
|
try {
|
||||||
|
ItemStack item = cosmetic.getItem();
|
||||||
|
if (item == null) return null;
|
||||||
|
if (!item.hasItemMeta()) return null;
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
if (itemMeta == null && itemMeta.hasItemModel() ) return null;
|
||||||
|
return itemMeta.getItemModel().asString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the cosmetic items item name
|
||||||
|
* @param cosmetic The cosmetic to get its items item name
|
||||||
|
* @return The cosmetic items item name
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getItemName(@NotNull Cosmetic cosmetic) {
|
||||||
|
try {
|
||||||
|
ItemStack item = cosmetic.getItem();
|
||||||
|
if (item == null) return null;
|
||||||
|
if (!item.hasItemMeta()) return null;
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
if (itemMeta == null || !itemMeta.hasItemName()) return null;
|
||||||
|
return itemMeta.getDisplayName();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the cosmetic items display name
|
* Gets the cosmetic items display name
|
||||||
* @param cosmetic The cosmetic to get its items display name
|
* @param cosmetic The cosmetic to get its items display name
|
||||||
* @return The cosmetic items display name
|
* @return The cosmetic items display name
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getItemName(@NotNull Cosmetic cosmetic) {
|
public String getDisplayName(@NotNull Cosmetic cosmetic) {
|
||||||
ItemStack item = cosmetic.getItem();
|
ItemStack item = cosmetic.getItem();
|
||||||
if (item == null) return null;
|
if (item == null) return null;
|
||||||
if (!item.hasItemMeta()) return null;
|
if (!item.hasItemMeta()) return null;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
|||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,19 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.listener;
|
package com.hibiscusmc.hmccosmetics.listener;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.*;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.Pair;
|
|
||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
|
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import me.lojosho.hibiscuscommons.api.events.*;
|
import me.lojosho.hibiscuscommons.api.events.*;
|
||||||
import me.lojosho.hibiscuscommons.nms.MinecraftVersion;
|
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
|
||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -51,18 +40,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class PlayerGameListener implements Listener {
|
public class PlayerGameListener implements Listener {
|
||||||
|
|
||||||
public PlayerGameListener() {
|
|
||||||
registerInventoryClickListener();
|
|
||||||
registerMenuChangeListener();
|
|
||||||
registerEntityStatusListener();
|
|
||||||
registerPlayerEquipmentListener();
|
|
||||||
registerPlayerArmListener();
|
|
||||||
registerEntityUseListener();
|
|
||||||
registerSlotChangeListener();
|
|
||||||
registerPassengerSetListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
public void onPlayerClick(@NotNull InventoryClickEvent event) {
|
public void onPlayerClick(@NotNull InventoryClickEvent event) {
|
||||||
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
|
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
|
||||||
@@ -117,19 +94,17 @@ public class PlayerGameListener implements Listener {
|
|||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||||
if (user.getEntity() == null || user.isInWardrobe()) return; // fixes disconnecting when in wardrobe (the entity stuff)
|
if (user.getEntity() == null || user.isInWardrobe()) return; // fixes disconnecting when in wardrobe (the entity stuff)
|
||||||
|
|
||||||
if (Settings.getDisabledWorlds().contains(user.getEntity().getLocation().getWorld().getName())) {
|
if (Settings.getDisabledWorlds().contains(user.getEntity().getLocation().getWorld().getName())) {
|
||||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
|
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||||
} else {
|
} else {
|
||||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
|
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||||
}
|
}
|
||||||
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
|
|
||||||
user.respawnBackpack();
|
user.respawnBackpack();
|
||||||
}
|
|
||||||
if (user.hasCosmeticInSlot(CosmeticSlot.BALLOON)) {
|
|
||||||
user.respawnBalloon();
|
user.respawnBalloon();
|
||||||
}
|
|
||||||
user.updateCosmetic();
|
user.updateCosmetic();
|
||||||
}, 2);
|
}, 4);
|
||||||
|
|
||||||
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
|
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
|
||||||
}
|
}
|
||||||
@@ -163,8 +138,7 @@ public class PlayerGameListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
public void onPlayerHit(EntityDamageByEntityEvent event) {
|
public void onPlayerHit(EntityDamageByEntityEvent event) {
|
||||||
Entity entity = event.getEntity();
|
Entity entity = event.getEntity();
|
||||||
if (!entity.getPersistentDataContainer().has(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT))
|
if (!entity.getPersistentDataContainer().has(HMCCServerUtils.getCosmemeticMobKey(), PersistentDataType.BOOLEAN)) return;
|
||||||
return;
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,15 +156,6 @@ public class PlayerGameListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
|
||||||
if (user == null) return;
|
|
||||||
user.updateCosmetic(CosmeticSlot.BACKPACK);
|
|
||||||
user.updateCosmetic(CosmeticSlot.BALLOON);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onPlayerPoseChange(EntityPoseChangeEvent event) {
|
public void onPlayerPoseChange(EntityPoseChangeEvent event) {
|
||||||
if (!(event.getEntity() instanceof Player player)) return;
|
if (!(event.getEntity() instanceof Player player)) return;
|
||||||
@@ -380,6 +345,15 @@ public class PlayerGameListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onPlayerInteract(PlayerInteractEntityEvent event) {
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
final Entity entity = event.getRightClicked();
|
||||||
|
// Balloons are technically actual entities, so we need to cancel any interactions with them
|
||||||
|
if (!entity.getPersistentDataContainer().has(HMCCServerUtils.getCosmemeticMobKey(), PersistentDataType.BOOLEAN)) return;
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onPlayerVanish(HibiscusPlayerVanishEvent event) {
|
public void onPlayerVanish(HibiscusPlayerVanishEvent event) {
|
||||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||||
@@ -426,251 +400,6 @@ public class PlayerGameListener implements Listener {
|
|||||||
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerInventoryClickListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, List.of(PacketType.Play.Client.WINDOW_CLICK), ListenerOptions.ASYNC) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
int invTypeClicked = event.getPacket().getIntegers().read(0);
|
|
||||||
int slotClicked = -999;
|
|
||||||
if (NMSHandlers.getVersion().isHigherOrEqual(MinecraftVersion.v1_21_5)) {
|
|
||||||
slotClicked = event.getPacket().getShorts().read(0);
|
|
||||||
} else {
|
|
||||||
slotClicked = event.getPacket().getIntegers().read(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must be a player inventory.
|
|
||||||
if (invTypeClicked != 0) return;
|
|
||||||
// -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory
|
|
||||||
if (slotClicked == -999) return;
|
|
||||||
if (event.getPlayer() == null) return;
|
|
||||||
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
|
||||||
if (user == null) return;
|
|
||||||
if (user.isInWardrobe()) return;
|
|
||||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotClicked);
|
|
||||||
if (cosmeticSlot == null) return;
|
|
||||||
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
|
|
||||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
|
|
||||||
MessagesUtil.sendDebugMessages("Packet fired, updated cosmetic " + cosmeticSlot);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerMenuChangeListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, List.of(PacketType.Play.Server.WINDOW_ITEMS), ListenerOptions.ASYNC) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
MessagesUtil.sendDebugMessages("Menu Initial ");
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (event.getPlayer() == null) return;
|
|
||||||
|
|
||||||
int windowID = event.getPacket().getIntegers().read(0);
|
|
||||||
List<ItemStack> slotData = event.getPacket().getItemListModifier().read(0);
|
|
||||||
if (windowID != 0) return;
|
|
||||||
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
|
||||||
if (user == null) return;
|
|
||||||
|
|
||||||
HashMap<Integer, ItemStack> items = new HashMap<>();
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);
|
|
||||||
packet.getIntegers().write(0, 0);
|
|
||||||
for (int slot = 0; slot < 46; slot++) {
|
|
||||||
if ((slot >= 5 && slot <= 8) || slot == 45) {
|
|
||||||
if (!items.containsKey(slot)) continue;
|
|
||||||
slotData.set(slot, items.get(slot));
|
|
||||||
if (Settings.isDebugMode()) MessagesUtil.sendDebugMessages("Set " + slot + " as " + items.get(slot));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
packet.getItemListModifier().write(0, slotData);
|
|
||||||
packet.getItemModifier().write(0, event.getPacket().getItemModifier().read(0));
|
|
||||||
event.setPacket(packet);
|
|
||||||
MessagesUtil.sendDebugMessages("Menu Fired, updated cosmetics " + " on slotdata " + windowID + " with " + slotData.size());
|
|
||||||
/*
|
|
||||||
for (Cosmetic cosmetic : user.getCosmetic()) {
|
|
||||||
if ((cosmetic instanceof CosmeticArmorType) || (cosmetic instanceof CosmeticMainhandType)) {
|
|
||||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
|
||||||
user.updateCosmetic(cosmetic);
|
|
||||||
}, 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerSlotChangeListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.SET_SLOT) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
MessagesUtil.sendDebugMessages("SetSlot Initial ");
|
|
||||||
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (event.getPlayer() == null) return;
|
|
||||||
|
|
||||||
int windowID = event.getPacket().getIntegers().read(0);
|
|
||||||
if (windowID != 0) return;
|
|
||||||
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
|
||||||
if (user == null) return;
|
|
||||||
if (user.isInWardrobe()) return;
|
|
||||||
|
|
||||||
int slot = event.getPacket().getIntegers().read(2);
|
|
||||||
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerPlayerEquipmentListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
Player player = event.getPlayer(); // Player that's sent
|
|
||||||
int entityID = event.getPacket().getIntegers().read(0);
|
|
||||||
// User
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(entityID);
|
|
||||||
if (user == null) return;
|
|
||||||
if (user.isInWardrobe()) return;
|
|
||||||
|
|
||||||
List<com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack>> armor = event.getPacket().getSlotStackPairLists().read(0);
|
|
||||||
|
|
||||||
for (int i = 0; i < armor.size(); i++) {
|
|
||||||
com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack> pair = armor.get(i);
|
|
||||||
switch (pair.getFirst()) {
|
|
||||||
case MAINHAND -> {
|
|
||||||
if (user.getPlayer() == event.getPlayer()) continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
|
|
||||||
if (user.getPlayer() != null && user.getPlayer().isInvisible()) continue; // Fixes integration with GSit still showing mainhand even when hidden
|
|
||||||
armor.set(i, new Pair<>(pair.getFirst(), user.getPlayer().getInventory().getItemInMainHand()));
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
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(slot), item);
|
|
||||||
armor.set(i, armorPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.getPacket().getSlotStackPairLists().write(0, armor);
|
|
||||||
MessagesUtil.sendDebugMessages("Equipment for " + user.getPlayer().getName() + " has been updated for " + player.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerEntityStatusListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_STATUS) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
int entityid = event.getPacket().getIntegers().read(0);
|
|
||||||
byte status = event.getPacket().getBytes().read(0);
|
|
||||||
|
|
||||||
MessagesUtil.sendDebugMessages("EntityStatus Initial " + entityid + " - " + status);
|
|
||||||
if (status != 55) return;
|
|
||||||
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(entityid);
|
|
||||||
if (user == null) {
|
|
||||||
MessagesUtil.sendDebugMessages("EntityStatus User is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) return;
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerPassengerSetListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.MOUNT) {
|
|
||||||
@Override
|
|
||||||
public void onPacketSending(PacketEvent event) {
|
|
||||||
CosmeticUser viewerUser = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
|
|
||||||
if (viewerUser == null) return;
|
|
||||||
if (viewerUser.isInWardrobe()) return;
|
|
||||||
|
|
||||||
int ownerId = event.getPacket().getIntegers().read(0);
|
|
||||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId);
|
|
||||||
Entity entity = HMCCServerUtils.getEntity(ownerId);
|
|
||||||
if (entity == null) return;
|
|
||||||
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(entity.getUniqueId());
|
|
||||||
if (user == null) return;
|
|
||||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - " + user.getUniqueId());
|
|
||||||
|
|
||||||
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
|
|
||||||
if (user.getUserBackpackManager() == null) return;
|
|
||||||
|
|
||||||
// Basically, take the original passengers and "bump" them to the end of the list
|
|
||||||
int[] originalPassengers = event.getPacket().getIntegerArrays().read(0);
|
|
||||||
List<Integer> passengers = new ArrayList<>(user.getUserBackpackManager().getEntityManager().getIds());
|
|
||||||
|
|
||||||
passengers.addAll(Arrays.stream(originalPassengers).boxed().toList());
|
|
||||||
|
|
||||||
event.getPacket().getIntegerArrays().write(0, passengers.stream().mapToInt(Integer::intValue).toArray());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerPlayerArmListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
if (event.getPlayer() == null) return;
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
|
||||||
if (user == null) return;
|
|
||||||
if (!user.isInWardrobe()) return;
|
|
||||||
if (!user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
|
|
||||||
|
|
||||||
Menu menu = user.getWardrobeManager().getLastOpenMenu();
|
|
||||||
if (menu == null) return;
|
|
||||||
menu.openMenu(user);
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerEntityUseListener() {
|
|
||||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
|
|
||||||
@Override
|
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
|
||||||
if (event.getPlayer() == null) return;
|
|
||||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
|
||||||
if (user == null) return;
|
|
||||||
if (user.isInWardrobe()) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private EquipmentSlot getArmorSlot(final Material material) {
|
private EquipmentSlot getArmorSlot(final Material material) {
|
||||||
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.listener;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class PlayerMovementListener implements Listener {
|
||||||
|
private static final List<CosmeticSlot> MOVEMENT_COSMETICS = List.of(
|
||||||
|
CosmeticSlot.BACKPACK,
|
||||||
|
CosmeticSlot.BALLOON
|
||||||
|
);
|
||||||
|
|
||||||
|
// Player Id -> Small Location
|
||||||
|
private final Map<UUID, SmallLocation> locations = new HashMap<>();
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent ev) {
|
||||||
|
final Player player = ev.getPlayer();
|
||||||
|
|
||||||
|
final CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if(user == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!updateDirtyLocation(ev.getPlayer(), ev.getTo())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(final CosmeticSlot slot : MOVEMENT_COSMETICS) {
|
||||||
|
user.updateMovementCosmetic(slot, ev.getFrom(), ev.getTo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateDirtyLocation(final Player player, final Location nextLoc) {
|
||||||
|
final SmallLocation previous = locations.computeIfAbsent(
|
||||||
|
player.getUniqueId(),
|
||||||
|
$ -> SmallLocation.fromLocation(nextLoc)
|
||||||
|
);
|
||||||
|
final SmallLocation next = SmallLocation.fromLocation(nextLoc);
|
||||||
|
|
||||||
|
if(next.distanceTo(previous) > 0.25) {
|
||||||
|
this.locations.put(player.getUniqueId(), next);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(next.yawDistanceTo(previous) > 5) {
|
||||||
|
this.locations.put(player.getUniqueId(), next);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void onWorldChange(final PlayerChangedWorldEvent ev) {
|
||||||
|
this.locations.remove(ev.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerQuit(final PlayerQuitEvent ev) {
|
||||||
|
locations.remove(ev.getPlayer().getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
record SmallLocation(
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
double z,
|
||||||
|
float yaw
|
||||||
|
) {
|
||||||
|
public double distanceTo(SmallLocation other) {
|
||||||
|
double dx = this.x - other.x;
|
||||||
|
double dy = this.y - other.y;
|
||||||
|
double dz = this.z - other.z;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float yawDistanceTo(SmallLocation other) {
|
||||||
|
float diff = Math.abs(this.yaw - other.yaw) % 360;
|
||||||
|
return diff > 180 ? 360 - diff : diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SmallLocation fromLocation(final Location location) {
|
||||||
|
return new SmallLocation(location.getX(), location.getY(), location.getZ(), location.getYaw());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.packets;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||||
|
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
|
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||||
|
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.packets.PacketAction;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.PacketInterface;
|
||||||
|
import me.lojosho.hibiscuscommons.packets.wrapper.*;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class CosmeticPacketInterface implements PacketInterface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction writeContainerContent(@NotNull Player player, @NotNull ContainerContentWrapper wrapper) {
|
||||||
|
int windowId = wrapper.getWindowId();
|
||||||
|
MessagesUtil.sendDebugMessages("writeContainerContent (windowid: " + windowId + " )");
|
||||||
|
if (windowId != 0) return PacketAction.NOTHING;
|
||||||
|
List<ItemStack> slotData = wrapper.getSlotData();
|
||||||
|
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
HashMap<Integer, ItemStack> cosmeticItems = new HashMap<>();
|
||||||
|
|
||||||
|
if (!user.isInWardrobe()) {
|
||||||
|
for (Cosmetic cosmetic : user.getCosmetics()) {
|
||||||
|
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||||
|
boolean requireEmpty = Settings.getSlotOption(armorType.getEquipSlot()).isRequireEmpty();
|
||||||
|
boolean isAir = user.getPlayer().getInventory().getItem(armorType.getEquipSlot()).getType().isAir();
|
||||||
|
MessagesUtil.sendDebugMessages("Menu Fired (Checks) - " + armorType.getId() + " - " + requireEmpty + " - " + isAir);
|
||||||
|
if (requireEmpty && !isAir) continue;
|
||||||
|
cosmeticItems.put(HMCCInventoryUtils.getPacketArmorSlot(armorType.getEquipSlot()), user.getUserCosmeticItem(armorType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int slot = 0; slot < 46; slot++) {
|
||||||
|
if ((slot >= 5 && slot <= 8) || slot == 45) {
|
||||||
|
if (!cosmeticItems.containsKey(slot)) continue;
|
||||||
|
slotData.set(slot, cosmeticItems.get(slot));
|
||||||
|
if (Settings.isDebugMode()) MessagesUtil.sendDebugMessages("Set " + slot + " as " + cosmeticItems.get(slot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper.setSlotData(slotData);
|
||||||
|
MessagesUtil.sendDebugMessages("Menu Fired, updated cosmetics " + " on slotdata " + windowId + " with " + slotData.size());
|
||||||
|
return PacketAction.CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction writeSlotContent(@NotNull Player player, @NotNull SlotContentWrapper wrapper) {
|
||||||
|
int windowId = wrapper.getWindowId();
|
||||||
|
int slot = wrapper.getSlot();
|
||||||
|
ItemStack itemStack = wrapper.getItemStack();
|
||||||
|
|
||||||
|
MessagesUtil.sendDebugMessages("SetSlot Initial ");
|
||||||
|
if (windowId != 0) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null || user.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
|
||||||
|
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slot);
|
||||||
|
EquipmentSlot equipmentSlot = HMCCInventoryUtils.getPacketArmorSlot(slot);
|
||||||
|
if (cosmeticSlot == null || equipmentSlot == null) return PacketAction.NOTHING;
|
||||||
|
if (!user.hasCosmeticInSlot(cosmeticSlot)) return PacketAction.NOTHING;
|
||||||
|
if (Settings.getSlotOption(equipmentSlot).isRequireEmpty()) {
|
||||||
|
if (!player.getInventory().getItem(equipmentSlot).getType().isAir()) return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
wrapper.setItemStack(user.getUserCosmeticItem(cosmeticSlot));
|
||||||
|
return PacketAction.CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction writeEquipmentContent(@NotNull Player player, @NotNull EntityEquipmentWrapper wrapper) {
|
||||||
|
if (player.getEntityId() != wrapper.getEntityId()) return PacketAction.NOTHING;
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null || user.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
Map<EquipmentSlot, ItemStack> armor = wrapper.getArmor();
|
||||||
|
|
||||||
|
for (Map.Entry<EquipmentSlot, ItemStack> armorSlot : armor.entrySet()) {
|
||||||
|
EquipmentSlot slot = armorSlot.getKey();
|
||||||
|
|
||||||
|
if (slot == EquipmentSlot.HAND) {
|
||||||
|
if (user.getPlayer().getUniqueId() == player.getUniqueId())
|
||||||
|
continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
|
||||||
|
if (user.getPlayer() != null && user.getPlayer().isInvisible())
|
||||||
|
continue; // Fixes integration with GSit still showing mainhand even when hidden
|
||||||
|
armor.put(slot, player.getInventory().getItemInMainHand());
|
||||||
|
} else {
|
||||||
|
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.BukkitCosmeticSlot(slot);
|
||||||
|
if (cosmeticSlot == null) continue;
|
||||||
|
if (Settings.getSlotOption(slot).isRequireEmpty() && player.getInventory().getItem(slot).getType().isAir())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(cosmeticSlot);
|
||||||
|
if (cosmeticArmor == null) continue;
|
||||||
|
ItemStack item = user.getUserCosmeticItem(cosmeticSlot);
|
||||||
|
if (item == null) continue;
|
||||||
|
armor.put(slot, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper.setArmor(armor);
|
||||||
|
MessagesUtil.sendDebugMessages("Equipment for " + user.getPlayer().getName() + " has been updated for " + player.getName());
|
||||||
|
return PacketAction.CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction writePassengerContent(@NotNull Player player, @NotNull PassengerWrapper wrapper) {
|
||||||
|
// TODO: Figure out what to do with this, because with it in, it ruins backpacks (they keep getting thrown to random locations).
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
/*
|
||||||
|
CosmeticUser viewerUser = CosmeticUsers.getUser(player);
|
||||||
|
if (viewerUser == null || viewerUser.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
int ownerId = wrapper.getOwner();
|
||||||
|
|
||||||
|
Optional<CosmeticUser> optionalCosmeticUser = CosmeticUsers.values().stream().filter(user -> user.getPlayer() != null).filter(user -> ownerId == user.getPlayer().getEntityId()).findFirst();
|
||||||
|
if (optionalCosmeticUser.isEmpty()) return PacketAction.NOTHING;
|
||||||
|
CosmeticUser user = optionalCosmeticUser.get();
|
||||||
|
|
||||||
|
Cosmetic backpackCosmetic = user.getCosmetic(CosmeticSlot.BACKPACK);
|
||||||
|
if (backpackCosmetic == null) return PacketAction.NOTHING;
|
||||||
|
if (!(backpackCosmetic instanceof CosmeticBackpackType cosmeticBackpackType)) return PacketAction.NOTHING;
|
||||||
|
if (user.getUniqueId().equals(viewerUser.getUniqueId())) {
|
||||||
|
if (cosmeticBackpackType.isFirstPersonCompadible()) return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.getUserBackpackManager() == null) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
List<Integer> originalPassengers = wrapper.getPassengers();
|
||||||
|
List<Integer> passengers = new ArrayList<>(user.getUserBackpackManager().getEntityManager().getIds());
|
||||||
|
passengers.addAll(originalPassengers);
|
||||||
|
wrapper.setPassengers(passengers);
|
||||||
|
return PacketAction.CHANGED;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketAction readPlayerScale(@NotNull Player player, @NotNull PlayerScaleWrapper wrapper) {
|
||||||
|
int entityId = wrapper.getEntityId();
|
||||||
|
Player changedPlayer = Bukkit.getOnlinePlayers().stream()
|
||||||
|
.filter(onlinePlayer -> onlinePlayer.getEntityId() == entityId)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (changedPlayer == null) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
CosmeticUser cosmeticUser = CosmeticUsers.getUser(changedPlayer.getUniqueId());
|
||||||
|
if (cosmeticUser == null || cosmeticUser.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
UserBackpackManager backpack = cosmeticUser.getUserBackpackManager();
|
||||||
|
if (backpack != null) {
|
||||||
|
for (int cosmeticId : backpack.getEntityManager().getIds()) {
|
||||||
|
HMCCPacketManager.sendEntityScalePacket(cosmeticId, wrapper.getScale(), Collections.singletonList(player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction readInventoryClick(@NotNull Player player, @NotNull InventoryClickWrapper wrapper) {
|
||||||
|
int clickType = wrapper.getClickType();
|
||||||
|
int slotNumber = wrapper.getSlotNumber();
|
||||||
|
if (clickType != 0 || slotNumber == -999) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null || user.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotNumber);
|
||||||
|
if (cosmeticSlot == null || !user.hasCosmeticInSlot(cosmeticSlot)) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
|
||||||
|
MessagesUtil.sendDebugMessages("Packet fired, updated cosmetic " + cosmeticSlot);
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction readPlayerAction(@NotNull Player player, @NotNull PlayerActionWrapper wrapper) {
|
||||||
|
if (!Settings.isPreventOffhandSwapping()) return PacketAction.NOTHING;
|
||||||
|
String actionType = wrapper.getActionType();
|
||||||
|
MessagesUtil.sendDebugMessages("EntityStatus Initial " + player.getEntityId() + " - " + actionType);
|
||||||
|
// If it's not SWAP_ITEM_WITH_OFFHAND, ignore
|
||||||
|
if (!actionType.equalsIgnoreCase("SWAP_ITEM_WITH_OFFHAND")) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null) {
|
||||||
|
MessagesUtil.sendDebugMessages("EntityStatus User is null");
|
||||||
|
return PacketAction.NOTHING;
|
||||||
|
}
|
||||||
|
if (!user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) return PacketAction.NOTHING;
|
||||||
|
return PacketAction.CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction readPlayerArm(@NotNull Player player, @NotNull PlayerSwingWrapper wrapper) {
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null || !user.isInWardrobe() || !user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return PacketAction.NOTHING;
|
||||||
|
|
||||||
|
Menu menu = user.getWardrobeManager().getLastOpenMenu();
|
||||||
|
if (menu == null) return PacketAction.NOTHING;
|
||||||
|
menu.openMenu(user);
|
||||||
|
return PacketAction.CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull PacketAction readEntityHandle(@NotNull Player player, @NotNull PlayerInteractWrapper wrapper) {
|
||||||
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
|
if (user == null || !user.isInWardrobe()) return PacketAction.NOTHING;
|
||||||
|
else return PacketAction.CANCELLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,11 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
|||||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticMovementBehavior;
|
||||||
|
import com.hibiscusmc.hmccosmetics.cosmetic.behavior.CosmeticUpdateBehavior;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticMainhandType;
|
|
||||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||||
@@ -22,7 +23,6 @@ import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
|
|||||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import com.ticxo.modelengine.api.nms.NMSHandler;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
@@ -30,7 +30,7 @@ import me.lojosho.hibiscuscommons.util.InventoryUtils;
|
|||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.FireworkEffect;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
@@ -39,6 +39,7 @@ import org.bukkit.inventory.EquipmentSlot;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.*;
|
import org.bukkit.inventory.meta.*;
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -53,7 +54,7 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
private final HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
|
private final HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
|
||||||
private UserWardrobeManager userWardrobeManager;
|
private UserWardrobeManager userWardrobeManager;
|
||||||
private UserBalloonManager userBalloonManager;
|
private UserBalloonManager userBalloonManager;
|
||||||
@Getter
|
@Getter @Nullable
|
||||||
private UserBackpackManager userBackpackManager;
|
private UserBackpackManager userBackpackManager;
|
||||||
|
|
||||||
// Cosmetic Settings/Toggles
|
// Cosmetic Settings/Toggles
|
||||||
@@ -98,7 +99,7 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
Color color = null;
|
Color color = null;
|
||||||
if (colorRGBInt != -1) color = Color.fromRGB(colorRGBInt); // -1 is defined as no color; anything else is a color
|
if (colorRGBInt != -1) color = Color.fromRGB(colorRGBInt); // -1 is defined as no color; anything else is a color
|
||||||
|
|
||||||
this.addPlayerCosmetic(cosmetic, color);
|
this.addCosmetic(cosmetic, color);
|
||||||
}
|
}
|
||||||
this.applyHiddenState(userData.getHiddenReasons());
|
this.applyHiddenState(userData.getHiddenReasons());
|
||||||
}
|
}
|
||||||
@@ -111,7 +112,7 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
* This is used to help hooking plugins apply custom logic to the user.
|
* This is used to help hooking plugins apply custom logic to the user.
|
||||||
*/
|
*/
|
||||||
protected boolean applyCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color) {
|
protected boolean applyCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||||
this.addPlayerCosmetic(cosmetic, color);
|
this.addCosmetic(cosmetic, color);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +152,11 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
MessagesUtil.sendDebugMessages("Showing Cosmetics due to world");
|
MessagesUtil.sendDebugMessages("Showing Cosmetics due to world");
|
||||||
showCosmetics(HiddenReason.WORLD);
|
showCosmetics(HiddenReason.WORLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bukkitPlayer != null && bukkitPlayer.hasPotionEffect(PotionEffectType.INVISIBILITY)) {
|
||||||
|
hideCosmetics(HiddenReason.POTION);
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings.isAllPlayersHidden()) {
|
if (Settings.isAllPlayersHidden()) {
|
||||||
hideCosmetics(HiddenReason.DISABLED);
|
hideCosmetics(HiddenReason.DISABLED);
|
||||||
}
|
}
|
||||||
@@ -295,23 +301,52 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateCosmetic(@NotNull CosmeticSlot slot) {
|
public boolean updateCosmetic(@NotNull CosmeticSlot slot) {
|
||||||
Cosmetic cosmetic = playerCosmetics.get(slot);
|
final Cosmetic cosmetic = playerCosmetics.get(slot);
|
||||||
if (cosmetic != null) {
|
if(cosmetic == null) {
|
||||||
cosmetic.update(this);
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCosmetic(Cosmetic cosmetic) {
|
if(!(cosmetic instanceof CosmeticUpdateBehavior behavior)) {
|
||||||
updateCosmetic(cosmetic.getSlot());
|
MessagesUtil.sendDebugMessages("Attempted to update cosmetic that does not implement CosmeticUpdateBehavior");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
behavior.dispatchUpdate(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateMovementCosmetic(@NotNull CosmeticSlot slot, @NotNull final Location from, @NotNull final Location to) {
|
||||||
|
final Cosmetic cosmetic = playerCosmetics.get(slot);
|
||||||
|
if(cosmetic == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(cosmetic instanceof CosmeticMovementBehavior behavior)) {
|
||||||
|
MessagesUtil.sendDebugMessages("Attempted to update cosmetic that does not implement CosmeticMovementBehavior");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
behavior.dispatchMove(this, from, to);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateCosmetic(@NotNull final Cosmetic cosmetic) {
|
||||||
|
return updateCosmetic(cosmetic.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCosmetic() {
|
public void updateCosmetic() {
|
||||||
MessagesUtil.sendDebugMessages("updateCosmetic (All) - start");
|
MessagesUtil.sendDebugMessages("updateCosmetic (All) - start");
|
||||||
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
|
final HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
|
||||||
|
|
||||||
for (Cosmetic cosmetic : playerCosmetics.values()) {
|
for(final Cosmetic cosmetic : playerCosmetics.values()) {
|
||||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
if(!(cosmetic instanceof CosmeticUpdateBehavior behavior)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// defers item updates to end of operation
|
||||||
|
if(cosmetic instanceof CosmeticArmorType armorType) {
|
||||||
if (isInWardrobe()) return;
|
if (isInWardrobe()) return;
|
||||||
if (!(getEntity() instanceof HumanEntity humanEntity)) return;
|
if (!(getEntity() instanceof HumanEntity humanEntity)) return;
|
||||||
|
|
||||||
@@ -322,15 +357,22 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
|
|
||||||
items.put(HMCCInventoryUtils.getEquipmentSlot(armorType.getSlot()), armorType.getItem(this));
|
items.put(HMCCInventoryUtils.getEquipmentSlot(armorType.getSlot()), armorType.getItem(this));
|
||||||
} else {
|
} else {
|
||||||
cosmetic.update(this);
|
behavior.dispatchUpdate(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (items.isEmpty() || getEntity() == null) return;
|
|
||||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), items, HMCCPacketManager.getViewers(getEntity().getLocation()));
|
|
||||||
MessagesUtil.sendDebugMessages("updateCosmetic (All) - end - " + items.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getUserCosmeticItem(CosmeticSlot slot) {
|
final Entity entity = this.getEntity();
|
||||||
|
if(!items.isEmpty() && entity != null) {
|
||||||
|
PacketManager.equipmentSlotUpdate(
|
||||||
|
entity.getEntityId(),
|
||||||
|
items,
|
||||||
|
HMCCPacketManager.getViewers(entity.getLocation())
|
||||||
|
);
|
||||||
|
MessagesUtil.sendDebugMessages("updateCosmetic (All) - end - " + items.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getUserCosmeticItem(@NotNull CosmeticSlot slot) {
|
||||||
Cosmetic cosmetic = getCosmetic(slot);
|
Cosmetic cosmetic = getCosmetic(slot);
|
||||||
if (cosmetic == null) return new ItemStack(Material.AIR);
|
if (cosmetic == null) return new ItemStack(Material.AIR);
|
||||||
return getUserCosmeticItem(cosmetic);
|
return getUserCosmeticItem(cosmetic);
|
||||||
@@ -345,7 +387,7 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||||
item = armorType.getItem(this, cosmetic.getItem());
|
item = armorType.getItem(this, cosmetic.getItem());
|
||||||
}
|
}
|
||||||
if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticMainhandType) {
|
if (cosmetic instanceof CosmeticBackpackType) {
|
||||||
item = cosmetic.getItem();
|
item = cosmetic.getItem();
|
||||||
}
|
}
|
||||||
if (cosmetic instanceof CosmeticBalloonType) {
|
if (cosmetic instanceof CosmeticBalloonType) {
|
||||||
@@ -603,7 +645,7 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
* @return Entity
|
* @return Entity
|
||||||
*/
|
*/
|
||||||
public Entity getEntity() {
|
public Entity getEntity() {
|
||||||
return Bukkit.getEntity(uniqueId);
|
return getPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color getCosmeticColor(CosmeticSlot slot) {
|
public Color getCosmeticColor(CosmeticSlot slot) {
|
||||||
@@ -626,7 +668,12 @@ public class CosmeticUser implements CosmeticHolder {
|
|||||||
if (isInWardrobe() && !ignoreWardrobe) {
|
if (isInWardrobe() && !ignoreWardrobe) {
|
||||||
if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
|
if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
|
||||||
}
|
}
|
||||||
return getEntity().hasPermission(cosmetic.getPermission());
|
final Player player = getPlayer();
|
||||||
|
if (player != null) return player.hasPermission(cosmetic.getPermission());
|
||||||
|
// This sucks, but basically if we can find a player, use that. If not, try to find the entity. If it can't find the entity, just return false.
|
||||||
|
final Entity entity = getEntity();
|
||||||
|
if (entity != null) return entity.hasPermission(cosmetic.getPermission());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hidePlayer() {
|
public void hidePlayer() {
|
||||||
|
|||||||
@@ -5,22 +5,21 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
|||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
|
||||||
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class UserBackpackManager {
|
public class UserBackpackManager {
|
||||||
|
|
||||||
@@ -31,7 +30,7 @@ public class UserBackpackManager {
|
|||||||
private ArrayList<Integer> particleCloud = new ArrayList<>();
|
private ArrayList<Integer> particleCloud = new ArrayList<>();
|
||||||
@Getter
|
@Getter
|
||||||
private final CosmeticUser user;
|
private final CosmeticUser user;
|
||||||
@Getter
|
@Getter @Nullable
|
||||||
private UserEntity entityManager;
|
private UserEntity entityManager;
|
||||||
|
|
||||||
public UserBackpackManager(CosmeticUser user) {
|
public UserBackpackManager(CosmeticUser user) {
|
||||||
@@ -56,8 +55,15 @@ public class UserBackpackManager {
|
|||||||
getEntityManager().setIds(List.of(invisibleArmorStand));
|
getEntityManager().setIds(List.of(invisibleArmorStand));
|
||||||
getEntityManager().teleport(user.getEntity().getLocation());
|
getEntityManager().teleport(user.getEntity().getLocation());
|
||||||
List<Player> outsideViewers = getEntityManager().getViewers();
|
List<Player> outsideViewers = getEntityManager().getViewers();
|
||||||
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), getFirstArmorStandId(), EntityType.ARMOR_STAND, UUID.randomUUID(), getEntityManager().getViewers());
|
|
||||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), outsideViewers);
|
HMCCPacketManager.spawnInvisibleArmorstand(getFirstArmorStandId(), user.getEntity().getLocation(), UUID.randomUUID(), outsideViewers);
|
||||||
|
|
||||||
|
if (user.getPlayer() != null) {
|
||||||
|
AttributeInstance scaleAttribute = user.getPlayer().getAttribute(Attribute.SCALE);
|
||||||
|
if (scaleAttribute != null) {
|
||||||
|
HMCCPacketManager.sendEntityScalePacket(getFirstArmorStandId(), scaleAttribute.getValue(), outsideViewers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Entity entity = user.getEntity();
|
Entity entity = user.getEntity();
|
||||||
|
|
||||||
@@ -75,8 +81,7 @@ public class UserBackpackManager {
|
|||||||
if (cosmeticBackpackType.isFirstPersonCompadible()) {
|
if (cosmeticBackpackType.isFirstPersonCompadible()) {
|
||||||
for (int i = particleCloud.size(); i < cosmeticBackpackType.getHeight(); i++) {
|
for (int i = particleCloud.size(); i < cosmeticBackpackType.getHeight(); i++) {
|
||||||
int entityId = ServerUtils.getNextEntityId();
|
int entityId = ServerUtils.getNextEntityId();
|
||||||
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), entityId, EntityType.AREA_EFFECT_CLOUD, UUID.randomUUID());
|
HMCCPacketManager.spawnCloudAndHandleEffect(entityId, user.getEntity().getLocation(), UUID.randomUUID(), HMCCPacketManager.getViewers(user.getEntity().getLocation()));
|
||||||
HMCCPacketManager.sendCloudEffect(entityId, HMCCPacketManager.getViewers(user.getEntity().getLocation()));
|
|
||||||
this.particleCloud.add(entityId);
|
this.particleCloud.add(entityId);
|
||||||
}
|
}
|
||||||
// Copied code from updating the backpack
|
// Copied code from updating the backpack
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
|||||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
|
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||||
@@ -49,7 +50,8 @@ public class UserBalloonManager {
|
|||||||
e.setSmall(true);
|
e.setSmall(true);
|
||||||
e.setMarker(true);
|
e.setMarker(true);
|
||||||
e.setPersistent(false);
|
e.setPersistent(false);
|
||||||
e.getPersistentDataContainer().set(new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticMob"), PersistentDataType.SHORT, Short.valueOf("1"));
|
e.setAI(false);
|
||||||
|
e.getPersistentDataContainer().set(HMCCServerUtils.getCosmemeticMobKey(), PersistentDataType.BOOLEAN, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +101,12 @@ public class UserBalloonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
pufferfish.destroyPufferfish();
|
// This code is like a brick road, always bumpy.
|
||||||
|
// Basically, the balloon viewers ignore people in wardrobe, which well, if your the user in the wardrobe, ain't including you.
|
||||||
|
// This manually passes in the viewers for it to destroy, which includes the person in the wardrobe
|
||||||
|
if (user.getPlayer() != null && user.isInWardrobe()) pufferfish.destroyPufferfish(List.of(user.getPlayer()));
|
||||||
|
else pufferfish.destroyPufferfish();
|
||||||
|
|
||||||
if (balloonType == BalloonType.MODELENGINE) {
|
if (balloonType == BalloonType.MODELENGINE) {
|
||||||
final ModeledEntity entity = ModelEngineAPI.getModeledEntity(modelEntity);
|
final ModeledEntity entity = ModelEngineAPI.getModeledEntity(modelEntity);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||||
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -26,6 +21,7 @@ public class UserBalloonPufferfish extends UserEntity {
|
|||||||
public UserBalloonPufferfish(UUID owner, int pufferFishEntityId, UUID uuid) {
|
public UserBalloonPufferfish(UUID owner, int pufferFishEntityId, UUID uuid) {
|
||||||
super(owner);
|
super(owner);
|
||||||
this.pufferFishEntityId = pufferFishEntityId;
|
this.pufferFishEntityId = pufferFishEntityId;
|
||||||
|
setIds(List.of(pufferFishEntityId));
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,8 +31,11 @@ public class UserBalloonPufferfish extends UserEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void spawnPufferfish(Location location, List<Player> sendTo) {
|
public void spawnPufferfish(Location location, List<Player> sendTo) {
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendInvisibleEntity(pufferFishEntityId, EntityType.PUFFERFISH, location, uuid, sendTo);
|
||||||
|
/*
|
||||||
HMCCPacketManager.sendEntitySpawnPacket(location, pufferFishEntityId, EntityType.PUFFERFISH, uuid, sendTo);
|
HMCCPacketManager.sendEntitySpawnPacket(location, pufferFishEntityId, EntityType.PUFFERFISH, uuid, sendTo);
|
||||||
HMCCPacketManager.sendInvisibilityPacket(pufferFishEntityId, sendTo);
|
HMCCPacketManager.sendInvisibilityPacket(pufferFishEntityId, sendTo);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroyPufferfish() {
|
public void destroyPufferfish() {
|
||||||
@@ -45,6 +44,12 @@ public class UserBalloonPufferfish extends UserEntity {
|
|||||||
destroyed = true;
|
destroyed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void destroyPufferfish(List<Player> viewers) {
|
||||||
|
HMCCPacketManager.sendEntityDestroyPacket(pufferFishEntityId, viewers);
|
||||||
|
//getViewers().clear();
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Player> refreshViewers(Location location) {
|
public List<Player> refreshViewers(Location location) {
|
||||||
if (destroyed) return List.of(); //Prevents refreshing a destroyed entity
|
if (destroyed) return List.of(); //Prevents refreshing a destroyed entity
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -13,9 +13,7 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class UserEntity {
|
public class UserEntity {
|
||||||
|
|
||||||
@@ -41,46 +39,73 @@ public class UserEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Player> refreshViewers(Location location) {
|
public List<Player> refreshViewers(Location location) {
|
||||||
if (System.currentTimeMillis() - viewerLastUpdate <= 1000) return List.of(); //Prevents mass refreshes
|
//Prevents mass refreshes
|
||||||
ArrayList<Player> newPlayers = new ArrayList<>();
|
//if(System.currentTimeMillis() - viewerLastUpdate <= 3000) {
|
||||||
ArrayList<Player> removePlayers = new ArrayList<>();
|
// return List.of();
|
||||||
List<Player> players = HMCCPacketManager.getViewers(location);
|
//}
|
||||||
|
|
||||||
Entity ownerPlayer = Bukkit.getEntity(owner);
|
Entity ownerPlayer = Bukkit.getEntity(owner);
|
||||||
if (ownerPlayer == null) {
|
if (ownerPlayer == null) {
|
||||||
MessagesUtil.sendDebugMessages("Owner is null (refreshViewers), returning empty list");
|
MessagesUtil.sendDebugMessages("Owner is null (refreshViewers), returning empty list");
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<Player> players = HMCCosmeticsPlugin.getInstance()
|
||||||
|
.getPlayerSearchManager()
|
||||||
|
.getPlayersInRange(location, Settings.getViewDistance());
|
||||||
|
|
||||||
|
final ArrayList<UUID> newPlayerIds = new ArrayList<>();
|
||||||
|
final ArrayList<UUID> removePlayerIds = new ArrayList<>();
|
||||||
|
|
||||||
|
// Go through all nearby players, check if they are new to the viewers list.
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||||
if (user != null && owner != user.getUniqueId() && user.isInWardrobe() && !player.canSee(ownerPlayer)) { // Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
|
if(
|
||||||
removePlayers.add(player);
|
user != null
|
||||||
HMCCPacketManager.sendEntityDestroyPacket(ids, List.of(player));
|
&& owner != user.getUniqueId()
|
||||||
|
&& user.isInWardrobe()
|
||||||
|
// Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
|
||||||
|
&& !player.canSee(ownerPlayer)
|
||||||
|
) {
|
||||||
|
removePlayerIds.add(player.getUniqueId());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!viewers.contains(player)) {
|
if (!viewers.contains(player)) {
|
||||||
viewers.add(player);
|
viewers.add(player);
|
||||||
newPlayers.add(player);
|
newPlayerIds.add(player.getUniqueId());
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// bad loopdy loops
|
}
|
||||||
|
// Basically, if they are not nearby, they are still in the viewers and we need to kick em to the curb
|
||||||
for (Player viewerPlayer : viewers) {
|
for (Player viewerPlayer : viewers) {
|
||||||
if (!players.contains(viewerPlayer)) {
|
if (!players.contains(viewerPlayer)) {
|
||||||
removePlayers.add(viewerPlayer);
|
removePlayerIds.add(viewerPlayer.getUniqueId());
|
||||||
HMCCPacketManager.sendEntityDestroyPacket(ids, List.of(viewerPlayer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are players for removal, send the packets to them
|
||||||
|
if (!removePlayerIds.isEmpty()) {
|
||||||
|
final List<Player> removePlayers = removePlayerIds.stream()
|
||||||
|
.map(Bukkit::getPlayer)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
HMCCPacketManager.sendEntityDestroyPacket(ids, removePlayers);
|
||||||
viewers.removeAll(removePlayers);
|
viewers.removeAll(removePlayers);
|
||||||
setViewerLastUpdate(System.currentTimeMillis());
|
}
|
||||||
return newPlayers;
|
|
||||||
|
this.setViewerLastUpdate(System.currentTimeMillis());
|
||||||
|
return newPlayerIds.stream()
|
||||||
|
.map(Bukkit::getPlayer)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void teleport(Location location) {
|
public void teleport(Location location) {
|
||||||
if (this.getLocation() != null && this.getLocation().getWorld() == location.getWorld()) {
|
if (this.getLocation() != null && this.getLocation().getWorld() == location.getWorld()) {
|
||||||
// Was thinking about using schedulers to just send the packet later... but that would be a lot of tasks and
|
// Was thinking about using schedulers to just send the packet later... but that would be a lot of tasks and
|
||||||
// would probably cause more lag. Furthermore, the server "ticks" the cosmetics every second by defualt. So it's fine like this.
|
// would probably cause more lag. Furthermore, the server "ticks" the cosmetics every second by defualt. So it's fine like this.
|
||||||
if (System.currentTimeMillis() - getLastPositionUpdate() <= Settings.getPacketEntityTeleportCooldown()) return;
|
//if (System.currentTimeMillis() - getLastPositionUpdate() <= Settings.getPacketEntityTeleportCooldown()) return;
|
||||||
}
|
}
|
||||||
this.location = location;
|
this.location = location;
|
||||||
for (Integer entity : ids) {
|
for (Integer entity : ids) {
|
||||||
@@ -99,7 +124,7 @@ public class UserEntity {
|
|||||||
// First person backpacks need both packets to rotate properly, otherwise they look off
|
// First person backpacks need both packets to rotate properly, otherwise they look off
|
||||||
// Regular backpacks just need the look packet
|
// Regular backpacks just need the look packet
|
||||||
if (additonalPacket) HMCCPacketManager.sendRotationPacket(entity, yaw, false, getViewers());
|
if (additonalPacket) HMCCPacketManager.sendRotationPacket(entity, yaw, false, getViewers());
|
||||||
HMCCPacketManager.sendLookPacket(entity, location, getViewers());
|
HMCCPacketManager.sendRotateHeadPacket(entity, location, getViewers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
|||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import net.kyori.adventure.audience.Audience;
|
import net.kyori.adventure.audience.Audience;
|
||||||
import net.kyori.adventure.bossbar.BossBar;
|
import net.kyori.adventure.bossbar.BossBar;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.attribute.Attribute;
|
||||||
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
@@ -117,12 +118,14 @@ public class UserWardrobeManager {
|
|||||||
// Armorstand
|
// Armorstand
|
||||||
HMCCPacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
|
HMCCPacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
|
||||||
HMCCPacketManager.sendArmorstandMetadata(ARMORSTAND_ID, viewer);
|
HMCCPacketManager.sendArmorstandMetadata(ARMORSTAND_ID, viewer);
|
||||||
HMCCPacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
NMSHandlers.getHandler().getPacketHandler().sendTeleportPacket(ARMORSTAND_ID, viewingLocation.getX(), viewingLocation.getY(), viewingLocation.getZ(), viewingLocation.getYaw(), viewingLocation.getPitch(), false, viewer);
|
||||||
|
//NMSHandlers.getHandler().getPacketHandler().sendLookAtPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
||||||
|
HMCCPacketManager.sendRotateHeadPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
||||||
|
|
||||||
// Player
|
// Player
|
||||||
player.teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
player.teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||||
player.setInvisible(true);
|
player.setInvisible(true);
|
||||||
HMCCPacketManager.gamemodeChangePacket(player, 3);
|
HMCCPacketManager.gamemodeChangePacket(player, GameMode.SPECTATOR);
|
||||||
HMCCPacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
|
HMCCPacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
|
||||||
|
|
||||||
// NPC
|
// NPC
|
||||||
@@ -139,10 +142,14 @@ public class UserWardrobeManager {
|
|||||||
HMCCPacketManager.sendPlayerOverlayPacket(NPC_ID, viewer);
|
HMCCPacketManager.sendPlayerOverlayPacket(NPC_ID, viewer);
|
||||||
MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation);
|
MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation);
|
||||||
NMSHandlers.getHandler().getPacketHandler().sendScoreboardHideNamePacket(player, npcName);
|
NMSHandlers.getHandler().getPacketHandler().sendScoreboardHideNamePacket(player, npcName);
|
||||||
|
AttributeInstance scaleAttribute = user.getPlayer().getAttribute(Attribute.SCALE);
|
||||||
|
if (scaleAttribute != null) {
|
||||||
|
HMCCPacketManager.sendEntityScalePacket(NPC_ID, scaleAttribute.getValue(), viewer);
|
||||||
|
}
|
||||||
}, 4);
|
}, 4);
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
HMCCPacketManager.sendLookPacket(NPC_ID, npcLocation, viewer);
|
HMCCPacketManager.sendRotateHeadPacket(NPC_ID, npcLocation, viewer);
|
||||||
HMCCPacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer);
|
HMCCPacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer);
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
@@ -176,9 +183,9 @@ public class UserWardrobeManager {
|
|||||||
Component message = MessagesUtil.processStringNoKey(player, WardrobeSettings.getBossbarMessage());
|
Component message = MessagesUtil.processStringNoKey(player, WardrobeSettings.getBossbarMessage());
|
||||||
|
|
||||||
bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay());
|
bossBar = BossBar.bossBar(message, progress, WardrobeSettings.getBossbarColor(), WardrobeSettings.getBossbarOverlay());
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
//Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
||||||
|
|
||||||
target.showBossBar(bossBar);
|
player.showBossBar(bossBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WardrobeSettings.isEnterOpenMenu()) {
|
if (WardrobeSettings.isEnterOpenMenu()) {
|
||||||
@@ -247,11 +254,11 @@ public class UserWardrobeManager {
|
|||||||
if (WardrobeSettings.isForceExitGamemode()) {
|
if (WardrobeSettings.isForceExitGamemode()) {
|
||||||
MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode());
|
MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode());
|
||||||
player.setGameMode(WardrobeSettings.getExitGamemode());
|
player.setGameMode(WardrobeSettings.getExitGamemode());
|
||||||
HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(WardrobeSettings.getExitGamemode())); // Success
|
HMCCPacketManager.gamemodeChangePacket(player, WardrobeSettings.getExitGamemode()); // Success
|
||||||
} else {
|
} else {
|
||||||
MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode);
|
MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode);
|
||||||
player.setGameMode(this.originalGamemode);
|
player.setGameMode(this.originalGamemode);
|
||||||
HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(this.originalGamemode)); // Success
|
HMCCPacketManager.gamemodeChangePacket(player, this.originalGamemode); // Success
|
||||||
}
|
}
|
||||||
user.showPlayer();
|
user.showPlayer();
|
||||||
|
|
||||||
@@ -280,9 +287,8 @@ public class UserWardrobeManager {
|
|||||||
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), items, viewer);
|
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), items, viewer);
|
||||||
|
|
||||||
if (WardrobeSettings.isEnabledBossbar()) {
|
if (WardrobeSettings.isEnabledBossbar()) {
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
//Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
||||||
|
player.hideBossBar(bossBar);
|
||||||
target.hideBossBar(bossBar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user.updateCosmetic();
|
user.updateCosmetic();
|
||||||
@@ -311,11 +317,13 @@ public class UserWardrobeManager {
|
|||||||
int yaw = data.get();
|
int yaw = data.get();
|
||||||
location.setYaw(yaw);
|
location.setYaw(yaw);
|
||||||
|
|
||||||
HMCCPacketManager.sendLookPacket(NPC_ID, location, viewer);
|
HMCCPacketManager.sendRotateHeadPacket(NPC_ID, location, viewer);
|
||||||
user.hidePlayer();
|
user.hidePlayer();
|
||||||
int rotationSpeed = WardrobeSettings.getRotationSpeed();
|
int rotationSpeed = WardrobeSettings.getRotationSpeed();
|
||||||
location.setYaw(HMCCServerUtils.getNextYaw(yaw - 30, rotationSpeed));
|
int newYaw = HMCCServerUtils.getNextYaw(yaw - 30, rotationSpeed);
|
||||||
HMCCPacketManager.sendRotationPacket(NPC_ID, location, true, viewer);
|
location.setYaw(newYaw);
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(NPC_ID, newYaw, 0, false, viewer);
|
||||||
|
HMCCPacketManager.sendRotationPacket(NPC_ID, newYaw, true, viewer);
|
||||||
int nextyaw = HMCCServerUtils.getNextYaw(yaw, rotationSpeed);
|
int nextyaw = HMCCServerUtils.getNextYaw(yaw, rotationSpeed);
|
||||||
data.set(nextyaw);
|
data.set(nextyaw);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util;
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
@@ -28,22 +27,6 @@ public class HMCCInventoryUtils {
|
|||||||
SLOT_MAP.put(CosmeticSlot.MAINHAND, EquipmentSlot.HAND);
|
SLOT_MAP.put(CosmeticSlot.MAINHAND, EquipmentSlot.HAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts from the Bukkit item slots to ProtocolLib item slots. Will produce a null if an improper bukkit item slot is sent through
|
|
||||||
* @param slot The BUKKIT item slot to convert.
|
|
||||||
* @return The ProtocolLib item slot that is returned
|
|
||||||
*/
|
|
||||||
public static EnumWrappers.ItemSlot itemBukkitSlot(final EquipmentSlot slot) {
|
|
||||||
return switch (slot) {
|
|
||||||
case HEAD -> EnumWrappers.ItemSlot.HEAD;
|
|
||||||
case CHEST -> EnumWrappers.ItemSlot.CHEST;
|
|
||||||
case LEGS -> EnumWrappers.ItemSlot.LEGS;
|
|
||||||
case FEET -> EnumWrappers.ItemSlot.FEET;
|
|
||||||
case HAND -> EnumWrappers.ItemSlot.MAINHAND;
|
|
||||||
case OFF_HAND -> EnumWrappers.ItemSlot.OFFHAND;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getPacketArmorSlot(final EquipmentSlot slot) {
|
public static int getPacketArmorSlot(final EquipmentSlot slot) {
|
||||||
return switch (slot) {
|
return switch (slot) {
|
||||||
case HEAD -> 5;
|
case HEAD -> 5;
|
||||||
@@ -67,18 +50,6 @@ public class HMCCInventoryUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CosmeticSlot getItemSlotToCosmeticSlot(final EnumWrappers.ItemSlot slot) {
|
|
||||||
return switch (slot) {
|
|
||||||
case HEAD -> CosmeticSlot.HELMET;
|
|
||||||
case CHEST -> CosmeticSlot.CHESTPLATE;
|
|
||||||
case LEGS -> CosmeticSlot.LEGGINGS;
|
|
||||||
case FEET -> CosmeticSlot.BOOTS;
|
|
||||||
case OFFHAND -> CosmeticSlot.OFFHAND;
|
|
||||||
case MAINHAND -> CosmeticSlot.MAINHAND;
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CosmeticSlot BukkitCosmeticSlot(EquipmentSlot slot) {
|
public static CosmeticSlot BukkitCosmeticSlot(EquipmentSlot slot) {
|
||||||
return switch (slot) {
|
return switch (slot) {
|
||||||
case HAND -> CosmeticSlot.MAINHAND;
|
case HAND -> CosmeticSlot.MAINHAND;
|
||||||
@@ -147,32 +118,6 @@ public class HMCCInventoryUtils {
|
|||||||
return SLOT_MAP.get(slot);
|
return SLOT_MAP.get(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
public static boolean isCosmeticItem(ItemStack itemStack) {
|
||||||
if (itemStack == null) return false;
|
if (itemStack == null) return false;
|
||||||
itemStack = itemStack.clone();
|
itemStack = itemStack.clone();
|
||||||
|
|||||||
@@ -1,29 +1,15 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util;
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HMCCPlayerUtils {
|
public class HMCCPlayerUtils {
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static WrappedSignedProperty getSkin(Player player) {
|
|
||||||
WrappedSignedProperty skinData = WrappedGameProfile.fromPlayer(player).getProperties()
|
|
||||||
.get("textures").stream().findAny().orElse(null);
|
|
||||||
|
|
||||||
if (skinData == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new WrappedSignedProperty("textures", skinData.getValue(), skinData.getSignature());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get nearby players. {@link com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager#getViewers(Location)}
|
* Get nearby players. {@link com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager#getViewers(Location)}
|
||||||
* @param player
|
* @param player
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util;
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
import com.owen1212055.particlehelper.api.particle.MultiParticle;
|
import com.owen1212055.particlehelper.api.particle.MultiParticle;
|
||||||
import com.owen1212055.particlehelper.api.particle.Particle;
|
import com.owen1212055.particlehelper.api.particle.Particle;
|
||||||
import com.owen1212055.particlehelper.api.particle.types.*;
|
import com.owen1212055.particlehelper.api.particle.types.*;
|
||||||
@@ -9,6 +10,8 @@ import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
|||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@@ -157,4 +160,8 @@ public class HMCCServerUtils {
|
|||||||
}
|
}
|
||||||
return nextYaw;
|
return nextYaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NamespacedKey getCosmemeticMobKey() {
|
||||||
|
return new NamespacedKey(HMCCosmeticsPlugin.getInstance(), "cosmeticmob");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import me.lojosho.hibiscuscommons.hooks.Hooks;
|
|||||||
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
import net.kyori.adventure.audience.Audience;
|
import net.kyori.adventure.audience.Audience;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
@@ -43,41 +42,35 @@ public class MessagesUtil {
|
|||||||
public static void sendMessage(Player player, String key) {
|
public static void sendMessage(Player player, String key) {
|
||||||
Component finalMessage = processString(player, key);
|
Component finalMessage = processString(player, key);
|
||||||
if (finalMessage == null) return;
|
if (finalMessage == null) return;
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
|
||||||
|
|
||||||
target.sendMessage(finalMessage);
|
player.sendMessage(finalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendMessage(CommandSender sender, String key) {
|
public static void sendMessage(CommandSender sender, String key) {
|
||||||
Component finalMessage = processString(null, key);
|
Component finalMessage = processString(null, key);
|
||||||
if (finalMessage == null) return;
|
if (finalMessage == null) return;
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).sender(sender);
|
|
||||||
|
|
||||||
target.sendMessage(finalMessage);
|
sender.sendMessage(finalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendMessage(Player player, String key, TagResolver placeholder) {
|
public static void sendMessage(Player player, String key, TagResolver placeholder) {
|
||||||
Component finalMessage = processString(player, key, placeholder);
|
Component finalMessage = processString(player, key, placeholder);
|
||||||
if (finalMessage == null) return;
|
if (finalMessage == null) return;
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
|
||||||
|
|
||||||
target.sendMessage(finalMessage);
|
player.sendMessage(finalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendMessageNoKey(Player player, String message) {
|
public static void sendMessageNoKey(Player player, String message) {
|
||||||
Component finalMessage = processStringNoKey(player, message);
|
Component finalMessage = processStringNoKey(player, message);
|
||||||
if (finalMessage == null) return;
|
if (finalMessage == null) return;
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
|
||||||
|
|
||||||
target.sendMessage(finalMessage);
|
player.sendMessage(finalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendActionBar(Player player, String key) {
|
public static void sendActionBar(Player player, String key) {
|
||||||
Component finalMessage = processString(player, key);
|
Component finalMessage = processString(player, key);
|
||||||
if (finalMessage == null) return;
|
if (finalMessage == null) return;
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
player.sendActionBar(finalMessage);
|
||||||
|
|
||||||
target.sendActionBar(finalMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendTitle(Player player, String message) {
|
public static void sendTitle(Player player, String message) {
|
||||||
@@ -85,12 +78,10 @@ public class MessagesUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void sendTitle(Player player, String message, int fadein, int stay, int fadeout) {
|
public static void sendTitle(Player player, String message, int fadein, int stay, int fadeout) {
|
||||||
Audience target = BukkitAudiences.create(HMCCosmeticsPlugin.getInstance()).player(player);
|
|
||||||
|
|
||||||
Title.Times times = Title.Times.times(Duration.ofMillis(fadein), Duration.ofMillis(stay), Duration.ofMillis(fadeout));
|
Title.Times times = Title.Times.times(Duration.ofMillis(fadein), Duration.ofMillis(stay), Duration.ofMillis(fadeout));
|
||||||
Title title = Title.title(processStringNoKey(player, message), Component.empty(), times);
|
Title title = Title.title(processStringNoKey(player, message), Component.empty(), times);
|
||||||
|
|
||||||
target.showTitle(title);
|
player.showTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Component processString(Player player, String key) {
|
public static Component processString(Player player, String key) {
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Octree<T> {
|
||||||
|
|
||||||
|
private static final int MAX_CAPACITY = 8;
|
||||||
|
private BoundingBox boundary;
|
||||||
|
private List<Entry> points;
|
||||||
|
private Octree<T>[] children;
|
||||||
|
private boolean isDivided;
|
||||||
|
|
||||||
|
public Octree(BoundingBox boundary) {
|
||||||
|
this.boundary = boundary;
|
||||||
|
this.points = new ArrayList<>();
|
||||||
|
this.isDivided = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean insert(Point3D position, T data) {
|
||||||
|
if (!boundary.contains(position)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.size() < MAX_CAPACITY && !isDivided) {
|
||||||
|
points.add(new Entry(position, data));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDivided) {
|
||||||
|
subdivide();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Octree<T> child : children) {
|
||||||
|
if (child.insert(position, data)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Point3D point, T player) {
|
||||||
|
if (!boundary.contains(point)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.size() < MAX_CAPACITY && !isDivided) {
|
||||||
|
points.removeIf(entry -> entry.position.equals(point) && entry.data.equals(player));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDivided) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Octree<T> child : children) {
|
||||||
|
if (child.remove(point, player)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> queryRange(BoundingBox range) {
|
||||||
|
List<T> found = new ArrayList<>();
|
||||||
|
|
||||||
|
if (!boundary.intersects(range)) {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Entry entry : points) {
|
||||||
|
if (range.contains(entry.position)) {
|
||||||
|
found.add(entry.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDivided) {
|
||||||
|
for (Octree<T> child : children) {
|
||||||
|
found.addAll(child.queryRange(range));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void subdivide() {
|
||||||
|
double x = boundary.center.x;
|
||||||
|
double y = boundary.center.y;
|
||||||
|
double z = boundary.center.z;
|
||||||
|
double newHalfSize = boundary.halfSize / 2.0;
|
||||||
|
|
||||||
|
children = new Octree[8];
|
||||||
|
children[0] = new Octree<>(new BoundingBox(new Point3D(x - newHalfSize, y - newHalfSize, z - newHalfSize), newHalfSize));
|
||||||
|
children[1] = new Octree<>(new BoundingBox(new Point3D(x + newHalfSize, y - newHalfSize, z - newHalfSize), newHalfSize));
|
||||||
|
children[2] = new Octree<>(new BoundingBox(new Point3D(x - newHalfSize, y + newHalfSize, z - newHalfSize), newHalfSize));
|
||||||
|
children[3] = new Octree<>(new BoundingBox(new Point3D(x + newHalfSize, y + newHalfSize, z - newHalfSize), newHalfSize));
|
||||||
|
children[4] = new Octree<>(new BoundingBox(new Point3D(x - newHalfSize, y - newHalfSize, z + newHalfSize), newHalfSize));
|
||||||
|
children[5] = new Octree<>(new BoundingBox(new Point3D(x + newHalfSize, y - newHalfSize, z + newHalfSize), newHalfSize));
|
||||||
|
children[6] = new Octree<>(new BoundingBox(new Point3D(x - newHalfSize, y + newHalfSize, z + newHalfSize), newHalfSize));
|
||||||
|
children[7] = new Octree<>(new BoundingBox(new Point3D(x + newHalfSize, y + newHalfSize, z + newHalfSize), newHalfSize));
|
||||||
|
|
||||||
|
isDivided = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Point3D {
|
||||||
|
double x, y, z;
|
||||||
|
|
||||||
|
public Point3D(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BoundingBox {
|
||||||
|
Point3D center;
|
||||||
|
double halfSize;
|
||||||
|
|
||||||
|
public BoundingBox(Point3D center, double halfSize) {
|
||||||
|
this.center = center;
|
||||||
|
this.halfSize = halfSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Point3D point) {
|
||||||
|
return Math.abs(point.x - center.x) <= halfSize &&
|
||||||
|
Math.abs(point.y - center.y) <= halfSize &&
|
||||||
|
Math.abs(point.z - center.z) <= halfSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean intersects(BoundingBox other) {
|
||||||
|
return Math.abs(center.x - other.center.x) <= halfSize + other.halfSize &&
|
||||||
|
Math.abs(center.y - other.center.y) <= halfSize + other.halfSize &&
|
||||||
|
Math.abs(center.z - other.center.z) <= halfSize + other.halfSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Entry {
|
||||||
|
Point3D position;
|
||||||
|
T data;
|
||||||
|
|
||||||
|
Entry(Point3D position, T data) {
|
||||||
|
this.position = position;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
|
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class PlayerSearchManager implements Listener {
|
||||||
|
private final Map<UUID, Octree<Player>> worldOctrees = new HashMap<>();
|
||||||
|
private final Map<UUID, Octree.Point3D> playerPositions = new HashMap<>();
|
||||||
|
|
||||||
|
//private static final double WORLD_HALF_SIZE = 30_000_000; // Previous built in value
|
||||||
|
private final double WORLD_HALF_SIZE;
|
||||||
|
|
||||||
|
public PlayerSearchManager(@NotNull HMCCosmeticsPlugin plugin) {
|
||||||
|
WORLD_HALF_SIZE = (double) plugin.getServer().getMaxWorldSize() / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Octree<Player> getOrCreateOctree(World world) {
|
||||||
|
return worldOctrees.computeIfAbsent(world.getUID(), $ -> {
|
||||||
|
Octree.BoundingBox worldBoundary = new Octree.BoundingBox(
|
||||||
|
new Octree.Point3D(0, 160, 0), WORLD_HALF_SIZE
|
||||||
|
);
|
||||||
|
return new Octree<>(worldBoundary);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Octree.Point3D toPoint3D(Location location) {
|
||||||
|
return new Octree.Point3D(location.getX(), location.getY(), location.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addPlayer(Player player) {
|
||||||
|
Octree<Player> octree = getOrCreateOctree(player.getWorld());
|
||||||
|
Octree.Point3D point = toPoint3D(player.getLocation());
|
||||||
|
|
||||||
|
if(octree.insert(point, player)) {
|
||||||
|
playerPositions.put(player.getUniqueId(), point);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removePlayer(Player player) {
|
||||||
|
Octree<Player> octree = worldOctrees.get(player.getWorld().getUID());
|
||||||
|
if (octree == null) return false;
|
||||||
|
|
||||||
|
Octree.Point3D point = playerPositions.remove(player.getUniqueId());
|
||||||
|
if (point != null) return octree.remove(point, player);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlayerPosition(Player player) {
|
||||||
|
removePlayer(player);
|
||||||
|
addPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Player> getPlayersInRange(Location location, double range) {
|
||||||
|
Octree<Player> octree = worldOctrees.get(location.getWorld().getUID());
|
||||||
|
if (octree == null) return Collections.emptyList();
|
||||||
|
|
||||||
|
Octree.Point3D point = toPoint3D(location);
|
||||||
|
Octree.BoundingBox searchArea = new Octree.BoundingBox(point, range);
|
||||||
|
|
||||||
|
return octree.queryRange(searchArea)
|
||||||
|
.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
worldOctrees.clear();
|
||||||
|
playerPositions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
if (event.hasChangedBlock()) updatePlayerPosition(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
|
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||||
|
updatePlayerPosition(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
removePlayer(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
addPlayer(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util;
|
package com.hibiscusmc.hmccosmetics.util;
|
||||||
|
|
||||||
import me.lojosho.hibiscuscommons.util.StringUtils;
|
|
||||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -32,7 +31,7 @@ public class TranslationUtil {
|
|||||||
public static String getTranslation(String key, String message) {
|
public static String getTranslation(String key, String message) {
|
||||||
List<TranslationPair> pairs = keys.get(key);
|
List<TranslationPair> pairs = keys.get(key);
|
||||||
for (TranslationPair pair : pairs) {
|
for (TranslationPair pair : pairs) {
|
||||||
if (pair.key().equals(message)) return StringUtils.parseStringToString(pair.value());
|
if (pair.key().equals(message)) return pair.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util.packets;
|
package com.hibiscusmc.hmccosmetics.util.packets;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.wrappers.*;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
|
|
||||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
import me.lojosho.hibiscuscommons.nms.MinecraftVersion;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerNamedEntitySpawn;
|
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerPlayerInfo;
|
|
||||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerRelEntityMove;
|
|
||||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Display;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.ItemDisplay;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class HMCCPacketManager extends PacketManager {
|
public class HMCCPacketManager extends PacketManager {
|
||||||
|
|
||||||
|
// The cloud effect map, in case it gets lost: Map<Integer, Number> dataValues = Map.of(0, (byte) 0x20, 8, 0f);
|
||||||
private static final List<CosmeticSlot> EQUIPMENT_SLOTS = List.of(CosmeticSlot.HELMET, CosmeticSlot.CHESTPLATE, CosmeticSlot.LEGGINGS, CosmeticSlot.BOOTS, CosmeticSlot.MAINHAND, CosmeticSlot.OFFHAND);
|
private static final List<CosmeticSlot> EQUIPMENT_SLOTS = List.of(CosmeticSlot.HELMET, CosmeticSlot.CHESTPLATE, CosmeticSlot.LEGGINGS, CosmeticSlot.BOOTS, CosmeticSlot.MAINHAND, CosmeticSlot.OFFHAND);
|
||||||
|
|
||||||
public static void sendEntitySpawnPacket(
|
public static void sendEntitySpawnPacket(
|
||||||
@@ -46,16 +46,7 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final UUID uuid,
|
final UUID uuid,
|
||||||
final @NotNull List<Player> sendTo
|
final @NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
NMSHandlers.getHandler().getPacketHandler().sendSpawnEntityPacket(entityId, uuid, entityType, location, sendTo);
|
||||||
packet.getModifier().writeDefaults();
|
|
||||||
packet.getUUIDs().write(0, uuid);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getEntityTypeModifier().write(0, entityType);
|
|
||||||
packet.getDoubles().
|
|
||||||
write(0, location.getX()).
|
|
||||||
write(1, location.getY()).
|
|
||||||
write(2, location.getZ());
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void equipmentSlotUpdate(
|
public static void equipmentSlotUpdate(
|
||||||
@@ -97,53 +88,55 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
|
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendArmorstandMetadata(
|
|
||||||
int entityId,
|
|
||||||
List<Player> sendTo
|
|
||||||
) {
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
|
||||||
packet.getModifier().writeDefaults();
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
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)
|
|
||||||
byte mask = 0x20;
|
|
||||||
if (Settings.isBackpackPreventDarkness()) mask = 0x21;
|
|
||||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), mask));
|
|
||||||
wrappedDataValueList.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x10));
|
|
||||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendInvisibilityPacket(
|
public static void sendInvisibilityPacket(
|
||||||
int entityId,
|
int entityId,
|
||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(entityId, Map.of(0, (byte) 0x20), sendTo);
|
||||||
packet.getModifier().writeDefaults();
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendCloudEffect(
|
public static void spawnCloudAndHandleEffect(
|
||||||
|
int entityId,
|
||||||
|
Location location,
|
||||||
|
UUID uuid,
|
||||||
|
List<Player> sendTo
|
||||||
|
) {
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendInvisibleParticleCloud(entityId, location, uuid, sendTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This handles both spawn + metadata in a bundle packet
|
||||||
|
* @param entityId
|
||||||
|
* @param location
|
||||||
|
* @param uuid
|
||||||
|
* @param sendTo
|
||||||
|
*/
|
||||||
|
public static void spawnInvisibleArmorstand(
|
||||||
|
int entityId,
|
||||||
|
Location location,
|
||||||
|
UUID uuid,
|
||||||
|
List<Player> sendTo
|
||||||
|
) {
|
||||||
|
byte mask = getMask();
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendInvisibleArmorstand(entityId, location, uuid, mask, sendTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is just a normal meta data packet (non-bundled)
|
||||||
|
* @param entityId
|
||||||
|
* @param sendTo
|
||||||
|
*/
|
||||||
|
public static void sendArmorstandMetadata(
|
||||||
int entityId,
|
int entityId,
|
||||||
List<Player> sendTo
|
List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
byte mask = getMask();
|
||||||
packet.getModifier().writeDefaults();
|
Map<Integer, Number> dataValues = Map.of(0, mask, 15, (byte) 0x10);
|
||||||
packet.getIntegers().write(0, entityId);
|
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(entityId, dataValues, sendTo);
|
||||||
|
}
|
||||||
|
|
||||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
private static byte getMask() {
|
||||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
return (byte) (Settings.isBackpackPreventDarkness() ? 0x21 : 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendRotationPacket(
|
public static void sendRotationPacket(
|
||||||
@@ -160,17 +153,7 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
@NotNull List<Player> sendTo
|
@NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, location.getYaw(), location.getPitch(), onGround, sendTo);
|
||||||
float yaw = location.getYaw() * ROTATION_FACTOR;
|
|
||||||
float pitch = location.getPitch() * ROTATION_FACTOR;
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getBytes().write(0, (byte) yaw);
|
|
||||||
packet.getBytes().write(1, (byte) pitch);
|
|
||||||
|
|
||||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
|
||||||
packet.getBooleans().write(0, onGround);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendRotationPacket(
|
public static void sendRotationPacket(
|
||||||
@@ -179,19 +162,9 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
boolean onGround,
|
boolean onGround,
|
||||||
@NotNull List<Player> sendTo
|
@NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, yaw, 0, onGround, sendTo);
|
||||||
float yaw2 = yaw * ROTATION_FACTOR;
|
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
|
||||||
packet.getIntegers().write(0, entityId);
|
|
||||||
packet.getBytes().write(0, (byte) yaw2);
|
|
||||||
packet.getBytes().write(1, (byte) 0);
|
|
||||||
|
|
||||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
|
||||||
packet.getBooleans().write(0, onGround);
|
|
||||||
for (Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mostly to deal with backpacks, this deals with entities riding other entities.
|
* Mostly to deal with backpacks, this deals with entities riding other entities.
|
||||||
* @param mountId The entity that is the "mount", ex. a player
|
* @param mountId The entity that is the "mount", ex. a player
|
||||||
@@ -216,12 +189,7 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final int[] passengerIds,
|
final int[] passengerIds,
|
||||||
final @NotNull List<Player> sendTo
|
final @NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
|
NMSHandlers.getHandler().getPacketHandler().sendMountPacket(mountId, passengerIds, sendTo);
|
||||||
packet.getIntegers().write(0, mountId);
|
|
||||||
packet.getIntegerArrays().write(0, passengerIds);
|
|
||||||
for (final Player p : sendTo) {
|
|
||||||
sendPacket(p, packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -238,32 +206,6 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
sendRidingPacket(mountId, new int[] {passengerId}, sendTo);
|
sendRidingPacket(mountId, new int[] {passengerId}, sendTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param location Location of the fake player.
|
|
||||||
* @param uuid UUID of the fake player. Should be random.
|
|
||||||
* @param entityId The entityID that the entity will take on.
|
|
||||||
* @param sendTo Who should it send the packet to?
|
|
||||||
*/
|
|
||||||
public static void sendFakePlayerSpawnPacket(
|
|
||||||
final @NotNull Location location,
|
|
||||||
final UUID uuid,
|
|
||||||
final int entityId,
|
|
||||||
final @NotNull List<Player> sendTo
|
|
||||||
) {
|
|
||||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) {
|
|
||||||
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
|
|
||||||
wrapper.setEntityID(entityId);
|
|
||||||
wrapper.setPlayerUUID(uuid);
|
|
||||||
wrapper.setPosition(location.toVector());
|
|
||||||
wrapper.setPitch(location.getPitch());
|
|
||||||
wrapper.setYaw(location.getYaw());
|
|
||||||
for (final Player p : sendTo) sendPacket(p, wrapper.getHandle());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendEntitySpawnPacket(location, entityId, EntityType.PLAYER, uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a fake player entity.
|
* Creates a fake player entity.
|
||||||
* @param skinnedPlayer The original player it bases itself off of.
|
* @param skinnedPlayer The original player it bases itself off of.
|
||||||
@@ -274,28 +216,10 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final Player skinnedPlayer,
|
final Player skinnedPlayer,
|
||||||
final int entityId,
|
final int entityId,
|
||||||
final UUID uuid,
|
final UUID uuid,
|
||||||
final String NPCName,
|
final String npcName,
|
||||||
final List<Player> sendTo
|
final List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
NMSHandlers.getHandler().getPacketHandler().sendFakePlayerInfoPacket(skinnedPlayer, entityId, uuid, npcName, sendTo);
|
||||||
info.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
|
||||||
|
|
||||||
String name = NPCName;
|
|
||||||
while (name.length() > 16) {
|
|
||||||
name = name.substring(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
|
|
||||||
WrappedSignedProperty skinData = HMCCPlayerUtils.getSkin(skinnedPlayer);
|
|
||||||
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -307,27 +231,10 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final int playerId,
|
final int playerId,
|
||||||
final @NotNull List<Player> sendTo
|
final @NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
/*
|
// https://minecraft.wiki/w/Java_Edition_protocol/Entity_metadata#Avatar
|
||||||
0x01 = Is on fire
|
|
||||||
0x02 = Is courching
|
|
||||||
0x04 = Unusued
|
|
||||||
0x08 = Sprinting
|
|
||||||
0x10 = Is swimming
|
|
||||||
0x20 = Invisibile
|
|
||||||
0x40 = Is Glowing
|
|
||||||
0x80 = Is flying with an elytra
|
|
||||||
https://wiki.vg/Entity_metadata#Entity
|
|
||||||
*/
|
|
||||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
if (NMSHandlers.getVersion().isLowerOrEqual(MinecraftVersion.v1_21_8)) NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(playerId, Map.of(17, mask), sendTo);
|
||||||
packet.getModifier().writeDefaults();
|
else NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(playerId, Map.of(16, mask), sendTo);
|
||||||
packet.getIntegers().write(0, playerId);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,9 +249,7 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final UUID uuid,
|
final UUID uuid,
|
||||||
final List<Player> sendTo
|
final List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE);
|
NMSHandlers.getHandler().getPacketHandler().sendPlayerInfoRemovePacket(uuid, sendTo);
|
||||||
packet.getUUIDLists().write(0, List.of(uuid));
|
|
||||||
for (final Player p : sendTo) sendPacket(p, packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendLeashPacket(
|
public static void sendLeashPacket(
|
||||||
@@ -370,16 +275,51 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
final boolean onGround,
|
final boolean onGround,
|
||||||
@NotNull List<Player> sendTo
|
@NotNull List<Player> sendTo
|
||||||
) {
|
) {
|
||||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
NMSHandlers.getHandler().getPacketHandler().sendMovePacket(entityId, from, to, onGround, sendTo);
|
||||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
|
||||||
wrapper.setEntityID(entityId);
|
|
||||||
wrapper.setDx(to.getX() - from.getX());
|
|
||||||
wrapper.setDy(to.getY() - from.getY());
|
|
||||||
wrapper.setDz(to.getZ() - from.getZ());
|
|
||||||
wrapper.setOnGround(onGround);
|
|
||||||
for (final Player p : sendTo) {
|
|
||||||
sendPacket(p, wrapper.getHandle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendEntityScalePacket(
|
||||||
|
int entityId,
|
||||||
|
double scale,
|
||||||
|
List<Player> sendTo
|
||||||
|
) {
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendEntityScalePacket(entityId, scale, sendTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For future transition to display entities
|
||||||
|
public static void sendDisplayEntityMetadataPacket(
|
||||||
|
int entityid,
|
||||||
|
ItemStack backpackItem,
|
||||||
|
List<Player> sendTo) {
|
||||||
|
// TODO: Make the default values adjustable
|
||||||
|
Vector3f translation = new Vector3f(0, 3, 0);
|
||||||
|
Vector3f scale = new Vector3f(1, 1, 1);
|
||||||
|
Quaternionf rotationLeft = new Quaternionf();
|
||||||
|
Quaternionf rotationRight = new Quaternionf();
|
||||||
|
Display.Billboard billboard = Display.Billboard.FIXED;
|
||||||
|
int blockLight = 15;
|
||||||
|
int skylight = 15;
|
||||||
|
int viewRange = Settings.getViewDistance();
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
ItemDisplay.ItemDisplayTransform transform = ItemDisplay.ItemDisplayTransform.HEAD;
|
||||||
|
|
||||||
|
NMSHandlers.getHandler().getPacketHandler().sendItemDisplayMetadata(
|
||||||
|
entityid,
|
||||||
|
translation,
|
||||||
|
scale,
|
||||||
|
rotationLeft,
|
||||||
|
rotationRight,
|
||||||
|
billboard,
|
||||||
|
blockLight,
|
||||||
|
skylight,
|
||||||
|
viewRange,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
transform,
|
||||||
|
backpackItem,
|
||||||
|
sendTo
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -391,9 +331,4 @@ public class HMCCPacketManager extends PacketManager {
|
|||||||
public static List<Player> getViewers(@NotNull Location location) {
|
public static List<Player> getViewers(@NotNull Location location) {
|
||||||
return PacketManager.getViewers(location, Settings.getViewDistance());
|
return PacketManager.getViewers(location, Settings.getViewDistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPacket(Player player, PacketContainer packet) {
|
|
||||||
if (player == null) return;
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, null,false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.google.common.base.Objects;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
// Courtesy of Packet Wrapper
|
|
||||||
public class AbstractPacket {
|
|
||||||
|
|
||||||
// The packet we will be modifying
|
|
||||||
protected PacketContainer handle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new strongly typed wrapper for the given packet.
|
|
||||||
*
|
|
||||||
* @param handle - handle to the raw packet data.
|
|
||||||
* @param type - the packet type.
|
|
||||||
*/
|
|
||||||
protected AbstractPacket(PacketContainer handle, PacketType type) {
|
|
||||||
// Make sure we're given a valid packet
|
|
||||||
if (handle == null)
|
|
||||||
throw new IllegalArgumentException("Packet handle cannot be NULL.");
|
|
||||||
if (!Objects.equal(handle.getType(), type))
|
|
||||||
throw new IllegalArgumentException(handle.getHandle()
|
|
||||||
+ " is not a packet of type " + type);
|
|
||||||
|
|
||||||
this.handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a handle to the raw packet data.
|
|
||||||
*
|
|
||||||
* @return Raw packet data.
|
|
||||||
*/
|
|
||||||
public PacketContainer getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the current packet to the given receiver.
|
|
||||||
*
|
|
||||||
* @param receiver - the receiver.
|
|
||||||
* @throws RuntimeException If the packet cannot be sent.
|
|
||||||
*/
|
|
||||||
public void sendPacket(Player receiver) {
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver,
|
|
||||||
getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the current packet to all online players.
|
|
||||||
*/
|
|
||||||
public void broadcastPacket() {
|
|
||||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulate receiving the current packet from the given sender.
|
|
||||||
*
|
|
||||||
* @param sender - the sender.
|
|
||||||
* @throws RuntimeException If the packet cannot be received.
|
|
||||||
* @deprecated Misspelled. recieve to receive
|
|
||||||
* @see #receivePacket(Player)
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void recievePacket(Player sender) {
|
|
||||||
try {
|
|
||||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
|
||||||
getHandle());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Cannot recieve packet.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulate receiving the current packet from the given sender.
|
|
||||||
*
|
|
||||||
* @param sender - the sender.
|
|
||||||
* @throws RuntimeException if the packet cannot be received.
|
|
||||||
*/
|
|
||||||
public void receivePacket(Player sender) {
|
|
||||||
try {
|
|
||||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
|
||||||
getHandle());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Cannot receive packet.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket {
|
|
||||||
public static final PacketType TYPE =
|
|
||||||
PacketType.Play.Server.NAMED_ENTITY_SPAWN;
|
|
||||||
|
|
||||||
public WrapperPlayServerNamedEntitySpawn() {
|
|
||||||
super(new PacketContainer(TYPE), TYPE);
|
|
||||||
handle.getModifier().writeDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WrapperPlayServerNamedEntitySpawn(PacketContainer packet) {
|
|
||||||
super(packet, TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve Entity ID.
|
|
||||||
* <p>
|
|
||||||
* Notes: entity's ID
|
|
||||||
*
|
|
||||||
* @return The current Entity ID
|
|
||||||
*/
|
|
||||||
public int getEntityID() {
|
|
||||||
return handle.getIntegers().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Entity ID.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setEntityID(int value) {
|
|
||||||
handle.getIntegers().write(0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the entity of the painting that will be spawned.
|
|
||||||
*
|
|
||||||
* @param world - the current world of the entity.
|
|
||||||
* @return The spawned entity.
|
|
||||||
*/
|
|
||||||
public Entity getEntity(World world) {
|
|
||||||
return handle.getEntityModifier(world).read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the entity of the painting that will be spawned.
|
|
||||||
*
|
|
||||||
* @param event - the packet event.
|
|
||||||
* @return The spawned entity.
|
|
||||||
*/
|
|
||||||
public Entity getEntity(@NotNull PacketEvent event) {
|
|
||||||
return getEntity(event.getPlayer().getWorld());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve Player UUID.
|
|
||||||
* <p>
|
|
||||||
* Notes: player's UUID
|
|
||||||
*
|
|
||||||
* @return The current Player UUID
|
|
||||||
*/
|
|
||||||
public UUID getPlayerUUID() {
|
|
||||||
return handle.getUUIDs().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Player UUID.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setPlayerUUID(UUID value) {
|
|
||||||
handle.getUUIDs().write(0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the position of the spawned entity as a vector.
|
|
||||||
*
|
|
||||||
* @return The position as a vector.
|
|
||||||
*/
|
|
||||||
public Vector getPosition() {
|
|
||||||
return new Vector(getX(), getY(), getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the position of the spawned entity using a vector.
|
|
||||||
*
|
|
||||||
* @param position - the new position.
|
|
||||||
*/
|
|
||||||
public void setPosition(@NotNull Vector position) {
|
|
||||||
setX(position.getX());
|
|
||||||
setY(position.getY());
|
|
||||||
setZ(position.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getX() {
|
|
||||||
return handle.getDoubles().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setX(double value) {
|
|
||||||
handle.getDoubles().write(0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getY() {
|
|
||||||
return handle.getDoubles().read(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setY(double value) {
|
|
||||||
handle.getDoubles().write(1, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getZ() {
|
|
||||||
return handle.getDoubles().read(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setZ(double value) {
|
|
||||||
handle.getDoubles().write(2, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the yaw of the spawned entity.
|
|
||||||
*
|
|
||||||
* @return The current Yaw
|
|
||||||
*/
|
|
||||||
public float getYaw() {
|
|
||||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the yaw of the spawned entity.
|
|
||||||
*
|
|
||||||
* @param value - new yaw.
|
|
||||||
*/
|
|
||||||
public void setYaw(float value) {
|
|
||||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the pitch of the spawned entity.
|
|
||||||
*
|
|
||||||
* @return The current pitch
|
|
||||||
*/
|
|
||||||
public float getPitch() {
|
|
||||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pitch of the spawned entity.
|
|
||||||
*
|
|
||||||
* @param value - new pitch.
|
|
||||||
*/
|
|
||||||
public void setPitch(float value) {
|
|
||||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class WrapperPlayServerPlayerInfo extends AbstractPacket {
|
|
||||||
public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO;
|
|
||||||
|
|
||||||
public WrapperPlayServerPlayerInfo() {
|
|
||||||
super(new PacketContainer(TYPE), TYPE);
|
|
||||||
handle.getModifier().writeDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WrapperPlayServerPlayerInfo(PacketContainer packet) {
|
|
||||||
super(packet, TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerInfoAction getAction() {
|
|
||||||
return handle.getPlayerInfoAction().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(PlayerInfoAction value) {
|
|
||||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_17_R1") || HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
|
||||||
handle.getPlayerInfoAction().write(0, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// New way of handling it 1.19.3+
|
|
||||||
handle.getPlayerInfoActions().write(0, Set.of(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PlayerInfoData> getData() {
|
|
||||||
return handle.getPlayerInfoDataLists().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(List<PlayerInfoData> value) {
|
|
||||||
handle.getPlayerInfoDataLists().write(0, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class WrapperPlayServerRelEntityMove extends AbstractPacket {
|
|
||||||
public static final PacketType TYPE =
|
|
||||||
PacketType.Play.Server.REL_ENTITY_MOVE;
|
|
||||||
|
|
||||||
public WrapperPlayServerRelEntityMove() {
|
|
||||||
super(new PacketContainer(TYPE), TYPE);
|
|
||||||
handle.getModifier().writeDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WrapperPlayServerRelEntityMove(PacketContainer packet) {
|
|
||||||
super(packet, TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve Entity ID.
|
|
||||||
* <p>
|
|
||||||
* Notes: entity's ID
|
|
||||||
*
|
|
||||||
* @return The current Entity ID
|
|
||||||
*/
|
|
||||||
public int getEntityID() {
|
|
||||||
return handle.getIntegers().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Entity ID.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setEntityID(int value) {
|
|
||||||
handle.getIntegers().write(0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the entity of the painting that will be spawned.
|
|
||||||
*
|
|
||||||
* @param world - the current world of the entity.
|
|
||||||
* @return The spawned entity.
|
|
||||||
*/
|
|
||||||
public Entity getEntity(World world) {
|
|
||||||
return handle.getEntityModifier(world).read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the entity of the painting that will be spawned.
|
|
||||||
*
|
|
||||||
* @param event - the packet event.
|
|
||||||
* @return The spawned entity.
|
|
||||||
*/
|
|
||||||
public Entity getEntity(@NotNull PacketEvent event) {
|
|
||||||
return getEntity(event.getPlayer().getWorld());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve DX.
|
|
||||||
*
|
|
||||||
* @return The current DX
|
|
||||||
*/
|
|
||||||
public double getDx() {
|
|
||||||
return handle.getShorts().read(0) / 4096D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set DX.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setDx(double value) {
|
|
||||||
handle.getShorts().write(0, (short) (value * 4096));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve DY.
|
|
||||||
*
|
|
||||||
* @return The current DY
|
|
||||||
*/
|
|
||||||
public double getDy() {
|
|
||||||
return handle.getShorts().read(1) / 4096D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set DY.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setDy(double value) {
|
|
||||||
handle.getShorts().write(1, (short) (value * 4096));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve DZ.
|
|
||||||
*
|
|
||||||
* @return The current DZ
|
|
||||||
*/
|
|
||||||
public double getDz() {
|
|
||||||
return handle.getShorts().read(2) / 4096D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set DZ.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setDz(double value) {
|
|
||||||
handle.getShorts().write(2, (short) (value * 4096));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the yaw of the current entity.
|
|
||||||
*
|
|
||||||
* @return The current Yaw
|
|
||||||
*/
|
|
||||||
public float getYaw() {
|
|
||||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the yaw of the current entity.
|
|
||||||
*
|
|
||||||
* @param value - new yaw.
|
|
||||||
*/
|
|
||||||
public void setYaw(float value) {
|
|
||||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the pitch of the current entity.
|
|
||||||
*
|
|
||||||
* @return The current pitch
|
|
||||||
*/
|
|
||||||
public float getPitch() {
|
|
||||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pitch of the current entity.
|
|
||||||
*
|
|
||||||
* @param value - new pitch.
|
|
||||||
*/
|
|
||||||
public void setPitch(float value) {
|
|
||||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve On Ground.
|
|
||||||
*
|
|
||||||
* @return The current On Ground
|
|
||||||
*/
|
|
||||||
public boolean getOnGround() {
|
|
||||||
return handle.getBooleans().read(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set On Ground.
|
|
||||||
*
|
|
||||||
* @param value - new value.
|
|
||||||
*/
|
|
||||||
public void setOnGround(boolean value) {
|
|
||||||
handle.getBooleans().write(0, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,32 +3,42 @@
|
|||||||
#
|
#
|
||||||
config-version: 1
|
config-version: 1
|
||||||
|
|
||||||
default-menu: defaultmenu
|
default-menu: defaultmenu_hats
|
||||||
debug-mode: false
|
debug-mode: false
|
||||||
database-settings:
|
database-settings:
|
||||||
type: sqlite # SQLite (Default), MYSQL, NONE
|
# SQLite (Default), MYSQL, NONE
|
||||||
|
type: sqlite
|
||||||
mysql:
|
mysql:
|
||||||
database: database
|
database: "database"
|
||||||
password: cherryBomb
|
password: "cherryBomb"
|
||||||
port: 3306
|
port: 3306
|
||||||
host: localhost
|
host: "localhost"
|
||||||
user: username
|
user: "username"
|
||||||
delay:
|
delay:
|
||||||
enabled: false # This is for if other plugins need to handle certain aspects of a player first.
|
# This is for if other plugins need to handle certain aspects of a player first.
|
||||||
delay: 20 # In ticks
|
enabled: false
|
||||||
|
# Delay in ticks from when a player joins
|
||||||
|
delay: 20
|
||||||
cosmetic-settings:
|
cosmetic-settings:
|
||||||
tick-period: 20 # In ticks, determines how many times a player cosmetics should be updated. -1 to disable.
|
# In ticks, determines how many times a player cosmetics should be updated. -1 to disable.
|
||||||
# Ticking periods is something that ensures new players near a player get the packets to actually apply to the user.
|
# Ticking periods is something that ensures new players near a player get the packets to actually apply to the user.
|
||||||
|
tick-period: 20
|
||||||
|
|
||||||
unapply-on-death: false # If when a player dies, their cosmetics should be unapplied. If this is true, use hmccosmetics.unapplydeath.bypass to bypass
|
# If when a player dies, their cosmetics should be unapplied. If this is true, use hmccosmetics.unapplydeath.bypass to bypass
|
||||||
force-permission-join: true # Checks a player permission if they can have a cosmetic when they join the server.
|
unapply-on-death: false
|
||||||
force-show-join: false # If the plugin should force show a player's cosmetics when they join the server.
|
# Checks a player permission if they can have a cosmetic when they join the server.
|
||||||
|
force-permission-join: true
|
||||||
|
# If the plugin should attempt to force show a player's cosmetics when they join the server by removing all hidden flags.
|
||||||
|
force-show-join: false
|
||||||
|
|
||||||
# This determines what to process what areas to process placeholders when displaying the item to the user.
|
# This determines what to process what areas to process placeholders when displaying the item to the user.
|
||||||
# This can be heavy on servers with a lot of players, so if experiencing lag issues relating to setting display/lores of items, disable this.
|
# This can be heavy on servers with a lot of players, so if experiencing lag issues relating to setting display/lores of items, disable this.
|
||||||
item-processing:
|
item-processing:
|
||||||
display-name: true
|
display-name: false
|
||||||
lore: true
|
lore: false
|
||||||
|
|
||||||
|
# This prevents the offhand from being swapped with the mainhand. Only affects if a user has a cosmetic in their offhand
|
||||||
|
offhand-prevent-swapping: false
|
||||||
|
|
||||||
# This is a list of worlds that cosmetics are hidden in. When a player enters one of these worlds, their cosmetics will be hidden.
|
# This is a list of worlds that cosmetics are hidden in. When a player enters one of these worlds, their cosmetics will be hidden.
|
||||||
disabled-worlds:
|
disabled-worlds:
|
||||||
@@ -41,13 +51,9 @@ cosmetic-settings:
|
|||||||
- "SPECTATOR"
|
- "SPECTATOR"
|
||||||
|
|
||||||
# This make it so it always sends the riding packets for the backpack. This sends more packets but is more reliable for servers which modify player passengers.
|
# This make it so it always sends the riding packets for the backpack. This sends more packets but is more reliable for servers which modify player passengers.
|
||||||
backpack-force-riding-packet: false
|
backpack-force-riding-packet: true
|
||||||
# This prevents the backpack from being dark when the player is below a block at the expense of making the backpack bright
|
# This prevents the backpack from being dark when the player is below a block at the expense of making the backpack bright
|
||||||
backpack-prevent-darkness: true
|
backpack-prevent-darkness: true
|
||||||
# This helps reduce the amount of packets sent for packet entities, but reduces accuracy of the entity. This is in milliseconds. -1 to disable.
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
slot-options:
|
slot-options:
|
||||||
helmet:
|
helmet:
|
||||||
@@ -85,6 +91,7 @@ cosmetic-settings:
|
|||||||
x: 0.5
|
x: 0.5
|
||||||
y: 3
|
y: 3
|
||||||
z: 0.5
|
z: 0.5
|
||||||
|
|
||||||
menu-settings:
|
menu-settings:
|
||||||
click-cooldown:
|
click-cooldown:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -96,23 +103,23 @@ menu-settings:
|
|||||||
# The shading is done through the title and by shifting textures around. This is done by offsets.
|
# The shading is done through the title and by shifting textures around. This is done by offsets.
|
||||||
# Only Nexo is support by default. Vanilla can't properly handle it without a lot of unicodes and ItemsAdder adds weird offsets and decolors it. (This is why it is disabled by default)
|
# Only Nexo is support by default. Vanilla can't properly handle it without a lot of unicodes and ItemsAdder adds weird offsets and decolors it. (This is why it is disabled by default)
|
||||||
enabled: false # Default of menus having shading. This can be toggled individually in menus with "shading: true/false"
|
enabled: false # Default of menus having shading. This can be toggled individually in menus with "shading: true/false"
|
||||||
first-row-shift: "<shift:-169>" # Nexo: "<shift:-169>"
|
first-row-shift: "<shift:-153>" # Nexo: "<shift:-153>"
|
||||||
sequent-row-shift: " <shift:-169>" # Nexo: " <shift:-169>" (Space is important here!)
|
sequent-row-shift: " <shift:-153>" # Nexo: " <shift:-153>" (Space is important here!)
|
||||||
individual-column-shift: "<shift:-3>" # Nexo: "<shift:-3>"
|
individual-column-shift: "<shift:-3>" # Nexo: "<shift:-3>"
|
||||||
background: "<glyph:shade_row_<row>:colorable> " # Nexo: "<glyph:shade_row_<row>:colorable>
|
background: "<glyph:hmcc_shade_row_<row>:colorable> " # Nexo: "<glyph:shade_row_<row>:colorable>
|
||||||
clear-background: "<glyph:clear_row_<row>:colorable> " # Nexo: "<glyph:clear_row_<row>:colorable> "
|
clear-background: "<glyph:hmcc_clear_row_<row>:colorable> " # Nexo: "<glyph:clear_row_<row>:colorable> "
|
||||||
#These use MiniMessage for color! https://docs.advntr.dev/minimessage/format.html#color
|
#These use MiniMessage for color! https://docs.advntr.dev/minimessage/format.html#color
|
||||||
equipped-cosmetic-color: "<yellow>"
|
equipped-cosmetic-color: "<yellow>"
|
||||||
equipable-cosmetic-color: "<green>"
|
equipable-cosmetic-color: "<green>"
|
||||||
locked-cosmetic-color: "<red>"
|
locked-cosmetic-color: "<red>"
|
||||||
cosmetic-type:
|
cosmetic-type:
|
||||||
# This allows you to specify if it should require a special click type for the interaction to work.
|
# This allows you to specify if it should require a special click type for the interaction to work.
|
||||||
equip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/1.20/org/bukkit/event/inventory/ClickType.html
|
equip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/org/bukkit/event/inventory/ClickType.html
|
||||||
unequip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/1.20/org/bukkit/event/inventory/ClickType.html
|
unequip-click: "ANY" # ANY or ClickType, https://jd.papermc.io/paper/org/bukkit/event/inventory/ClickType.html
|
||||||
dye-menu:
|
dye-menu:
|
||||||
# If you use ItemsAdder, set this to "<white>:img_offset_-8::img_dye_menu:"
|
# If you use ItemsAdder, set this to "<white>:img_offset_-8::img_hmcc_dye_menu:"
|
||||||
# If you use Oraxen, set this to "<white><s:-8><g:dye_menu>"
|
# If you use Oraxen, set this to "<white><s:-8><g:hmcc_dye_menu>"
|
||||||
# If you use Nexo, set this to "<white><shift:-8><glyph:dye_menu>"
|
# If you use Nexo, set this to "<white><shift:-8><glyph:hmcc_dye_menu>"
|
||||||
title: "<white>"
|
title: "<white>"
|
||||||
input-slot: 10
|
input-slot: 10
|
||||||
output-slot: 16
|
output-slot: 16
|
||||||
@@ -122,7 +129,8 @@ hook-settings:
|
|||||||
# could cause console spam as HMCCosmetics has to reload itself as well.
|
# could cause console spam as HMCCosmetics has to reload itself as well.
|
||||||
reload-on-change: false
|
reload-on-change: false
|
||||||
nexo:
|
nexo:
|
||||||
# This causes the plugin to reload itself after any Nexo change. This keeps the plugin fully up to date with Nexo
|
# This causes the plugin to reload itself after any Nexo change. This keeps the plugin fully up to date with Nexo, but
|
||||||
|
# could cause console spam as HMCCosmetics has to reload itself as well.
|
||||||
reload-on-change: true
|
reload-on-change: true
|
||||||
worldguard:
|
worldguard:
|
||||||
# Checks worldguard regions for HMCC flags. If set to false, flags will not work properly.
|
# Checks worldguard regions for HMCC flags. If set to false, flags will not work properly.
|
||||||
@@ -170,8 +178,10 @@ wardrobe:
|
|||||||
title-fade-out: 1000 # milliseconds
|
title-fade-out: 1000 # milliseconds
|
||||||
wardrobes:
|
wardrobes:
|
||||||
default:
|
default:
|
||||||
distance: -1 # Distance in blocks that a player can interact with the wardrobe. -1 to ignore.
|
# Distance in blocks that a player can interact with the wardrobe. -1 to ignore.
|
||||||
permission: "hmccosmetics.wardrobe.default" # Permission required to use the wardrobe.
|
distance: -1
|
||||||
|
# Permission required to use the wardrobe.
|
||||||
|
permission: "hmccosmetics.wardrobe.default"
|
||||||
default-menu: defaultmenu
|
default-menu: defaultmenu
|
||||||
npc-location:
|
npc-location:
|
||||||
world: "world"
|
world: "world"
|
||||||
|
|||||||
@@ -1,180 +0,0 @@
|
|||||||
title: "<white>"
|
|
||||||
rows: 6
|
|
||||||
refresh-rate: 20 # Set to -1 or remove to disable auto-updating, leading to it only using event-based updates.
|
|
||||||
items:
|
|
||||||
beanie:
|
|
||||||
slots:
|
|
||||||
- 0
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:beanie
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_beanie%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_beanie%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: beanie
|
|
||||||
backpack:
|
|
||||||
slots:
|
|
||||||
- 1
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:backpack
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_backpack%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_backpack%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: backpack
|
|
||||||
future_wings:
|
|
||||||
slots:
|
|
||||||
- 2
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:future_wings
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_future_wings%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_future_wings%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: future_wings
|
|
||||||
lantern_cosmetic:
|
|
||||||
slots:
|
|
||||||
- 3
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:lantern_cosmetic
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_lantern_cosmetic%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_lantern_cosmetic%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: lantern_cosmetic
|
|
||||||
baseball_hat:
|
|
||||||
slots:
|
|
||||||
- 4
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:baseball_hat
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_baseball_hat%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_baseball_hat%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: baseball_hat
|
|
||||||
frog_hat:
|
|
||||||
slots:
|
|
||||||
- 5
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:frog_hat
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_frog_hat%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_frog_hat%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: frog_hat
|
|
||||||
jetpack:
|
|
||||||
slots:
|
|
||||||
- 6
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:jetpack
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_jetpack%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_jetpack%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: jetpack
|
|
||||||
hammer:
|
|
||||||
slots:
|
|
||||||
- 7
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:hammer
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_hammer%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_hammer%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: hammer
|
|
||||||
chestplate:
|
|
||||||
slots:
|
|
||||||
- 8
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:chestplate
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_chestplate%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_chestplate%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: chestplate
|
|
||||||
pants:
|
|
||||||
slots:
|
|
||||||
- 9
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:pants
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_pants%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_pants%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: pants
|
|
||||||
boots:
|
|
||||||
slots:
|
|
||||||
- 10
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:boots
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_boots%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_boots%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: boots
|
|
||||||
kite:
|
|
||||||
slots:
|
|
||||||
- 11
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:kite
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_kite%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_kite%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: kite
|
|
||||||
explorer_backpack:
|
|
||||||
slots:
|
|
||||||
- 12
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:explorer_backpack
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_explorer_backpack%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_explorer_backpack%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: explorer_backpack
|
|
||||||
garbage_truck_balloon:
|
|
||||||
slots:
|
|
||||||
- 13
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:garbage_truck_balloon
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_garbage_truck_balloon%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_garbage_truck_balloon%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: garbage_truck_balloon
|
|
||||||
earth_day_grabber:
|
|
||||||
slots:
|
|
||||||
- 14
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:earth_day_grabber
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_earth_day_grabber%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_earth_day_grabber%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: earth_day_grabber
|
|
||||||
hibiscus_flower:
|
|
||||||
slots:
|
|
||||||
- 15
|
|
||||||
item:
|
|
||||||
material: hmccosmetics:hibiscus_flower
|
|
||||||
lore:
|
|
||||||
- ""
|
|
||||||
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_hibiscus_flower%"
|
|
||||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_hibiscus_flower%"
|
|
||||||
type: cosmetic
|
|
||||||
cosmetic: hibiscus_flower
|
|
||||||
99
common/src/main/resources/menus/defaultmenu_backpacks.yml
Executable file
99
common/src/main/resources/menus/defaultmenu_backpacks.yml
Executable file
@@ -0,0 +1,99 @@
|
|||||||
|
title: "<white>"
|
||||||
|
rows: 6
|
||||||
|
items:
|
||||||
|
backpack:
|
||||||
|
slots:
|
||||||
|
- 1
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:backpack
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_backpack%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_backpack%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: backpack
|
||||||
|
future_wings:
|
||||||
|
slots:
|
||||||
|
- 2
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:future_wings
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_future_wings%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_future_wings%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: future_wings
|
||||||
|
jetpack:
|
||||||
|
slots:
|
||||||
|
- 3
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:jetpack
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_jetpack%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_jetpack%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: jetpack
|
||||||
|
explorer_backpack:
|
||||||
|
slots:
|
||||||
|
- 4
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:explorer_backpack
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_explorer_backpack%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_explorer_backpack%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: explorer_backpack
|
||||||
|
button_backpacks_menu:
|
||||||
|
slots:
|
||||||
|
- 0
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 18
|
||||||
|
name: "<blue>Backpack Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_backpacks"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hand_menu:
|
||||||
|
slots:
|
||||||
|
- 18
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 19
|
||||||
|
name: "<blue>Hand Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hands"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_balloon_menu:
|
||||||
|
slots:
|
||||||
|
- 27
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 20
|
||||||
|
name: "<blue>Balloon Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_balloons"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hats_menu:
|
||||||
|
slots:
|
||||||
|
- 36
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 17
|
||||||
|
name: "<blue>Hat Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hats"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
77
common/src/main/resources/menus/defaultmenu_balloons.yml
Executable file
77
common/src/main/resources/menus/defaultmenu_balloons.yml
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
title: "<white>"
|
||||||
|
rows: 6
|
||||||
|
items:
|
||||||
|
garbage_truck_balloon:
|
||||||
|
slots:
|
||||||
|
- 1
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:garbage_truck_balloon
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_garbage_truck_balloon%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_garbage_truck_balloon%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: garbage_truck_balloon
|
||||||
|
kite:
|
||||||
|
slots:
|
||||||
|
- 2
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:kite
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_kite%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_kite%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: kite
|
||||||
|
button_backpacks_menu:
|
||||||
|
slots:
|
||||||
|
- 27
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 18
|
||||||
|
name: "<blue>Backpack Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_backpacks"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hand_menu:
|
||||||
|
slots:
|
||||||
|
- 36
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 19
|
||||||
|
name: "<blue>Hand Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hands"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_balloon_menu:
|
||||||
|
slots:
|
||||||
|
- 0
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 20
|
||||||
|
name: "<blue>Balloon Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_balloons"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hats_menu:
|
||||||
|
slots:
|
||||||
|
- 18
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 17
|
||||||
|
name: "<blue>Hat Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hats"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
99
common/src/main/resources/menus/defaultmenu_hands.yml
Executable file
99
common/src/main/resources/menus/defaultmenu_hands.yml
Executable file
@@ -0,0 +1,99 @@
|
|||||||
|
title: "<white>"
|
||||||
|
rows: 6
|
||||||
|
items:
|
||||||
|
lantern_cosmetic:
|
||||||
|
slots:
|
||||||
|
- 1
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:lantern_cosmetic
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_lantern_cosmetic%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_lantern_cosmetic%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: lantern_cosmetic
|
||||||
|
hammer:
|
||||||
|
slots:
|
||||||
|
- 2
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:hammer
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_hammer%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_hammer%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: hammer
|
||||||
|
earth_day_grabber:
|
||||||
|
slots:
|
||||||
|
- 3
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:earth_day_grabber
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_earth_day_grabber%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_earth_day_grabber%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: earth_day_grabber
|
||||||
|
hibiscus_flower:
|
||||||
|
slots:
|
||||||
|
- 4
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:hibiscus_flower
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_hibiscus_flower%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_hibiscus_flower%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: hibiscus_flower
|
||||||
|
button_backpacks_menu:
|
||||||
|
slots:
|
||||||
|
- 36
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 18
|
||||||
|
name: "<blue>Backpack Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_backpacks"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hand_menu:
|
||||||
|
slots:
|
||||||
|
- 0
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 19
|
||||||
|
name: "<blue>Hand Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hands"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_balloon_menu:
|
||||||
|
slots:
|
||||||
|
- 18
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 20
|
||||||
|
name: "<blue>Balloon Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_balloons"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hats_menu:
|
||||||
|
slots:
|
||||||
|
- 27
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 17
|
||||||
|
name: "<blue>Hat Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hats"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
88
common/src/main/resources/menus/defaultmenu_hats.yml
Executable file
88
common/src/main/resources/menus/defaultmenu_hats.yml
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
title: "<white>"
|
||||||
|
rows: 6
|
||||||
|
items:
|
||||||
|
beanie:
|
||||||
|
slots:
|
||||||
|
- 1
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:beanie
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_beanie%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_beanie%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: beanie
|
||||||
|
baseball_hat:
|
||||||
|
slots:
|
||||||
|
- 2
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:baseball_hat
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_baseball_hat%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_baseball_hat%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: baseball_hat
|
||||||
|
frog_hat:
|
||||||
|
slots:
|
||||||
|
- 3
|
||||||
|
item:
|
||||||
|
material: hmccosmetics:frog_hat
|
||||||
|
lore:
|
||||||
|
- ""
|
||||||
|
- "<gray>Enabled: <#6D9DC5>%HMCCosmetics_equipped_frog_hat%"
|
||||||
|
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_frog_hat%"
|
||||||
|
type: cosmetic
|
||||||
|
cosmetic: frog_hat
|
||||||
|
button_hats_menu:
|
||||||
|
slots:
|
||||||
|
- 0
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 17
|
||||||
|
name: "<blue>Hat Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hats"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_backpacks_menu:
|
||||||
|
slots:
|
||||||
|
- 18
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 18
|
||||||
|
name: "<blue>Backpack Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_backpacks"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_hand_menu:
|
||||||
|
slots:
|
||||||
|
- 27
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 19
|
||||||
|
name: "<blue>Hand Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_hands"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
|
button_balloon_menu:
|
||||||
|
slots:
|
||||||
|
- 36
|
||||||
|
item:
|
||||||
|
material: PAPER
|
||||||
|
model-data: 20
|
||||||
|
name: "<blue>Balloon Cosmetics"
|
||||||
|
amount: 1
|
||||||
|
type: empty
|
||||||
|
actions:
|
||||||
|
any:
|
||||||
|
- "[MENU] defaultmenu_balloons"
|
||||||
|
- "[SOUND] minecraft:ui.button.click 1 1"
|
||||||
Reference in New Issue
Block a user