mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-20 07:29:15 +00:00
Compare commits
160 Commits
display-en
...
v2.7.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8f035bbe2 | ||
|
|
301fd6a349 | ||
|
|
90b71e7dc9 | ||
|
|
e6827cdf72 | ||
|
|
1212ab2025 | ||
|
|
e31f000de6 | ||
|
|
70028598d5 | ||
|
|
07b772d228 | ||
|
|
065e48c125 | ||
|
|
49eb1d61ef | ||
|
|
9e1a30025f | ||
|
|
76429ed041 | ||
|
|
f5a01c0104 | ||
|
|
545f258f90 | ||
|
|
720437212b | ||
|
|
d932732d9b | ||
|
|
1118be1153 | ||
|
|
1dc549d645 | ||
|
|
4136d19396 | ||
|
|
52de7425e4 | ||
|
|
f470e55142 | ||
|
|
470de3b749 | ||
|
|
ea72499826 | ||
|
|
6b19bf442a | ||
|
|
436de38102 | ||
|
|
4bb00071d4 | ||
|
|
650cf75168 | ||
|
|
0d07e8a267 | ||
|
|
b7ec587d7d | ||
|
|
e807c7e2f7 | ||
|
|
15e1f0aaa9 | ||
|
|
f1e975f940 | ||
|
|
89fba800a4 | ||
|
|
863275a2ce | ||
|
|
b516cfced4 | ||
|
|
28034318ac | ||
|
|
c2e4764ace | ||
|
|
948bfb17f5 | ||
|
|
6c98b7696a | ||
|
|
2c4638fa47 | ||
|
|
ced2fe7b03 | ||
|
|
3a56f074fa | ||
|
|
dca5abe4ec | ||
|
|
1dd54ea1cb | ||
|
|
b81af97573 | ||
|
|
74d64b16d2 | ||
|
|
2174ec6124 | ||
|
|
1de84bce6f | ||
|
|
3aa5939225 | ||
|
|
44650250c5 | ||
|
|
49fff9b650 | ||
|
|
190f66a990 | ||
|
|
8a34f100d3 | ||
|
|
79687a22fc | ||
|
|
f5fac4e048 | ||
|
|
eac0812dbb | ||
|
|
93f5bfbb2a | ||
|
|
94cba225a6 | ||
|
|
ab614d8b07 | ||
|
|
e7fd39a077 | ||
|
|
530cdb282b | ||
|
|
97534f6916 | ||
|
|
22fb52acc6 | ||
|
|
cf0da580e0 | ||
|
|
64a590b581 | ||
|
|
afb3218bc1 | ||
|
|
170911a6a1 | ||
|
|
ea5b878f74 | ||
|
|
88af1cd68e | ||
|
|
34237e0a45 | ||
|
|
a037487497 | ||
|
|
e7b1fda73e | ||
|
|
c591641754 | ||
|
|
2a0aa1593a | ||
|
|
330723a45c | ||
|
|
f6a1438299 | ||
|
|
1f0f8e5f70 | ||
|
|
216c05ed9b | ||
|
|
89fbacafac | ||
|
|
8c45bfc76b | ||
|
|
4ad3c02d88 | ||
|
|
477729242b | ||
|
|
e96d06892a | ||
|
|
5b1b91f119 | ||
|
|
446e629474 | ||
|
|
57c2cd0719 | ||
|
|
8f2a01b348 | ||
|
|
6fe5817fd7 | ||
|
|
663b3d1647 | ||
|
|
bf0a372edd | ||
|
|
5d0237e28c | ||
|
|
349311cb58 | ||
|
|
a1098641b5 | ||
|
|
8c0ca5083d | ||
|
|
c42ecadd90 | ||
|
|
735386718e | ||
|
|
95459cc2d2 | ||
|
|
fe52edd833 | ||
|
|
d659128ae4 | ||
|
|
397eebf38f | ||
|
|
e18690496f | ||
|
|
c522581d46 | ||
|
|
c31d2e1aee | ||
|
|
9879c82d40 | ||
|
|
1873f5b9b5 | ||
|
|
68d94be743 | ||
|
|
14e38e7974 | ||
|
|
5cc19ab2db | ||
|
|
93b1c20c40 | ||
|
|
49435436cb | ||
|
|
0477e801a6 | ||
|
|
5779d278a9 | ||
|
|
0a8821d3e8 | ||
|
|
e96e9e00bb | ||
|
|
217fb5d332 | ||
|
|
6636cc9548 | ||
|
|
c3fcf760d7 | ||
|
|
7116767e22 | ||
|
|
0877165f9f | ||
|
|
b43466a793 | ||
|
|
401e6170e6 | ||
|
|
782eb4c464 | ||
|
|
1ef2c6b631 | ||
|
|
c7667b2dc2 | ||
|
|
e4c4933d46 | ||
|
|
1f94192772 | ||
|
|
8ebcea5465 | ||
|
|
4c7ccc06ca | ||
|
|
667f58ff4b | ||
|
|
69d318c4b0 | ||
|
|
0414f3be90 | ||
|
|
402203b4c2 | ||
|
|
6dcaf06ebe | ||
|
|
1b6adca00e | ||
|
|
0dce5822e3 | ||
|
|
0f1b75f09e | ||
|
|
19192c46a5 | ||
|
|
62a9e7d1ac | ||
|
|
06077201f9 | ||
|
|
b2795a705e | ||
|
|
1e6734bf6f | ||
|
|
ad382e5d9e | ||
|
|
6458a1e316 | ||
|
|
279d6edc34 | ||
|
|
439dc85aa3 | ||
|
|
60e23411dc | ||
|
|
33fb680c22 | ||
|
|
536b7ebdec | ||
|
|
5da95f2f5b | ||
|
|
30f4a84241 | ||
|
|
f34e126c85 | ||
|
|
d7d0f27e49 | ||
|
|
f42937a6d0 | ||
|
|
c8b7430998 | ||
|
|
42de76d84d | ||
|
|
5102fd77b7 | ||
|
|
9c66d4ee81 | ||
|
|
7ade2d9227 | ||
|
|
7b43b42740 | ||
|
|
25f050f387 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -115,3 +115,4 @@ run/
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
/qodana.yaml
|
||||
|
||||
@@ -2,13 +2,13 @@ import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||
|
||||
plugins {
|
||||
id("java")
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("xyz.jpenilla.run-paper") version "2.0.0"
|
||||
id("com.gradleup.shadow") version "8.3.2"
|
||||
id("xyz.jpenilla.run-paper") version "2.3.1"
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
|
||||
}
|
||||
|
||||
group = "com.hibiscusmc"
|
||||
version = "2.7.3-DEV"
|
||||
version = "2.7.7${getGitCommitHash()}"
|
||||
|
||||
allprojects {
|
||||
apply(plugin = "java")
|
||||
@@ -18,7 +18,7 @@ allprojects {
|
||||
mavenCentral()
|
||||
|
||||
// Paper Repo
|
||||
maven("https://papermc.io/repo/repository/maven-public/")
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
|
||||
// Jitpack
|
||||
@@ -49,9 +49,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateChecker
|
||||
maven("https://hub.jeff-media.com/nexus/repository/jeff-media-public/")
|
||||
|
||||
// ParticleHelper
|
||||
maven("https://repo.bytecode.space/repository/maven-public/")
|
||||
|
||||
@@ -67,6 +64,9 @@ allprojects {
|
||||
// Eco-Suite/Auxilor Repo
|
||||
maven("https://repo.auxilor.io/repository/maven-public/")
|
||||
|
||||
// Triumph GUI
|
||||
maven("https://repo.triumphteam.dev/snapshots")
|
||||
|
||||
// Hibiscus Commons
|
||||
maven("https://repo.hibiscusmc.com/releases")
|
||||
}
|
||||
@@ -75,31 +75,42 @@ allprojects {
|
||||
compileOnly(fileTree("${project.rootDir}/lib") { include("*.jar") })
|
||||
compileOnly("com.mojang:authlib:1.5.25")
|
||||
//compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
|
||||
compileOnly("org.jetbrains:annotations:24.1.0")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
|
||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.2")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
|
||||
compileOnly("it.unimi.dsi:fastutil:8.5.13")
|
||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.6")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.12")
|
||||
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:BetterCommand:1.3") //BetterCommand library
|
||||
//compileOnly("it.unimi.dsi:fastutil:8.5.14")
|
||||
compileOnly("org.projectlombok:lombok:1.18.34")
|
||||
compileOnly("me.lojosho:HibiscusCommons:0.4.1")
|
||||
compileOnly("me.lojosho:HibiscusCommons:0.6.2-d21ebed8")
|
||||
|
||||
// Handled by Spigot Library Loader
|
||||
compileOnly("net.kyori:adventure-api:4.17.0")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:4.17.0")
|
||||
compileOnly("net.kyori:adventure-platform-bukkit:4.3.3")
|
||||
compileOnly("net.kyori:adventure-api:4.19.0")
|
||||
compileOnly("net.kyori:adventure-text-minimessage:4.19.0")
|
||||
compileOnly("net.kyori:adventure-platform-bukkit:4.3.4")
|
||||
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.34")
|
||||
testCompileOnly("org.projectlombok:lombok:1.18.34")
|
||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.34")
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.36")
|
||||
testCompileOnly("org.projectlombok:lombok:1.18.36")
|
||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.36")
|
||||
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.10") {
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.12-SNAPSHOT") {
|
||||
exclude("net.kyori") // Already have adventure API
|
||||
}
|
||||
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
|
||||
implementation("com.ticxo.playeranimator:PlayerAnimator:R1.2.7")
|
||||
}
|
||||
|
||||
tasks {
|
||||
javadoc {
|
||||
// javadoc spec has these added.
|
||||
(options as StandardJavadocDocletOptions)
|
||||
.tags("apiNote:a:API:", "implSpec:a:Implementation Requirements", "implNote:a:Implementation Note:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -123,15 +134,21 @@ tasks {
|
||||
}
|
||||
|
||||
runServer {
|
||||
minecraftVersion("1.20.6")
|
||||
minecraftVersion("1.21.4")
|
||||
|
||||
downloadPlugins {
|
||||
hangar("PlaceholderAPI", "2.11.6")
|
||||
url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
|
||||
url("https://download.luckperms.net/1567/bukkit/loader/LuckPerms-Bukkit-5.4.150.jar")
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
mergeServiceFiles()
|
||||
|
||||
relocate("dev.triumphteam.gui", "com.hisbiscusmc.hmccosmetics.gui")
|
||||
relocate("com.owen1212055.particlehelper", "com.hisbiscusmc.hmccosmetics.particlehelper")
|
||||
relocate("com.ticxo.playeranimator", "com.hisbiscusmc.hmccosmetics.playeranimator")
|
||||
relocate("dev.triumphteam.gui", "com.hibiscusmc.hmccosmetics.shaded.gui")
|
||||
relocate("com.owen1212055.particlehelper", "com.hibiscusmc.hmccosmetics.shaded.particlehelper")
|
||||
relocate("com.ticxo.playeranimator", "com.hibiscusmc.hmccosmetics.shaded.playeranimator")
|
||||
archiveFileName.set("HMCCosmeticsRemapped-${project.version}.jar")
|
||||
|
||||
dependencies {
|
||||
@@ -156,10 +173,10 @@ tasks {
|
||||
bukkit {
|
||||
load = BukkitPluginDescription.PluginLoadOrder.POSTWORLD
|
||||
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
|
||||
apiVersion = "1.19"
|
||||
apiVersion = "1.20"
|
||||
authors = listOf("LoJoSho")
|
||||
depend = listOf("HibiscusCommons", "ProtocolLib")
|
||||
softDepend = listOf("ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
||||
softDepend = listOf("BetterHud", "ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
||||
version = "${project.version}"
|
||||
loadBefore = listOf(
|
||||
"Cosmin" // Fixes an issue with Cosmin loading before and taking /cosmetic, when messing with what we do.
|
||||
@@ -257,6 +274,28 @@ bukkit {
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21
|
||||
))
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
fun getGitCommitHash(): String {
|
||||
var includeHash = true
|
||||
val includeHashVariable = System.getenv("HMCC_INCLUDE_HASH")
|
||||
|
||||
if (!includeHashVariable.isNullOrEmpty()) includeHash = includeHashVariable.toBoolean()
|
||||
|
||||
if (includeHash) {
|
||||
return try {
|
||||
val process = ProcessBuilder("git", "rev-parse", "--short", "HEAD")
|
||||
.redirectErrorStream(true)
|
||||
.start()
|
||||
|
||||
process.inputStream.bufferedReader().use { "-" + it.readLine().trim() }
|
||||
} catch (e: Exception) {
|
||||
"-unknown" // Fallback if Git is not available or an error occurs
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -4,8 +4,10 @@ plugins {
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17
|
||||
))
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
||||
@@ -14,12 +14,14 @@ import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.hooks.items.HookHMCCosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.hooks.misc.HookBetterHud;
|
||||
import com.hibiscusmc.hmccosmetics.hooks.placeholders.HMCPlaceholderExpansion;
|
||||
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook;
|
||||
import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGListener;
|
||||
import com.hibiscusmc.hmccosmetics.listener.PaperPlayerGameListener;
|
||||
import com.hibiscusmc.hmccosmetics.listener.PlayerConnectionListener;
|
||||
import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener;
|
||||
import com.hibiscusmc.hmccosmetics.listener.ServerListener;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
@@ -51,6 +53,7 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
public HMCCosmeticsPlugin() {
|
||||
super(13873, 1879);
|
||||
new HookHMCCosmetics();
|
||||
new HookBetterHud();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,8 +68,8 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
if (!Path.of(getDataFolder().getPath() + "/cosmetics/").toFile().exists()) saveResource("cosmetics/defaultcosmetics.yml", false);
|
||||
if (!Path.of(getDataFolder().getPath() + "/menus/").toFile().exists()) saveResource("menus/defaultmenu.yml", false);
|
||||
|
||||
// Player Animator
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) PlayerAnimatorImpl.initialize(this); // PlayerAnimator does not support 1.20.2 yet
|
||||
// Player Animator ~ Do no longer support running this on a version that PlayerAnimator is supported
|
||||
// if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) PlayerAnimatorImpl.initialize(this); // PlayerAnimator does not support 1.20.2 yet
|
||||
|
||||
// Configuration Sync
|
||||
final File configFile = Path.of(getInstance().getDataFolder().getPath(), "config.yml").toFile();
|
||||
@@ -94,7 +97,8 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
// Listener
|
||||
getServer().getPluginManager().registerEvents(new PlayerConnectionListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new PlayerGameListener(), this);
|
||||
// Taken from PaperLib
|
||||
getServer().getPluginManager().registerEvents(new ServerListener(), this);
|
||||
|
||||
if (HibiscusCommonsPlugin.isOnPaper()) {
|
||||
getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this);
|
||||
}
|
||||
@@ -225,7 +229,7 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.isEmotesEnabled() && (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1"))) EmoteManager.loadEmotes(); // PlayerAnimator does not support 1.20.2 yet
|
||||
//if (Settings.isEmotesEnabled() && (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1"))) EmoteManager.loadEmotes(); // PlayerAnimator does not support 1.20.2 yet
|
||||
|
||||
getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
|
||||
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
|
||||
|
||||
@@ -2,116 +2,216 @@ package com.hibiscusmc.hmccosmetics.api;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticProvider;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUserProvider;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import me.lojosho.hibiscuscommons.nms.MinecraftVersion;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class HMCCosmeticsAPI {
|
||||
|
||||
/**
|
||||
* Attempts to get a cosmetic from HMCCosmetics
|
||||
*
|
||||
* @param cosmetic Cosmetic Id
|
||||
* @return A {@link Cosmetic} if exists or null if it does not
|
||||
*/
|
||||
@Nullable
|
||||
public static Cosmetic getCosmetic(@NotNull String cosmetic) {
|
||||
return Cosmetics.getCosmetic(cosmetic);
|
||||
/**
|
||||
* The main API class for HMCCosmetics. This class provides methods to interact with the plugin.
|
||||
*/
|
||||
public final class HMCCosmeticsAPI {
|
||||
private HMCCosmeticsAPI() {
|
||||
throw new UnsupportedOperationException("This class cannot be instantiated.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the CosmeticUser from an online user. If a player is offline it will return null.
|
||||
* A player maybe online but not have a CosmeticUser attached to them, either from delay specified in the config
|
||||
* or from a /reload. Always check if it's null!
|
||||
*
|
||||
* @param uuid Player Unique ID
|
||||
* @return A {@link CosmeticUser} if exists or null if it does not
|
||||
* Retrieves a {@link Cosmetic} associated with the specified id.
|
||||
* <p>
|
||||
* This method attempts to fetch a {@link Cosmetic} using the given id. If no {@link Cosmetic} exists
|
||||
* with the specified id, it will return {@code null}.
|
||||
* </p>
|
||||
* @param id the id of the {@link Cosmetic} to retrieve
|
||||
* @return the {@link Cosmetic} if it exists, or {@code null} if no cosmetic is associated with the given id
|
||||
*/
|
||||
@Nullable
|
||||
public static CosmeticUser getUser(@NotNull UUID uuid) {
|
||||
public static @Nullable Cosmetic getCosmetic(@NotNull String id) {
|
||||
return Cosmetics.getCosmetic(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the {@link CosmeticUser} associated with the specified player's {@link UUID}.
|
||||
* <p>
|
||||
* This method attempts to fetch a {@link CosmeticUser} for an online player. If the player is offline,
|
||||
* or if no {@link CosmeticUser} is currently associated with them, it will return {@code null}.
|
||||
* </p>
|
||||
* Note that a player may be online but not have a {@link CosmeticUser} attached due to:
|
||||
* <ul>
|
||||
* <li>A delay specified in the configuration</li>
|
||||
* <li>A recent server reload (e.g., via the {@code /reload} command)</li>
|
||||
* </ul>
|
||||
* Always perform a {@code null} check before using the returned object to ensure safe operation.
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player whose {@link CosmeticUser} is being retrieved
|
||||
* @return the {@link CosmeticUser} if it exists, or {@code null} if the player is offline or unassociated
|
||||
*/
|
||||
public static @Nullable CosmeticUser getUser(@NotNull UUID uuid) {
|
||||
return CosmeticUsers.getUser(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get a HMCCosmetics Menu. Returns null if no menu exists under that id.
|
||||
* Retrieves a {@link Menu} associated with the specified id, or {@code null} if no menu exists with the given id.
|
||||
*
|
||||
* @param id Menu ID
|
||||
* @return A {@link Menu} if exists or null if it does not
|
||||
* @param id the id of the menu to retrieve
|
||||
* @return the {@link Menu} if it exists, or {@code null} if no menu is associated with the given id
|
||||
*/
|
||||
@Nullable
|
||||
public static Menu getMenu(@NotNull String id) {
|
||||
public static @Nullable Menu getMenu(@NotNull String id) {
|
||||
return Menus.getMenu(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equips a cosmetic to a player. You can use getUser and getCosmetic to get the CosmeticUser and Cosmetic to equip.
|
||||
* @param user CosmeticUser to equip cosmetic to
|
||||
* @param cosmetic Cosmetic to equip
|
||||
* Equips a {@link Cosmetic} to a player. To retrieve the necessary {@code CosmeticUser} and {@code Cosmetic}, use the {@link #getUser}
|
||||
* and {@link #getCosmetic} methods respectively.
|
||||
*
|
||||
* @param user the {@link CosmeticUser} to equip the cosmetic to
|
||||
* @param cosmetic the {@link Cosmetic} to equip
|
||||
*/
|
||||
public static void equipCosmetic(@NotNull CosmeticUser user, @NotNull Cosmetic cosmetic) {
|
||||
equipCosmetic(user, cosmetic, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equips a cosmetic to a player with a color. You can use getUser and getCosmetic to get the CosmeticUser and Cosmetic to equip.
|
||||
* @param user CosmeticUser to equip cosmetic to
|
||||
* @param cosmetic Cosmetic to equip
|
||||
* @param color Color to apply to cosmetic
|
||||
* Equips a {@link Cosmetic} to a player with an optional color customization. To retrieve the necessary
|
||||
* {@code CosmeticUser} and {@code Cosmetic}, use the {@link #getUser} and {@link #getCosmetic} methods
|
||||
* respectively.
|
||||
*
|
||||
* @param user the {@link CosmeticUser} to equip the cosmetic to
|
||||
* @param cosmetic the {@link Cosmetic} to equip
|
||||
* @param color the color to apply to the cosmetic, or {@code null} if the cosmetic does not support color
|
||||
* customization
|
||||
*/
|
||||
public static void equipCosmetic(@NotNull CosmeticUser user, @NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||
user.addPlayerCosmetic(cosmetic, color);
|
||||
user.addCosmetic(cosmetic, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a cosmetic in cosmeticslot.
|
||||
* @param user The user to remove the cosmetic from
|
||||
* @param slot The slot to remove the cosmetic from
|
||||
* Removes a cosmetic from a specified slot for the given user.
|
||||
*
|
||||
* @param user the {@link CosmeticUser} from whom the cosmetic will be removed
|
||||
* @param slot the {@link CosmeticSlot} from which the cosmetic will be removed
|
||||
*/
|
||||
public static void unequipCosmetic(@NotNull CosmeticUser user, @NotNull CosmeticSlot slot) {
|
||||
user.removeCosmeticSlot(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all Cosmetics that are currently registered with HMCC. This list is immutable!
|
||||
* @return A list of all registered cosmetics
|
||||
* Retrieves a list of all cosmetics currently registered with HMCC.
|
||||
*
|
||||
* @return an {@code immutable} list containing all registered {@link Cosmetic} object
|
||||
*/
|
||||
public static List<Cosmetic> getAllCosmetics() {
|
||||
public static @NotNull List<Cosmetic> getAllCosmetics() {
|
||||
return List.copyOf(Cosmetics.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all CosmeticUsers that are currently registered with HMCC. This list is immutable!
|
||||
* @return A list of all registered CosmeticUsers
|
||||
* Retrieves a list of all cosmetic users currently registered with HMCC.
|
||||
*
|
||||
* @return an immutable list containing all registered {@link CosmeticUser} objects
|
||||
*/
|
||||
public static List<CosmeticUser> getAllCosmeticUsers() {
|
||||
public static @NotNull List<CosmeticUser> getAllCosmeticUsers() {
|
||||
return List.copyOf(CosmeticUsers.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the NMS version of the server as recognized by HMCCosmetics. This will be null until HMCC setup has been completed.
|
||||
* @return The NMS version of the server in String format
|
||||
* Retrieves a map of all cosmetic slots currently registered with HMCC.
|
||||
*
|
||||
* @return an immutable {@link Map} containing all registered cosmetic slots
|
||||
*/
|
||||
@Nullable
|
||||
public static String getNMSVersion() {
|
||||
return NMSHandlers.getVersion();
|
||||
public static @NotNull Map<String, CosmeticSlot> getAllCosmeticSlots() {
|
||||
return Map.copyOf(CosmeticSlot.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the HMCCosmetics version.
|
||||
* @return The HMCCosmetics version in String format
|
||||
* Registers a new cosmetic slot with the specified id. If a slot with the same id already exists,
|
||||
* the existing slot will be returned.
|
||||
*
|
||||
* <p>
|
||||
* The provided id will automatically be converted to uppercase when registering the slot.
|
||||
* </p>
|
||||
*
|
||||
* @param id the id for the cosmetic slot
|
||||
* @return the {@link CosmeticSlot} associated with the given id
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
@NotNull
|
||||
public static String getHMCCVersion() {
|
||||
public static @NotNull CosmeticSlot registerCosmeticSlot(@NotNull String id) {
|
||||
return CosmeticSlot.register(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new cosmetic user provider to use for constructing {@link CosmeticUser} instances.
|
||||
*
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if another plugin has already registered a provider
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
public static void registerCosmeticUserProvider(@NotNull CosmeticUserProvider provider) {
|
||||
CosmeticUsers.registerProvider(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current {@link CosmeticUserProvider} that is in use.
|
||||
*
|
||||
* @return the current {@link CosmeticUserProvider}
|
||||
*/
|
||||
public static @NotNull CosmeticUserProvider getCosmeticUserProvider() {
|
||||
return CosmeticUsers.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new cosmetic user provider to use for constructing {@link Cosmetic} instances.
|
||||
*
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if another plugin has already registered a provider
|
||||
* @apiNote this should be done in your {@link JavaPlugin#onLoad()} or it may error.
|
||||
*/
|
||||
public static void registerCosmeticProvider(@NotNull CosmeticProvider provider) {
|
||||
Cosmetics.registerProvider(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current {@link CosmeticProvider} that is in use.
|
||||
*
|
||||
* @return the current {@link CosmeticProvider}
|
||||
*/
|
||||
public static @NotNull CosmeticProvider getCosmeticProvider() {
|
||||
return Cosmetics.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the NMS version of the server as recognized by HMCCosmetics.
|
||||
*
|
||||
* <p>This value will be {@code null} until the HMCC setup has been completed. Ensure setup is finished
|
||||
* before attempting to access this version.</p>
|
||||
*
|
||||
* @return the NMS version of the server in string format, or {@code null} if setup is not complete.
|
||||
*/
|
||||
public static @Nullable String getNMSVersion() {
|
||||
MinecraftVersion version = NMSHandlers.getVersion();
|
||||
if (version == null) return null;
|
||||
return version.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the version of HMCCosmetics currently in use.
|
||||
*
|
||||
* @return the HMCCosmetics version in string format
|
||||
*/
|
||||
public static @NotNull String getHMCCVersion() {
|
||||
return HMCCosmeticsPlugin.getInstance().getDescription().getVersion();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,42 +6,50 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a cosmetic type not registered with HMCC default cosmetics is attempted to be registered. So if someone puts "test" in the config slot, and it's not a default cosmetic, this event will be called.
|
||||
* Called when an attempt is made to register a cosmetic type that is not part of the default HMCC cosmetics.
|
||||
* <p>
|
||||
* For example, if a user specifies "test" in the config slot, and it is not a default cosmetic, this event will be
|
||||
* triggered.
|
||||
* </p>
|
||||
*/
|
||||
public class CosmeticTypeRegisterEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final String id;
|
||||
private final ConfigurationNode config;
|
||||
|
||||
public CosmeticTypeRegisterEvent(String id, ConfigurationNode config) {
|
||||
public CosmeticTypeRegisterEvent(@NotNull String id, @NotNull ConfigurationNode config) {
|
||||
this.id = id;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the cosmetic trying to be registered. For example, "beanie" or "test"
|
||||
* @return The id. This is the key in the cosmetic config
|
||||
* Returns the id of the cosmetic attempting to be registered.
|
||||
*
|
||||
* @return the id of the cosmetic. This is the key in the cosmetic configuration.
|
||||
*/
|
||||
public String getId() {
|
||||
public @NotNull String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will already be in the nested node below the id in the config.
|
||||
* @return The cosmetic config node in the cosmetic config that was attempted to get registered
|
||||
* Retrieves the {@link ConfigurationNode} for the cosmetic that was attempted to be registered.
|
||||
* <p>
|
||||
* This node is nested below the id in the configuration.
|
||||
* </p>
|
||||
*
|
||||
* @return the configuration node for the cosmetic in the cosmetic configuration
|
||||
*/
|
||||
public ConfigurationNode getConfig() {
|
||||
public @NotNull ConfigurationNode getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,17 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when the plugin is set up and/or reloaded
|
||||
* Called when the plugin is set up and/or reloaded.
|
||||
*/
|
||||
public class HMCCosmeticSetupEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,22 +7,24 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player equips a cosmetic
|
||||
* Called when a player equips a {@link Cosmetic}.
|
||||
*/
|
||||
public class PlayerCosmeticEquipEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private Cosmetic cosmetic;
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerCosmeticEquipEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
|
||||
super(who);
|
||||
this.cosmetic = cosmetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Cosmetic} being equipped in this event
|
||||
* Gets the {@link Cosmetic} being equipped in this event.
|
||||
*
|
||||
* @return The {@link Cosmetic} which is being equipped in this event
|
||||
* @return the cosmetic which is being equipped in this event
|
||||
*/
|
||||
@NotNull
|
||||
public Cosmetic getCosmetic() {
|
||||
@@ -30,9 +32,9 @@ public class PlayerCosmeticEquipEvent extends PlayerCosmeticEvent implements Can
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Cosmetic} that the player will equip
|
||||
* Sets the {@link Cosmetic} that the player will equip.
|
||||
*
|
||||
* @param cosmetic The {@link Cosmetic} that the player will equip
|
||||
* @param cosmetic the cosmetic that the player will equip
|
||||
*/
|
||||
public void setCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
this.cosmetic = cosmetic;
|
||||
@@ -43,28 +45,17 @@ public class PlayerCosmeticEquipEvent extends PlayerCosmeticEvent implements Can
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from equipping the cosmetic
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,22 +5,22 @@ import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a cosmetic user related event
|
||||
* Represents an event related to a {@link CosmeticUser}.
|
||||
*/
|
||||
public abstract class PlayerCosmeticEvent extends Event {
|
||||
protected CosmeticUser user;
|
||||
public abstract class PlayerCosmeticEvent extends PlayerEvent {
|
||||
protected final CosmeticUser user;
|
||||
|
||||
public PlayerCosmeticEvent(@NotNull final CosmeticUser who) {
|
||||
public PlayerCosmeticEvent(@NotNull CosmeticUser who) {
|
||||
super(who.getUniqueId());
|
||||
user = who;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user involved in this event
|
||||
* Returns the {@link CosmeticUser} involved in this event.
|
||||
*
|
||||
* @return User who is involved in this event
|
||||
* @return the user who is involved in this event
|
||||
*/
|
||||
@NotNull
|
||||
public final CosmeticUser getUser() {
|
||||
public final @NotNull CosmeticUser getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,25 +6,26 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when cosmetics are hidden from a player
|
||||
* Called when cosmetics are hidden from a player.
|
||||
*/
|
||||
public class PlayerCosmeticHideEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final CosmeticUser.HiddenReason reason;
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerCosmeticHideEvent(@NotNull CosmeticUser who, @NotNull CosmeticUser.HiddenReason reason) {
|
||||
super(who);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link CosmeticUser.HiddenReason} as to why cosmetics are being hidden for the player
|
||||
* Gets the {@link CosmeticUser.HiddenReason} as to why cosmetics are being hidden for the player.
|
||||
*
|
||||
* @return The {@link CosmeticUser.HiddenReason} why cosmetics are being hidden for the player
|
||||
* @return the reason why cosmetics are being hidden for the player
|
||||
*/
|
||||
@NotNull
|
||||
public CosmeticUser.HiddenReason getReason() {
|
||||
public @NotNull CosmeticUser.HiddenReason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@@ -33,28 +34,17 @@ public class PlayerCosmeticHideEvent extends PlayerCosmeticEvent implements Canc
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from hiding cosmetics
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,12 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player has equipped a {@link Cosmetic}.
|
||||
*/
|
||||
public class PlayerCosmeticPostEquipEvent extends PlayerCosmeticEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private Cosmetic cosmetic;
|
||||
|
||||
public PlayerCosmeticPostEquipEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
|
||||
@@ -15,32 +19,29 @@ public class PlayerCosmeticPostEquipEvent extends PlayerCosmeticEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Cosmetic} being equipped in this event
|
||||
* Gets the {@link Cosmetic} being equipped in this event.
|
||||
*
|
||||
* @return The {@link Cosmetic} which is being equipped in this event
|
||||
* @return the cosmetic which is being equipped in this event
|
||||
*/
|
||||
@NotNull
|
||||
public Cosmetic getCosmetic() {
|
||||
public @NotNull Cosmetic getCosmetic() {
|
||||
return cosmetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Cosmetic} that the player will equip
|
||||
* Sets the {@link Cosmetic} that the player will equip.
|
||||
*
|
||||
* @param cosmetic The {@link Cosmetic} that the player will equip
|
||||
* @param cosmetic the cosmetic that the player will equip
|
||||
*/
|
||||
public void setCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
this.cosmetic = cosmetic;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,22 +7,24 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player removes a cosmetic
|
||||
* Called when a player removes a {@link Cosmetic}.
|
||||
*/
|
||||
public class PlayerCosmeticRemoveEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final Cosmetic cosmetic;
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerCosmeticRemoveEvent(@NotNull CosmeticUser who, @NotNull Cosmetic cosmetic) {
|
||||
super(who);
|
||||
this.cosmetic = cosmetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Cosmetic} being removed in this event
|
||||
* Gets the {@link Cosmetic} being removed in this event.
|
||||
*
|
||||
* @return The {@link Cosmetic} which is being removed in this event
|
||||
* @return the cosmetic which is being removed in this event
|
||||
*/
|
||||
public Cosmetic getCosmetic() {
|
||||
return cosmetic;
|
||||
@@ -33,27 +35,17 @@ public class PlayerCosmeticRemoveEvent extends PlayerCosmeticEvent implements Ca
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from removing the cosmetic
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,11 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when cosmetics are shown from a player
|
||||
* Called when cosmetics are shown from a player.
|
||||
*/
|
||||
public class PlayerCosmeticShowEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerCosmeticShowEvent(@NotNull CosmeticUser who) {
|
||||
@@ -21,28 +22,17 @@ public class PlayerCosmeticShowEvent extends PlayerCosmeticEvent implements Canc
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from showing cosmetics
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -6,23 +6,27 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player starts playing an emote
|
||||
* Called when a player starts playing an emote.
|
||||
*/
|
||||
public class PlayerEmoteStartEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final String animationId;
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerEmoteStartEvent(@NotNull CosmeticUser who, @NotNull String animationId) {
|
||||
super(who);
|
||||
this.animationId = animationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the animation id of the emote the player started playing
|
||||
* @implNote The returned string of this method may be an invalid animation id. Make sure to validate it before use
|
||||
* Gets the animation id of the emote the player started playing.
|
||||
*
|
||||
* @return The animation id of the emote which the player started playing
|
||||
* @implNote The returned string of this method may be an invalid animation id.
|
||||
* Make sure to validate it before use by calling {@link com.hibiscusmc.hmccosmetics.emotes.EmoteManager#get(String)}.
|
||||
*
|
||||
* @return the animation id of the emote which the player started playing
|
||||
*/
|
||||
@NotNull
|
||||
public String getAnimationId() {
|
||||
@@ -34,28 +38,17 @@ public class PlayerEmoteStartEvent extends PlayerCosmeticEvent implements Cancel
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from playing the emote
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,15 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player stops playing an emote
|
||||
* Called when a player stops playing an emote.
|
||||
*/
|
||||
public class PlayerEmoteStopEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private final UserEmoteManager.StopEmoteReason reason;
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerEmoteStopEvent(@NotNull CosmeticUser who, @NotNull UserEmoteManager.StopEmoteReason reason) {
|
||||
super(who);
|
||||
this.reason = reason;
|
||||
@@ -25,20 +27,19 @@ public class PlayerEmoteStopEvent extends PlayerCosmeticEvent implements Cancell
|
||||
* @return The {@link UserEmoteManager.StopEmoteReason} why the emote has stopped playing
|
||||
* @deprecated As of release 2.2.5+, replaced by {@link #getReason()}
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
@NotNull
|
||||
public UserEmoteManager.StopEmoteReason getStopEmoteReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing
|
||||
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing.
|
||||
*
|
||||
* @return The {@link UserEmoteManager.StopEmoteReason} why the emote has stopped playing
|
||||
* @return the reason why the emote has stopped playing
|
||||
* @since 2.2.5
|
||||
*/
|
||||
@NotNull
|
||||
public UserEmoteManager.StopEmoteReason getReason() {
|
||||
public @NotNull UserEmoteManager.StopEmoteReason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@@ -47,28 +48,17 @@ public class PlayerEmoteStopEvent extends PlayerCosmeticEvent implements Cancell
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from stopping the emote
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents an event related to a {@link org.bukkit.entity.Player}.
|
||||
*/
|
||||
public abstract class PlayerEvent extends Event {
|
||||
protected final UUID player;
|
||||
|
||||
public PlayerEvent(@NotNull UUID uuid) {
|
||||
this.player = uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link UUID} of the player involved in this event.
|
||||
*
|
||||
* @return the UUID of the player who is involved in this event
|
||||
*/
|
||||
public final @NotNull UUID getUniqueId() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player's cosmetic data is loaded.
|
||||
*/
|
||||
public class PlayerLoadEvent extends PlayerCosmeticEvent {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
public PlayerLoadEvent(@NotNull CosmeticUser who) {
|
||||
super(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -3,26 +3,35 @@ package com.hibiscusmc.hmccosmetics.api.events;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a menu is closed by a player
|
||||
* Called when a {@link Menu} is closed by a player.
|
||||
*/
|
||||
public class PlayerMenuCloseEvent extends PlayerMenuEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
private final InventoryCloseEvent.Reason reason;
|
||||
|
||||
public PlayerMenuCloseEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
|
||||
public PlayerMenuCloseEvent(@NotNull CosmeticUser who, @NotNull Menu menu, @NotNull InventoryCloseEvent.Reason reason) {
|
||||
super(who, menu);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link InventoryCloseEvent.Reason} why the menu was closed.
|
||||
* @return The reason why the menu was closed.
|
||||
*/
|
||||
public InventoryCloseEvent.Reason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a menu related event
|
||||
* Represents an event related to a player's interaction with a {@link Menu}.
|
||||
*/
|
||||
public abstract class PlayerMenuEvent extends PlayerCosmeticEvent {
|
||||
protected Menu menu;
|
||||
protected final Menu menu;
|
||||
|
||||
public PlayerMenuEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
|
||||
super(who);
|
||||
@@ -16,12 +16,11 @@ public abstract class PlayerMenuEvent extends PlayerCosmeticEvent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Menu} involved with this event
|
||||
* Gets the {@link Menu} involved with this event.
|
||||
*
|
||||
* @return The {@link Menu} which is involved with the event
|
||||
* @return the menu involved in this event
|
||||
*/
|
||||
@NotNull
|
||||
public final Menu getMenu() {
|
||||
public @NotNull final Menu getMenu() {
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a menu is opened by a player
|
||||
* Called when a {@link Menu} is opened by a player.
|
||||
*/
|
||||
public class PlayerMenuOpenEvent extends PlayerMenuEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerMenuOpenEvent(@NotNull CosmeticUser who, @NotNull Menu menu) {
|
||||
@@ -22,28 +23,17 @@ public class PlayerMenuOpenEvent extends PlayerMenuEvent implements Cancellable
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from opening a {@link Menu}
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Called before a player's data is loaded into the plugin.
|
||||
*
|
||||
* <p>
|
||||
* If this event is cancelled, the player's data will not be loaded,
|
||||
* and the player will not be able to interact with the plugin.
|
||||
* </p>
|
||||
*/
|
||||
public class PlayerPreLoadEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public PlayerPreLoadEvent(@NotNull UUID id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a players data is unloaded from the plugin. This is called when a player leaves the server.
|
||||
*/
|
||||
public class PlayerUnloadEvent extends PlayerCosmeticEvent {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
public PlayerUnloadEvent(@NotNull CosmeticUser who) {
|
||||
super(who);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,18 @@ package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player enters their wardrobe
|
||||
* Called when a player enters their {@link Wardrobe}.
|
||||
*/
|
||||
public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancel = false;
|
||||
@Getter @Setter
|
||||
|
||||
private Wardrobe wardrobe;
|
||||
|
||||
public PlayerWardrobeEnterEvent(@NotNull CosmeticUser who, @NotNull Wardrobe wardrobe) {
|
||||
@@ -22,33 +21,38 @@ public class PlayerWardrobeEnterEvent extends PlayerCosmeticEvent implements Can
|
||||
this.wardrobe = wardrobe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Wardrobe} the player is entering.
|
||||
* @return The wardrobe being entered
|
||||
*/
|
||||
public Wardrobe getWardrobe() {
|
||||
return wardrobe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link Wardrobe} the player is entering.
|
||||
* @param wardrobe the wardrobe being entered
|
||||
*/
|
||||
public void setWardrobe(Wardrobe wardrobe) {
|
||||
this.wardrobe = wardrobe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from entering their wardrobe
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player leaves their wardrobe
|
||||
* Called when a player leaves their {@link com.hibiscusmc.hmccosmetics.config.Wardrobe}.
|
||||
*/
|
||||
public class PlayerWardrobeLeaveEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancel = false;
|
||||
|
||||
public PlayerWardrobeLeaveEvent(@NotNull CosmeticUser who) {
|
||||
@@ -21,28 +22,17 @@ public class PlayerWardrobeLeaveEvent extends PlayerCosmeticEvent implements Can
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancellation state of this event
|
||||
*
|
||||
* <p>
|
||||
* Canceling this event will prevent the player from leaving their wardrobe
|
||||
* </p>
|
||||
*
|
||||
* @param cancel true if you wish to cancel this event
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,10 +43,14 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||
boolean silent = false;
|
||||
boolean console = false;
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
console = true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
if (!(sender instanceof Player)) {
|
||||
// Console
|
||||
if (console) {
|
||||
return true;
|
||||
}
|
||||
if (!sender.hasPermission("hmccosmetics.cmd.default")) {
|
||||
@@ -140,7 +144,12 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
|
||||
if (!user.canEquipCosmetic(cosmetic)) {
|
||||
if (user == null) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!user.canEquipCosmetic(cosmetic) && !console) {
|
||||
if (!silent) MessagesUtil.sendMessage(player, "no-cosmetic-permission");
|
||||
return true;
|
||||
}
|
||||
@@ -148,11 +157,11 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
TagResolver placeholders =
|
||||
TagResolver.resolver(Placeholder.parsed("cosmetic", cosmetic.getId()),
|
||||
TagResolver.resolver(Placeholder.parsed("player", player.getName())),
|
||||
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmetic.getSlot().name())));
|
||||
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmetic.getSlot().toString())));
|
||||
|
||||
if (!silent) MessagesUtil.sendMessage(player, "equip-cosmetic", placeholders);
|
||||
|
||||
user.addPlayerCosmetic(cosmetic, color);
|
||||
user.addCosmetic(cosmetic, color);
|
||||
user.updateCosmetic(cosmetic.getSlot());
|
||||
return true;
|
||||
}
|
||||
@@ -183,11 +192,12 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
if (args[1].equalsIgnoreCase("all")) {
|
||||
cosmeticSlots = user.getSlotsWithCosmetics();
|
||||
} else {
|
||||
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args[1].toUpperCase())) {
|
||||
String rawSlot = args[1].toUpperCase();
|
||||
if (!CosmeticSlot.contains(rawSlot)) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "invalid-slot");
|
||||
return true;
|
||||
}
|
||||
cosmeticSlots = Set.of(CosmeticSlot.valueOf(args[1].toUpperCase()));
|
||||
cosmeticSlots = Set.of(CosmeticSlot.valueOf(rawSlot));
|
||||
}
|
||||
|
||||
for (CosmeticSlot cosmeticSlot : cosmeticSlots) {
|
||||
@@ -199,7 +209,7 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
TagResolver placeholders =
|
||||
TagResolver.resolver(Placeholder.parsed("cosmetic", user.getCosmetic(cosmeticSlot).getId()),
|
||||
TagResolver.resolver(Placeholder.parsed("player", player.getName())),
|
||||
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmeticSlot.name())));
|
||||
TagResolver.resolver(Placeholder.parsed("cosmeticslot", cosmeticSlot.toString())));
|
||||
|
||||
if (!silent) MessagesUtil.sendMessage(player, "unequip-cosmetic", placeholders);
|
||||
|
||||
@@ -239,20 +249,24 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
|
||||
if (user.isInWardrobe()) {
|
||||
user.leaveWardrobe();
|
||||
user.leaveWardrobe(false);
|
||||
} else {
|
||||
user.enterWardrobe(false, wardrobe);
|
||||
user.enterWardrobe(wardrobe, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// cosmetic menu exampleMenu playerName
|
||||
case ("menu") -> {
|
||||
if (args.length == 1) return true;
|
||||
if (!sender.hasPermission("hmccosmetics.cmd.menu")) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
|
||||
return true;
|
||||
}
|
||||
Menu menu = Menus.getMenu(args[1]);
|
||||
Menu menu;
|
||||
if (args.length == 1) {
|
||||
menu = Menus.getDefaultMenu();
|
||||
} else {
|
||||
menu = Menus.getMenu(args[1]);
|
||||
}
|
||||
|
||||
if (sender instanceof Player) player = ((Player) sender).getPlayer();
|
||||
if (sender.hasPermission("hmccosmetics.cmd.menu.other")) {
|
||||
@@ -298,11 +312,12 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args[1])) {
|
||||
String rawSlot = args[1];
|
||||
if (!CosmeticSlot.contains(rawSlot)) {
|
||||
if (!silent) MessagesUtil.sendMessage(player, "invalid-slot");
|
||||
return true;
|
||||
}
|
||||
CosmeticSlot slot = CosmeticSlot.valueOf(args[1]);
|
||||
CosmeticSlot slot = CosmeticSlot.valueOf(rawSlot);
|
||||
Cosmetic cosmetic = user.getCosmetic(slot);
|
||||
|
||||
if (args.length >= 3) {
|
||||
@@ -315,7 +330,7 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
if (!silent) MessagesUtil.sendMessage(player, "invalid-color");
|
||||
return true;
|
||||
}
|
||||
user.addPlayerCosmetic(cosmetic, color); // #FFFFFF
|
||||
user.addCosmetic(cosmetic, color); // #FFFFFF
|
||||
} else {
|
||||
DyeMenu.openMenu(user, cosmetic);
|
||||
}
|
||||
@@ -334,7 +349,7 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
}
|
||||
Wardrobe wardrobe = WardrobeSettings.getWardrobe(args[1]);
|
||||
if (wardrobe == null) {
|
||||
wardrobe = new Wardrobe(args[1], new WardrobeLocation(null, null, null), null, -1);
|
||||
wardrobe = new Wardrobe(args[1], new WardrobeLocation(null, null, null), null, -1, null);
|
||||
WardrobeSettings.addWardrobe(wardrobe);
|
||||
//MessagesUtil.sendMessage(player, "no-wardrobes");
|
||||
//return true;
|
||||
@@ -369,6 +384,11 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-distance");
|
||||
return true;
|
||||
}
|
||||
if (args[2].equalsIgnoreCase("defaultmenu")) {
|
||||
WardrobeSettings.setWardrobeDefaultMenu(wardrobe, args[3]);
|
||||
if (!silent) MessagesUtil.sendMessage(player, "set-wardrobe-menu");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
case ("dump") -> {
|
||||
|
||||
@@ -94,7 +94,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
}
|
||||
case "dye" -> {
|
||||
for (CosmeticSlot slot : user.getDyeableSlots()) {
|
||||
completions.add(slot.name());
|
||||
completions.add(slot.toString());
|
||||
}
|
||||
}
|
||||
case "setwardrobesetting" -> {
|
||||
@@ -123,6 +123,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
completions.add("leavelocation");
|
||||
completions.add("permission");
|
||||
completions.add("distance");
|
||||
completions.add("defaultmenu");
|
||||
}
|
||||
}
|
||||
StringUtil.copyPartialMatches(args[2], completions, finalCompletions);
|
||||
@@ -135,6 +136,11 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
if (Hooks.isActiveHook("HMCColor")) completions.addAll(HMCColorContextKt.getHmcColor().getConfig().getColors().keySet());
|
||||
completions.add("#FFFFFF");
|
||||
}
|
||||
case "setwardrobesetting" -> {
|
||||
if (args[2].equalsIgnoreCase("defaultmenu")) {
|
||||
completions.addAll(Menus.getMenuNames());
|
||||
}
|
||||
}
|
||||
}
|
||||
StringUtil.copyPartialMatches(args[3], completions, finalCompletions);
|
||||
}
|
||||
|
||||
@@ -30,11 +30,15 @@ public class Settings {
|
||||
private static final String UNAPPLY_DEATH_PATH = "unapply-on-death";
|
||||
private static final String FORCE_PERMISSION_JOIN_PATH = "force-permission-join";
|
||||
private static final String FORCE_SHOW_COSMETICS_PATH = "force-show-join";
|
||||
private static final String ITEM_PROCESSING_PATH = "item-processing";
|
||||
private static final String ITEM_PROCESS_DISPLAY_NAME_PATH = "display-name";
|
||||
private static final String ITEM_PROCESS_LORE_PATH = "lore";
|
||||
private static final String DISABLED_GAMEMODE_PATH = "disabled-gamemode";
|
||||
private static final String DISABLED_GAMEMODE_GAMEMODES_PATH = "gamemodes";
|
||||
private static final String EMOTE_DISTANCE_PATH = "emote-distance";
|
||||
private static final String HOOK_SETTING_PATH = "hook-settings";
|
||||
private static final String HOOK_ITEMADDER_PATH = "itemsadder";
|
||||
private static final String HOOK_NEXO_PATH = "nexo";
|
||||
private static final String HOOK_RELOAD_CHANGE_PATH = "reload-on-change";
|
||||
private static final String HOOK_WORLDGUARD_PATH = "worldguard";
|
||||
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
|
||||
@@ -49,8 +53,6 @@ public class Settings {
|
||||
private static final String COSMETIC_DISABLED_WORLDS_PATH = "disabled-worlds";
|
||||
private static final String COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH = "entity-cooldown-teleport-packet";
|
||||
private static final String COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH = "backpack-force-riding-packet";
|
||||
private static final String COSMETIC_BACKPACK_LIGHT_EMINATION_PATH = "backpack-light-emination";
|
||||
private static final String COSMETIC_BACKPACK_LIGHT_BLOCK_DETECTION = "backpack-block-detection";
|
||||
private static final String COSMETIC_DESTROY_LOOSE_COSMETIC_PATH = "destroy-loose-cosmetics";
|
||||
private static final String COSMETIC_BALLOON_HEAD_FORWARD_PATH = "balloon-head-forward";
|
||||
private static final String MENU_SETTINGS_PATH = "menu-settings";
|
||||
@@ -70,6 +72,9 @@ public class Settings {
|
||||
private static final String LOCKED_COSMETIC_COLOR_PATH = "locked-cosmetic-color";
|
||||
private static final String ENABLED_PATH = "enabled";
|
||||
private static final String SLOT_OPTIONS_PATH = "slot-options";
|
||||
private static final String BACKPACK_PREVENT_DARKNESS_PATH = "backpack-prevent-darkness";
|
||||
private static final String BETTER_HUD_PATH = "betterhud";
|
||||
private static final String BETTER_HUD_HIDE_IN_WARDROBE_PATH = "wardrobe-hide";
|
||||
|
||||
@Getter
|
||||
private static String defaultMenu;
|
||||
@@ -90,8 +95,14 @@ public class Settings {
|
||||
@Getter
|
||||
private static boolean forceShowOnJoin;
|
||||
@Getter
|
||||
private static boolean itemProcessingDisplayName;
|
||||
@Getter
|
||||
private static boolean itemProcessingLore;
|
||||
@Getter
|
||||
private static boolean itemsAdderChangeReload;
|
||||
@Getter
|
||||
private static boolean nexoChangeReload;
|
||||
@Getter
|
||||
private static boolean worldGuardMoveCheck;
|
||||
@Getter
|
||||
private static boolean cosmeticEmoteBlockCheck;
|
||||
@@ -107,16 +118,14 @@ public class Settings {
|
||||
@Getter
|
||||
private static boolean backpackForceRidingEnabled;
|
||||
@Getter
|
||||
private static boolean backpackLightEmination;
|
||||
@Getter
|
||||
private static boolean backpackBlockDetection;
|
||||
@Getter
|
||||
private static boolean emotesEnabled;
|
||||
@Getter
|
||||
private static boolean disabledGamemodesEnabled;
|
||||
@Getter
|
||||
private static boolean balloonHeadForward;
|
||||
@Getter
|
||||
private static boolean backpackPreventDarkness;
|
||||
@Getter
|
||||
private static List<String> disabledGamemodes;
|
||||
@Getter
|
||||
private static List<String> disabledWorlds;
|
||||
@@ -162,6 +171,8 @@ public class Settings {
|
||||
private static boolean emoteMoveCheck;
|
||||
@Getter @Setter
|
||||
private static boolean allPlayersHidden;
|
||||
@Getter
|
||||
private static boolean wardrobeHideHud;
|
||||
|
||||
|
||||
public static void load(ConfigurationNode source) {
|
||||
@@ -191,6 +202,10 @@ public class Settings {
|
||||
disabledWorlds = new ArrayList<>();
|
||||
}
|
||||
|
||||
ConfigurationNode itemProcessingSettings = cosmeticSettings.node(ITEM_PROCESSING_PATH);
|
||||
itemProcessingDisplayName = itemProcessingSettings.node(ITEM_PROCESS_DISPLAY_NAME_PATH).getBoolean(true);
|
||||
itemProcessingLore = itemProcessingSettings.node(ITEM_PROCESS_LORE_PATH).getBoolean(true);
|
||||
|
||||
unapplyOnDeath = cosmeticSettings.node(UNAPPLY_DEATH_PATH).getBoolean(false);
|
||||
forcePermissionJoin = cosmeticSettings.node(FORCE_PERMISSION_JOIN_PATH).getBoolean(false);
|
||||
forceShowOnJoin = cosmeticSettings.node(FORCE_SHOW_COSMETICS_PATH).getBoolean(false);
|
||||
@@ -202,8 +217,6 @@ public class Settings {
|
||||
emoteInvincible = cosmeticSettings.node(COSMETIC_EMOTE_INVINCIBLE_PATH).getBoolean(false);
|
||||
destroyLooseCosmetics = cosmeticSettings.node(COSMETIC_DESTROY_LOOSE_COSMETIC_PATH).getBoolean(false);
|
||||
backpackForceRidingEnabled = cosmeticSettings.node(COSMETIC_BACKPACK_FORCE_RIDING_PACKET_PATH).getBoolean(false);
|
||||
backpackLightEmination = cosmeticSettings.node(COSMETIC_BACKPACK_LIGHT_EMINATION_PATH).getBoolean(true);
|
||||
backpackBlockDetection = cosmeticSettings.node(COSMETIC_BACKPACK_LIGHT_BLOCK_DETECTION).getBoolean(true);
|
||||
|
||||
cosmeticSettings.node(SLOT_OPTIONS_PATH).childrenMap().forEach((key, value) -> {
|
||||
EquipmentSlot slot = convertConfigToEquipment(key.toString().toLowerCase());
|
||||
@@ -222,6 +235,7 @@ public class Settings {
|
||||
emoteMoveCheck = cosmeticSettings.node(COSMETIC_EMOTE_MOVE_CHECK_PATH).getBoolean(false);
|
||||
packetEntityTeleportCooldown = cosmeticSettings.node(COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH).getInt(-1);
|
||||
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false);
|
||||
backpackPreventDarkness = cosmeticSettings.node(BACKPACK_PREVENT_DARKNESS_PATH).getBoolean(true);
|
||||
|
||||
ConfigurationNode menuSettings = source.node(MENU_SETTINGS_PATH);
|
||||
|
||||
@@ -254,9 +268,16 @@ public class Settings {
|
||||
dyeMenuOutputSlot = dyeMenuSettings.node(DYE_MENU_OUTPUT_SLOT).getInt(25);
|
||||
|
||||
ConfigurationNode hookSettings = source.node(HOOK_SETTING_PATH);
|
||||
|
||||
ConfigurationNode itemsAdderSettings = hookSettings.node(HOOK_ITEMADDER_PATH);
|
||||
itemsAdderChangeReload = itemsAdderSettings.node(HOOK_RELOAD_CHANGE_PATH).getBoolean(false);
|
||||
|
||||
ConfigurationNode nexoSettings = hookSettings.node(HOOK_NEXO_PATH);
|
||||
nexoChangeReload = nexoSettings.node(HOOK_RELOAD_CHANGE_PATH).getBoolean(true);
|
||||
|
||||
ConfigurationNode betterHudSettings = hookSettings.node(BETTER_HUD_PATH);
|
||||
wardrobeHideHud = betterHudSettings.node(BETTER_HUD_HIDE_IN_WARDROBE_PATH).getBoolean(true);
|
||||
|
||||
ConfigurationNode worldGuardSettings = hookSettings.node(HOOK_WORLDGUARD_PATH);
|
||||
worldGuardMoveCheck = worldGuardSettings.node(HOOK_WG_MOVE_CHECK_PATH).getBoolean(true);
|
||||
// I messed up in release 2.2.6 and forgot to change player_move_check to player-move-check.
|
||||
|
||||
@@ -14,10 +14,12 @@ public class Wardrobe {
|
||||
private final String id;
|
||||
@Getter @Setter
|
||||
private int distance;
|
||||
@Getter @Setter
|
||||
@Getter @Setter @Nullable
|
||||
private String permission;
|
||||
@Getter @Setter
|
||||
private WardrobeLocation location;
|
||||
@Getter @Setter @Nullable
|
||||
private String defaultMenu;
|
||||
|
||||
/**
|
||||
* This creates a Wardrobe object with all the information that a user will need when entering.
|
||||
@@ -25,12 +27,14 @@ public class Wardrobe {
|
||||
* @param location The 3 locations of the Wardrobe, if any of these 3 locations are null, the wardrobe will not work
|
||||
* @param permission The permission required to enter the wardrobe, if null, no permission is required
|
||||
* @param distance The distance from the wardrobe that the player can be to enter, if -1, the player can enter from any distance
|
||||
* @param defaultMenu The default menu that the player will open when entering the wardrobe.
|
||||
*/
|
||||
public Wardrobe(@NotNull String id, @NotNull WardrobeLocation location, @Nullable String permission, int distance) {
|
||||
public Wardrobe(@NotNull String id, @NotNull WardrobeLocation location, @Nullable String permission, int distance, @Nullable String defaultMenu) {
|
||||
this.id = id;
|
||||
this.location = location;
|
||||
this.distance = distance;
|
||||
if (permission != null) this.permission = permission;
|
||||
if (defaultMenu != null) this.defaultMenu = defaultMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +54,7 @@ public class Wardrobe {
|
||||
Location wardrobeLocation = location.getNpcLocation();
|
||||
Location location = user.getEntity().getLocation();
|
||||
if (wardrobeLocation == null) return false;
|
||||
if (distance == -1) return true;
|
||||
if (distance <= 0) return true;
|
||||
if (!wardrobeLocation.getWorld().equals(location.getWorld())) return false;
|
||||
return wardrobeLocation.distanceSquared(location) <= distance * distance;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.hibiscusmc.hmccosmetics.config;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.misc.Utils;
|
||||
import lombok.Getter;
|
||||
import me.lojosho.hibiscuscommons.config.serializer.LocationSerializer;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
@@ -45,6 +44,7 @@ public class WardrobeSettings {
|
||||
private static final String WARDROBES_PATH = "wardrobes";
|
||||
private static final String PERMISSION_PATH = "permission";
|
||||
private static final String DISTANCE_PATH = "distance";
|
||||
private static final String WARDROBE_DEFAULT_MENU = "default-menu";
|
||||
private static final String BOSSBAR_PATH = "bossbar";
|
||||
private static final String BOSSBAR_ENABLE_PATH = "enabled";
|
||||
private static final String BOSSBAR_TEXT_PATH = "text";
|
||||
@@ -169,14 +169,16 @@ public class WardrobeSettings {
|
||||
MessagesUtil.sendDebugMessages("Wardrobe Location: " + npcLocation);
|
||||
Location viewerLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(VIEWER_LOCATION_PATH));
|
||||
MessagesUtil.sendDebugMessages("Viewer Location: " + viewerLocation);
|
||||
Location leaveLocation = Utils.replaceIfNull(LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(LEAVE_LOCATION_PATH)), viewerLocation);
|
||||
Location leaveLocation = LocationSerializer.INSTANCE.deserialize(Location.class, wardrobesNode.node(LEAVE_LOCATION_PATH));
|
||||
if (leaveLocation == null) leaveLocation = viewerLocation;
|
||||
MessagesUtil.sendDebugMessages("Leave Location: " + leaveLocation);
|
||||
WardrobeLocation wardrobeLocation = new WardrobeLocation(npcLocation, viewerLocation, leaveLocation);
|
||||
|
||||
String permission = wardrobesNode.node(PERMISSION_PATH).getString();
|
||||
String defaultMenu = wardrobesNode.node(WARDROBE_DEFAULT_MENU).getString();
|
||||
int distance = wardrobesNode.node(DISTANCE_PATH).getInt(-1);
|
||||
|
||||
Wardrobe wardrobe = new Wardrobe(id, wardrobeLocation, permission, distance);
|
||||
Wardrobe wardrobe = new Wardrobe(id, wardrobeLocation, permission, distance, defaultMenu);
|
||||
addWardrobe(wardrobe);
|
||||
} catch (Exception e) {
|
||||
MessagesUtil.sendDebugMessages("Unable to create wardrobe " + id, Level.SEVERE);
|
||||
@@ -280,4 +282,14 @@ public class WardrobeSettings {
|
||||
|
||||
plugin.saveConfig();
|
||||
}
|
||||
|
||||
public static void setWardrobeDefaultMenu(Wardrobe wardrobe, String defaultMenu) {
|
||||
wardrobe.setDefaultMenu(defaultMenu);
|
||||
|
||||
HMCCosmeticsPlugin plugin = HMCCosmeticsPlugin.getInstance();
|
||||
|
||||
plugin.getConfig().set("wardrobe.wardrobes." + wardrobe.getId() + ".default-menu", defaultMenu);
|
||||
|
||||
plugin.saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents any object that can wear/hold cosmetics,
|
||||
* users, for example.
|
||||
*/
|
||||
public interface CosmeticHolder {
|
||||
@Nullable Cosmetic getCosmetic(@NotNull CosmeticSlot slot);
|
||||
|
||||
@NotNull ImmutableCollection<Cosmetic> getCosmetics();
|
||||
|
||||
void addCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color);
|
||||
|
||||
default void addCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
addCosmetic(cosmetic, null);
|
||||
}
|
||||
|
||||
default void removeCosmetics() {
|
||||
// Small optimization could be made, but Concurrent modification prevents us from both getting and removing
|
||||
for (CosmeticSlot slot : CosmeticSlot.values().values()) {
|
||||
removeCosmeticSlot(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void removeCosmeticSlot(@NotNull CosmeticSlot slot);
|
||||
|
||||
default void removeCosmeticSlot(@NotNull Cosmetic cosmetic) {
|
||||
removeCosmeticSlot(cosmetic.getSlot());
|
||||
}
|
||||
|
||||
default boolean hasCosmeticInSlot(@NotNull CosmeticSlot slot) {
|
||||
return getCosmetic(slot) != null;
|
||||
}
|
||||
|
||||
default boolean hasCosmeticInSlot(@NotNull Cosmetic cosmetic) {
|
||||
final var existingCosmetic = getCosmetic(cosmetic.getSlot());
|
||||
if (existingCosmetic == null) return false;
|
||||
return Objects.equals(cosmetic.getId(), existingCosmetic.getId());
|
||||
}
|
||||
|
||||
default boolean canEquipCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
return canEquipCosmetic(cosmetic, false);
|
||||
}
|
||||
|
||||
boolean canEquipCosmetic(@NotNull Cosmetic cosmetic, boolean ignoreWardrobe);
|
||||
|
||||
void updateCosmetic(@NotNull CosmeticSlot slot);
|
||||
|
||||
/**
|
||||
* Just for backwards compatibility, ensures that the given viewer and the given cosmetic holder
|
||||
* represent the same user.
|
||||
*
|
||||
* @param viewer the viewer
|
||||
* @param cosmeticHolder the cosmetic holder
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
static @NotNull CosmeticUser ensureSingleCosmeticUser(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder) {
|
||||
if (!(cosmeticHolder instanceof CosmeticUser user) || !user.getUniqueId().equals(viewer.getUniqueId())) {
|
||||
throw new IllegalStateException("This method does not support having a different viewer than" +
|
||||
" the same cosmetic holder. Needs to be updated to support the overload that takes a viewer and" +
|
||||
" a cosmetic holder instead of a single CosmeticUser.");
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Allow custom implementations of a {@link Cosmetic}.
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class CosmeticProvider {
|
||||
protected static final Map<CosmeticSlot, BiFunction<String, ConfigurationNode, Cosmetic>> MAPPINGS = Map.ofEntries(
|
||||
Map.entry(CosmeticSlot.HELMET, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.CHESTPLATE, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.LEGGINGS, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.BOOTS, CosmeticArmorType::new),
|
||||
Map.entry(CosmeticSlot.OFFHAND, CosmeticArmorType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.MAINHAND, CosmeticMainhandType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.BACKPACK, CosmeticBackpackType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.EMOTE, CosmeticEmoteType::new)
|
||||
);
|
||||
|
||||
private static final String EXCEPTION_MESSAGE = "Unknown slot %s provided for mapping, if you registered your own CosmeticSlot please ensure that you've also registered a custom CosmeticProvider! Or if you have already registered a custom CosmeticProvider ensure it is registered in your plugins `onLoad` method instead of `onEnable`!";
|
||||
|
||||
/**
|
||||
* Construct the {@link Cosmetic}.
|
||||
* @param id the cosmetic id
|
||||
* @param config the configuration node of the cosmetic
|
||||
* @param slot the occupying slot of the cosmetic
|
||||
* @return the {@link Cosmetic}
|
||||
* @throws IllegalArgumentException if the provided cosmetic could not be mapped
|
||||
*/
|
||||
public @NotNull Cosmetic createCosmetic(String id, ConfigurationNode config, CosmeticSlot slot) throws IllegalArgumentException {
|
||||
final var mapper = MAPPINGS.get(slot);
|
||||
if(mapper == null) {
|
||||
throw new IllegalArgumentException(
|
||||
EXCEPTION_MESSAGE.formatted(slot)
|
||||
);
|
||||
}
|
||||
|
||||
return mapper.apply(id, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the plugin that is providing this {@link CosmeticProvider}
|
||||
* @return the plugin
|
||||
*/
|
||||
public abstract Plugin getProviderPlugin();
|
||||
|
||||
/**
|
||||
* Default Implementation.
|
||||
*/
|
||||
static class Default extends CosmeticProvider {
|
||||
public static final CosmeticProvider INSTANCE = new Default();
|
||||
|
||||
@Override
|
||||
public Plugin getProviderPlugin() {
|
||||
return HMCCosmeticsPlugin.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,82 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
public enum CosmeticSlot {
|
||||
HELMET,
|
||||
CHESTPLATE,
|
||||
LEGGINGS,
|
||||
BOOTS,
|
||||
MAINHAND,
|
||||
OFFHAND,
|
||||
BACKPACK,
|
||||
BALLOON,
|
||||
EMOTE,
|
||||
CUSTOM
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
public class CosmeticSlot {
|
||||
private static final ConcurrentHashMap<String, CosmeticSlot> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
public static final CosmeticSlot HELMET = register("HELMET");
|
||||
public static final CosmeticSlot CHESTPLATE = register("CHESTPLATE");
|
||||
public static final CosmeticSlot LEGGINGS = register("LEGGINGS");
|
||||
public static final CosmeticSlot BOOTS = register("BOOTS");
|
||||
public static final CosmeticSlot MAINHAND = register("MAINHAND");
|
||||
public static final CosmeticSlot OFFHAND = register("OFFHAND");
|
||||
public static final CosmeticSlot BACKPACK = register("BACKPACK");
|
||||
public static final CosmeticSlot BALLOON = register("BALLOON");
|
||||
public static final CosmeticSlot EMOTE = register("EMOTE");
|
||||
|
||||
private final String name;
|
||||
|
||||
private CosmeticSlot(@NotNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new slot with the given name. If a slot with the given name already exists, it will be returned.
|
||||
* @param name The name of the slot (This will automatically be converted into all UPPERCASE)
|
||||
* @return The slot that was registered or already exists.
|
||||
* @throws IllegalArgumentException if a cosmetic slot by that name has already been registered
|
||||
*/
|
||||
@NotNull
|
||||
public static CosmeticSlot register(@NotNull String name) {
|
||||
final String upperName = name.toUpperCase();
|
||||
if(REGISTRY.containsKey(upperName)) {
|
||||
throw new IllegalArgumentException("A cosmetic slot with name '" + name + "' is already registered.");
|
||||
}
|
||||
|
||||
final CosmeticSlot slot = new CosmeticSlot(upperName);
|
||||
REGISTRY.put(upperName, slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An unmodifiable map of all the slots that have been registered.
|
||||
*/
|
||||
@NotNull
|
||||
public static Map<String, CosmeticSlot> values() {
|
||||
return Collections.unmodifiableMap(REGISTRY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the slot with the given name.
|
||||
* @param name The name of the slot to get. This is automatically converted to all UPPERCASE.
|
||||
* @return The slot with the given name, or null if it does not exist.
|
||||
*/
|
||||
@Nullable
|
||||
public static CosmeticSlot valueOf(@NotNull String name) {
|
||||
final String upperName = name.toUpperCase();
|
||||
return REGISTRY.get(upperName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the registry contains a slot with the given name.
|
||||
* @param name The name of the slot to check for. This is automatically converted to all UPPERCASE.
|
||||
* @return True if the slot exists, false otherwise.
|
||||
*/
|
||||
public static boolean contains(@NotNull String name) {
|
||||
final String upperName = name.toUpperCase();
|
||||
return REGISTRY.containsKey(upperName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,12 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.CosmeticTypeRegisterEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.*;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.ConfigurateException;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -22,10 +19,12 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Slf4j
|
||||
public class Cosmetics {
|
||||
|
||||
private static final HashBiMap<String, Cosmetic> COSMETICS = HashBiMap.create();
|
||||
|
||||
private static CosmeticProvider PROVIDER = CosmeticProvider.Default.INSTANCE;
|
||||
|
||||
public static void addCosmetic(Cosmetic cosmetic) {
|
||||
COSMETICS.put(cosmetic.getId(), cosmetic);
|
||||
}
|
||||
@@ -35,7 +34,7 @@ public class Cosmetics {
|
||||
}
|
||||
|
||||
public static void removeCosmetic(Cosmetic cosmetic) {
|
||||
COSMETICS.remove(cosmetic);
|
||||
COSMETICS.remove(cosmetic.getId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -92,30 +91,51 @@ public class Cosmetics {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom {@link CosmeticProvider} to provide your own user implementation to
|
||||
* be used and queried.
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if the provider is already registered by another plugin
|
||||
*/
|
||||
public static void registerProvider(final CosmeticProvider provider) {
|
||||
if(PROVIDER != CosmeticProvider.Default.INSTANCE) {
|
||||
throw new IllegalArgumentException("CosmeticProvider already registered by %s, this conflicts with %s attempting to register their own.".formatted(
|
||||
PROVIDER.getProviderPlugin().getName(),
|
||||
provider.getProviderPlugin().getName()
|
||||
));
|
||||
}
|
||||
|
||||
PROVIDER = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current {@link CosmeticProvider} being used.
|
||||
* @return the current {@link CosmeticProvider} being used
|
||||
*/
|
||||
public static CosmeticProvider getProvider() {
|
||||
return PROVIDER;
|
||||
}
|
||||
|
||||
private static void setupCosmetics(@NotNull CommentedConfigurationNode config) {
|
||||
for (ConfigurationNode cosmeticConfig : config.childrenMap().values()) {
|
||||
String id = cosmeticConfig.key().toString();
|
||||
MessagesUtil.sendDebugMessages("Attempting to add " + id);
|
||||
ConfigurationNode slotNode = cosmeticConfig.node("slot");
|
||||
if (slotNode.virtual()) {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because there is no slot defined!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
String slot = slotNode.getString("");
|
||||
CosmeticSlot cosmeticSlot = CosmeticSlot.valueOf(slot);
|
||||
if (cosmeticSlot == null) {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because " + slotNode.getString() + " is not a valid slot!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
String id = cosmeticConfig.key().toString();
|
||||
MessagesUtil.sendDebugMessages("Attempting to add " + id);
|
||||
ConfigurationNode slotNode = cosmeticConfig.node("slot");
|
||||
if (slotNode.virtual()) {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because there is no slot defined!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
if (!EnumUtils.isValidEnum(CosmeticSlot.class, slotNode.getString())) {
|
||||
MessagesUtil.sendDebugMessages("Unable to create " + id + " because " + slotNode.getString() + " is not a valid slot!", Level.WARNING);
|
||||
continue;
|
||||
}
|
||||
switch (CosmeticSlot.valueOf(slotNode.getString())) {
|
||||
case BALLOON -> new CosmeticBalloonType(id, cosmeticConfig);
|
||||
case BACKPACK -> new CosmeticBackpackType(id, cosmeticConfig);
|
||||
case MAINHAND -> new CosmeticMainhandType(id, cosmeticConfig);
|
||||
case EMOTE -> new CosmeticEmoteType(id, cosmeticConfig);
|
||||
case HELMET, CHESTPLATE, LEGGINGS, BOOTS, OFFHAND -> new CosmeticArmorType(id, cosmeticConfig);
|
||||
default -> new CosmeticTypeRegisterEvent(id, cosmeticConfig).callEvent();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (Settings.isDebugMode()) e.printStackTrace();
|
||||
addCosmetic(PROVIDER.createCosmetic(id, cosmeticConfig, cosmeticSlot));
|
||||
} catch(Exception ex) {
|
||||
log.error("Unable to construct cosmetic for {}, skipping processing it.", id, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,12 @@ public class CosmeticArmorType extends Cosmetic {
|
||||
public CosmeticArmorType(String id, ConfigurationNode config) {
|
||||
super(id, config);
|
||||
|
||||
this.equipSlot = HMCCInventoryUtils.getEquipmentSlot(getSlot());
|
||||
EquipmentSlot slot = HMCCInventoryUtils.getEquipmentSlot(getSlot());
|
||||
if (slot == null) {
|
||||
// Hypothetically it shouldn't be null, but it was happening on some random servers? Adding this just in case
|
||||
throw new IllegalArgumentException("Invalid slot for cosmetic armor type: " + getSlot() + " in " + id + " cosmetic config.");
|
||||
}
|
||||
this.equipSlot = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,6 +57,7 @@ public class CosmeticArmorType extends Cosmetic {
|
||||
return cosmeticItem;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EquipmentSlot getEquipSlot() {
|
||||
return this.equipSlot;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEntity;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import lombok.Getter;
|
||||
@@ -11,7 +12,6 @@ import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -26,8 +26,6 @@ import java.util.logging.Level;
|
||||
|
||||
public class CosmeticBackpackType extends Cosmetic {
|
||||
|
||||
@Getter
|
||||
private final String modelName;
|
||||
@Getter
|
||||
private int height = -1;
|
||||
private ItemStack firstPersonBackpack;
|
||||
@@ -35,8 +33,6 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
public CosmeticBackpackType(String id, ConfigurationNode config) {
|
||||
super(id, config);
|
||||
|
||||
modelName = config.node("model").getString();
|
||||
|
||||
if (!config.node("firstperson-item").virtual()) {
|
||||
this.firstPersonBackpack = generateItemStack(config.node("firstperson-item"));
|
||||
this.height = config.node("height").getInt(5);
|
||||
@@ -45,10 +41,11 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
|
||||
@Override
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||
Entity entity = user.getEntity();
|
||||
if (entity == null) return;
|
||||
|
||||
Location loc = entity.getLocation().clone().add(0, 2, 0);
|
||||
Location entityLocation = entity.getLocation();
|
||||
Location loc = entityLocation.clone().add(0, 2, 0);
|
||||
|
||||
if (user.isInWardrobe() || !user.isBackpackSpawned()) return;
|
||||
if (user.isHidden()) {
|
||||
@@ -56,18 +53,22 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
user.despawnBackpack();
|
||||
return;
|
||||
}
|
||||
List<Player> outsideViewers = user.getUserBackpackManager().getEntityManager().refreshViewers(loc);
|
||||
|
||||
UserBackpackManager backpackManager = user.getUserBackpackManager();
|
||||
backpackManager.getEntityManager().teleport(loc);
|
||||
backpackManager.getEntityManager().setRotation((int) loc.getYaw(), isFirstPersonCompadible());
|
||||
UserEntity entityManager = backpackManager.getEntityManager();
|
||||
int firstArmorStandId = backpackManager.getFirstArmorStandId();
|
||||
|
||||
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), backpackManager.getFirstArmorStandId(), EntityType.ARMOR_STAND, UUID.randomUUID(), outsideViewers);
|
||||
//HMCCPacketManager.sendArmorstandMetadata(backpackManager.getFirstArmorStandId(), outsideViewers);
|
||||
PacketManager.equipmentSlotUpdate(backpackManager.getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(this, getItem()), outsideViewers);
|
||||
List<Player> outsideViewers = entityManager.refreshViewers(loc);
|
||||
|
||||
entityManager.teleport(loc);
|
||||
entityManager.setRotation((int) loc.getYaw(), isFirstPersonCompadible());
|
||||
|
||||
HMCCPacketManager.sendEntitySpawnPacket(entityLocation, firstArmorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), outsideViewers);
|
||||
HMCCPacketManager.sendArmorstandMetadata(firstArmorStandId, outsideViewers);
|
||||
PacketManager.equipmentSlotUpdate(firstArmorStandId, EquipmentSlot.HEAD, user.getUserCosmeticItem(this, getItem()), outsideViewers);
|
||||
// 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(), backpackManager.getFirstArmorStandId(), backpackManager.getEntityManager().getViewers());
|
||||
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers);
|
||||
if (Settings.isBackpackForceRidingEnabled()) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, entityManager.getViewers());
|
||||
else HMCCPacketManager.sendRidingPacket(entity.getEntityId(), firstArmorStandId, outsideViewers);
|
||||
|
||||
if (!user.isInWardrobe() && isFirstPersonCompadible() && user.getPlayer() != null) {
|
||||
List<Player> owner = List.of(user.getPlayer());
|
||||
@@ -80,16 +81,15 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
HMCCPacketManager.sendRidingPacket(particleCloud.get(i - 1), particleCloud.get(i) , owner);
|
||||
}
|
||||
}
|
||||
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), backpackManager.getFirstArmorStandId(), owner);
|
||||
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), firstArmorStandId, owner);
|
||||
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(backpackManager.getFirstArmorStandId(), 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);
|
||||
//MessagesUtil.sendDebugMessages("First Person Backpack Update[owner=" + user.getUniqueId() + ",player_location=" + loc + "]!", Level.INFO);
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("TTTTTTT " + backpackManager.refreshBlock(backpackManager.getEntityManager().getViewers()));
|
||||
backpackManager.showBackpack();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
}
|
||||
|
||||
Vector velocity = newLocation.toVector().subtract(currentLocation.toVector());
|
||||
userBalloonManager.setVelocity(velocity.multiply(1.1));
|
||||
userBalloonManager.setLocation(newLocation);
|
||||
userBalloonManager.setVelocity(velocity.multiply(1.1));
|
||||
|
||||
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
|
||||
HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
|
||||
|
||||
@@ -18,6 +18,6 @@ public class CosmeticMainhandType extends Cosmetic {
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
Player player = user.getPlayer();
|
||||
|
||||
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), HMCCPlayerUtils.getNearbyPlayers(player));
|
||||
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), HMCCPacketManager.getViewers(player.getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import lombok.Getter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Database {
|
||||
@@ -56,7 +57,7 @@ public class Database {
|
||||
data.save(CosmeticUsers.getUser(player));
|
||||
}
|
||||
|
||||
public static CosmeticUser get(UUID uniqueId) {
|
||||
public static CompletableFuture<UserData> get(UUID uniqueId) {
|
||||
return data.get(uniqueId);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.hibiscusmc.hmccosmetics.database;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserData {
|
||||
|
||||
@Getter
|
||||
private UUID owner;
|
||||
@Setter
|
||||
@Getter
|
||||
private HashMap<CosmeticSlot, Map.Entry<Cosmetic, Integer>> cosmetics;
|
||||
@Getter
|
||||
private ArrayList<CosmeticUser.HiddenReason> hiddenReasons;
|
||||
|
||||
public UserData(UUID owner) {
|
||||
this.owner = owner;
|
||||
this.cosmetics = new HashMap<>();
|
||||
this.hiddenReasons = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addCosmetic(CosmeticSlot slot, Cosmetic cosmetic, Integer color) {
|
||||
cosmetics.put(slot, Map.entry(cosmetic, color));
|
||||
}
|
||||
|
||||
public void addHiddenReason(CosmeticUser.HiddenReason reason) {
|
||||
hiddenReasons.add(reason);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
@@ -14,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class Data {
|
||||
|
||||
@@ -22,7 +24,7 @@ public abstract class Data {
|
||||
public abstract void save(CosmeticUser user);
|
||||
|
||||
@Nullable
|
||||
public abstract CosmeticUser get(UUID uniqueId);
|
||||
public abstract CompletableFuture<UserData> get(UUID uniqueId);
|
||||
|
||||
public abstract void clear(UUID uniqueId);
|
||||
|
||||
@@ -48,13 +50,9 @@ public abstract class Data {
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw) {
|
||||
return deserializeData(user, raw, Settings.isForcePermissionJoin());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final Map<CosmeticSlot, Map<Cosmetic, Color>> deserializeData(CosmeticUser user, @NotNull String raw, boolean permissionCheck) {
|
||||
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = new HashMap<>();
|
||||
public final HashMap<CosmeticSlot, Map.Entry<Cosmetic, Integer>> deserializeData(@NotNull String raw) {
|
||||
HashMap<CosmeticSlot, Map.Entry<Cosmetic, Integer>> cosmetics = new HashMap<>();
|
||||
|
||||
String[] rawData = raw.split(",");
|
||||
ArrayList<CosmeticUser.HiddenReason> hiddenReason = new ArrayList<>();
|
||||
@@ -76,59 +74,14 @@ public abstract class Data {
|
||||
String[] colorSplitData = splitData[1].split("&");
|
||||
if (Cosmetics.hasCosmetic(colorSplitData[0])) cosmetic = Cosmetics.getCosmetic(colorSplitData[0]);
|
||||
if (slot == null || cosmetic == null) continue;
|
||||
if (permissionCheck && cosmetic.requiresPermission()) {
|
||||
if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cosmetics.put(slot, Map.of(cosmetic, Color.fromRGB(Integer.parseInt(colorSplitData[1]))));
|
||||
cosmetics.put(slot, Map.entry(cosmetic, Integer.parseInt(colorSplitData[1])));
|
||||
} else {
|
||||
if (Cosmetics.hasCosmetic(splitData[1])) cosmetic = Cosmetics.getCosmetic(splitData[1]);
|
||||
if (slot == null || cosmetic == null) continue;
|
||||
if (permissionCheck && cosmetic.requiresPermission()) {
|
||||
if (user.getPlayer() != null && !user.getPlayer().hasPermission(cosmetic.getPermission())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
HashMap<Cosmetic, Color> cosmeticColorHashMap = new HashMap<>();
|
||||
cosmeticColorHashMap.put(cosmetic, null);
|
||||
cosmetics.put(slot, cosmeticColorHashMap);
|
||||
cosmetics.put(slot, Map.entry(cosmetic, -1));
|
||||
}
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("Hidden Reason: " + hiddenReason);
|
||||
// if else this, if else that, if else I got to deal with this anymore i'll lose my mind
|
||||
if (!hiddenReason.isEmpty()) {
|
||||
for (CosmeticUser.HiddenReason reason : hiddenReason) user.silentlyAddHideFlag(reason);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
// Handle gamemode check
|
||||
if (user.getPlayer() != null && Settings.isDisabledGamemodesEnabled() && Settings.getDisabledGamemodes().contains(user.getPlayer().getGameMode().toString())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to gamemode");
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
|
||||
return;
|
||||
} else {
|
||||
if (user.isHidden(CosmeticUser.HiddenReason.GAMEMODE)) {
|
||||
MessagesUtil.sendDebugMessages("Join Gamemode Check: Showing Cosmetics");
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.GAMEMODE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Handle world check
|
||||
if (user.getPlayer() != null && Settings.getDisabledWorlds().contains(user.getPlayer().getWorld().getName())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to world");
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||
} else {
|
||||
if (user.isHidden(CosmeticUser.HiddenReason.WORLD)) {
|
||||
MessagesUtil.sendDebugMessages("Join World Check: Showing Cosmetics");
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||
}
|
||||
}
|
||||
if (Settings.isAllPlayersHidden()) {
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.DISABLED);
|
||||
}
|
||||
});
|
||||
}
|
||||
return cosmetics;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.hibiscusmc.hmccosmetics.database.types;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class NoneData extends Data {
|
||||
@Override
|
||||
@@ -17,8 +19,8 @@ public class NoneData extends Data {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CosmeticUser get(UUID uniqueId) {
|
||||
return new CosmeticUser(uniqueId);
|
||||
public @Nullable CompletableFuture<UserData> get(UUID uniqueId) {
|
||||
return CompletableFuture.completedFuture(new UserData(uniqueId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.database.types;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
@@ -13,14 +14,15 @@ import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class SQLData extends Data {
|
||||
@Override
|
||||
@SuppressWarnings({"resource"}) // Duplicate is from deprecated InternalData
|
||||
public CosmeticUser get(UUID uniqueId) {
|
||||
CosmeticUser user = new CosmeticUser(uniqueId);
|
||||
public CompletableFuture<UserData> get(UUID uniqueId) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
UserData data = new UserData(uniqueId);
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
PreparedStatement preparedStatement = null;
|
||||
try {
|
||||
preparedStatement = preparedStatement("SELECT * FROM COSMETICDATABASE WHERE UUID = ?;");
|
||||
@@ -28,21 +30,8 @@ public abstract class SQLData extends Data {
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
if (rs.next()) {
|
||||
String rawData = rs.getString("COSMETICS");
|
||||
Map<CosmeticSlot, Map<Cosmetic, Color>> cosmetics = deserializeData(user, rawData);
|
||||
// Load cosmetics, put them into the addedCosmetic hashmap
|
||||
HashMap<Cosmetic, Color> addedCosmetics = new HashMap<>();
|
||||
for (Map<Cosmetic, Color> cosmeticColors : cosmetics.values()) {
|
||||
for (Cosmetic cosmetic : cosmeticColors.keySet()) {
|
||||
addedCosmetics.put(cosmetic, cosmeticColors.get(cosmetic));
|
||||
}
|
||||
}
|
||||
// Run a task on the main thread, adding the cosmetics to the player
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
// This can not be async.
|
||||
for (Cosmetic cosmetic : addedCosmetics.keySet()) {
|
||||
user.addPlayerCosmetic(cosmetic, addedCosmetics.get(cosmetic));
|
||||
}
|
||||
});
|
||||
HashMap<CosmeticSlot, Map.Entry<Cosmetic, Integer>> cosmetics = deserializeData(rawData);
|
||||
data.setCosmetics(cosmetics);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
@@ -51,9 +40,8 @@ public abstract class SQLData extends Data {
|
||||
if (preparedStatement != null) preparedStatement.close();
|
||||
} catch (SQLException e) {}
|
||||
}
|
||||
return data;
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerMenuCloseEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerMenuOpenEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
||||
import com.hibiscusmc.hmccosmetics.gui.type.Types;
|
||||
@@ -11,6 +13,8 @@ import com.hibiscusmc.hmccosmetics.gui.type.types.TypeCosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import dev.triumphteam.gui.builder.item.ItemBuilder;
|
||||
import dev.triumphteam.gui.components.GuiType;
|
||||
import dev.triumphteam.gui.components.InventoryProvider;
|
||||
import dev.triumphteam.gui.guis.Gui;
|
||||
import dev.triumphteam.gui.guis.GuiItem;
|
||||
import lombok.Getter;
|
||||
@@ -24,6 +28,7 @@ import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -104,8 +109,7 @@ public class Menu {
|
||||
|
||||
int priority = config.node("priority").getInt(1);
|
||||
|
||||
Type type = null;
|
||||
|
||||
Type type = Types.getDefaultType();
|
||||
if (!config.node("type").virtual()) {
|
||||
String typeId = config.node("type").getString("");
|
||||
if (Types.isType(typeId)) type = Types.getType(typeId);
|
||||
@@ -119,7 +123,7 @@ public class Menu {
|
||||
menuItems.sort(priorityCompare);
|
||||
items.put(slot, menuItems);
|
||||
} else {
|
||||
items.put(slot, new ArrayList<>(Arrays.asList(menuItem)));
|
||||
items.put(slot, new ArrayList<>(List.of(menuItem)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,16 +136,26 @@ public class Menu {
|
||||
public void openMenu(@NotNull CosmeticUser user, boolean ignorePermission) {
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
openMenu(player, user, ignorePermission);
|
||||
}
|
||||
|
||||
public void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder) {
|
||||
openMenu(viewer, cosmeticHolder, false);
|
||||
}
|
||||
|
||||
public void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, boolean ignorePermission) {
|
||||
if (!ignorePermission && !permissionNode.isEmpty()) {
|
||||
if (!player.hasPermission(permissionNode) && !player.isOp()) {
|
||||
MessagesUtil.sendMessage(player, "no-permission");
|
||||
if (!viewer.hasPermission(permissionNode) && !viewer.isOp()) {
|
||||
MessagesUtil.sendMessage(viewer, "no-permission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Component component = AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(player, this.title));
|
||||
final Component component = AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(viewer, this.title));
|
||||
Gui gui = Gui.gui()
|
||||
.title(component)
|
||||
.type(GuiType.CHEST)
|
||||
.rows(this.rows)
|
||||
.inventory((title, owner, rows) -> Bukkit.createInventory(owner, rows, title))
|
||||
.create();
|
||||
|
||||
gui.setDefaultClickAction(event -> event.setCancelled(true));
|
||||
@@ -153,7 +167,7 @@ public class Menu {
|
||||
Bukkit.getScheduler().cancelTask(taskid.get());
|
||||
}
|
||||
|
||||
updateMenu(user, gui);
|
||||
updateMenu(viewer, cosmeticHolder, gui);
|
||||
};
|
||||
|
||||
if (refreshRate != -1) {
|
||||
@@ -164,22 +178,29 @@ public class Menu {
|
||||
});
|
||||
|
||||
gui.setCloseGuiAction(event -> {
|
||||
if (cosmeticHolder instanceof CosmeticUser user) {
|
||||
PlayerMenuCloseEvent closeEvent = new PlayerMenuCloseEvent(user, this, event.getReason());
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(closeEvent));
|
||||
}
|
||||
|
||||
if (taskid.get() != -1) Bukkit.getScheduler().cancelTask(taskid.get());
|
||||
});
|
||||
|
||||
// API
|
||||
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(event));
|
||||
if (event.isCancelled()) return;
|
||||
if (cosmeticHolder instanceof CosmeticUser user) {
|
||||
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> Bukkit.getPluginManager().callEvent(event));
|
||||
if (event.isCancelled()) return;
|
||||
}
|
||||
// Internal
|
||||
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
gui.open(player);
|
||||
updateMenu(user, gui); // fixes shading? I know I do this twice but it's easier than writing a whole new class to deal with this shit
|
||||
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(CosmeticUser user, Gui gui) {
|
||||
private void updateMenu(Player viewer, CosmeticHolder cosmeticHolder, Gui gui) {
|
||||
StringBuilder title = new StringBuilder(this.title);
|
||||
|
||||
int row = 0;
|
||||
@@ -203,15 +224,15 @@ public class Menu {
|
||||
// Handles the items
|
||||
List<MenuItem> menuItems = items.get(i);
|
||||
MenuItem item = menuItems.get(0);
|
||||
updateItem(user, gui, i);
|
||||
updateItem(viewer, cosmeticHolder, gui, i);
|
||||
|
||||
if (item.type() instanceof TypeCosmetic) {
|
||||
Cosmetic cosmetic = Cosmetics.getCosmetic(item.itemConfig().node("cosmetic").getString(""));
|
||||
if (cosmetic == null) continue;
|
||||
if (user.hasCosmeticInSlot(cosmetic)) {
|
||||
if (cosmeticHolder.hasCosmeticInSlot(cosmetic)) {
|
||||
title.append(Settings.getEquippedCosmeticColor());
|
||||
} else {
|
||||
if (user.canEquipCosmetic(cosmetic, true)) {
|
||||
if (cosmeticHolder.canEquipCosmetic(cosmetic, true)) {
|
||||
title.append(Settings.getEquipableCosmeticColor());
|
||||
} else {
|
||||
title.append(Settings.getLockedCosmeticColor());
|
||||
@@ -227,42 +248,42 @@ public class Menu {
|
||||
}
|
||||
}
|
||||
MessagesUtil.sendDebugMessages("Updated menu with title " + title);
|
||||
gui.updateTitle(StringUtils.parseStringToString(Hooks.processPlaceholders(user.getPlayer(), title.toString())));
|
||||
gui.updateTitle(StringUtils.parseStringToString(Hooks.processPlaceholders(viewer, title.toString())));
|
||||
} else {
|
||||
for (int i = 0; i < gui.getInventory().getSize(); i++) {
|
||||
if (items.containsKey(i)) {
|
||||
updateItem(user, gui, i);
|
||||
updateItem(viewer, cosmeticHolder, gui, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItem(CosmeticUser user, Gui gui, int slot) {
|
||||
private void updateItem(Player viewer, CosmeticHolder cosmeticHolder, Gui gui, int slot) {
|
||||
if (!items.containsKey(slot)) return;
|
||||
List<MenuItem> menuItems = items.get(slot);
|
||||
if (menuItems.isEmpty()) return;
|
||||
|
||||
for (MenuItem item : menuItems) {
|
||||
Type type = item.type();
|
||||
ItemStack modifiedItem = getMenuItem(user, type, item.itemConfig(), item.item().clone(), slot);
|
||||
ItemStack modifiedItem = getMenuItem(viewer, cosmeticHolder, type, item.itemConfig(), item.item().clone(), slot);
|
||||
if (modifiedItem.getType().isAir()) continue;
|
||||
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
|
||||
guiItem.setAction(event -> {
|
||||
UUID uuid = user.getUniqueId();
|
||||
UUID uuid = viewer.getUniqueId();
|
||||
if (Settings.isMenuClickCooldown()) {
|
||||
Long userCooldown = Menus.getCooldown(uuid);
|
||||
if (userCooldown != 0 && (System.currentTimeMillis() - Menus.getCooldown(uuid) <= getCooldown())) {
|
||||
MessagesUtil.sendDebugMessages("Cooldown for " + user.getUniqueId() + " System time: " + System.currentTimeMillis() + " Cooldown: " + Menus.getCooldown(user.getUniqueId()) + " Difference: " + (System.currentTimeMillis() - Menus.getCooldown(user.getUniqueId())));
|
||||
MessagesUtil.sendMessage(user.getPlayer(), "on-click-cooldown");
|
||||
MessagesUtil.sendDebugMessages("Cooldown for " + viewer.getUniqueId() + " System time: " + System.currentTimeMillis() + " Cooldown: " + Menus.getCooldown(viewer.getUniqueId()) + " Difference: " + (System.currentTimeMillis() - Menus.getCooldown(viewer.getUniqueId())));
|
||||
MessagesUtil.sendMessage(viewer, "on-click-cooldown");
|
||||
return;
|
||||
} else {
|
||||
Menus.addCooldown(user.getUniqueId(), System.currentTimeMillis());
|
||||
Menus.addCooldown(uuid, System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
MessagesUtil.sendDebugMessages("Updated Menu Item in slot number " + slot);
|
||||
final ClickType clickType = event.getClick();
|
||||
if (type != null) type.run(user, item.itemConfig(), clickType);
|
||||
updateMenu(user, gui);
|
||||
if (type != null) type.run(viewer, cosmeticHolder, item.itemConfig(), clickType);
|
||||
updateMenu(viewer, cosmeticHolder, gui);
|
||||
});
|
||||
|
||||
MessagesUtil.sendDebugMessages("Set an item in slot " + slot + " in the menu of " + getId());
|
||||
@@ -297,11 +318,11 @@ public class Menu {
|
||||
return slots;
|
||||
}
|
||||
|
||||
@Contract("_, _, _, _, _ -> param2")
|
||||
@Contract("_, _, _, _, _, _ -> param4")
|
||||
@NotNull
|
||||
private ItemStack getMenuItem(CosmeticUser user, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
private ItemStack getMenuItem(Player viewer, CosmeticHolder cosmeticHolder, Type type, ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
if (!itemStack.hasItemMeta()) return itemStack;
|
||||
return type.setItem(user, config, itemStack, slot);
|
||||
return type.setItem(viewer, cosmeticHolder, config, itemStack, slot);
|
||||
}
|
||||
|
||||
public boolean canOpen(Player player) {
|
||||
|
||||
@@ -3,9 +3,10 @@ package com.hibiscusmc.hmccosmetics.gui;
|
||||
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record MenuItem(List<Integer> slots, ItemStack item, Type type, int priority, ConfigurationNode itemConfig) {
|
||||
public record MenuItem(@NotNull List<Integer> slots, @NotNull ItemStack item, Type type, int priority, ConfigurationNode itemConfig) {
|
||||
|
||||
}
|
||||
|
||||
@@ -3,12 +3,15 @@ package com.hibiscusmc.hmccosmetics.gui;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lojosho.shaded.configurate.CommentedConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.ConfigurateException;
|
||||
import me.lojosho.shaded.configurate.yaml.YamlConfigurationLoader;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
@@ -22,10 +25,11 @@ public class Menus {
|
||||
private static final HashMap<String, Menu> MENUS = new HashMap<>();
|
||||
private static final HashMap<UUID, Long> COOLDOWNS = new HashMap<>();
|
||||
|
||||
public static void addMenu(Menu menu) {
|
||||
public static void addMenu(@NotNull Menu menu) {
|
||||
MENUS.put(menu.getId().toUpperCase(), menu);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Menu getMenu(@NotNull String id) {
|
||||
return MENUS.get(id.toUpperCase());
|
||||
}
|
||||
@@ -40,11 +44,18 @@ public class Menus {
|
||||
return MENUS.containsKey(id.toUpperCase());
|
||||
}
|
||||
|
||||
public static boolean hasMenu(Menu menu) {
|
||||
public static boolean hasMenu(@NotNull Menu menu) {
|
||||
return MENUS.containsValue(menu);
|
||||
}
|
||||
|
||||
public static Menu getDefaultMenu() { return Menus.getMenu(Settings.getDefaultMenu()); }
|
||||
public static boolean hasDefaultMenu() {
|
||||
return MENUS.containsKey(Settings.getDefaultMenu());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Menu getDefaultMenu() {
|
||||
return Menus.getMenu(Settings.getDefaultMenu());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> getMenuNames() {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class Action {
|
||||
@@ -16,5 +18,13 @@ public abstract class Action {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
run(CosmeticHolder.ensureSingleCosmeticUser(viewer, cosmeticHolder), raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Override {@link #run(Player, CosmeticHolder, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void run(CosmeticUser user, String raw);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.actions.*;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -41,16 +43,20 @@ public class Actions {
|
||||
actions.put(action.getId().toUpperCase(), action);
|
||||
}
|
||||
|
||||
public static void runActions(CosmeticUser user, @NotNull List<String> raw) {
|
||||
public static void runActions(Player viewer, CosmeticHolder cosmeticHolder, @NotNull List<String> raw) {
|
||||
for (String a : raw) {
|
||||
String id = StringUtils.substringBetween(a, "[", "]").toUpperCase();
|
||||
String message = StringUtils.substringAfter(a, "] ");
|
||||
MessagesUtil.sendDebugMessages("ID is " + id + " // Raw Data is " + message);
|
||||
if (isAction(id)) {
|
||||
getAction(id).run(user, message);
|
||||
getAction(id).run(viewer, cosmeticHolder, message);
|
||||
} else {
|
||||
MessagesUtil.sendDebugMessages("Possible ids: " + actions.keySet());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void runActions(CosmeticUser user, @NotNull List<String> raw) {
|
||||
runActions(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionCloseMenu extends Action {
|
||||
@@ -10,8 +12,13 @@ public class ActionCloseMenu extends Action {
|
||||
super("close");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
viewer.closeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
user.getPlayer().closeInventory();
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionConsoleCommand extends Action {
|
||||
@@ -13,8 +15,15 @@ public class ActionConsoleCommand extends Action {
|
||||
super("console-command");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
// todo: some of these generalizations may require more specific implementations, for example,
|
||||
// todo: what if we wanted to execute console commands only for the cosmetic holder?
|
||||
HMCCosmeticsPlugin.getInstance().getServer().dispatchCommand(Bukkit.getConsoleSender(), Hooks.processPlaceholders(viewer, raw));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
HMCCosmeticsPlugin.getInstance().getServer().dispatchCommand(Bukkit.getConsoleSender(), Hooks.processPlaceholders(user.getPlayer(), raw));
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionCosmeticHide extends Action {
|
||||
@@ -11,8 +13,14 @@ public class ActionCosmeticHide extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
if (!(cosmeticHolder instanceof CosmeticUser user)) return;
|
||||
if (user.isHidden()) return;
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionCosmeticShow extends Action {
|
||||
@@ -11,11 +13,17 @@ public class ActionCosmeticShow extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
if (!(cosmeticHolder instanceof CosmeticUser user)) return;
|
||||
if (!user.isHidden()) return;
|
||||
|
||||
// Do not hide if it's already off for WG
|
||||
if (!user.isHidden(CosmeticUser.HiddenReason.ACTION) && !user.isHidden(CosmeticUser.HiddenReason.COMMAND)) return;
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionCosmeticToggle extends Action {
|
||||
@@ -11,7 +13,8 @@ public class ActionCosmeticToggle extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
if (!(cosmeticHolder instanceof CosmeticUser user)) return;
|
||||
if (user.isHidden()) {
|
||||
if (!user.isHidden(CosmeticUser.HiddenReason.ACTION) && !user.isHidden(CosmeticUser.HiddenReason.COMMAND)) return;
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.ACTION);
|
||||
@@ -20,4 +23,9 @@ public class ActionCosmeticToggle extends Action {
|
||||
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ActionEquip extends Action {
|
||||
|
||||
@@ -12,10 +14,15 @@ public class ActionEquip extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
Cosmetic cosmetic = Cosmetics.getCosmetic(raw);
|
||||
if (cosmetic == null) return;
|
||||
|
||||
user.addPlayerCosmetic(cosmetic);
|
||||
cosmeticHolder.addCosmetic(cosmetic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
@@ -15,7 +17,7 @@ public class ActionMenu extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
boolean ignorePermission = false;
|
||||
|
||||
raw = raw.replaceAll(" ", ""); // Removes all spaces
|
||||
@@ -32,6 +34,11 @@ public class ActionMenu extends Action {
|
||||
|
||||
Menu menu = Menus.getMenu(raw);
|
||||
MessagesUtil.sendDebugMessages(raw + " | " + ignorePermission);
|
||||
menu.openMenu(user, ignorePermission);
|
||||
menu.openMenu(viewer, cosmeticHolder, ignorePermission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionMessage extends Action {
|
||||
@@ -11,8 +13,13 @@ public class ActionMessage extends Action {
|
||||
super("message");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
MessagesUtil.sendMessageNoKey(viewer, raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
MessagesUtil.sendMessageNoKey(user.getPlayer(), raw);
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
@@ -24,7 +25,7 @@ public class ActionParticle extends Action {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public void run(CosmeticUser user, @NotNull String raw) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
String[] rawString = raw.split(" ");
|
||||
ParticleType<?, ?> particleType = Particles.fromKey(NamespacedKey.minecraft(rawString[0].toLowerCase()));
|
||||
if (particleType == null) {
|
||||
@@ -43,9 +44,14 @@ public class ActionParticle extends Action {
|
||||
}
|
||||
|
||||
particle = HMCCServerUtils.addParticleValues(particle, rawString);
|
||||
Location location = user.getPlayer().getLocation();
|
||||
Location location = viewer.getLocation();
|
||||
for (Player player : HMCCPacketManager.getViewers(location)) {
|
||||
particle.compile().send(player, location);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, @NotNull String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionPlayerCommand extends Action {
|
||||
@@ -12,8 +14,14 @@ public class ActionPlayerCommand extends Action {
|
||||
super("player-command");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
// todo: what if we wanted the cosmetic holder to execute the command instead
|
||||
viewer.performCommand(MessagesUtil.processStringNoKeyString(viewer, Hooks.processPlaceholders(viewer, raw)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, String raw) {
|
||||
user.getPlayer().performCommand(MessagesUtil.processStringNoKeyString(user.getPlayer(), Hooks.processPlaceholders(user.getPlayer(), raw)));
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
@@ -16,8 +17,7 @@ public class ActionSound extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, @NotNull String raw) {
|
||||
Player player = user.getPlayer();
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
String[] processedString = raw.split(" ");
|
||||
|
||||
String soundName = processedString[0];
|
||||
@@ -31,6 +31,11 @@ public class ActionSound extends Action {
|
||||
|
||||
MessagesUtil.sendDebugMessages("Attempting to play " + soundName, Level.INFO);
|
||||
|
||||
player.playSound(player.getLocation(), soundName, volume, pitch);
|
||||
viewer.playSound(viewer.getLocation(), soundName, volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(@NotNull CosmeticUser user, @NotNull String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.action.actions;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Action;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ActionUnequip extends Action {
|
||||
|
||||
@@ -12,10 +13,15 @@ public class ActionUnequip extends Action {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
if (!EnumUtils.isValidEnum(CosmeticSlot.class, raw)) return;
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, String raw) {
|
||||
if (!CosmeticSlot.contains(raw)) return;
|
||||
|
||||
CosmeticSlot slot = CosmeticSlot.valueOf(raw);
|
||||
user.removeCosmeticSlot(slot);
|
||||
cosmeticHolder.removeCosmeticSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, String raw) {
|
||||
run(user.getPlayer(), user, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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.user.CosmeticUser;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.hibiscuscommons.util.ColorBuilder;
|
||||
@@ -15,23 +16,19 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DyeMenu {
|
||||
|
||||
public static void openMenu(@NotNull CosmeticUser user, Cosmetic cosmetic) {
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
public static void openMenu(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, Cosmetic cosmetic) {
|
||||
if (!Hooks.isActiveHook("HMCColor")) {
|
||||
addCosmetic(user, cosmetic, null);
|
||||
addCosmetic(viewer, cosmeticHolder, cosmetic, null);
|
||||
return;
|
||||
}
|
||||
ItemStack originalItem = user.getUserCosmeticItem(cosmetic);
|
||||
ItemStack originalItem = cosmetic.getItem();
|
||||
if (originalItem == null || !cosmetic.isDyable()) return;
|
||||
|
||||
Gui gui = HMCColorApi.createColorMenu(player);
|
||||
gui.updateTitle(Hooks.processPlaceholders(player, StringUtils.parseStringToString(Settings.getDyeMenuName())));
|
||||
Gui gui = HMCColorApi.createColorMenu(viewer);
|
||||
gui.updateTitle(Hooks.processPlaceholders(viewer, StringUtils.parseStringToString(Settings.getDyeMenuName())));
|
||||
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
|
||||
gui.setDefaultTopClickAction(event -> {
|
||||
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {
|
||||
@@ -55,23 +52,28 @@ public class DyeMenu {
|
||||
}
|
||||
if (color == null) return;
|
||||
|
||||
addCosmetic(user, cosmetic, color);
|
||||
addCosmetic(viewer, cosmeticHolder, cosmetic, color);
|
||||
event.setCancelled(true);
|
||||
} else event.setCancelled(true);
|
||||
});
|
||||
|
||||
gui.setPlayerInventoryAction(event -> event.setCancelled(true));
|
||||
gui.setCloseGuiAction(event -> {});
|
||||
gui.open(player);
|
||||
gui.open(viewer);
|
||||
}
|
||||
|
||||
private static void addCosmetic(@NotNull CosmeticUser user, Cosmetic cosmetic, Color color) {
|
||||
public static void openMenu(@NotNull CosmeticUser user, Cosmetic cosmetic) {
|
||||
Player player = user.getPlayer();
|
||||
user.addPlayerCosmetic(cosmetic, color);
|
||||
player.setItemOnCursor(new ItemStack(Material.AIR));
|
||||
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(), () -> {
|
||||
player.closeInventory();
|
||||
user.updateCosmetic(cosmetic.getSlot());
|
||||
viewer.closeInventory();
|
||||
cosmeticHolder.updateCosmetic(cosmetic.getSlot());
|
||||
}, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.type;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -18,11 +20,32 @@ public abstract class Type {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void run(CosmeticUser user, ConfigurationNode config) {
|
||||
run(user, config, null);
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, ConfigurationNode config) {
|
||||
run(viewer, cosmeticHolder, config, null);
|
||||
}
|
||||
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, ConfigurationNode config, ClickType clickType) {
|
||||
run(CosmeticHolder.ensureSingleCosmeticUser(viewer, cosmeticHolder), config, clickType);
|
||||
}
|
||||
|
||||
public void run(CosmeticUser user, ConfigurationNode config) {
|
||||
final var player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
run(player, user, config, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Override {@link #run(Player, CosmeticHolder, ConfigurationNode, ClickType)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void run(CosmeticUser user, ConfigurationNode config, ClickType clickType);
|
||||
|
||||
public ItemStack setItem(Player viewer, CosmeticHolder cosmeticHolder, ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
return setItem(CosmeticHolder.ensureSingleCosmeticUser(viewer, cosmeticHolder), config, itemStack, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Override {@link #setItem(Player, CosmeticHolder, ConfigurationNode, ItemStack, int)} instead.
|
||||
*/
|
||||
public abstract ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot);
|
||||
}
|
||||
|
||||
@@ -10,18 +10,43 @@ public class Types {
|
||||
|
||||
private static final HashMap<String, Type> types = new HashMap<>();
|
||||
|
||||
private static TypeCosmetic TYPE_COSMETIC = new TypeCosmetic();
|
||||
private static TypeEmpty TYPE_EMPTY = new TypeEmpty();
|
||||
private static final TypeCosmetic TYPE_COSMETIC = new TypeCosmetic();
|
||||
private static final TypeEmpty TYPE_EMPTY = new TypeEmpty();
|
||||
|
||||
/**
|
||||
* Get's a Menu Item type. Add custom menu item types with {@link #addType(Type)}
|
||||
* @param id A non-case sensitive ID
|
||||
* @return The type of Menu Item
|
||||
*/
|
||||
public static Type getType(@NotNull String id) {
|
||||
return types.get(id.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a type is valid. Add custom menu item types with {@link #addType(Type)}
|
||||
* @param id A non-case sensitive ID
|
||||
* @return True if exists, False if not.
|
||||
*/
|
||||
public static boolean isType(@NotNull String id) {
|
||||
return types.containsKey(id.toUpperCase());
|
||||
}
|
||||
|
||||
public static void addType(Type type) {
|
||||
types.put(type.getId().toUpperCase(), type);
|
||||
/**
|
||||
* Adds a Menu Item Type to the types HashMap for reference. Menu Types will automatically be added using this method.
|
||||
* @param type A non-null {@link Type} that'll be added. ID should be unique; can't be duplicated
|
||||
*/
|
||||
public static boolean addType(@NotNull Type type) {
|
||||
String id = type.getId().toUpperCase();
|
||||
if (types.containsKey(id)) return false;
|
||||
types.put(id, type);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default menu item; {@link TypeEmpty}
|
||||
* @return The empty menu type.
|
||||
*/
|
||||
public static TypeEmpty getDefaultType() {
|
||||
return TYPE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.hibiscusmc.hmccosmetics.gui.type.types;
|
||||
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.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
|
||||
@@ -38,7 +39,7 @@ public class TypeCosmetic extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, ConfigurationNode config, ClickType clickType) {
|
||||
MessagesUtil.sendDebugMessages("Running Cosmetic Click Type");
|
||||
if (config.node("cosmetic").virtual()) {
|
||||
MessagesUtil.sendDebugMessages("Cosmetic Config Field Virtual");
|
||||
@@ -46,21 +47,20 @@ public class TypeCosmetic extends Type {
|
||||
}
|
||||
String cosmeticName = config.node("cosmetic").getString();
|
||||
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
|
||||
Player player = user.getPlayer();
|
||||
if (cosmetic == null) {
|
||||
MessagesUtil.sendDebugMessages("No Cosmetic Found");
|
||||
MessagesUtil.sendMessage(player, "invalid-cosmetic");
|
||||
MessagesUtil.sendMessage(viewer, "invalid-cosmetic");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.canEquipCosmetic(cosmetic)) {
|
||||
if (!cosmeticHolder.canEquipCosmetic(cosmetic)) {
|
||||
MessagesUtil.sendDebugMessages("No Cosmetic Permission");
|
||||
MessagesUtil.sendMessage(player, "no-cosmetic-permission");
|
||||
MessagesUtil.sendMessage(viewer, "no-cosmetic-permission");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isUnEquippingCosmetic = false;
|
||||
if (user.getCosmetic(cosmetic.getSlot()) == cosmetic) isUnEquippingCosmetic = true;
|
||||
if (cosmeticHolder.getCosmetic(cosmetic.getSlot()) == cosmetic) isUnEquippingCosmetic = true;
|
||||
|
||||
String requiredClick;
|
||||
if (isUnEquippingCosmetic) requiredClick = Settings.getCosmeticUnEquipClickType();
|
||||
@@ -69,7 +69,7 @@ public class TypeCosmetic extends Type {
|
||||
MessagesUtil.sendDebugMessages("Required click type: " + requiredClick);
|
||||
MessagesUtil.sendDebugMessages("Click type: " + clickType.name());
|
||||
if (!requiredClick.equalsIgnoreCase("ANY") && !requiredClick.equalsIgnoreCase(clickType.name())) {
|
||||
MessagesUtil.sendMessage(user.getPlayer(), "invalid-click-type");
|
||||
MessagesUtil.sendMessage(viewer.getPlayer(), "invalid-click-type");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,25 +99,25 @@ public class TypeCosmetic extends Type {
|
||||
if (isUnEquippingCosmetic) {
|
||||
if (!actionConfig.node("on-unequip").virtual()) actionStrings.addAll(actionConfig.node("on-unequip").getList(String.class));
|
||||
MessagesUtil.sendDebugMessages("on-unequip");
|
||||
user.removeCosmeticSlot(cosmetic);
|
||||
cosmeticHolder.removeCosmeticSlot(cosmetic);
|
||||
} else {
|
||||
if (!actionConfig.node("on-equip").virtual()) actionStrings.addAll(actionConfig.node("on-equip").getList(String.class));
|
||||
MessagesUtil.sendDebugMessages("on-equip");
|
||||
// TODO: Redo this
|
||||
if (cosmetic.isDyable() && Hooks.isActiveHook("HMCColor")) {
|
||||
DyeMenu.openMenu(user, cosmetic);
|
||||
DyeMenu.openMenu(viewer, cosmeticHolder, cosmetic);
|
||||
} else {
|
||||
user.addPlayerCosmetic(cosmetic);
|
||||
cosmeticHolder.addCosmetic(cosmetic);
|
||||
}
|
||||
}
|
||||
|
||||
Actions.runActions(user, actionStrings);
|
||||
Actions.runActions(viewer, cosmeticHolder, actionStrings);
|
||||
|
||||
} catch (SerializationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Fixes issue with offhand cosmetics not appearing. Yes, I know this is dumb
|
||||
Runnable run = () -> user.updateCosmetic(cosmetic.getSlot());
|
||||
Runnable run = () -> cosmeticHolder.updateCosmetic(cosmetic.getSlot());
|
||||
if (cosmetic instanceof CosmeticArmorType) {
|
||||
if (((CosmeticArmorType) cosmetic).getEquipSlot().equals(EquipmentSlot.OFF_HAND)) {
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, 1);
|
||||
@@ -128,8 +128,19 @@ public class TypeCosmetic extends Type {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack setItem(CosmeticUser user, @NotNull ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
|
||||
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
|
||||
run(user.getPlayer(), user, config, clickType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
return setItem(user.getPlayer(), user, config, itemStack, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack setItem(@NotNull Player viewer, @NotNull CosmeticHolder cosmeticHolder, @NotNull ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processLoreLines(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta?");
|
||||
|
||||
if (config.node("cosmetic").virtual()) {
|
||||
return itemStack;
|
||||
@@ -140,9 +151,9 @@ public class TypeCosmetic extends Type {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
if (user.hasCosmeticInSlot(cosmetic) && (!config.node("equipped-item").virtual() || !config.node("locked-equipped-item").virtual())) {
|
||||
if (cosmeticHolder.hasCosmeticInSlot(cosmetic) && (!config.node("equipped-item").virtual() || !config.node("locked-equipped-item").virtual())) {
|
||||
MessagesUtil.sendDebugMessages("GUI Equipped Item");
|
||||
ConfigurationNode equippedItem = config.node(user.canEquipCosmetic(cosmetic, true) && !config.node("equipped-item").virtual() ? "equipped-item" : "locked-equipped-item");
|
||||
ConfigurationNode equippedItem = config.node(cosmeticHolder.canEquipCosmetic(cosmetic, true) && !config.node("equipped-item").virtual() ? "equipped-item" : "locked-equipped-item");
|
||||
try {
|
||||
if (equippedItem.node("material").virtual()) equippedItem.node("material").set(config.node("item", "material").getString());
|
||||
} catch (SerializationException e) {
|
||||
@@ -153,11 +164,12 @@ public class TypeCosmetic extends Type {
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processLoreLines(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta in equipped item?");
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
if (!user.canEquipCosmetic(cosmetic, true) && !config.node("locked-item").virtual()) {
|
||||
if (!cosmeticHolder.canEquipCosmetic(cosmetic, true) && !config.node("locked-item").virtual()) {
|
||||
MessagesUtil.sendDebugMessages("GUI Locked Item");
|
||||
ConfigurationNode lockedItem = config.node("locked-item");
|
||||
try {
|
||||
@@ -170,7 +182,8 @@ public class TypeCosmetic extends Type {
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
itemStack.setItemMeta(processLoreLines(user, itemStack.getItemMeta()));
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processLoreLines(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta in locked item?");
|
||||
return itemStack;
|
||||
}
|
||||
return itemStack;
|
||||
@@ -179,22 +192,22 @@ public class TypeCosmetic extends Type {
|
||||
@Contract("_, _ -> param2")
|
||||
@NotNull
|
||||
@SuppressWarnings("Duplicates")
|
||||
private ItemMeta processLoreLines(CosmeticUser user, @NotNull ItemMeta itemMeta) {
|
||||
private ItemMeta processLoreLines(Player viewer, @NotNull ItemMeta itemMeta) {
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(viewer, itemMeta.getDisplayName()));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
|
||||
processedLore.add(Hooks.processPlaceholders(viewer, loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner()) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
itemMeta.setLore(processedLore);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui.type.types;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.gui.action.Actions;
|
||||
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
@@ -23,9 +25,10 @@ public class TypeEmpty extends Type {
|
||||
// This is an empty type, meaning, when a menu item has a type of "empty" it will run the code in the method run.
|
||||
}
|
||||
|
||||
// This is the code that's run when the item is clicked.
|
||||
// This is the code that's run when the item is clicked. The item is clicked by the "viewer" player in a menu for the
|
||||
// given "cosmeticHolder". They're the same player by default, but it's not guaranteed.
|
||||
@Override
|
||||
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
|
||||
public void run(Player viewer, CosmeticHolder cosmeticHolder, @NotNull ConfigurationNode config, ClickType clickType) {
|
||||
List<String> actionStrings = new ArrayList<>(); // List where we keep the actions the server will execute.
|
||||
ConfigurationNode actionConfig = config.node("actions"); // Configuration node that actions are under.
|
||||
|
||||
@@ -52,31 +55,45 @@ public class TypeEmpty extends Type {
|
||||
}
|
||||
|
||||
// We run the actions once we got the raw strings from the config.
|
||||
Actions.runActions(user, actionStrings);
|
||||
Actions.runActions(viewer, cosmeticHolder, actionStrings);
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// backward-compatibility method, will not be required in the future
|
||||
@Override
|
||||
public void run(CosmeticUser user, ConfigurationNode config, ClickType clickType) {
|
||||
final var player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
run(player, user, config, clickType);
|
||||
}
|
||||
|
||||
// backward-compatibility method, will not be required in the future
|
||||
@Override
|
||||
public ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot) {
|
||||
return setItem(user.getPlayer(), user, config, itemStack, slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
public ItemStack setItem(CosmeticUser user, ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
|
||||
public ItemStack setItem(Player viewer, CosmeticHolder cosmeticHolder, ConfigurationNode config, @NotNull ItemStack itemStack, int slot) {
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(user.getPlayer(), itemMeta.getDisplayName()));
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(viewer, itemMeta.getDisplayName()));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(user.getPlayer(), loreLine));
|
||||
processedLore.add(Hooks.processPlaceholders(viewer, loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner()) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(user.getPlayer(), skullMeta.getOwner()));
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class HookHMCCosmetics extends Hook {
|
||||
public HookHMCCosmetics() {
|
||||
super("HMCCosmetics", HookFlag.ITEM_SUPPORT);
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,5 +25,4 @@ public class HookHMCCosmetics extends Hook {
|
||||
if (cosmetic == null) return null;
|
||||
return cosmetic.getItem();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.hibiscusmc.hmccosmetics.hooks.misc;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerWardrobeEnterEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerWardrobeLeaveEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import kr.toxicity.hud.api.BetterHud;
|
||||
import kr.toxicity.hud.api.player.HudPlayer;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hook;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class HookBetterHud extends Hook {
|
||||
|
||||
public HookBetterHud() {
|
||||
super("BetterHUD");
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerEnterWardrobe(@NotNull PlayerWardrobeEnterEvent event) {
|
||||
if (!Settings.isWardrobeHideHud()) return;
|
||||
UUID uuid = event.getUniqueId();
|
||||
HudPlayer hudPlayer = BetterHud.getInstance().getPlayerManager().getHudPlayer(uuid);
|
||||
if (hudPlayer == null) return;
|
||||
hudPlayer.setHudEnabled(false);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onPlayerLeaveWardrobe(@NotNull PlayerWardrobeLeaveEvent event) {
|
||||
if (!Settings.isWardrobeHideHud()) return;
|
||||
UUID uuid = event.getUniqueId();
|
||||
HudPlayer hudPlayer = BetterHud.getInstance().getPlayerManager().getHudPlayer(uuid);
|
||||
if (hudPlayer == null) return;
|
||||
hudPlayer.setHudEnabled(true);
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,8 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
|
||||
if (placeholderArgs.size() >= 2) {
|
||||
String args1 = placeholderArgs.get(1);
|
||||
|
||||
if (EnumUtils.isValidEnum(CosmeticSlot.class, args1.toUpperCase())) {
|
||||
String rawSlot = args1.toUpperCase();
|
||||
if (CosmeticSlot.contains(rawSlot)) {
|
||||
return TranslationUtil.getTranslation("equipped-cosmetic", String.valueOf(user.getCosmetic(CosmeticSlot.valueOf(args1.toUpperCase())) != null));
|
||||
}
|
||||
|
||||
@@ -150,7 +151,7 @@ public class HMCPlaceholderExpansion extends PlaceholderExpansion {
|
||||
if (placeholderArgs.size() >= 2) {
|
||||
String args1 = placeholderArgs.get(1).toUpperCase(); // changes offhand to OFFHAND
|
||||
|
||||
if (!EnumUtils.isValidEnum(CosmeticSlot.class, args1)) return null;
|
||||
if (!CosmeticSlot.contains(args1)) return null;
|
||||
|
||||
CosmeticSlot slot = CosmeticSlot.valueOf(args1);
|
||||
int amount = 0;
|
||||
|
||||
@@ -39,15 +39,14 @@ public class WGListener implements Listener {
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
|
||||
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
return;
|
||||
} else {
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
}
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
return;
|
||||
}
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
|
||||
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
|
||||
Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
|
||||
user.enterWardrobe(true, wardrobe);
|
||||
user.enterWardrobe(wardrobe, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +74,7 @@ public class WGListener implements Listener {
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticWardrobeFlag())) {
|
||||
if (!WardrobeSettings.getWardrobeNames().contains(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString())) return;
|
||||
Wardrobe wardrobe = WardrobeSettings.getWardrobe(protectedRegion.getFlags().get(WGHook.getCosmeticWardrobeFlag()).toString());
|
||||
user.enterWardrobe(true, wardrobe);
|
||||
user.enterWardrobe(wardrobe, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class PaperPlayerGameListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerArmorEquip(PlayerArmorChangeEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
@@ -18,7 +19,7 @@ public class PaperPlayerGameListener implements Listener {
|
||||
user.updateCosmetic(slotTypeToCosmeticType(event.getSlotType()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlayerRespawn(PlayerPostRespawnEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerLoadEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerPreLoadEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerUnloadEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
@@ -17,6 +19,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerConnectionListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@@ -33,17 +37,42 @@ public class PlayerConnectionListener implements Listener {
|
||||
);
|
||||
}
|
||||
|
||||
// This literally makes me want to end it all but I can't do that so I'll just cry instead
|
||||
Runnable run = () -> {
|
||||
if (!event.getPlayer().isOnline()) return; // If a player is no longer online, don't run this.
|
||||
CosmeticUser user = Database.get(event.getPlayer().getUniqueId());
|
||||
CosmeticUsers.addUser(user);
|
||||
MessagesUtil.sendDebugMessages("Run User Join");
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
|
||||
// And finally, launch an update for the cosmetics they have.
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
if (user.getPlayer() == null) return;
|
||||
user.updateCosmetic();
|
||||
}, 4);
|
||||
PlayerPreLoadEvent preLoadEvent = new PlayerPreLoadEvent(uuid);
|
||||
Bukkit.getPluginManager().callEvent(preLoadEvent);
|
||||
if (preLoadEvent.isCancelled()) return;
|
||||
|
||||
Database.get(uuid).thenAccept(userData -> {
|
||||
if (userData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
CosmeticUser cosmeticUser = CosmeticUsers.getProvider()
|
||||
.createCosmeticUser(uuid)
|
||||
.initialize(userData);
|
||||
cosmeticUser.startTicking();
|
||||
|
||||
CosmeticUsers.addUser(cosmeticUser);
|
||||
MessagesUtil.sendDebugMessages("Run User Join for " + uuid);
|
||||
|
||||
PlayerLoadEvent playerLoadEvent = new PlayerLoadEvent(cosmeticUser);
|
||||
Bukkit.getPluginManager().callEvent(playerLoadEvent);
|
||||
|
||||
// And finally, launch an update for the cosmetics they have.
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
if (cosmeticUser.getPlayer() == null) return;
|
||||
cosmeticUser.updateCosmetic();
|
||||
}, 4);
|
||||
});
|
||||
}).exceptionally(ex -> {
|
||||
MessagesUtil.sendDebugMessages("Unable to load Cosmetic User " + uuid + ". Exception: " + ex.getMessage());
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
if (DatabaseSettings.isEnabledDelay()) {
|
||||
@@ -58,6 +87,10 @@ public class PlayerConnectionListener implements Listener {
|
||||
public void onPlayerQuit(@NotNull PlayerQuitEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return; // Player never initialized, don't do anything
|
||||
|
||||
PlayerUnloadEvent playerUnloadEvent = new PlayerUnloadEvent(user);
|
||||
Bukkit.getPluginManager().callEvent(playerUnloadEvent);
|
||||
|
||||
if (user.isInWardrobe()) {
|
||||
user.leaveWardrobe(true);
|
||||
user.getPlayer().setInvisible(false);
|
||||
|
||||
@@ -2,10 +2,7 @@ package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.*;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.Pair;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
@@ -19,16 +16,15 @@ import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBalloonType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import me.lojosho.hibiscuscommons.api.events.*;
|
||||
import me.lojosho.hibiscuscommons.hooks.items.HookItemAdder;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -51,8 +47,6 @@ import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||
import org.spigotmc.event.entity.EntityMountEvent;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -66,10 +60,7 @@ public class PlayerGameListener implements Listener {
|
||||
registerPlayerArmListener();
|
||||
registerEntityUseListener();
|
||||
registerSlotChangeListener();
|
||||
|
||||
//registerLookMovement();
|
||||
//registerMoveListener();
|
||||
//registerTeleportMovement();
|
||||
registerPassengerSetListener();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
@@ -111,7 +102,7 @@ public class PlayerGameListener implements Listener {
|
||||
if (!event.isSneaking()) return;
|
||||
if (!user.isInWardrobe()) return;
|
||||
|
||||
user.leaveWardrobe();
|
||||
user.leaveWardrobe(false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
@@ -125,7 +116,7 @@ public class PlayerGameListener implements Listener {
|
||||
}
|
||||
|
||||
if (user.isInWardrobe()) {
|
||||
user.leaveWardrobe();
|
||||
user.leaveWardrobe(false);
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
@@ -202,7 +193,7 @@ public class PlayerGameListener implements Listener {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (WardrobeSettings.isDamagedKicked()) user.leaveWardrobe();
|
||||
if (WardrobeSettings.isDamagedKicked()) user.leaveWardrobe(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +336,7 @@ public class PlayerGameListener implements Listener {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getEntity());
|
||||
if (user == null) return;
|
||||
|
||||
if (user.isInWardrobe()) user.leaveWardrobe();
|
||||
if (user.isInWardrobe()) user.leaveWardrobe(false);
|
||||
|
||||
if (Settings.isUnapplyOnDeath() && !event.getEntity().hasPermission("hmccosmetics.unapplydeath.bypass")) {
|
||||
user.removeCosmetics();
|
||||
@@ -379,6 +370,10 @@ public class PlayerGameListener implements Listener {
|
||||
public void onPlayerCosmeticEquip(PlayerCosmeticPostEquipEvent event) {
|
||||
CosmeticUser user = event.getUser();
|
||||
if (user.isInWardrobe() && event.getCosmetic().getSlot().equals(CosmeticSlot.BALLOON)) {
|
||||
if (user.getBalloonManager() == null) {
|
||||
MessagesUtil.sendDebugMessages("Balloon Manager is null? " + user.getEntity().getName());
|
||||
return;
|
||||
}
|
||||
CosmeticBalloonType cosmetic = (CosmeticBalloonType) event.getCosmetic();
|
||||
Location npclocation = user.getWardrobeManager().getNpcLocation().clone().add(cosmetic.getBalloonOffset());
|
||||
// We know that no other entity besides a regular player will be in the wardrobe
|
||||
@@ -425,21 +420,6 @@ public class PlayerGameListener implements Listener {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onHookReload(HibiscusHookReload event) {
|
||||
if (event.getHook() instanceof HookItemAdder hook) {
|
||||
switch (event.getReloadType()) {
|
||||
case INITIAL -> {
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
case RELOAD -> {
|
||||
if (!Settings.isItemsAdderChangeReload()) return;
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These emote mostly handles emotes from other plugins, such as ItemsAdder
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerPlayEmote(HibiscusPlayerEmotePlayEvent event) {
|
||||
@@ -455,8 +435,24 @@ public class PlayerGameListener implements Listener {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.EMOTE);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerHibiscusPose(HibiscusPlayerPoseEvent event) {
|
||||
if (event.isGettingUp()) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerHibiscusGetUpPose(HibiscusPlayerPoseEvent event) {
|
||||
if (!event.isGettingUp()) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
||||
}
|
||||
|
||||
private void registerInventoryClickListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.WINDOW_CLICK) {
|
||||
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();
|
||||
@@ -482,7 +478,7 @@ public class PlayerGameListener implements Listener {
|
||||
}
|
||||
|
||||
private void registerMenuChangeListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.WINDOW_ITEMS) {
|
||||
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 ");
|
||||
@@ -516,7 +512,7 @@ public class PlayerGameListener implements Listener {
|
||||
if ((slot >= 5 && slot <= 8) || slot == 45) {
|
||||
if (!items.containsKey(slot)) continue;
|
||||
slotData.set(slot, items.get(slot));
|
||||
MessagesUtil.sendDebugMessages("Set " + slot + " as " + items.get(slot));
|
||||
if (Settings.isDebugMode()) MessagesUtil.sendDebugMessages("Set " + slot + " as " + items.get(slot));
|
||||
}
|
||||
}
|
||||
packet.getItemListModifier().write(0, slotData);
|
||||
@@ -585,6 +581,7 @@ public class PlayerGameListener implements Listener {
|
||||
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 -> {
|
||||
@@ -630,6 +627,37 @@ public class PlayerGameListener implements Listener {
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
@@ -667,68 +695,11 @@ public class PlayerGameListener implements Listener {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerLookMovement() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.LOOK) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
// TODO: Finish
|
||||
MessagesUtil.sendDebugMessages("Look Packet ");
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.isBackpackSpawned()) {
|
||||
user.getUserBackpackManager().getEntityManager().setRotation(Math.round(event.getPacket().getFloat().read(0)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerMoveListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.POSITION) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
// TODO: Finish
|
||||
MessagesUtil.sendDebugMessages("Position Packet ");
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.isBackpackSpawned()) {
|
||||
// The yaw follows the head, which makes it look weird and do weird things when moving around
|
||||
user.getUserBackpackManager().getEntityManager().teleport(new Location(player.getWorld(), event.getPacket().getDoubles().read(0), event.getPacket().getDoubles().read(1), event.getPacket().getDoubles().read(2), event.getPacket().getFloat().read(0), event.getPacket().getFloat().read(1)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerTeleportMovement() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.POSITION_LOOK) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
// TODO: Finish
|
||||
MessagesUtil.sendDebugMessages("Teleport Packet ");
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.isBackpackSpawned()) {
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(CosmeticSlot.BACKPACK));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Nullable
|
||||
private EquipmentSlot getArmorSlot(final Material material) {
|
||||
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
final Set<Material> armorItems = ARMOR_ITEMS.get(slot);
|
||||
if (armorItems == null) continue;
|
||||
if (material == null) continue;
|
||||
if (armorItems.contains(material)) return slot;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import me.lojosho.hibiscuscommons.api.events.HibiscusHookReload;
|
||||
import me.lojosho.hibiscuscommons.api.events.HibiscusHooksAllActiveEvent;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hook;
|
||||
import me.lojosho.hibiscuscommons.hooks.items.HookItemAdder;
|
||||
import me.lojosho.hibiscuscommons.hooks.items.HookNexo;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class ServerListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onHookReload(HibiscusHookReload event) {
|
||||
Hook hook = event.getHook();
|
||||
HibiscusHookReload.ReloadType reloadType = event.getReloadType();
|
||||
if (hook instanceof HookItemAdder) {
|
||||
if (reloadType == HibiscusHookReload.ReloadType.RELOAD) {
|
||||
if (!Settings.isItemsAdderChangeReload()) return;
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
}
|
||||
if (hook instanceof HookNexo) {
|
||||
if (reloadType == HibiscusHookReload.ReloadType.RELOAD) {
|
||||
if (!Settings.isNexoChangeReload()) return;
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onAllHooksReady(HibiscusHooksAllActiveEvent event) {
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,13 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
|
||||
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
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.CosmeticBalloonType;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticMainhandType;
|
||||
import com.hibiscusmc.hmccosmetics.database.UserData;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBackpackManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserBalloonManager;
|
||||
@@ -20,7 +22,6 @@ import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserWardrobeManager;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import lombok.Getter;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
@@ -38,16 +39,16 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CosmeticUser {
|
||||
|
||||
public class CosmeticUser implements CosmeticHolder {
|
||||
@Getter
|
||||
private final UUID uniqueId;
|
||||
private int taskId;
|
||||
private int taskId = -1;
|
||||
private final HashMap<CosmeticSlot, Cosmetic> playerCosmetics = new HashMap<>();
|
||||
private UserWardrobeManager userWardrobeManager;
|
||||
private UserBalloonManager userBalloonManager;
|
||||
@@ -58,49 +59,167 @@ public class CosmeticUser {
|
||||
|
||||
// Cosmetic Settings/Toggles
|
||||
private final ArrayList<HiddenReason> hiddenReason = new ArrayList<>();
|
||||
private final HashMap<CosmeticSlot, ItemStack> cachedCosmeticItems = new HashMap<>();
|
||||
private final HashMap<CosmeticSlot, Color> colors = new HashMap<>();
|
||||
|
||||
public CosmeticUser(UUID uuid) {
|
||||
this.uniqueId = uuid;
|
||||
userEmoteManager = new UserEmoteManager(this);
|
||||
tick();
|
||||
/**
|
||||
* Use {@link #CosmeticUser(UUID)} instead and use {@link #initialize(UserData)} to populate the user with data.
|
||||
* @param uuid
|
||||
* @param data
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.7.5")
|
||||
public CosmeticUser(UUID uuid, UserData data) {
|
||||
this(uuid);
|
||||
initialize(data);
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
// Occasionally updates the entity cosmetics
|
||||
Runnable run = () -> {
|
||||
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
|
||||
updateCosmetic();
|
||||
if (isHidden() && !getUserEmoteManager().isPlayingEmote() && !getCosmetics().isEmpty()) MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
|
||||
};
|
||||
public CosmeticUser(@NotNull UUID uuid) {
|
||||
this.uniqueId = uuid;
|
||||
this.userEmoteManager = new UserEmoteManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the {@link CosmeticUser}.
|
||||
* @param userData the associated {@link UserData}
|
||||
* @return the {@link CosmeticUser}
|
||||
* @apiNote Initialize is called after {@link CosmeticUserProvider#createCosmeticUser(UUID)} so it is possible to
|
||||
* populate an extending version of {@link CosmeticUser} with data then override this method to apply your
|
||||
* own state.
|
||||
*/
|
||||
public CosmeticUser initialize(final @Nullable UserData userData) {
|
||||
if(userData != null) {
|
||||
// CosmeticSlot -> Entry<Cosmetic, Integer>
|
||||
for(final Map.Entry<CosmeticSlot, Map.Entry<Cosmetic, Integer>> entry : userData.getCosmetics().entrySet()) {
|
||||
final Cosmetic cosmetic = entry.getValue().getKey();
|
||||
final Integer colorRGBInt = entry.getValue().getValue();
|
||||
|
||||
if (!this.canApplyCosmetic(cosmetic)) {
|
||||
MessagesUtil.sendDebugMessages("Cannot apply cosmetic[id=" + cosmetic.getId() + "]");
|
||||
continue;
|
||||
}
|
||||
|
||||
Color color = null;
|
||||
if (colorRGBInt != -1) color = Color.fromRGB(colorRGBInt); // -1 is defined as no color; anything else is a color
|
||||
|
||||
this.addPlayerCosmetic(cosmetic, color);
|
||||
}
|
||||
this.applyHiddenState(userData.getHiddenReasons());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only called from {@link #initialize(UserData)} and can't be called directly.
|
||||
* This is used to help hooking plugins apply custom logic to the user.
|
||||
*/
|
||||
protected boolean applyCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||
this.addPlayerCosmetic(cosmetic, color);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only called from {@link #initialize(UserData)} and can't be called directly.
|
||||
* This is used to help hooking plugins apply custom logic to the user.
|
||||
*/
|
||||
protected boolean canApplyCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
return canEquipCosmetic(cosmetic, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only called from {@link #initialize(UserData)} and can't be called directly.
|
||||
* This is used to help hooking plugins apply custom logic to the user.
|
||||
*/
|
||||
protected void applyHiddenState(@NotNull List<HiddenReason> hiddenReasons) {
|
||||
if(!hiddenReason.isEmpty()) {
|
||||
for(final HiddenReason reason : this.hiddenReason) {
|
||||
this.silentlyAddHideFlag(reason);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Player bukkitPlayer = getPlayer();
|
||||
if (bukkitPlayer != null && Settings.isDisabledGamemodesEnabled() && Settings.getDisabledGamemodes().contains(bukkitPlayer.getGameMode().toString())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding cosmetics due to gamemode");
|
||||
hideCosmetics(HiddenReason.GAMEMODE);
|
||||
} else if (this.isHidden(HiddenReason.GAMEMODE)) {
|
||||
MessagesUtil.sendDebugMessages("Showing cosmetics for gamemode");
|
||||
showCosmetics(HiddenReason.GAMEMODE);
|
||||
}
|
||||
|
||||
if (bukkitPlayer != null && Settings.getDisabledWorlds().contains(getEntity().getLocation().getWorld().getName())) {
|
||||
MessagesUtil.sendDebugMessages("Hiding Cosmetics due to world");
|
||||
hideCosmetics(CosmeticUser.HiddenReason.WORLD);
|
||||
} else if (this.isHidden(HiddenReason.WORLD)) {
|
||||
MessagesUtil.sendDebugMessages("Showing Cosmetics due to world");
|
||||
showCosmetics(HiddenReason.WORLD);
|
||||
}
|
||||
if (Settings.isAllPlayersHidden()) {
|
||||
hideCosmetics(HiddenReason.DISABLED);
|
||||
}
|
||||
|
||||
for (final HiddenReason reason : hiddenReasons) {
|
||||
this.silentlyAddHideFlag(reason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start ticking against the {@link CosmeticUser}.
|
||||
* @implNote The tick-rate is determined by the tick period specified in the configuration, if it is less-than or equal to 0
|
||||
* there will be no {@link BukkitTask} created, and the {@link CosmeticUser#taskId} will be -1
|
||||
*/
|
||||
public final void startTicking() {
|
||||
int tickPeriod = Settings.getTickPeriod();
|
||||
if (tickPeriod > 0) {
|
||||
BukkitTask task = Bukkit.getScheduler().runTaskTimer(HMCCosmeticsPlugin.getInstance(), run, 0, tickPeriod);
|
||||
taskId = task.getTaskId();
|
||||
if(tickPeriod <= 0) {
|
||||
MessagesUtil.sendDebugMessages("CosmeticUser tick is disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
final BukkitTask task = Bukkit.getScheduler().runTaskTimer(HMCCosmeticsPlugin.getInstance(), this::tick, 0, tickPeriod);
|
||||
this.taskId = task.getTaskId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch an operation to happen against this {@link CosmeticUser}
|
||||
* at a pre-determined tick-rate.
|
||||
* The tick-rate is determined by the tick period specified in the configuration.
|
||||
*/
|
||||
protected void tick() {
|
||||
MessagesUtil.sendDebugMessages("Tick[uuid=" + uniqueId + "]", Level.INFO);
|
||||
|
||||
if (Hooks.isInvisible(uniqueId)) {
|
||||
this.hideCosmetics(HiddenReason.VANISH);
|
||||
} else {
|
||||
this.showCosmetics(HiddenReason.VANISH);
|
||||
}
|
||||
|
||||
this.updateCosmetic();
|
||||
|
||||
if(isHidden() && !getUserEmoteManager().isPlayingEmote() && !playerCosmetics.isEmpty()) {
|
||||
MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
Bukkit.getScheduler().cancelTask(taskId);
|
||||
if(this.taskId != -1) { // ensure we're actually ticking this user.
|
||||
Bukkit.getScheduler().cancelTask(taskId);
|
||||
}
|
||||
|
||||
despawnBackpack();
|
||||
despawnBalloon();
|
||||
}
|
||||
|
||||
public Cosmetic getCosmetic(CosmeticSlot slot) {
|
||||
@Override
|
||||
public Cosmetic getCosmetic(@NotNull CosmeticSlot slot) {
|
||||
return playerCosmetics.get(slot);
|
||||
}
|
||||
|
||||
public ImmutableCollection<Cosmetic> getCosmetics() {
|
||||
@Override
|
||||
public @NotNull ImmutableCollection<Cosmetic> getCosmetics() {
|
||||
return ImmutableList.copyOf(playerCosmetics.values());
|
||||
}
|
||||
|
||||
public void addPlayerCosmetic(Cosmetic cosmetic) {
|
||||
addPlayerCosmetic(cosmetic, null);
|
||||
}
|
||||
|
||||
public void addPlayerCosmetic(Cosmetic cosmetic, Color color) {
|
||||
@Override
|
||||
public void addCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||
// API
|
||||
PlayerCosmeticEquipEvent event = new PlayerCosmeticEquipEvent(this, cosmetic);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
@@ -132,15 +251,24 @@ public class CosmeticUser {
|
||||
Bukkit.getPluginManager().callEvent(postEquipEvent);
|
||||
}
|
||||
|
||||
public void removeCosmetics() {
|
||||
// Small optimization could be made, but Concurrent modification prevents us from both getting and removing
|
||||
for (CosmeticSlot slot : CosmeticSlot.values()) {
|
||||
removeCosmeticSlot(slot);
|
||||
}
|
||||
/**
|
||||
* @deprecated Use {@link #addCosmetic(Cosmetic)} instead
|
||||
*/
|
||||
@Deprecated(since = "2.7.7", forRemoval = true)
|
||||
public void addPlayerCosmetic(@NotNull Cosmetic cosmetic) {
|
||||
addCosmetic(cosmetic);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #addCosmetic(Cosmetic, Color)} instead
|
||||
*/
|
||||
@Deprecated(since = "2.7.7", forRemoval = true)
|
||||
public void addPlayerCosmetic(@NotNull Cosmetic cosmetic, @Nullable Color color) {
|
||||
addCosmetic(cosmetic, color);
|
||||
}
|
||||
|
||||
public void removeCosmeticSlot(CosmeticSlot slot) {
|
||||
@Override
|
||||
public void removeCosmeticSlot(@NotNull CosmeticSlot slot) {
|
||||
// API
|
||||
PlayerCosmeticRemoveEvent event = new PlayerCosmeticRemoveEvent(this, getCosmetic(slot));
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
@@ -157,36 +285,26 @@ public class CosmeticUser {
|
||||
if (slot == CosmeticSlot.EMOTE) {
|
||||
if (getUserEmoteManager().isPlayingEmote()) getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.UNEQUIP);
|
||||
}
|
||||
cachedCosmeticItems.remove(slot);
|
||||
colors.remove(slot);
|
||||
playerCosmetics.remove(slot);
|
||||
removeArmor(slot);
|
||||
}
|
||||
|
||||
|
||||
public void removeCosmeticSlot(Cosmetic cosmetic) {
|
||||
removeCosmeticSlot(cosmetic.getSlot());
|
||||
}
|
||||
|
||||
public boolean hasCosmeticInSlot(CosmeticSlot slot) {
|
||||
@Override
|
||||
public boolean hasCosmeticInSlot(@NotNull CosmeticSlot slot) {
|
||||
return playerCosmetics.containsKey(slot);
|
||||
}
|
||||
|
||||
public boolean hasCosmeticInSlot(Cosmetic cosmetic) {
|
||||
if (getCosmetic(cosmetic.getSlot()) == null) return false;
|
||||
return Objects.equals(cosmetic.getId(), getCosmetic(cosmetic.getSlot()).getId());
|
||||
}
|
||||
|
||||
public Set<CosmeticSlot> getSlotsWithCosmetics() {
|
||||
return Set.copyOf(playerCosmetics.keySet());
|
||||
}
|
||||
|
||||
public void updateCosmetic(CosmeticSlot slot) {
|
||||
if (getCosmetic(slot) == null) {
|
||||
return;
|
||||
@Override
|
||||
public void updateCosmetic(@NotNull CosmeticSlot slot) {
|
||||
Cosmetic cosmetic = playerCosmetics.get(slot);
|
||||
if (cosmetic != null) {
|
||||
cosmetic.update(this);
|
||||
}
|
||||
getCosmetic(slot).update(this);
|
||||
return;
|
||||
}
|
||||
|
||||
public void updateCosmetic(Cosmetic cosmetic) {
|
||||
@@ -197,7 +315,7 @@ public class CosmeticUser {
|
||||
MessagesUtil.sendDebugMessages("updateCosmetic (All) - start");
|
||||
HashMap<EquipmentSlot, ItemStack> items = new HashMap<>();
|
||||
|
||||
for (Cosmetic cosmetic : getCosmetics()) {
|
||||
for (Cosmetic cosmetic : playerCosmetics.values()) {
|
||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||
if (getUserEmoteManager().isPlayingEmote() || isInWardrobe()) return;
|
||||
if (!(getEntity() instanceof HumanEntity humanEntity)) return;
|
||||
@@ -209,11 +327,11 @@ public class CosmeticUser {
|
||||
|
||||
items.put(HMCCInventoryUtils.getEquipmentSlot(armorType.getSlot()), armorType.getItem(this));
|
||||
} else {
|
||||
updateCosmetic(cosmetic.getSlot());
|
||||
cosmetic.update(this);
|
||||
}
|
||||
}
|
||||
if (items.isEmpty() || getEntity() == null) return;
|
||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), items, HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
|
||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), items, HMCCPacketManager.getViewers(getEntity().getLocation()));
|
||||
MessagesUtil.sendDebugMessages("updateCosmetic (All) - end - " + items.size());
|
||||
}
|
||||
|
||||
@@ -223,16 +341,12 @@ public class CosmeticUser {
|
||||
return getUserCosmeticItem(cosmetic);
|
||||
}
|
||||
|
||||
public ItemStack getUserCosmeticItem(Cosmetic cosmetic) {
|
||||
public ItemStack getUserCosmeticItem(@NotNull Cosmetic cosmetic) {
|
||||
ItemStack item = null;
|
||||
if (!hiddenReason.isEmpty()) {
|
||||
if (cosmetic instanceof CosmeticBackpackType || cosmetic instanceof CosmeticBalloonType) return new ItemStack(Material.AIR);
|
||||
return getPlayer().getInventory().getItem(HMCCInventoryUtils.getEquipmentSlot(cosmetic.getSlot()));
|
||||
}
|
||||
// Check if the item is cached. This helps with performance as we don't need to keep recreating the item
|
||||
if (cachedCosmeticItems.containsKey(cosmetic.getSlot())) {
|
||||
return cachedCosmeticItems.get(cosmetic.getSlot());
|
||||
}
|
||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||
item = armorType.getItem(this, cosmetic.getItem());
|
||||
}
|
||||
@@ -250,15 +364,11 @@ public class CosmeticUser {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public ItemStack getUserCosmeticItem(Cosmetic cosmetic, ItemStack item) {
|
||||
public ItemStack getUserCosmeticItem(@NotNull Cosmetic cosmetic, @Nullable ItemStack item) {
|
||||
if (item == null) {
|
||||
//MessagesUtil.sendDebugMessages("GetUserCosemticUser Item is null");
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
// Check if the item is cached. This helps with performance as we don't need to keep recreating the item
|
||||
if (cachedCosmeticItems.containsKey(cosmetic.getSlot())) {
|
||||
return cachedCosmeticItems.get(cosmetic.getSlot());
|
||||
}
|
||||
if (item.hasItemMeta()) {
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
|
||||
@@ -285,18 +395,22 @@ public class CosmeticUser {
|
||||
itemMeta = skullMeta;
|
||||
}
|
||||
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(getPlayer(), loreLine));
|
||||
if (Settings.isItemProcessingDisplayName()) {
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
String displayName = itemMeta.getDisplayName();
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(getPlayer(), displayName));
|
||||
}
|
||||
}
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
String displayName = itemMeta.getDisplayName();
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(getPlayer(), displayName));
|
||||
if (Settings.isItemProcessingLore()) {
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(getPlayer(), loreLine));
|
||||
}
|
||||
}
|
||||
itemMeta.setLore(processedLore);
|
||||
}
|
||||
itemMeta.setLore(processedLore);
|
||||
|
||||
|
||||
if (colors.containsKey(cosmetic.getSlot())) {
|
||||
Color color = colors.get(cosmetic.getSlot());
|
||||
@@ -322,7 +436,6 @@ public class CosmeticUser {
|
||||
|
||||
item.setItemMeta(itemMeta);
|
||||
}
|
||||
cachedCosmeticItems.put(cosmetic.getSlot(), item);
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -334,7 +447,22 @@ public class CosmeticUser {
|
||||
return userWardrobeManager;
|
||||
}
|
||||
|
||||
public void enterWardrobe(boolean ignoreDistance, Wardrobe wardrobe) {
|
||||
/**
|
||||
* Use {@link #enterWardrobe(Wardrobe, boolean)} instead.
|
||||
* @param ignoreDistance
|
||||
* @param wardrobe
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.7.5")
|
||||
public void enterWardrobe(boolean ignoreDistance, @NotNull Wardrobe wardrobe) {
|
||||
enterWardrobe(wardrobe, ignoreDistance);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to enter a wardrobe. You can listen to the {@link PlayerWardrobeEnterEvent} to cancel the event or modify any data.
|
||||
* @param wardrobe The wardrobe to enter. Use {@link WardrobeSettings#getWardrobe(String)} to get pre-existing wardrobe or use your own by {@link Wardrobe}.
|
||||
* @param ignoreDistance If true, the player can enter the wardrobe from any distance. If false, the player must be within the distance set in the wardrobe (If wardrobe has a distance of 0 or lower, the player can enter from any distance).
|
||||
*/
|
||||
public void enterWardrobe(@NotNull Wardrobe wardrobe, boolean ignoreDistance) {
|
||||
if (wardrobe.hasPermission() && !getPlayer().hasPermission(wardrobe.getPermission())) {
|
||||
MessagesUtil.sendMessage(getPlayer(), "no-permission");
|
||||
return;
|
||||
@@ -360,10 +488,18 @@ public class CosmeticUser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #leaveWardrobe(boolean)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.7.5")
|
||||
public void leaveWardrobe() {
|
||||
leaveWardrobe(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the player to leave the wardrobe. If a player is not in the wardrobe, this will do nothing, use (@{@link #isInWardrobe()} to check if they are).
|
||||
* @param ejected If true, the player was ejected from the wardrobe (Skips transition). If false, the player left the wardrobe normally.
|
||||
*/
|
||||
public void leaveWardrobe(boolean ejected) {
|
||||
PlayerWardrobeLeaveEvent event = new PlayerWardrobeLeaveEvent(this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
@@ -394,6 +530,10 @@ public class CosmeticUser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This checks if the player is in a wardrobe. If they are, it will return true, else false. See {@link #getWardrobeManager()} to get the wardrobe manager.
|
||||
* @return If the player is in a wardrobe.
|
||||
*/
|
||||
public boolean isInWardrobe() {
|
||||
return userWardrobeManager != null;
|
||||
}
|
||||
@@ -435,10 +575,6 @@ public class CosmeticUser {
|
||||
|
||||
public void despawnBalloon() {
|
||||
if (this.userBalloonManager == null) return;
|
||||
List<Player> sentTo = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
|
||||
|
||||
HMCCPacketManager.sendEntityDestroyPacket(userBalloonManager.getPufferfishBalloonId(), sentTo);
|
||||
|
||||
this.userBalloonManager.remove();
|
||||
this.userBalloonManager = null;
|
||||
}
|
||||
@@ -465,9 +601,9 @@ public class CosmeticUser {
|
||||
EquipmentSlot equipmentSlot = HMCCInventoryUtils.getEquipmentSlot(slot);
|
||||
if (equipmentSlot == null) return;
|
||||
if (getPlayer() != null) {
|
||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), equipmentSlot, getPlayer().getInventory().getItem(equipmentSlot), HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
|
||||
PacketManager.equipmentSlotUpdate(getEntity().getEntityId(), equipmentSlot, getPlayer().getInventory().getItem(equipmentSlot), HMCCPacketManager.getViewers(getEntity().getLocation()));
|
||||
} else {
|
||||
HMCCPacketManager.equipmentSlotUpdate(getEntity().getEntityId(), this, slot, HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation()));
|
||||
HMCCPacketManager.equipmentSlotUpdate(getEntity().getEntityId(), this, slot, HMCCPacketManager.getViewers(getEntity().getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,23 +632,20 @@ public class CosmeticUser {
|
||||
public List<CosmeticSlot> getDyeableSlots() {
|
||||
ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
|
||||
|
||||
for (Cosmetic cosmetic : getCosmetics()) {
|
||||
for (Cosmetic cosmetic : playerCosmetics.values()) {
|
||||
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
|
||||
}
|
||||
|
||||
return dyableSlots;
|
||||
}
|
||||
|
||||
public boolean canEquipCosmetic(Cosmetic cosmetic) {
|
||||
return canEquipCosmetic(cosmetic, false);
|
||||
}
|
||||
|
||||
public boolean canEquipCosmetic(Cosmetic cosmetic, boolean ignoreWardrobe) {
|
||||
@Override
|
||||
public boolean canEquipCosmetic(@NotNull Cosmetic cosmetic, boolean ignoreWardrobe) {
|
||||
if (!cosmetic.requiresPermission()) return true;
|
||||
if (isInWardrobe() && !ignoreWardrobe) {
|
||||
if (WardrobeSettings.isTryCosmeticsInWardrobe() && userWardrobeManager.getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return true;
|
||||
}
|
||||
return getPlayer().hasPermission(cosmetic.getPermission());
|
||||
return getEntity().hasPermission(cosmetic.getPermission());
|
||||
}
|
||||
|
||||
public void hidePlayer() {
|
||||
@@ -576,7 +709,7 @@ public class CosmeticUser {
|
||||
if (!isBalloonSpawned()) respawnBalloon();
|
||||
CosmeticBalloonType balloonType = (CosmeticBalloonType) getCosmetic(CosmeticSlot.BALLOON);
|
||||
getBalloonManager().addPlayerToModel(this, balloonType);
|
||||
List<Player> viewer = HMCCPlayerUtils.getNearbyPlayers(getEntity().getLocation());
|
||||
List<Player> viewer = HMCCPacketManager.getViewers(getEntity().getLocation());
|
||||
HMCCPacketManager.sendLeashPacket(getBalloonManager().getPufferfishBalloonId(), getPlayer().getEntityId(), viewer);
|
||||
}
|
||||
if (hasCosmeticInSlot(CosmeticSlot.BACKPACK)) {
|
||||
@@ -619,6 +752,7 @@ public class CosmeticUser {
|
||||
NONE,
|
||||
WORLDGUARD,
|
||||
PLUGIN,
|
||||
VANISH,
|
||||
POTION,
|
||||
ACTION,
|
||||
COMMAND,
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.hibiscusmc.hmccosmetics.user;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Allow custom implementations of a {@link CosmeticUser}.
|
||||
*/
|
||||
public abstract class CosmeticUserProvider {
|
||||
/**
|
||||
* Construct the custom {@link CosmeticUser}.
|
||||
* @param playerId the player uuid
|
||||
* @return the {@link CosmeticUser}
|
||||
* @apiNote This method is called during the {@link PlayerJoinEvent}.
|
||||
*/
|
||||
public abstract @NotNull CosmeticUser createCosmeticUser(@NotNull UUID playerId);
|
||||
|
||||
/**
|
||||
* Represents the plugin that is providing this {@link CosmeticUserProvider}
|
||||
* @return the plugin
|
||||
*/
|
||||
public abstract Plugin getProviderPlugin();
|
||||
|
||||
/**
|
||||
* Default implementation.
|
||||
*/
|
||||
static class Default extends CosmeticUserProvider {
|
||||
public static CosmeticUserProvider INSTANCE = new Default();
|
||||
|
||||
@Override
|
||||
public @NotNull CosmeticUser createCosmeticUser(@NotNull UUID playerId) {
|
||||
return new CosmeticUser(playerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getProviderPlugin() {
|
||||
return HMCCosmeticsPlugin.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.user;
|
||||
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -9,10 +8,13 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class CosmeticUsers {
|
||||
|
||||
private static final HashBiMap<UUID, CosmeticUser> COSMETIC_USERS = HashBiMap.create();
|
||||
private static final ConcurrentHashMap<UUID, CosmeticUser> COSMETIC_USERS = new ConcurrentHashMap<>();
|
||||
|
||||
private static CosmeticUserProvider PROVIDER = CosmeticUserProvider.Default.INSTANCE;
|
||||
|
||||
/**
|
||||
* Adds a user to the Hashmap of stored CosmeticUsers. This will not override an entry if it already exists. If you need to override, delete then add.
|
||||
@@ -52,7 +54,7 @@ public class CosmeticUsers {
|
||||
/**
|
||||
* This method allows you to get a CosmeticUser from just using the player class. This just allows you to have a bit less boilerplate.
|
||||
* @param player The player to lookup (will take their UUID from the class)
|
||||
* @return Returns the user if there is a vlaid user, returns null if not.
|
||||
* @return Returns the user if there is a valid user, returns null if not.
|
||||
*/
|
||||
@Nullable
|
||||
public static CosmeticUser getUser(@NotNull Player player) {
|
||||
@@ -72,12 +74,38 @@ public class CosmeticUsers {
|
||||
return COSMETIC_USERS.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom {@link CosmeticUserProvider} to provide your own user implementation to
|
||||
* be used and queried.
|
||||
* @param provider the provider to register
|
||||
* @throws IllegalArgumentException if the provider is already registered by another plugin
|
||||
*/
|
||||
public static void registerProvider(final CosmeticUserProvider provider) {
|
||||
if(PROVIDER != CosmeticUserProvider.Default.INSTANCE) {
|
||||
throw new IllegalArgumentException("CosmeticUserProvider already registered by %s, this conflicts with %s attempting to register their own.".formatted(
|
||||
PROVIDER.getProviderPlugin().getName(),
|
||||
provider.getProviderPlugin().getName()
|
||||
));
|
||||
}
|
||||
|
||||
PROVIDER = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current {@link CosmeticUserProvider} being used.
|
||||
* @return the current {@link CosmeticUserProvider} being used
|
||||
*/
|
||||
public static CosmeticUserProvider getProvider() {
|
||||
return PROVIDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the values for CosmeticUsers to allow you to iterate over everyone.
|
||||
* @return CosmeticUsers in a set. This will never be null, but might be empty.
|
||||
*/
|
||||
@NotNull
|
||||
public static Set<CosmeticUser> values() {
|
||||
return COSMETIC_USERS.values();
|
||||
// fix this later; this is a temporary fix. It was originally a set, now it's a collection
|
||||
return Set.copyOf(COSMETIC_USERS.values());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticBackpackType;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
@@ -8,12 +7,10 @@ import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -30,19 +27,16 @@ public class UserBackpackManager {
|
||||
@Getter
|
||||
private boolean backpackHidden;
|
||||
@Getter
|
||||
private int invisibleArmorStand;
|
||||
private final int invisibleArmorStand;
|
||||
private ArrayList<Integer> particleCloud = new ArrayList<>();
|
||||
@Getter
|
||||
private final CosmeticUser user;
|
||||
@Getter
|
||||
private UserEntity entityManager;
|
||||
@Getter @Setter
|
||||
private boolean inBlock;
|
||||
|
||||
public UserBackpackManager(CosmeticUser user) {
|
||||
this.user = user;
|
||||
this.backpackHidden = false;
|
||||
this.inBlock = false;
|
||||
this.invisibleArmorStand = ServerUtils.getNextEntityId();
|
||||
this.entityManager = new UserEntity(user.getUniqueId());
|
||||
if (user.getEntity() != null) this.entityManager.refreshViewers(user.getEntity().getLocation()); // Fixes an issue where a player, who somehow removes their potions, but doesn't have an entity produces an NPE (it's dumb)
|
||||
@@ -63,17 +57,7 @@ public class UserBackpackManager {
|
||||
getEntityManager().teleport(user.getEntity().getLocation());
|
||||
List<Player> outsideViewers = getEntityManager().getViewers();
|
||||
HMCCPacketManager.sendEntitySpawnPacket(user.getEntity().getLocation(), getFirstArmorStandId(), EntityType.ARMOR_STAND, UUID.randomUUID(), getEntityManager().getViewers());
|
||||
if (Settings.isBackpackBlockDetection()) {
|
||||
if (checkBlock()) {
|
||||
setInBlock(true);
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), isInBlock(), outsideViewers);
|
||||
} else {
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), isInBlock(), outsideViewers);
|
||||
}
|
||||
//refreshBlock(outsideViewers);
|
||||
} else {
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), Settings.isBackpackLightEmination(), outsideViewers);
|
||||
}
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), outsideViewers);
|
||||
|
||||
Entity entity = user.getEntity();
|
||||
|
||||
@@ -106,20 +90,6 @@ public class UserBackpackManager {
|
||||
PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(cosmeticBackpackType), outsideViewers);
|
||||
HMCCPacketManager.sendRidingPacket(entity.getEntityId(), passengerIDs, outsideViewers);
|
||||
|
||||
// No one should be using ME because it barely works but some still use it, so it's here
|
||||
if (cosmeticBackpackType.getModelName() != null && Hooks.isActiveHook("ModelEngine")) {
|
||||
if (ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName()) == null) {
|
||||
MessagesUtil.sendDebugMessages("Invalid Model Engine Blueprint " + cosmeticBackpackType.getModelName(), Level.SEVERE);
|
||||
return;
|
||||
}
|
||||
/* TODO: Readd ModelEngine support
|
||||
ModeledEntity modeledEntity = ModelEngineAPI.createModeledEntity(new PacketBaseEntity(getFirstArmorStandId(), UUID.randomUUID(), entity.getLocation()));
|
||||
ActiveModel model = ModelEngineAPI.createActiveModel(ModelEngineAPI.getBlueprint(cosmeticBackpackType.getModelName()));
|
||||
model.setCanHurt(false);
|
||||
modeledEntity.addModel(model, false);
|
||||
*/
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("spawnBackpack Bukkit - Finish");
|
||||
}
|
||||
|
||||
@@ -163,33 +133,4 @@ public class UserBackpackManager {
|
||||
ItemStack item = new ItemStack(Material.AIR);
|
||||
PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, item, getEntityManager().getViewers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the block detection for the backpack
|
||||
* @param outsideViewers
|
||||
* @return true if the entity was updated, false if not
|
||||
*/
|
||||
public boolean refreshBlock(List<Player> outsideViewers) {
|
||||
if (Settings.isBackpackBlockDetection()) {
|
||||
if (isInBlock() && checkBlock()) {
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), false, outsideViewers);
|
||||
setInBlock(false);
|
||||
return true;
|
||||
}
|
||||
if (!isInBlock() && !checkBlock()) {
|
||||
HMCCPacketManager.sendArmorstandMetadata(getFirstArmorStandId(), true, outsideViewers);
|
||||
setInBlock(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkBlock() {
|
||||
if (Settings.isBackpackBlockDetection()) {
|
||||
Block block = getEntityManager().getLocation().clone().add(0, 1.5, 0).getBlock();
|
||||
return block.getType().isAir();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import com.ticxo.modelengine.api.entity.data.BukkitEntityData;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import com.ticxo.modelengine.api.nms.RenderParsers;
|
||||
import lombok.Getter;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
@@ -30,16 +31,17 @@ import java.util.logging.Level;
|
||||
|
||||
public class UserBalloonManager {
|
||||
|
||||
private CosmeticUser user;
|
||||
private final CosmeticUser user;
|
||||
@Getter
|
||||
private BalloonType balloonType;
|
||||
private CosmeticBalloonType cosmeticBalloonType;
|
||||
@Getter
|
||||
private UserBalloonPufferfish pufferfish;
|
||||
private final ArmorStand modelEntity;
|
||||
|
||||
public UserBalloonManager(CosmeticUser user, @NotNull Location location) {
|
||||
this.user = user;
|
||||
this.pufferfish = new UserBalloonPufferfish(user.getUniqueId(), NMSHandlers.getHandler().getNextEntityId(), UUID.randomUUID());
|
||||
this.pufferfish = new UserBalloonPufferfish(user.getUniqueId(), NMSHandlers.getHandler().getUtilHandler().getNextEntityId(), UUID.randomUUID());
|
||||
this.modelEntity = location.getWorld().spawn(location, ArmorStand.class, (e) -> {
|
||||
e.setInvisible(true);
|
||||
e.setGravity(false);
|
||||
@@ -82,7 +84,7 @@ public class UserBalloonManager {
|
||||
modeledEntity.getModels().forEach((d, singleModel) -> {
|
||||
if (cosmeticBalloonType.isDyablePart(d)) {
|
||||
singleModel.setDefaultTint(color);
|
||||
singleModel.getModelRenderer().sendToClient();
|
||||
singleModel.getModelRenderer().sendToClient(ModelEngineAPI.getNMSHandler().createParsers());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -98,6 +100,7 @@ public class UserBalloonManager {
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
pufferfish.destroyPufferfish();
|
||||
if (balloonType == BalloonType.MODELENGINE) {
|
||||
final ModeledEntity entity = ModelEngineAPI.getModeledEntity(modelEntity);
|
||||
if (entity == null) {
|
||||
@@ -156,6 +159,7 @@ public class UserBalloonManager {
|
||||
public int getPufferfishBalloonId() {
|
||||
return pufferfish.getPufferFishEntityId();
|
||||
}
|
||||
|
||||
public UUID getPufferfishBalloonUniqueId() {
|
||||
return pufferfish.getUuid();
|
||||
}
|
||||
@@ -176,6 +180,10 @@ public class UserBalloonManager {
|
||||
this.getModelEntity().teleport(location);
|
||||
}
|
||||
|
||||
public Vector getVelocity() {
|
||||
return getModelEntity().getVelocity();
|
||||
}
|
||||
|
||||
public void setVelocity(Vector vector) {
|
||||
this.getModelEntity().setVelocity(vector);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ 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 lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -14,8 +17,11 @@ import java.util.UUID;
|
||||
|
||||
public class UserBalloonPufferfish extends UserEntity {
|
||||
|
||||
private int pufferFishEntityId;
|
||||
private UUID uuid;
|
||||
@Getter
|
||||
private final int pufferFishEntityId;
|
||||
@Getter
|
||||
private final UUID uuid;
|
||||
private boolean destroyed = false;
|
||||
|
||||
public UserBalloonPufferfish(UUID owner, int pufferFishEntityId, UUID uuid) {
|
||||
super(owner);
|
||||
@@ -23,14 +29,6 @@ public class UserBalloonPufferfish extends UserEntity {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public int getPufferFishEntityId() {
|
||||
return pufferFishEntityId;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void hidePufferfish() {
|
||||
HMCCPacketManager.sendEntityDestroyPacket(pufferFishEntityId, getViewers());
|
||||
getViewers().clear();
|
||||
@@ -41,35 +39,15 @@ public class UserBalloonPufferfish extends UserEntity {
|
||||
HMCCPacketManager.sendInvisibilityPacket(pufferFishEntityId, sendTo);
|
||||
}
|
||||
|
||||
public void destroyPufferfish() {
|
||||
HMCCPacketManager.sendEntityDestroyPacket(pufferFishEntityId, getViewers());
|
||||
getViewers().clear();
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Player> refreshViewers(Location location) {
|
||||
if (System.currentTimeMillis() - getViewerLastUpdate() <= 1000) return List.of(); //Prevents mass refreshes
|
||||
ArrayList<Player> newPlayers = new ArrayList<>();
|
||||
ArrayList<Player> removePlayers = new ArrayList<>();
|
||||
List<Player> players = HMCCPlayerUtils.getNearbyPlayers(location);
|
||||
|
||||
for (Player player : players) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user != null && getOwner() != user.getUniqueId() && user.isInWardrobe()) { // Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
|
||||
removePlayers.add(player);
|
||||
HMCCPacketManager.sendEntityDestroyPacket(getPufferFishEntityId(), List.of(player));
|
||||
continue;
|
||||
}
|
||||
if (!getViewers().contains(player)) {
|
||||
getViewers().add(player);
|
||||
newPlayers.add(player);
|
||||
continue;
|
||||
}
|
||||
// bad loopdy loops
|
||||
for (Player viewerPlayer : getViewers()) {
|
||||
if (!players.contains(viewerPlayer)) {
|
||||
removePlayers.add(viewerPlayer);
|
||||
HMCCPacketManager.sendEntityDestroyPacket(getPufferFishEntityId(), List.of(viewerPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
getViewers().removeAll(removePlayers);
|
||||
setViewerLastUpdate(System.currentTimeMillis());
|
||||
return newPlayers;
|
||||
if (destroyed) return List.of(); //Prevents refreshing a destroyed entity
|
||||
return super.refreshViewers(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@ import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
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 lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -41,11 +44,16 @@ public class UserEntity {
|
||||
if (System.currentTimeMillis() - viewerLastUpdate <= 1000) return List.of(); //Prevents mass refreshes
|
||||
ArrayList<Player> newPlayers = new ArrayList<>();
|
||||
ArrayList<Player> removePlayers = new ArrayList<>();
|
||||
List<Player> players = HMCCPlayerUtils.getNearbyPlayers(location);
|
||||
List<Player> players = HMCCPacketManager.getViewers(location);
|
||||
Entity ownerPlayer = Bukkit.getEntity(owner);
|
||||
if (ownerPlayer == null) {
|
||||
MessagesUtil.sendDebugMessages("Owner is null (refreshViewers), returning empty list");
|
||||
return List.of();
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user != null && owner != user.getUniqueId() && user.isInWardrobe()) { // Fixes issue where players in wardrobe would see other players cosmetics if they were not in wardrobe
|
||||
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
|
||||
removePlayers.add(player);
|
||||
HMCCPacketManager.sendEntityDestroyPacket(ids, List.of(player));
|
||||
continue;
|
||||
|
||||
@@ -64,6 +64,7 @@ public class UserWardrobeManager {
|
||||
private BossBar bossBar;
|
||||
@Getter
|
||||
private boolean active;
|
||||
@Setter
|
||||
@Getter
|
||||
private WardrobeStatus wardrobeStatus;
|
||||
@Getter
|
||||
@@ -83,8 +84,11 @@ public class UserWardrobeManager {
|
||||
this.viewingLocation = wardrobeLocation.getViewerLocation();
|
||||
this.npcLocation = wardrobeLocation.getNpcLocation();
|
||||
|
||||
String defaultMenu = wardrobe.getDefaultMenu();
|
||||
if (defaultMenu != null && Menus.hasMenu(defaultMenu)) this.lastOpenMenu = Menus.getMenu(defaultMenu);
|
||||
else this.lastOpenMenu = Menus.getDefaultMenu();
|
||||
|
||||
wardrobeStatus = WardrobeStatus.SETUP;
|
||||
this.lastOpenMenu = Menus.getDefaultMenu();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -105,14 +109,19 @@ public class UserWardrobeManager {
|
||||
MessagesUtil.sendMessage(player, "opened-wardrobe");
|
||||
|
||||
Runnable run = () -> {
|
||||
if (!player.isOnline()) {
|
||||
end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Armorstand
|
||||
HMCCPacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
|
||||
HMCCPacketManager.sendArmorstandMetadata(ARMORSTAND_ID, viewer);
|
||||
HMCCPacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
||||
|
||||
// Player
|
||||
user.getPlayer().teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
user.getPlayer().setInvisible(true);
|
||||
player.teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
player.setInvisible(true);
|
||||
HMCCPacketManager.gamemodeChangePacket(player, 3);
|
||||
HMCCPacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
|
||||
|
||||
@@ -129,7 +138,7 @@ public class UserWardrobeManager {
|
||||
HMCCPacketManager.sendFakePlayerSpawnPacket(npcLocation, WARDROBE_UUID, NPC_ID, viewer);
|
||||
HMCCPacketManager.sendPlayerOverlayPacket(NPC_ID, viewer);
|
||||
MessagesUtil.sendDebugMessages("Spawned Fake Player on " + npcLocation);
|
||||
NMSHandlers.getHandler().hideNPCName(player, npcName);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendScoreboardHideNamePacket(player, npcName);
|
||||
}, 4);
|
||||
|
||||
// Location
|
||||
@@ -281,7 +290,7 @@ public class UserWardrobeManager {
|
||||
run.run();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
private void update() {
|
||||
final AtomicInteger data = new AtomicInteger();
|
||||
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
@@ -310,7 +319,7 @@ public class UserWardrobeManager {
|
||||
int nextyaw = HMCCServerUtils.getNextYaw(yaw, rotationSpeed);
|
||||
data.set(nextyaw);
|
||||
|
||||
for (CosmeticSlot slot : CosmeticSlot.values()) {
|
||||
for (CosmeticSlot slot : CosmeticSlot.values().values()) {
|
||||
HMCCPacketManager.equipmentSlotUpdate(NPC_ID, user, slot, viewer);
|
||||
}
|
||||
|
||||
@@ -343,10 +352,6 @@ public class UserWardrobeManager {
|
||||
runnable.runTaskTimer(HMCCosmeticsPlugin.getInstance(), 0, 2);
|
||||
}
|
||||
|
||||
public void setWardrobeStatus(WardrobeStatus status) {
|
||||
this.wardrobeStatus = status;
|
||||
}
|
||||
|
||||
public enum WardrobeStatus {
|
||||
SETUP,
|
||||
STARTING,
|
||||
|
||||
@@ -12,10 +12,22 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HMCCInventoryUtils {
|
||||
|
||||
private static final Map<CosmeticSlot, EquipmentSlot> SLOT_MAP = new HashMap<>();
|
||||
static {
|
||||
SLOT_MAP.put(CosmeticSlot.HELMET, EquipmentSlot.HEAD);
|
||||
SLOT_MAP.put(CosmeticSlot.CHESTPLATE, EquipmentSlot.CHEST);
|
||||
SLOT_MAP.put(CosmeticSlot.LEGGINGS, EquipmentSlot.LEGS);
|
||||
SLOT_MAP.put(CosmeticSlot.BOOTS, EquipmentSlot.FEET);
|
||||
SLOT_MAP.put(CosmeticSlot.OFFHAND, EquipmentSlot.OFF_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.
|
||||
@@ -63,6 +75,7 @@ public class HMCCInventoryUtils {
|
||||
case FEET -> CosmeticSlot.BOOTS;
|
||||
case OFFHAND -> CosmeticSlot.OFFHAND;
|
||||
case MAINHAND -> CosmeticSlot.MAINHAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -131,29 +144,7 @@ public class HMCCInventoryUtils {
|
||||
@Contract(pure = true)
|
||||
@Nullable
|
||||
public static EquipmentSlot getEquipmentSlot(@NotNull CosmeticSlot slot) {
|
||||
switch (slot) {
|
||||
case HELMET -> {
|
||||
return EquipmentSlot.HEAD;
|
||||
}
|
||||
case CHESTPLATE -> {
|
||||
return EquipmentSlot.CHEST;
|
||||
}
|
||||
case LEGGINGS -> {
|
||||
return EquipmentSlot.LEGS;
|
||||
}
|
||||
case BOOTS -> {
|
||||
return EquipmentSlot.FEET;
|
||||
}
|
||||
case OFFHAND -> {
|
||||
return EquipmentSlot.OFF_HAND;
|
||||
}
|
||||
case MAINHAND -> {
|
||||
return EquipmentSlot.HAND;
|
||||
}
|
||||
default -> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return SLOT_MAP.get(slot);
|
||||
}
|
||||
|
||||
public static EquipmentSlot getEquipmentSlot(@NotNull EnumWrappers.ItemSlot slot) {
|
||||
|
||||
@@ -24,12 +24,24 @@ public class HMCCPlayerUtils {
|
||||
return new WrappedSignedProperty("textures", skinData.getValue(), skinData.getSignature());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nearby players. {@link com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager#getViewers(Location)}
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "2.7.5", forRemoval = true)
|
||||
public static List<Player> getNearbyPlayers(@NotNull Player player) {
|
||||
return getNearbyPlayers(player.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nearby players. {@link com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager#getViewers(Location)}
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "2.7.5", forRemoval = true)
|
||||
public static List<Player> getNearbyPlayers(@NotNull Location location) {
|
||||
return PacketManager.getViewers(location, Settings.getViewDistance());
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class HMCCServerUtils {
|
||||
}
|
||||
|
||||
public static org.bukkit.entity.Entity getEntity(int entityId) {
|
||||
return NMSHandlers.getHandler().getEntity(entityId);
|
||||
return NMSHandlers.getHandler().getUtilHandler().getEntity(entityId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,13 +157,4 @@ public class HMCCServerUtils {
|
||||
}
|
||||
return nextYaw;
|
||||
}
|
||||
|
||||
public static boolean hasClass(String className) {
|
||||
try {
|
||||
Class.forName(className);
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.misc;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Utils {
|
||||
|
||||
/**
|
||||
* @param original Object to be checked if null
|
||||
* @param replacement Object returned if original is null
|
||||
* @return original if not null, otherwise replacement
|
||||
*/
|
||||
|
||||
public static <T> T replaceIfNull(final @Nullable T original, final @NotNull T replacement) {
|
||||
return replaceIfNull(original, replacement, t -> {
|
||||
});
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> T replaceIf(final @Nullable T original, final T replacement, final @Nullable T... checks) {
|
||||
for (final T check : checks) {
|
||||
if (original == check) return replacement;
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
public static <T> T replaceIf(final @Nullable T original, final T replacement, final @NotNull Predicate<T> predicate) {
|
||||
if (predicate.test(original)) return replacement;
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param original Object to be checked if null
|
||||
* @param replacement Object returned if original is null
|
||||
* @param consumer accepts the original object, can be used for logging
|
||||
* @return original if not null, otherwise replacement
|
||||
*/
|
||||
|
||||
public static <T> T replaceIfNull(final @Nullable T original, final T replacement,
|
||||
final @NotNull Consumer<T> consumer) {
|
||||
if (original == null) {
|
||||
consumer.accept(replacement);
|
||||
return replacement;
|
||||
}
|
||||
consumer.accept(original);
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param t object being checked
|
||||
* @param consumer accepted if t is not null
|
||||
* @param <T> type
|
||||
*/
|
||||
|
||||
public static <T> void doIfNotNull(final @Nullable T t, final @NotNull Consumer<T> consumer) {
|
||||
if (t == null) {
|
||||
return;
|
||||
}
|
||||
consumer.accept(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param t object being checked
|
||||
* @param function applied if t is not null
|
||||
* @param <T> type
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static <T> Optional<T> returnIfNotNull(final @Nullable T t,
|
||||
final @NotNull Function<T, T> function) {
|
||||
if (t == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(function.apply(t));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enumAsString Enum value as a string to be parsed
|
||||
* @param enumClass enum type enumAsString is to be converted to
|
||||
* @param defaultEnum default value to be returned
|
||||
* @return enumAsString as an enum, or default enum if it could not be parsed
|
||||
*/
|
||||
|
||||
public static <E extends Enum<E>> E stringToEnum(final @NotNull String enumAsString,
|
||||
final @NotNull Class<E> enumClass,
|
||||
E defaultEnum) {
|
||||
return stringToEnum(enumAsString, enumClass, defaultEnum, e -> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enumAsString Enum value as a string to be parsed
|
||||
* @param enumClass enum type enumAsString is to be converted to
|
||||
* @param defaultEnum default value to be returned
|
||||
* @param consumer accepts the returned enum, can be used for logging
|
||||
* @return enumAsString as an enum, or default enum if it could not be parsed
|
||||
*/
|
||||
|
||||
public static <E extends Enum<E>> E stringToEnum(final @NotNull String enumAsString,
|
||||
@NotNull final Class<E> enumClass,
|
||||
final E defaultEnum,
|
||||
final @NotNull Consumer<E> consumer) {
|
||||
try {
|
||||
final E value = Enum.valueOf(enumClass, enumAsString);
|
||||
consumer.accept(value);
|
||||
return value;
|
||||
} catch (final IllegalArgumentException exception) {
|
||||
consumer.accept(defaultEnum);
|
||||
return defaultEnum;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,8 @@ import java.util.*;
|
||||
|
||||
public class HMCCPacketManager extends PacketManager {
|
||||
|
||||
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(
|
||||
final @NotNull Location location,
|
||||
final int entityId,
|
||||
@@ -91,8 +93,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
CosmeticSlot cosmeticSlot,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
if (cosmeticSlot == CosmeticSlot.BACKPACK || cosmeticSlot == CosmeticSlot.CUSTOM || cosmeticSlot == CosmeticSlot.BALLOON || cosmeticSlot == CosmeticSlot.EMOTE) return;
|
||||
|
||||
if (!EQUIPMENT_SLOTS.contains(cosmeticSlot)) return;
|
||||
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
|
||||
}
|
||||
|
||||
@@ -100,25 +101,14 @@ public class HMCCPacketManager extends PacketManager {
|
||||
int entityId,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
sendArmorstandMetadata(entityId, false, sendTo);
|
||||
}
|
||||
|
||||
public static void sendArmorstandMetadata(
|
||||
int entityId,
|
||||
boolean onFire,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
byte mask = 0x20;
|
||||
if (onFire) {
|
||||
// 0x21 = Invisible + Fire (Aka, burns to make it not take the light of the block its in, avoiding turning it black)
|
||||
mask = 0x21;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -392,15 +382,14 @@ public class HMCCPacketManager extends PacketManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nearby players (or viewers) of a location through the view distance set in the config. If the view distance is 0, it will return all players in the world.
|
||||
* @param location
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
public static List<Player> getViewers(Location location) {
|
||||
ArrayList<Player> viewers = new ArrayList<>();
|
||||
if (Settings.getViewDistance() <= 0) {
|
||||
viewers.addAll(location.getWorld().getPlayers());
|
||||
} else {
|
||||
viewers.addAll(HMCCPlayerUtils.getNearbyPlayers(location));
|
||||
}
|
||||
return viewers;
|
||||
public static List<Player> getViewers(@NotNull Location location) {
|
||||
return PacketManager.getViewers(location, Settings.getViewDistance());
|
||||
}
|
||||
|
||||
public static void sendPacket(Player player, PacketContainer packet) {
|
||||
|
||||
@@ -24,6 +24,12 @@ cosmetic-settings:
|
||||
force-permission-join: true # Checks a player permission if they can have a cosmetic when they join the server.
|
||||
force-show-join: false # If the plugin should force show a player's cosmetics when they join the server.
|
||||
|
||||
# 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.
|
||||
item-processing:
|
||||
display-name: true
|
||||
lore: true
|
||||
|
||||
# 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:
|
||||
- "disabledworld"
|
||||
@@ -45,17 +51,10 @@ cosmetic-settings:
|
||||
emote-camera: true
|
||||
# If a player should be able to move in an emote. This option really only affects if "emote-camera" is false
|
||||
emote-move: false
|
||||
|
||||
|
||||
# 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
|
||||
# This makes the plugin either (true) always have the backpack eminate light to avoid the black backpack bug or (false) turns it off.
|
||||
backpack-light-emination: true
|
||||
# This activates the block detection for the backpack. This allows backpacks to not appear completely black when in a block.
|
||||
# Requires backpack-light-emination to be true.
|
||||
backpack-block-detection: true
|
||||
|
||||
|
||||
# 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
|
||||
# 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
|
||||
@@ -106,13 +105,13 @@ menu-settings:
|
||||
shading:
|
||||
# Below is the shading mechanism behind cosmetic items. This is a bit complicated, but it allows for a lot of customization.
|
||||
# The shading is done through the title and by shifting textures around. This is done by offsets.
|
||||
# Only Oraxen 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"
|
||||
first-row-shift: "<s:-169>" # Oraxen: "<s:-169>"
|
||||
sequent-row-shift: " <s:-169>" # Oraxen: " <s:-169>" (Space is important here!)
|
||||
individual-column-shift: "<s:-3>" # Oraxen: "<s:-3>"
|
||||
background: "<g:shade_row_<row>:colorable> " # Oraxen: "<g:shade_row_<row>:colorable>
|
||||
clear-background: "<g:clear_row_<row>:colorable> " # Oraxen: "<g:clear_row_<row>:colorable> "
|
||||
first-row-shift: "<shift:-169>" # Nexo: "<shift:-169>"
|
||||
sequent-row-shift: " <shift:-169>" # Nexo: " <shift:-169>" (Space is important here!)
|
||||
individual-column-shift: "<shift:-3>" # Nexo: "<shift:-3>"
|
||||
background: "<glyph:shade_row_<row>:colorable> " # Nexo: "<glyph:shade_row_<row>:colorable>
|
||||
clear-background: "<glyph:clear_row_<row>:colorable> " # Nexo: "<glyph:clear_row_<row>:colorable> "
|
||||
#These use MiniMessage for color! https://docs.advntr.dev/minimessage/format.html#color
|
||||
equipped-cosmetic-color: "<yellow>"
|
||||
equipable-cosmetic-color: "<green>"
|
||||
@@ -124,6 +123,7 @@ menu-settings:
|
||||
dye-menu:
|
||||
# If you use ItemsAdder, set this to "<white>:img_offset_-8::img_dye_menu:"
|
||||
# If you use Oraxen, set this to "<white><s:-8><g:dye_menu>"
|
||||
# If you use Nexo, set this to "<white><shift:-8><glyph:dye_menu>"
|
||||
title: "<white>"
|
||||
input-slot: 10
|
||||
output-slot: 16
|
||||
@@ -132,10 +132,15 @@ hook-settings:
|
||||
# This causes the plugin to reload itself after any ItemsAdder change. This keeps the plugin fully up to date with IA, but
|
||||
# could cause console spam as HMCCosmetics has to reload itself as well.
|
||||
reload-on-change: false
|
||||
nexo:
|
||||
# This causes the plugin to reload itself after any Nexo change. This keeps the plugin fully up to date with Nexo
|
||||
reload-on-change: true
|
||||
worldguard:
|
||||
# Checks worldguard regions for HMCC flags. If set to false, flags will not work properly.
|
||||
# Requires restart to apply changes.
|
||||
player-move-check: true
|
||||
betterhud:
|
||||
wardrobe-hide: true
|
||||
wardrobe:
|
||||
# how much yaw should change per tick, set to 0 for none
|
||||
rotation-speed: 3
|
||||
@@ -168,6 +173,7 @@ wardrobe:
|
||||
enabled: true
|
||||
# If you use ItemsAdder, set this to "<black>%img_title%
|
||||
# If you use Oraxen, set this to "<black><glyph:title>"
|
||||
# If you use Nexo, set this to "<black>%nexo_title%" and use PlaceholderAPI
|
||||
text: "<black>"
|
||||
delay: 40
|
||||
title-fade-in: 1000 # milliseconds
|
||||
@@ -177,6 +183,7 @@ wardrobe:
|
||||
default:
|
||||
distance: -1 # Distance in blocks that a player can interact with the wardrobe. -1 to ignore.
|
||||
permission: "hmccosmetics.wardrobe.default" # Permission required to use the wardrobe.
|
||||
default-menu: defaultmenu
|
||||
npc-location:
|
||||
world: "world"
|
||||
x: 0
|
||||
|
||||
@@ -19,6 +19,7 @@ set-wardrobe-viewing: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe viewi
|
||||
set-wardrobe-leaving: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe leaving location!"
|
||||
set-wardrobe-permission: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe permission!"
|
||||
set-wardrobe-distance: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe distance!"
|
||||
set-wardrobe-menu: "%prefix% <gradient:#6D9DC5:#45CDE9>Set new wardrobe menu!"
|
||||
no-wardrobes: "%prefix% <red>There are no wardrobes with that name!"
|
||||
wardrobe-not-setup: "%prefix% <red>This wardrobe does not have all required locations set!"
|
||||
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
51
gradlew
vendored
51
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright <EFBFBD> 2015-2021 the original authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,10 @@
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
|
||||
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
|
||||
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
|
||||
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
@@ -205,6 +214,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
||||
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@@ -25,7 +25,8 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
Reference in New Issue
Block a user