mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-20 15:39:16 +00:00
Compare commits
28 Commits
display_en
...
nms_packet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
684e02f768 | ||
|
|
63963cccc3 | ||
|
|
7cf6a3c75c | ||
|
|
22a5bb4cf1 | ||
|
|
148d163d9c | ||
|
|
ef36e66c51 | ||
|
|
e5fda588c3 | ||
|
|
3baf2694be | ||
|
|
a1dafdee5b | ||
|
|
e3a42d8b4a | ||
|
|
b366f5930b | ||
|
|
45eb1fa668 | ||
|
|
c466405a81 | ||
|
|
172ffc0333 | ||
|
|
41ac857a11 | ||
|
|
737d63642c | ||
|
|
7b9b7678a3 | ||
|
|
fe88d0c608 | ||
|
|
e14935af7b | ||
|
|
3e83d370f8 | ||
|
|
874a7f5624 | ||
|
|
3af992a291 | ||
|
|
9ef7791998 | ||
|
|
1cbe17ddd4 | ||
|
|
2841742af9 | ||
|
|
6e2f333404 | ||
|
|
af8949b713 | ||
|
|
d6f7d0fcb3 |
@@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "com.hibiscusmc"
|
||||
version = "2.7.7${getGitCommitHash()}"
|
||||
version = "2.7.8${getGitCommitHash()}"
|
||||
|
||||
allprojects {
|
||||
apply(plugin = "java")
|
||||
@@ -69,6 +69,7 @@ allprojects {
|
||||
|
||||
// Hibiscus Commons
|
||||
maven("https://repo.hibiscusmc.com/releases")
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -77,16 +78,21 @@ allprojects {
|
||||
//compileOnly("org.spigotmc:spigot-api:1.18.2-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.3.0")
|
||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.6")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.12")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.12") {
|
||||
exclude(group = "org.bukkit")
|
||||
exclude(group = "com.google.guava")
|
||||
exclude(group = "com.google.code.gson")
|
||||
exclude(group = "it.unimi.dsi")
|
||||
exclude(group = "com.sk89q.jnbt")
|
||||
}
|
||||
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.6.2-d21ebed8")
|
||||
compileOnly("me.lojosho:HibiscusCommons:0.6.3-32402bd")
|
||||
|
||||
// Handled by Spigot Library Loader
|
||||
compileOnly("net.kyori:adventure-api:4.19.0")
|
||||
@@ -97,7 +103,7 @@ allprojects {
|
||||
testCompileOnly("org.projectlombok:lombok:1.18.36")
|
||||
testAnnotationProcessor("org.projectlombok:lombok:1.18.36")
|
||||
|
||||
implementation("dev.triumphteam:triumph-gui:3.1.12-SNAPSHOT") {
|
||||
implementation("dev.triumphteam:triumph-gui:3.2.0-SNAPSHOT") {
|
||||
exclude("net.kyori") // Already have adventure API
|
||||
}
|
||||
implementation("com.owen1212055:particlehelper:1.0.0-SNAPSHOT")
|
||||
@@ -175,8 +181,8 @@ bukkit {
|
||||
main = "com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin"
|
||||
apiVersion = "1.20"
|
||||
authors = listOf("LoJoSho")
|
||||
depend = listOf("HibiscusCommons", "ProtocolLib")
|
||||
softDepend = listOf("BetterHud", "ModelEngine", "Oraxen", "ItemsAdder", "Geary", "HMCColor", "WorldGuard", "MythicMobs", "PlaceholderAPI", "SuperVanish", "PremiumVanish", "LibsDisguises", "Denizen", "MMOItems", "Eco")
|
||||
depend = listOf("HibiscusCommons")
|
||||
softDepend = listOf("BetterHud", "ModelEngine", "Nexo", "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.
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
plugins {
|
||||
id("java")
|
||||
id("maven-publish")
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.HMCCosmeticSetupEvent;
|
||||
import com.hibiscusmc.hmccosmetics.command.CosmeticCommand;
|
||||
import com.hibiscusmc.hmccosmetics.command.CosmeticCommandTabComplete;
|
||||
@@ -10,7 +9,6 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||
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;
|
||||
@@ -26,7 +24,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.TranslationUtil;
|
||||
import com.ticxo.playeranimator.PlayerAnimatorImpl;
|
||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||
import me.lojosho.hibiscuscommons.HibiscusPlugin;
|
||||
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
||||
@@ -68,9 +65,6 @@ 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 ~ 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();
|
||||
final File messageFile = Path.of(getInstance().getDataFolder().getPath(), "messages.yml").toFile();
|
||||
@@ -125,9 +119,6 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) continue;
|
||||
if (user.getUserEmoteManager().isPlayingEmote()) {
|
||||
player.setInvisible(false);
|
||||
}
|
||||
if (user.isInWardrobe()) {
|
||||
user.leaveWardrobe(true);
|
||||
}
|
||||
@@ -229,8 +220,6 @@ 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
|
||||
|
||||
getInstance().getLogger().info("Successfully Enabled HMCCosmetics");
|
||||
getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup");
|
||||
getInstance().getLogger().info(Menus.getMenuNames().size() + " Menus Successfully Setup");
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player starts playing an emote.
|
||||
*/
|
||||
public class PlayerEmoteStartEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
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 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() {
|
||||
return animationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called when a player stops playing an emote.
|
||||
*/
|
||||
public class PlayerEmoteStopEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing
|
||||
*
|
||||
* @return The {@link UserEmoteManager.StopEmoteReason} why the emote has stopped playing
|
||||
* @deprecated As of release 2.2.5+, replaced by {@link #getReason()}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@NotNull
|
||||
public UserEmoteManager.StopEmoteReason getStopEmoteReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link UserEmoteManager.StopEmoteReason} as to why the emote has stopped playing.
|
||||
*
|
||||
* @return the reason why the emote has stopped playing
|
||||
* @since 2.2.5
|
||||
*/
|
||||
public @NotNull UserEmoteManager.StopEmoteReason getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static @NotNull HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.hibiscusmc.hmccosmetics.api.events;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Called before a player's data is un-loaded from the plugin.
|
||||
*
|
||||
* <p>
|
||||
* If this event is cancelled, the player's data will not be un-loaded,
|
||||
* and will be kept in memory.
|
||||
* </p>
|
||||
*/
|
||||
public class PlayerPreUnloadEvent extends PlayerCosmeticEvent implements Cancellable {
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
public PlayerPreUnloadEvent(@NotNull CosmeticUser who) {
|
||||
super(who);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,7 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
|
||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu;
|
||||
@@ -23,7 +21,6 @@ import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@@ -464,59 +461,6 @@ public class CosmeticCommand implements CommandExecutor {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "debug-enabled");
|
||||
}
|
||||
}
|
||||
case ("emote") -> {
|
||||
if (!sender.hasPermission("hmccosmetics.cmd.emote")) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
|
||||
return true;
|
||||
}
|
||||
if (sender.hasPermission("hmccosmetics.cmd.emote.other")) {
|
||||
if (args.length >= 2) player = Bukkit.getPlayer(args[1]);
|
||||
}
|
||||
if (player == null) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
|
||||
return true;
|
||||
}
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (!user.hasCosmeticInSlot(CosmeticSlot.EMOTE)) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "emote-none");
|
||||
return true;
|
||||
}
|
||||
|
||||
CosmeticEmoteType cosmeticEmoteType = (CosmeticEmoteType) user.getCosmetic(CosmeticSlot.EMOTE);
|
||||
cosmeticEmoteType.run(user);
|
||||
return true;
|
||||
}
|
||||
|
||||
case ("playemote") -> {
|
||||
// /cosmetic playEmote <emoteId> [playerName]
|
||||
if (!sender.hasPermission("hmccosmetics.cmd.playemote")) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length < 2) {
|
||||
if (!silent) MessagesUtil.sendMessage(player, "not-enough-args");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EmoteManager.has(args[1])) {
|
||||
MessagesUtil.sendDebugMessages("Did not contain " + args[1]);
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) {
|
||||
if (args.length >= 3) player = Bukkit.getPlayer(args[2]);
|
||||
}
|
||||
if (player == null) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "invalid-player");
|
||||
return true;
|
||||
}
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
user.getUserEmoteManager().playEmote(args[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
case "disableall" -> {
|
||||
if (!sender.hasPermission("hmccosmetics.cmd.disableall")) {
|
||||
if (!silent) MessagesUtil.sendMessage(sender, "no-permission");
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics;
|
||||
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
@@ -44,8 +43,6 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.hide")) completions.add("hide");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.show")) completions.add("show");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.debug")) completions.add("debug");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.emote")) completions.add("emote");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.playemote")) completions.add("playemote");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.disableall")) completions.add("disableall");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.hiddenreasons")) completions.add("hiddenreasons");
|
||||
if (hasPermission(sender, "hmccosmetics.cmd.clearhiddenreasons")) completions.add("clearhiddenreasons");
|
||||
@@ -74,7 +71,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
if (menu.canOpen(user.getPlayer())) completions.add(menu.getId());
|
||||
}
|
||||
}
|
||||
case "dataclear", "hide", "show", "emote", "hiddenreasons", "clearhiddenreasons" -> {
|
||||
case "dataclear", "hide", "show", "hiddenreasons", "clearhiddenreasons" -> {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
completions.add(player.getName());
|
||||
}
|
||||
@@ -102,7 +99,6 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
completions.add(wardrobe.getId());
|
||||
}
|
||||
}
|
||||
case "playemote" -> completions.addAll(EmoteManager.getAllNames());
|
||||
}
|
||||
StringUtil.copyPartialMatches(args[1], completions, finalCompletions);
|
||||
}
|
||||
@@ -112,7 +108,7 @@ public class CosmeticCommandTabComplete implements TabCompleter {
|
||||
case "dye" -> {
|
||||
completions.add("#FFFFFF");
|
||||
}
|
||||
case "menu", "wardrobe", "apply", "unapply", "playemote" -> {
|
||||
case "menu", "wardrobe", "apply", "unapply" -> {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
completions.add(player.getName());
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ public class Settings {
|
||||
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";
|
||||
@@ -43,13 +42,6 @@ public class Settings {
|
||||
private static final String HOOK_WORLDGUARD_PATH = "worldguard";
|
||||
private static final String HOOK_WG_MOVE_CHECK_PATH = "player-move-check";
|
||||
private static final String HOOK_WG_MOVE_CHECK_PATH_LEGACY = "player_move_check";
|
||||
private static final String COSMETIC_EMOTE_ENABLE = "emote-enable";
|
||||
private static final String COSMETIC_EMOTE_CHECK_PATH = "emote-block-check";
|
||||
private static final String COSMETIC_EMOTE_AIR_CHECK_PATH = "emote-air-check";
|
||||
private static final String COSMETIC_EMOTE_DAMAGE_PATH = "emote-damage-leave";
|
||||
private static final String COSMETIC_EMOTE_INVINCIBLE_PATH = "emote-invincible";
|
||||
private static final String COSMETIC_EMOTE_CAMERA_PATH = "emote-camera";
|
||||
private static final String COSMETIC_EMOTE_MOVE_CHECK_PATH = "emote-move";
|
||||
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";
|
||||
@@ -61,6 +53,7 @@ public class Settings {
|
||||
private static final String COSMETIC_TYPE_SETTINGS_PATH = "cosmetic-type";
|
||||
private static final String EQUIP_CLICK_TYPE = "equip-click";
|
||||
private static final String UNEQUIP_CLICK_TYPE = "unequip-click";
|
||||
private static final String DYE_CLICK_TYPE = "dye-click";
|
||||
private static final String SHADING_PATH = "shading";
|
||||
private static final String FIRST_ROW_SHIFT_PATH = "first-row-shift";
|
||||
private static final String SEQUENT_ROW_SHIFT_PATH = "sequent-row-shift";
|
||||
@@ -104,22 +97,12 @@ public class Settings {
|
||||
private static boolean nexoChangeReload;
|
||||
@Getter
|
||||
private static boolean worldGuardMoveCheck;
|
||||
@Getter
|
||||
private static boolean cosmeticEmoteBlockCheck;
|
||||
private static final HashMap<EquipmentSlot, SlotOptionConfig> slotOptions = new HashMap<>();
|
||||
@Getter
|
||||
private static boolean emoteAirCheck;
|
||||
@Getter
|
||||
private static boolean emoteDamageLeave;
|
||||
@Getter
|
||||
private static boolean emoteInvincible;
|
||||
@Getter
|
||||
private static boolean destroyLooseCosmetics;
|
||||
@Getter
|
||||
private static boolean backpackForceRidingEnabled;
|
||||
@Getter
|
||||
private static boolean emotesEnabled;
|
||||
@Getter
|
||||
private static boolean disabledGamemodesEnabled;
|
||||
@Getter
|
||||
private static boolean balloonHeadForward;
|
||||
@@ -148,6 +131,8 @@ public class Settings {
|
||||
@Getter
|
||||
private static String cosmeticUnEquipClickType;
|
||||
@Getter
|
||||
private static String cosmeticDyeClickType;
|
||||
@Getter
|
||||
private static boolean defaultShading;
|
||||
@Getter
|
||||
private static String firstRowShift;
|
||||
@@ -165,10 +150,6 @@ public class Settings {
|
||||
private static String equipableCosmeticColor;
|
||||
@Getter
|
||||
private static String lockedCosmeticColor;
|
||||
@Getter
|
||||
private static boolean emoteCameraEnabled;
|
||||
@Getter
|
||||
private static boolean emoteMoveCheck;
|
||||
@Getter @Setter
|
||||
private static boolean allPlayersHidden;
|
||||
@Getter
|
||||
@@ -209,12 +190,6 @@ public class Settings {
|
||||
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);
|
||||
emotesEnabled = cosmeticSettings.node(COSMETIC_EMOTE_ENABLE).getBoolean(true);
|
||||
emoteDistance = cosmeticSettings.node(EMOTE_DISTANCE_PATH).getDouble(-3);
|
||||
cosmeticEmoteBlockCheck = cosmeticSettings.node(COSMETIC_EMOTE_CHECK_PATH).getBoolean(true);
|
||||
emoteAirCheck = cosmeticSettings.node(COSMETIC_EMOTE_AIR_CHECK_PATH).getBoolean(true);
|
||||
emoteDamageLeave = cosmeticSettings.node(COSMETIC_EMOTE_DAMAGE_PATH).getBoolean(false);
|
||||
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);
|
||||
|
||||
@@ -231,8 +206,6 @@ public class Settings {
|
||||
|
||||
tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1);
|
||||
viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3);
|
||||
emoteCameraEnabled = cosmeticSettings.node(COSMETIC_EMOTE_CAMERA_PATH).getBoolean(true);
|
||||
emoteMoveCheck = cosmeticSettings.node(COSMETIC_EMOTE_MOVE_CHECK_PATH).getBoolean(false);
|
||||
packetEntityTeleportCooldown = cosmeticSettings.node(COSMETIC_PACKET_ENTITY_TELEPORT_COOLDOWN_PATH).getInt(-1);
|
||||
balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false);
|
||||
backpackPreventDarkness = cosmeticSettings.node(BACKPACK_PREVENT_DARKNESS_PATH).getBoolean(true);
|
||||
@@ -257,6 +230,7 @@ public class Settings {
|
||||
ConfigurationNode cosmeticTypeSettings = menuSettings.node(COSMETIC_TYPE_SETTINGS_PATH);
|
||||
cosmeticEquipClickType = cosmeticTypeSettings.node(EQUIP_CLICK_TYPE).getString("ALL");
|
||||
cosmeticUnEquipClickType = cosmeticTypeSettings.node(UNEQUIP_CLICK_TYPE).getString("ALL");
|
||||
cosmeticDyeClickType = cosmeticTypeSettings.node(DYE_CLICK_TYPE).getString("ALL");
|
||||
|
||||
final var balloonSection = cosmeticSettings.node(BALLOON_OFFSET);
|
||||
balloonOffset = loadVector(balloonSection);
|
||||
|
||||
@@ -2,33 +2,59 @@ package com.hibiscusmc.hmccosmetics.cosmetic;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.lojosho.hibiscuscommons.config.serializer.ItemSerializer;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import me.lojosho.shaded.configurate.serialize.SerializationException;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class Cosmetic {
|
||||
protected static ItemStack UNDEFINED_DISPLAY_ITEM_STACK;
|
||||
|
||||
@Getter @Setter
|
||||
static {
|
||||
UNDEFINED_DISPLAY_ITEM_STACK = new ItemStack(Material.BARRIER);
|
||||
UNDEFINED_DISPLAY_ITEM_STACK.editMeta(meta -> {
|
||||
meta.displayName(Component.text("Undefined Item Display", NamedTextColor.RED));
|
||||
meta.lore(List.of(
|
||||
Component.text("Please check your configurations & console to", NamedTextColor.RED),
|
||||
Component.text("ensure there are no errors.", NamedTextColor.RED)
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/** Identifier of the cosmetic. */
|
||||
private String id;
|
||||
@Getter @Setter
|
||||
private String permission;
|
||||
private ItemStack item;
|
||||
@Getter @Setter
|
||||
private String material;
|
||||
@Getter @Setter
|
||||
private CosmeticSlot slot;
|
||||
@Getter @Setter
|
||||
private boolean dyable;
|
||||
|
||||
protected Cosmetic(String id, @NotNull ConfigurationNode config) {
|
||||
/** Permission to use the cosmetic. */
|
||||
private String permission;
|
||||
|
||||
/** The display {@link ItemStack} of the cosmetic. */
|
||||
@Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
|
||||
private ItemStack item;
|
||||
|
||||
/** The material string of the cosmetic. */
|
||||
private String material;
|
||||
|
||||
/** The {@link CosmeticSlot} this cosmetic occupies. */
|
||||
private CosmeticSlot slot;
|
||||
|
||||
/** Whether the cosmetic is dyeable or not. */
|
||||
private boolean dyeable;
|
||||
|
||||
protected Cosmetic(@NotNull String id, @NotNull ConfigurationNode config) {
|
||||
this.id = id;
|
||||
|
||||
if (!config.node("permission").virtual()) {
|
||||
@@ -39,23 +65,49 @@ public abstract class Cosmetic {
|
||||
|
||||
if (!config.node("item").virtual()) {
|
||||
this.material = config.node("item", "material").getString();
|
||||
try {
|
||||
this.item = generateItemStack(config.node("item"));
|
||||
} catch(Exception ex) {
|
||||
MessagesUtil.sendDebugMessages("Forcing %s to use undefined display".formatted(getId()));
|
||||
this.item = UNDEFINED_DISPLAY_ITEM_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("Slot: " + config.node("slot").getString());
|
||||
this.slot = CosmeticSlot.valueOf(config.node("slot").getString());
|
||||
|
||||
setSlot(CosmeticSlot.valueOf(config.node("slot").getString()));
|
||||
setDyable(config.node("dyeable").getBoolean(false));
|
||||
this.dyeable = config.node("dyeable").getBoolean(false);
|
||||
MessagesUtil.sendDebugMessages("Dyeable " + dyeable);
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("Dyeable " + dyable);
|
||||
Cosmetics.addCosmetic(this);
|
||||
protected Cosmetic(String id, String permission, ItemStack item, String material, CosmeticSlot slot, boolean dyeable) {
|
||||
this.id = id;
|
||||
this.permission = permission;
|
||||
this.item = item;
|
||||
this.material = material;
|
||||
this.slot = slot;
|
||||
this.dyeable = dyeable;
|
||||
}
|
||||
|
||||
public boolean requiresPermission() {
|
||||
return permission != null;
|
||||
}
|
||||
|
||||
public abstract void update(CosmeticUser user);
|
||||
/**
|
||||
* Dispatched when an update is requested upon the cosmetic.
|
||||
* @param user the user to preform the update against
|
||||
*/
|
||||
public final void update(CosmeticUser user) {
|
||||
this.doUpdate(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action preformed on the update.
|
||||
* @param user the user to preform the update against
|
||||
*/
|
||||
protected void doUpdate(final CosmeticUser user) {
|
||||
// NO-OP.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getItem() {
|
||||
@@ -63,6 +115,11 @@ public abstract class Cosmetic {
|
||||
return item.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an {@link ItemStack} from a {@link ConfigurationNode}.
|
||||
* @param config the configuration node
|
||||
* @return the {@link ItemStack}
|
||||
*/
|
||||
protected ItemStack generateItemStack(ConfigurationNode config) {
|
||||
try {
|
||||
ItemStack item = ItemSerializer.INSTANCE.deserialize(ItemStack.class, config);
|
||||
|
||||
@@ -28,9 +28,7 @@ public abstract class CosmeticProvider {
|
||||
|
||||
Map.entry(CosmeticSlot.BACKPACK, CosmeticBackpackType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::new),
|
||||
|
||||
Map.entry(CosmeticSlot.EMOTE, CosmeticEmoteType::new)
|
||||
Map.entry(CosmeticSlot.BALLOON, CosmeticBalloonType::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`!";
|
||||
|
||||
@@ -20,7 +20,6 @@ public class CosmeticSlot {
|
||||
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;
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ public class CosmeticArmorType extends Cosmetic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) return;
|
||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
||||
if (user.isInWardrobe()) return;
|
||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||
if (entity == null) return;
|
||||
if (Settings.getSlotOption(equipSlot).isRequireEmpty() && entity instanceof HumanEntity humanEntity) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public class CosmeticBackpackType extends Cosmetic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
||||
Entity entity = user.getEntity();
|
||||
if (entity == null) return;
|
||||
|
||||
|
||||
@@ -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.UserBalloonManager;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import lombok.Getter;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
@@ -22,7 +23,7 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
@Getter
|
||||
private final String modelName;
|
||||
@Getter
|
||||
private List<String> dyableParts;
|
||||
private List<String> dyeableParts;
|
||||
@Getter
|
||||
private final boolean showLead;
|
||||
@Getter
|
||||
@@ -41,8 +42,8 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
balloonOffset = Settings.loadVector(balloonOffsetNode);
|
||||
|
||||
try {
|
||||
if (!config.node("dyable-parts").virtual()) {
|
||||
dyableParts = config.node("dyable-parts").getList(String.class);
|
||||
if (!config.node("dyeable-parts").virtual()) {
|
||||
dyeableParts = config.node("dyeable-parts").getList(String.class);
|
||||
}
|
||||
} catch (SerializationException e) {
|
||||
// Seriously?
|
||||
@@ -53,7 +54,7 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
||||
Entity entity = Bukkit.getEntity(user.getUniqueId());
|
||||
UserBalloonManager userBalloonManager = user.getBalloonManager();
|
||||
|
||||
@@ -82,6 +83,11 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
userBalloonManager.setLocation(newLocation);
|
||||
userBalloonManager.setVelocity(velocity.multiply(1.1));
|
||||
|
||||
MessagesUtil.sendDebugMessages("Balloon Cosmetic Update for " + user.getEntity().getName());
|
||||
MessagesUtil.sendDebugMessages("Ballon previous location is " + currentLocation);
|
||||
MessagesUtil.sendDebugMessages("Balloon location set to " + newLocation);
|
||||
MessagesUtil.sendDebugMessages("Balloon velocity set to " + velocity);
|
||||
|
||||
HMCCPacketManager.sendTeleportPacket(userBalloonManager.getPufferfishBalloonId(), newLocation, false, viewer);
|
||||
HMCCPacketManager.sendLeashPacket(userBalloonManager.getPufferfishBalloonId(), entity.getEntityId(), viewer);
|
||||
if (user.isHidden()) {
|
||||
@@ -95,10 +101,10 @@ public class CosmeticBalloonType extends Cosmetic {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDyablePart(String name) {
|
||||
public boolean isDyeablePart(String name) {
|
||||
// If player does not define parts, dye whole model
|
||||
if (dyableParts == null) return true;
|
||||
if (dyableParts.isEmpty()) return true;
|
||||
return dyableParts.contains(name);
|
||||
if (dyeableParts == null) return true;
|
||||
if (dyeableParts.isEmpty()) return true;
|
||||
return dyeableParts.contains(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.cosmetic.types;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CosmeticEmoteType extends Cosmetic {
|
||||
|
||||
private final String animationId;
|
||||
private final String text;
|
||||
|
||||
public CosmeticEmoteType(String id, ConfigurationNode config) {
|
||||
super(id, config);
|
||||
|
||||
animationId = config.node("animation").getString();
|
||||
text = config.node("text").getString();
|
||||
MessagesUtil.sendDebugMessages("CosmeticEmoteType Animation id " + animationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CosmeticUser user) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
public void run(@NotNull CosmeticUser user) {
|
||||
user.getUserEmoteManager().playEmote(this);
|
||||
}
|
||||
|
||||
public String getAnimationId() {
|
||||
return animationId;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class CosmeticMainhandType extends Cosmetic {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull CosmeticUser user) {
|
||||
protected void doUpdate(@NotNull CosmeticUser user) {
|
||||
Player player = user.getPlayer();
|
||||
|
||||
HMCCPacketManager.equipmentSlotUpdate(player.getEntityId(), user, getSlot(), HMCCPacketManager.getViewers(player.getLocation()));
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.emotes;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.ticxo.playeranimator.api.PlayerAnimator;
|
||||
import com.ticxo.playeranimator.api.animation.pack.AnimationPack;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Manages Emotes
|
||||
*/
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public class EmoteManager {
|
||||
private static final @NotNull Map<String, String> emotes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry
|
||||
*/
|
||||
public static void loadEmotes() {
|
||||
// Clear the PlayerAnimator and local registries
|
||||
PlayerAnimator.api.getAnimationManager().clearRegistry();
|
||||
emotes.clear();
|
||||
|
||||
// Get the emote directory and check if it exists
|
||||
File emoteDir = new File(HMCCosmeticsPlugin.getInstance().getDataFolder().getPath() + "/emotes/");
|
||||
if (!emoteDir.exists()) return;
|
||||
|
||||
// Get all the files inside the directory and check if it isn't 0
|
||||
File[] emoteFiles = emoteDir.listFiles();
|
||||
if (emoteFiles == null || emoteFiles.length == 0) return;
|
||||
|
||||
// Remove any files that don't have the file extension ".bbmodel" and check if there are still resulting files
|
||||
emoteFiles = Arrays.stream(emoteFiles).filter(file -> file.getPath().endsWith(".bbmodel")).distinct().toArray(File[]::new);
|
||||
if (emoteFiles.length == 0) return;
|
||||
|
||||
// Loop through all files, importing all block bench animations into the registry
|
||||
for (File animationFile : emoteFiles) {
|
||||
String animationKey = FilenameUtils.removeExtension(animationFile.getName());
|
||||
PlayerAnimator.api.getAnimationManager().importAnimations(animationKey, animationFile);
|
||||
}
|
||||
|
||||
// Loops through all the entries in the registries and unpacks any animation packs to ensure if there were multiple animations
|
||||
// inside a singular file, that they are added to the local registry individually for tab completion
|
||||
for (Map.Entry<String, AnimationPack> packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) {
|
||||
packEntry.getValue().getAnimations().keySet().forEach(animationName -> {
|
||||
// API key is the format "animationKey.animationFileName.animationName"
|
||||
String apiKey = packEntry.getKey().replace(":", ".") + "." + animationName;
|
||||
emotes.put(animationName, apiKey);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is an animation with the specified name
|
||||
* @param animationName Name whose presence is to be tested
|
||||
* @return True if this registry contains a mapping for the specified name
|
||||
*/
|
||||
public static boolean has(@NotNull String animationName) {
|
||||
return emotes.containsKey(animationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code API key} to which the specified name is mapped, or {@code null} if this map contains no mapping for the name.
|
||||
* @param animationName Name whose {@code API key} is to be fetched
|
||||
* @return The {@code API key} of the specified name or {@code null} if there was no animation name found
|
||||
*/
|
||||
public static @Nullable String get(@NotNull String animationName) {
|
||||
return emotes.get(animationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a set of all the laoded animation names
|
||||
* @return A set of all loaded animation names
|
||||
*/
|
||||
public static @NotNull Set<String> getAllNames() {
|
||||
return emotes.keySet();
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class Menu {
|
||||
private final boolean shading;
|
||||
|
||||
public Menu(String id, @NotNull ConfigurationNode config) {
|
||||
this.id = id;
|
||||
this.id = config.node("id").getString(id);
|
||||
this.config = config;
|
||||
|
||||
title = config.node("title").getString("chest");
|
||||
@@ -154,8 +154,7 @@ public class Menu {
|
||||
Gui gui = Gui.gui()
|
||||
.title(component)
|
||||
.type(GuiType.CHEST)
|
||||
.rows(this.rows)
|
||||
.inventory((title, owner, rows) -> Bukkit.createInventory(owner, rows, title))
|
||||
.inventory((title, owner, type) -> Bukkit.createInventory(owner, rows * 9, title))
|
||||
.create();
|
||||
|
||||
gui.setDefaultClickAction(event -> event.setCancelled(true));
|
||||
@@ -248,7 +247,7 @@ public class Menu {
|
||||
}
|
||||
}
|
||||
MessagesUtil.sendDebugMessages("Updated menu with title " + title);
|
||||
gui.updateTitle(StringUtils.parseStringToString(Hooks.processPlaceholders(viewer, title.toString())));
|
||||
gui.updateTitle(AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(viewer, title.toString())));
|
||||
} else {
|
||||
for (int i = 0; i < gui.getInventory().getSize(); i++) {
|
||||
if (items.containsKey(i)) {
|
||||
|
||||
@@ -9,12 +9,14 @@ 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;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.util.AdventureUtils;
|
||||
import me.lojosho.hibiscuscommons.util.StringUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -25,31 +27,17 @@ public class DyeMenu {
|
||||
return;
|
||||
}
|
||||
ItemStack originalItem = cosmetic.getItem();
|
||||
if (originalItem == null || !cosmetic.isDyable()) return;
|
||||
if (originalItem == null || !cosmetic.isDyeable()) return;
|
||||
|
||||
Gui gui = HMCColorApi.createColorMenu(viewer);
|
||||
gui.updateTitle(Hooks.processPlaceholders(viewer, StringUtils.parseStringToString(Settings.getDyeMenuName())));
|
||||
gui.updateTitle(AdventureUtils.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(viewer, StringUtils.parseStringToString(Settings.getDyeMenuName()))));
|
||||
gui.setItem(Settings.getDyeMenuInputSlot(), new GuiItem(originalItem));
|
||||
gui.setDefaultTopClickAction(event -> {
|
||||
if (event.getSlot() == Settings.getDyeMenuOutputSlot()) {
|
||||
ItemStack item = event.getInventory().getItem(Settings.getDyeMenuOutputSlot());
|
||||
if (item == null) return;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) return;
|
||||
|
||||
Color color = null;
|
||||
if (meta instanceof LeatherArmorMeta leatherMeta) {
|
||||
color = leatherMeta.getColor();
|
||||
} else if (meta instanceof PotionMeta potionMeta) {
|
||||
color = potionMeta.getColor();
|
||||
} else if (meta instanceof MapMeta mapMeta) {
|
||||
color = mapMeta.getColor();
|
||||
} else if (meta instanceof FireworkEffectMeta fireworkEffectMeta) {
|
||||
FireworkEffect effect = fireworkEffectMeta.getEffect();
|
||||
if (effect != null) {
|
||||
color = effect.getColors().stream().findFirst().isPresent() ? effect.getColors().stream().findFirst().get() : null;
|
||||
}
|
||||
}
|
||||
Color color = NMSHandlers.getHandler().getUtilHandler().getColor(item);
|
||||
if (color == null) return;
|
||||
|
||||
addCosmetic(viewer, cosmeticHolder, cosmetic, color);
|
||||
|
||||
@@ -2,10 +2,22 @@ package com.hibiscusmc.hmccosmetics.gui.type;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticHolder;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.shaded.configurate.ConfigurationNode;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Type {
|
||||
|
||||
@@ -48,4 +60,59 @@ public abstract class Type {
|
||||
* @deprecated Override {@link #setItem(Player, CosmeticHolder, ConfigurationNode, ItemStack, int)} instead.
|
||||
*/
|
||||
public abstract ItemStack setItem(CosmeticUser user, ConfigurationNode config, ItemStack itemStack, int slot);
|
||||
|
||||
@Contract("_, _ -> param2")
|
||||
@NotNull
|
||||
@SuppressWarnings("Duplicates")
|
||||
protected ItemMeta processItemMeta(Player viewer, @NotNull ItemMeta itemMeta) {
|
||||
// New implementation - Paper and forks
|
||||
// I know this is a kinda batshit way to do it (with serializing and deserializing MiniMessage)
|
||||
// But currently I can't think of another good way of doing it without a big refactor. I'll come back to this
|
||||
// At a later date.
|
||||
if (HibiscusCommonsPlugin.isOnPaper()) {
|
||||
List<Component> processedLore = new ArrayList<>();
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
String displayName = MiniMessage.miniMessage().serialize(itemMeta.displayName());
|
||||
displayName = Hooks.processPlaceholders(viewer, displayName);
|
||||
itemMeta.displayName(MiniMessage.miniMessage().deserialize(displayName).decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (Component loreLine : itemMeta.lore()) {
|
||||
String loreStringLine = MiniMessage.miniMessage().serialize(loreLine);
|
||||
loreStringLine = Hooks.processPlaceholders(viewer, loreStringLine);
|
||||
processedLore.add(MiniMessage.miniMessage().deserialize(loreStringLine).decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
|
||||
itemMeta.lore(processedLore);
|
||||
} else {
|
||||
// Legacy implementation - Spigot
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(viewer, itemMeta.getDisplayName()));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(viewer, loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
itemMeta.setLore(processedLore);
|
||||
}
|
||||
|
||||
return itemMeta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -62,17 +59,22 @@ public class TypeCosmetic extends Type {
|
||||
boolean isUnEquippingCosmetic = false;
|
||||
if (cosmeticHolder.getCosmetic(cosmetic.getSlot()) == cosmetic) isUnEquippingCosmetic = true;
|
||||
|
||||
String dyeClick = Settings.getCosmeticDyeClickType();
|
||||
String requiredClick;
|
||||
if (isUnEquippingCosmetic) requiredClick = Settings.getCosmeticUnEquipClickType();
|
||||
else requiredClick = Settings.getCosmeticEquipClickType();
|
||||
|
||||
MessagesUtil.sendDebugMessages("Required click type: " + requiredClick);
|
||||
MessagesUtil.sendDebugMessages("Click type: " + clickType.name());
|
||||
if (!requiredClick.equalsIgnoreCase("ANY") && !requiredClick.equalsIgnoreCase(clickType.name())) {
|
||||
boolean isRequiredClick = requiredClick.equalsIgnoreCase("ANY") || requiredClick.equalsIgnoreCase(clickType.name());
|
||||
boolean isDyeClick = dyeClick.equalsIgnoreCase("ANY") || dyeClick.equalsIgnoreCase(clickType.name());
|
||||
if (!isRequiredClick && !isDyeClick) {
|
||||
MessagesUtil.sendMessage(viewer.getPlayer(), "invalid-click-type");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isRequiredClick && isDyeClick) isUnEquippingCosmetic = false;
|
||||
|
||||
List<String> actionStrings = new ArrayList<>();
|
||||
ConfigurationNode actionConfig = config.node("actions");
|
||||
|
||||
@@ -104,9 +106,9 @@ public class TypeCosmetic extends Type {
|
||||
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")) {
|
||||
if (cosmetic.isDyeable() && isDyeClick && Hooks.isActiveHook("HMCColor")) {
|
||||
DyeMenu.openMenu(viewer, cosmeticHolder, cosmetic);
|
||||
} else {
|
||||
} else if (isRequiredClick) {
|
||||
cosmeticHolder.addCosmetic(cosmetic);
|
||||
}
|
||||
}
|
||||
@@ -139,7 +141,7 @@ public class TypeCosmetic extends Type {
|
||||
|
||||
@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()));
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processItemMeta(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta?");
|
||||
|
||||
if (config.node("cosmetic").virtual()) {
|
||||
@@ -164,7 +166,7 @@ public class TypeCosmetic extends Type {
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processLoreLines(viewer, itemStack.getItemMeta()));
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processItemMeta(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta in equipped item?");
|
||||
return itemStack;
|
||||
}
|
||||
@@ -182,35 +184,10 @@ public class TypeCosmetic extends Type {
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processLoreLines(viewer, itemStack.getItemMeta()));
|
||||
if (itemStack.hasItemMeta()) itemStack.setItemMeta(processItemMeta(viewer, itemStack.getItemMeta()));
|
||||
else MessagesUtil.sendDebugMessages("ItemStack has no ItemMeta in locked item?");
|
||||
return itemStack;
|
||||
}
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Contract("_, _ -> param2")
|
||||
@NotNull
|
||||
@SuppressWarnings("Duplicates")
|
||||
private ItemMeta processLoreLines(Player viewer, @NotNull ItemMeta itemMeta) {
|
||||
List<String> processedLore = new ArrayList<>();
|
||||
|
||||
if (itemMeta.hasDisplayName()) {
|
||||
itemMeta.setDisplayName(Hooks.processPlaceholders(viewer, itemMeta.getDisplayName()));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(viewer, loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
itemMeta.setLore(processedLore);
|
||||
return itemMeta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,12 @@ 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;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -78,27 +76,9 @@ public class TypeEmpty extends Type {
|
||||
@Override
|
||||
@SuppressWarnings("Duplicates")
|
||||
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(viewer, itemMeta.getDisplayName()));
|
||||
}
|
||||
|
||||
if (itemMeta.hasLore()) {
|
||||
for (String loreLine : itemMeta.getLore()) {
|
||||
processedLore.add(Hooks.processPlaceholders(viewer, loreLine));
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMeta instanceof SkullMeta skullMeta) {
|
||||
if (skullMeta.hasOwner() && skullMeta.getOwner() != null) {
|
||||
skullMeta.setOwner(Hooks.processPlaceholders(viewer, skullMeta.getOwner()));
|
||||
}
|
||||
}
|
||||
|
||||
itemMeta.setLore(processedLore);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
itemStack.setItemMeta(processItemMeta(viewer, itemMeta));
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.hooks.worldguard;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStartEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Wardrobe;
|
||||
import com.hibiscusmc.hmccosmetics.config.WardrobeSettings;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
@@ -8,6 +7,7 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
@@ -20,32 +20,44 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Contains {@link com.sk89q.worldguard.WorldGuard WorldGuard} related event listeners
|
||||
*/
|
||||
public class WGListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerMove(@NotNull PlayerMoveEvent event) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
Player player = event.getPlayer();
|
||||
Location from = event.getFrom();
|
||||
Location to = event.getTo();
|
||||
if (from.getBlockX() == to.getBlockX() && from.getBlockY() == to.getBlockY() && from.getBlockZ() == to.getBlockZ()) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
Location location = event.getPlayer().getLocation();
|
||||
Location location = player.getLocation();
|
||||
ApplicableRegionSet set = getRegions(location);
|
||||
if (user.isHidden()) {
|
||||
if (set.getRegions().isEmpty()) {
|
||||
if (user.isHidden() && set.getRegions().isEmpty()) {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> wardrobeNames = WardrobeSettings.getWardrobeNames();
|
||||
for (ProtectedRegion protectedRegion : set.getRegions()) {
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getCosmeticEnableFlag())) {
|
||||
if (protectedRegion.getFlags().get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
|
||||
Map<Flag<?>, Object> flags = protectedRegion.getFlags();
|
||||
if (flags.containsKey(WGHook.getCosmeticEnableFlag())) {
|
||||
if (flags.get(WGHook.getCosmeticEnableFlag()).toString().equalsIgnoreCase("ALLOW")) {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
} else {
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.WORLDGUARD);
|
||||
}
|
||||
}
|
||||
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());
|
||||
if (flags.containsKey(WGHook.getCosmeticWardrobeFlag())) {
|
||||
String wardrobeName = flags.getOrDefault(WGHook.getCosmeticWardrobeFlag(), "").toString();
|
||||
if (wardrobeName.isEmpty() || !wardrobeNames.contains(wardrobeName)) return;
|
||||
Wardrobe wardrobe = WardrobeSettings.getWardrobe(wardrobeName);
|
||||
if (wardrobe == null) return;
|
||||
user.enterWardrobe(wardrobe, true);
|
||||
}
|
||||
}
|
||||
@@ -79,23 +91,6 @@ public class WGListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerEmote(PlayerEmoteStartEvent event) {
|
||||
Player player = event.getUser().getPlayer();
|
||||
if (player == null) return;
|
||||
Location location = player.getLocation();
|
||||
ApplicableRegionSet set = getRegions(location);
|
||||
for (ProtectedRegion protectedRegion : set.getRegions()) {
|
||||
if (protectedRegion.getFlags().containsKey(WGHook.getEmotesEnableFlag())) {
|
||||
if (protectedRegion.getFlags().get(WGHook.getEmotesEnableFlag()).toString().equalsIgnoreCase("DENY")) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ApplicableRegionSet getRegions(Location location) {
|
||||
com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(location);
|
||||
RegionContainer region = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
|
||||
@@ -3,15 +3,16 @@ 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.PlayerPreUnloadEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerUnloadEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.DatabaseSettings;
|
||||
import com.hibiscusmc.hmccosmetics.database.Database;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menus;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -22,43 +23,37 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerConnectionListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
|
||||
if (event.getPlayer().isOp() || event.getPlayer().hasPermission("hmccosmetics.notifyupdate")) {
|
||||
if (!HMCCosmeticsPlugin.getInstance().getLatestVersion().equalsIgnoreCase(HMCCosmeticsPlugin.getInstance().getDescription().getVersion()) && HMCCosmeticsPlugin.getInstance().getLatestVersion().isEmpty())
|
||||
MessagesUtil.sendMessageNoKey(
|
||||
event.getPlayer(),
|
||||
"<br>" +
|
||||
"<GRAY>There is a new version of <light_purple><Bold>HMCCosmetics<reset><gray> available!<br>" +
|
||||
"<GRAY>Current version: <red>" + HMCCosmeticsPlugin.getInstance().getDescription().getVersion() + " <GRAY>| Latest version: <light_purple>" + HMCCosmeticsPlugin.getInstance().getLatestVersion() + "<br>" +
|
||||
"<GRAY>Download it on <gold><click:OPEN_URL:'https://www.spigotmc.org/resources/100107/'>Spigot<reset> <gray>or <gold><click:OPEN_URL:'https://polymart.org/resource/1879'>Polymart<reset><gray>!" +
|
||||
"<br>"
|
||||
if (DatabaseSettings.isEnabledDelay()) {
|
||||
MessagesUtil.sendDebugMessages("Delay Enabled with " + DatabaseSettings.getDelayLength() + " ticks");
|
||||
Bukkit.getScheduler().runTaskLater(
|
||||
HMCCosmeticsPlugin.getInstance(),
|
||||
() -> this.loadUserData(event.getPlayer()),
|
||||
DatabaseSettings.getDelayLength()
|
||||
);
|
||||
} else {
|
||||
this.loadUserData(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
private void loadUserData(final Player player) {
|
||||
if(!player.isOnline()) return;
|
||||
final UUID playerId = player.getUniqueId();
|
||||
|
||||
PlayerPreLoadEvent preLoadEvent = new PlayerPreLoadEvent(uuid);
|
||||
PlayerPreLoadEvent preLoadEvent = new PlayerPreLoadEvent(playerId);
|
||||
Bukkit.getPluginManager().callEvent(preLoadEvent);
|
||||
if (preLoadEvent.isCancelled()) return;
|
||||
|
||||
Database.get(uuid).thenAccept(userData -> {
|
||||
if (userData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Database.get(playerId).thenAccept(userData -> {
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
CosmeticUser cosmeticUser = CosmeticUsers.getProvider()
|
||||
.createCosmeticUser(uuid)
|
||||
.createCosmeticUser(playerId)
|
||||
.initialize(userData);
|
||||
cosmeticUser.startTicking();
|
||||
|
||||
CosmeticUsers.addUser(cosmeticUser);
|
||||
MessagesUtil.sendDebugMessages("Run User Join for " + uuid);
|
||||
MessagesUtil.sendDebugMessages("Run User Join for " + playerId);
|
||||
|
||||
PlayerLoadEvent playerLoadEvent = new PlayerLoadEvent(cosmeticUser);
|
||||
Bukkit.getPluginManager().callEvent(playerLoadEvent);
|
||||
@@ -70,17 +65,9 @@ public class PlayerConnectionListener implements Listener {
|
||||
}, 4);
|
||||
});
|
||||
}).exceptionally(ex -> {
|
||||
MessagesUtil.sendDebugMessages("Unable to load Cosmetic User " + uuid + ". Exception: " + ex.getMessage());
|
||||
MessagesUtil.sendDebugMessages("Unable to load Cosmetic User " + playerId + ". Exception: " + ex.getMessage());
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
if (DatabaseSettings.isEnabledDelay()) {
|
||||
MessagesUtil.sendDebugMessages("Delay Enabled with " + DatabaseSettings.getDelayLength() + " ticks");
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), run, DatabaseSettings.getDelayLength());
|
||||
} else {
|
||||
run.run();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@@ -88,20 +75,37 @@ public class PlayerConnectionListener implements Listener {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return; // Player never initialized, don't do anything
|
||||
|
||||
PlayerPreUnloadEvent preUnloadEvent = new PlayerPreUnloadEvent(user);
|
||||
Bukkit.getPluginManager().callEvent(preUnloadEvent);
|
||||
if (preUnloadEvent.isCancelled()) return;
|
||||
|
||||
PlayerUnloadEvent playerUnloadEvent = new PlayerUnloadEvent(user);
|
||||
Bukkit.getPluginManager().callEvent(playerUnloadEvent);
|
||||
|
||||
if (user.isInWardrobe()) {
|
||||
user.leaveWardrobe(true);
|
||||
user.getPlayer().setInvisible(false);
|
||||
}
|
||||
if (user.getUserEmoteManager().isPlayingEmote()) {
|
||||
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.CONNECTION);
|
||||
event.getPlayer().setInvisible(false);
|
||||
|
||||
final Player player = user.getPlayer();
|
||||
if(player != null) player.setInvisible(false);
|
||||
}
|
||||
Menus.removeCooldown(event.getPlayer().getUniqueId()); // Removes any menu cooldowns a player might have
|
||||
Database.save(user);
|
||||
user.destroy();
|
||||
CosmeticUsers.removeUser(user.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void notifyAdminUpdate(final PlayerJoinEvent event) {
|
||||
if (event.getPlayer().isOp() || event.getPlayer().hasPermission("hmccosmetics.notifyupdate")) {
|
||||
if (!HMCCosmeticsPlugin.getInstance().getLatestVersion().equalsIgnoreCase(HMCCosmeticsPlugin.getInstance().getDescription().getVersion()) && HMCCosmeticsPlugin.getInstance().getLatestVersion().isEmpty())
|
||||
MessagesUtil.sendMessageNoKey(
|
||||
event.getPlayer(),
|
||||
"<br>" +
|
||||
"<GRAY>There is a new version of <light_purple><Bold>HMCCosmetics<reset><gray> available!<br>" +
|
||||
"<GRAY>Current version: <red>" + HMCCosmeticsPlugin.getInstance().getDescription().getVersion() + " <GRAY>| Latest version: <light_purple>" + HMCCosmeticsPlugin.getInstance().getLatestVersion() + "<br>" +
|
||||
"<GRAY>Download it on <gold><click:OPEN_URL:'https://www.spigotmc.org/resources/100107/'>Spigot<reset> <gray>or <gold><click:OPEN_URL:'https://polymart.org/resource/1879'>Polymart<reset><gray>!" +
|
||||
"<br>"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.*;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.Pair;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerCosmeticPostEquipEvent;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
@@ -14,17 +9,17 @@ 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.CosmeticEmoteType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
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.nms.MinecraftVersion;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -52,17 +47,6 @@ import java.util.*;
|
||||
|
||||
public class PlayerGameListener implements Listener {
|
||||
|
||||
public PlayerGameListener() {
|
||||
registerInventoryClickListener();
|
||||
registerMenuChangeListener();
|
||||
registerEntityStatusListener();
|
||||
registerPlayerEquipmentListener();
|
||||
registerPlayerArmListener();
|
||||
registerEntityUseListener();
|
||||
registerSlotChangeListener();
|
||||
registerPassengerSetListener();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerClick(@NotNull InventoryClickEvent event) {
|
||||
// || !event.getClickedInventory().getType().equals(InventoryType.PLAYER)
|
||||
@@ -95,10 +79,6 @@ public class PlayerGameListener implements Listener {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
|
||||
|
||||
if (user == null) return;
|
||||
if (event.isSneaking()) {
|
||||
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.SNEAK);
|
||||
}
|
||||
|
||||
if (!event.isSneaking()) return;
|
||||
if (!user.isInWardrobe()) return;
|
||||
|
||||
@@ -136,9 +116,6 @@ public class PlayerGameListener implements Listener {
|
||||
}, 2);
|
||||
|
||||
if (event.getCause().equals(PlayerTeleportEvent.TeleportCause.NETHER_PORTAL) || event.getCause().equals(PlayerTeleportEvent.TeleportCause.END_PORTAL)) return;
|
||||
if (user.getUserEmoteManager().isPlayingEmote()) {
|
||||
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.TELEPORT);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
@@ -180,14 +157,6 @@ public class PlayerGameListener implements Listener {
|
||||
if (!(event.getEntity() instanceof Player player)) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.getUserEmoteManager().isPlayingEmote()) {
|
||||
if (Settings.isEmoteInvincible()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (Settings.isEmoteDamageLeave()) {
|
||||
user.getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.DAMAGE);
|
||||
}
|
||||
}
|
||||
if (user.isInWardrobe()) {
|
||||
if (WardrobeSettings.isPreventDamage()) {
|
||||
event.setCancelled(true);
|
||||
@@ -202,10 +171,6 @@ public class PlayerGameListener implements Listener {
|
||||
Player player = event.getPlayer();
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (!Settings.isEmoteMoveCheck() && user.getUserEmoteManager().isPlayingEmote()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
user.updateCosmetic(CosmeticSlot.BACKPACK);
|
||||
user.updateCosmetic(CosmeticSlot.BALLOON);
|
||||
}
|
||||
@@ -269,12 +234,6 @@ public class PlayerGameListener implements Listener {
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
|
||||
if (user == null) return;
|
||||
// Really need to look into optimization of this
|
||||
if (user.hasCosmeticInSlot(CosmeticSlot.EMOTE) && event.getPlayer().isSneaking() && event.getPlayer().hasPermission("hmccosmetics.emote.shiftrun")) {
|
||||
CosmeticEmoteType cosmeticEmoteType = (CosmeticEmoteType) user.getCosmetic(CosmeticSlot.EMOTE);
|
||||
cosmeticEmoteType.run(user);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
if (user.getEntity() == null) return; // Player has likely logged off
|
||||
user.updateCosmetic(CosmeticSlot.OFFHAND);
|
||||
@@ -451,250 +410,6 @@ public class PlayerGameListener implements Listener {
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.PLUGIN);
|
||||
}
|
||||
|
||||
private void registerInventoryClickListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, List.of(PacketType.Play.Client.WINDOW_CLICK), ListenerOptions.ASYNC) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
int invTypeClicked = event.getPacket().getIntegers().read(0);
|
||||
int slotClicked = event.getPacket().getIntegers().read(2);
|
||||
|
||||
// Must be a player inventory.
|
||||
if (invTypeClicked != 0) return;
|
||||
// -999 is when a player clicks outside their inventory. https://wiki.vg/Inventory#Player_Inventory
|
||||
if (slotClicked == -999) return;
|
||||
if (event.getPlayer() == null) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.isInWardrobe()) return;
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotClicked);
|
||||
if (cosmeticSlot == null) return;
|
||||
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
|
||||
MessagesUtil.sendDebugMessages("Packet fired, updated cosmetic " + cosmeticSlot);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerMenuChangeListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, List.of(PacketType.Play.Server.WINDOW_ITEMS), ListenerOptions.ASYNC) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
MessagesUtil.sendDebugMessages("Menu Initial ");
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
|
||||
int windowID = event.getPacket().getIntegers().read(0);
|
||||
List<ItemStack> slotData = event.getPacket().getItemListModifier().read(0);
|
||||
if (windowID != 0) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
|
||||
HashMap<Integer, ItemStack> items = new HashMap<>();
|
||||
|
||||
if (!user.isInWardrobe()) {
|
||||
for (Cosmetic cosmetic : user.getCosmetics()) {
|
||||
if ((cosmetic instanceof CosmeticArmorType cosmeticArmorType)) {
|
||||
boolean requireEmpty = Settings.getSlotOption(cosmeticArmorType.getEquipSlot()).isRequireEmpty();
|
||||
boolean isAir = user.getPlayer().getInventory().getItem(cosmeticArmorType.getEquipSlot()).getType().isAir();
|
||||
MessagesUtil.sendDebugMessages("Menu Fired (Checks) - " + cosmeticArmorType.getId() + " - " + requireEmpty + " - " + isAir);
|
||||
if (requireEmpty && !isAir) continue;
|
||||
items.put(HMCCInventoryUtils.getPacketArmorSlot(cosmeticArmorType.getEquipSlot()), user.getUserCosmeticItem(cosmeticArmorType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);
|
||||
packet.getIntegers().write(0, 0);
|
||||
for (int slot = 0; slot < 46; slot++) {
|
||||
if ((slot >= 5 && slot <= 8) || slot == 45) {
|
||||
if (!items.containsKey(slot)) continue;
|
||||
slotData.set(slot, items.get(slot));
|
||||
if (Settings.isDebugMode()) MessagesUtil.sendDebugMessages("Set " + slot + " as " + items.get(slot));
|
||||
}
|
||||
}
|
||||
packet.getItemListModifier().write(0, slotData);
|
||||
packet.getItemModifier().write(0, event.getPacket().getItemModifier().read(0));
|
||||
event.setPacket(packet);
|
||||
MessagesUtil.sendDebugMessages("Menu Fired, updated cosmetics " + " on slotdata " + windowID + " with " + slotData.size());
|
||||
/*
|
||||
for (Cosmetic cosmetic : user.getCosmetic()) {
|
||||
if ((cosmetic instanceof CosmeticArmorType) || (cosmetic instanceof CosmeticMainhandType)) {
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
user.updateCosmetic(cosmetic);
|
||||
}, 1);
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerSlotChangeListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.SET_SLOT) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
MessagesUtil.sendDebugMessages("SetSlot Initial ");
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (event.getPlayer() == null) return;
|
||||
|
||||
int windowID = event.getPacket().getIntegers().read(0);
|
||||
if (windowID != 0) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.isInWardrobe()) return;
|
||||
|
||||
int slot = event.getPacket().getIntegers().read(2);
|
||||
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slot);
|
||||
EquipmentSlot equipmentSlot = HMCCInventoryUtils.getPacketArmorSlot(slot);
|
||||
if (cosmeticSlot == null || equipmentSlot == null) return;
|
||||
if (!user.hasCosmeticInSlot(cosmeticSlot)) return;
|
||||
if (Settings.getSlotOption(equipmentSlot).isRequireEmpty()) {
|
||||
if (!player.getInventory().getItem(equipmentSlot).getType().isAir()) return;
|
||||
}
|
||||
event.getPacket().getItemModifier().write(0, user.getUserCosmeticItem(cosmeticSlot));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPlayerEquipmentListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_EQUIPMENT) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
Player player = event.getPlayer(); // Player that's sent
|
||||
int entityID = event.getPacket().getIntegers().read(0);
|
||||
// User
|
||||
CosmeticUser user = CosmeticUsers.getUser(entityID);
|
||||
if (user == null) return;
|
||||
if (user.isInWardrobe()) return;
|
||||
|
||||
List<com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack>> armor = event.getPacket().getSlotStackPairLists().read(0);
|
||||
|
||||
for (int i = 0; i < armor.size(); i++) {
|
||||
com.comphenix.protocol.wrappers.Pair<EnumWrappers.ItemSlot, ItemStack> pair = armor.get(i);
|
||||
switch (pair.getFirst()) {
|
||||
case MAINHAND -> {
|
||||
if (user.getPlayer() == event.getPlayer()) continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
|
||||
if (user.getPlayer() != null && user.getPlayer().isInvisible()) continue; // Fixes integration with GSit still showing mainhand even when hidden
|
||||
armor.set(i, new Pair<>(pair.getFirst(), user.getPlayer().getInventory().getItemInMainHand()));
|
||||
}
|
||||
default -> {
|
||||
EquipmentSlot slot = HMCCInventoryUtils.getEquipmentSlot(pair.getFirst());
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.getItemSlotToCosmeticSlot(pair.getFirst());
|
||||
if (slot == null || cosmeticSlot == null) continue;
|
||||
if (Settings.getSlotOption(slot).isRequireEmpty()
|
||||
&& !user.getPlayer().getInventory().getItem(slot).getType().isAir()) continue;
|
||||
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(cosmeticSlot);
|
||||
if (cosmeticArmor == null) continue;
|
||||
ItemStack item = user.getUserCosmeticItem(cosmeticArmor);
|
||||
if (item == null) continue;
|
||||
Pair<EnumWrappers.ItemSlot, ItemStack> armorPair = new Pair<>(HMCCInventoryUtils.itemBukkitSlot(slot), item);
|
||||
armor.set(i, armorPair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event.getPacket().getSlotStackPairLists().write(0, armor);
|
||||
MessagesUtil.sendDebugMessages("Equipment for " + user.getPlayer().getName() + " has been updated for " + player.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerEntityStatusListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.ENTITY_STATUS) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
int entityid = event.getPacket().getIntegers().read(0);
|
||||
byte status = event.getPacket().getBytes().read(0);
|
||||
|
||||
MessagesUtil.sendDebugMessages("EntityStatus Initial " + entityid + " - " + status);
|
||||
if (status != 55) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(entityid);
|
||||
if (user == null) {
|
||||
MessagesUtil.sendDebugMessages("EntityStatus User is null");
|
||||
return;
|
||||
}
|
||||
if (!user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPassengerSetListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Server.MOUNT) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
CosmeticUser viewerUser = CosmeticUsers.getUser(event.getPlayer().getUniqueId());
|
||||
if (viewerUser == null) return;
|
||||
if (viewerUser.isInWardrobe()) return;
|
||||
|
||||
int ownerId = event.getPacket().getIntegers().read(0);
|
||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId);
|
||||
Entity entity = HMCCServerUtils.getEntity(ownerId);
|
||||
if (entity == null) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(entity.getUniqueId());
|
||||
if (user == null) return;
|
||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - " + user.getUniqueId());
|
||||
|
||||
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return;
|
||||
if (user.getUserBackpackManager() == null) return;
|
||||
|
||||
// Basically, take the original passengers and "bump" them to the end of the list
|
||||
int[] originalPassengers = event.getPacket().getIntegerArrays().read(0);
|
||||
List<Integer> passengers = new ArrayList<>(user.getUserBackpackManager().getEntityManager().getIds());
|
||||
|
||||
passengers.addAll(Arrays.stream(originalPassengers).boxed().toList());
|
||||
|
||||
event.getPacket().getIntegerArrays().write(0, passengers.stream().mapToInt(Integer::intValue).toArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerPlayerArmListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.ARM_ANIMATION) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
if (event.getPlayer() == null) return;
|
||||
Player player = event.getPlayer();
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return;
|
||||
if (user.getUserEmoteManager().isPlayingEmote()) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!user.isInWardrobe()) return;
|
||||
if (!user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return;
|
||||
|
||||
Menu menu = user.getWardrobeManager().getLastOpenMenu();
|
||||
if (menu == null) return;
|
||||
menu.openMenu(user);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerEntityUseListener() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(HMCCosmeticsPlugin.getInstance(), ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
if (event.getPlayer() == null) return;
|
||||
CosmeticUser user = CosmeticUsers.getUser(event.getPlayer());
|
||||
if (user == null) return;
|
||||
if (user.getUserEmoteManager().isPlayingEmote() || user.isInWardrobe()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private EquipmentSlot getArmorSlot(final Material material) {
|
||||
for (final EquipmentSlot slot : EquipmentSlot.values()) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.hibiscusmc.hmccosmetics.listener;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.nms.CosmeticChannelHandler;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import net.minecraft.network.Connection;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class PlayerPacketListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Channel channel = ((CraftPlayer) event.getPlayer()).getHandle().connection.connection.channel;
|
||||
ChannelPipeline pipeline = channel.pipeline();
|
||||
|
||||
CosmeticChannelHandler channelHandler = new CosmeticChannelHandler(player);
|
||||
for (String key : pipeline.toMap().keySet()) {
|
||||
if (!(pipeline.get(key) instanceof Connection)) continue;
|
||||
pipeline.addBefore(key, "hmccosmetics_channel_handler", channelHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,15 @@ import me.lojosho.hibiscuscommons.hooks.items.HookNexo;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
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();
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onHookReload(@NotNull HibiscusHookReload event) {
|
||||
final Hook hook = event.getHook();
|
||||
final HibiscusHookReload.ReloadType reloadType = event.getReloadType();
|
||||
|
||||
if (hook instanceof HookItemAdder) {
|
||||
if (reloadType == HibiscusHookReload.ReloadType.RELOAD) {
|
||||
if (!Settings.isItemsAdderChangeReload()) return;
|
||||
@@ -31,8 +33,8 @@ public class ServerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onAllHooksReady(HibiscusHooksAllActiveEvent event) {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onAllHooksReady(@NotNull HibiscusHooksAllActiveEvent event) {
|
||||
HMCCosmeticsPlugin.setup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
package com.hibiscusmc.hmccosmetics.nms;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticArmorType;
|
||||
import com.hibiscusmc.hmccosmetics.gui.Menu;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
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.mojang.datafixers.util.Pair;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket;
|
||||
import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftEquipmentSlot;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CosmeticChannelHandler extends ChannelDuplexHandler {
|
||||
private final Player player;
|
||||
|
||||
public CosmeticChannelHandler(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
if (!(msg instanceof Packet packet)) {
|
||||
super.write(ctx, msg, promise);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (packet) {
|
||||
case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket);
|
||||
case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket);
|
||||
case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket);
|
||||
case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket);
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
if (msg == null) return;
|
||||
else super.write(ctx, msg, promise);
|
||||
}
|
||||
|
||||
private Packet<?> handleMenuChange(ClientboundContainerSetContentPacket packet) {
|
||||
MessagesUtil.sendDebugMessages("Menu Initial ");
|
||||
int windowId = packet.getContainerId();
|
||||
NonNullList<ItemStack> slotData = NonNullList.create();
|
||||
slotData.addAll(packet.getItems());
|
||||
if (windowId != 0) return packet;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) return packet;
|
||||
|
||||
HashMap<Integer, ItemStack> items = new HashMap<>();
|
||||
|
||||
if (!user.isInWardrobe()) for (Cosmetic cosmetic : user.getCosmetics()) if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||
boolean requireEmpty = Settings.getSlotOption(armorType.getEquipSlot()).isRequireEmpty();
|
||||
boolean isAir = user.getPlayer().getInventory().getItem(armorType.getEquipSlot()).getType().isAir();
|
||||
MessagesUtil.sendDebugMessages("Menu Fired (Checks) - " + armorType.getId() + " - " + requireEmpty + " - " + isAir);
|
||||
if (requireEmpty && !isAir) continue;
|
||||
items.put(HMCCInventoryUtils.getPacketArmorSlot(armorType.getEquipSlot()), CraftItemStack.asNMSCopy(user.getUserCosmeticItem(armorType)));
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < 46; slot++) {
|
||||
if ((slot >= 5 && slot <= 8) || slot == 45) {
|
||||
if (!items.containsKey(slot)) continue;
|
||||
slotData.set(slot, items.get(slot));
|
||||
if (Settings.isDebugMode()) MessagesUtil.sendDebugMessages("Set " + slot + " as " + items.get(slot));
|
||||
}
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("Menu Fired, updated cosmetics " + " on slotdata " + windowId + " with " + slotData.size());
|
||||
return new ClientboundContainerSetContentPacket(0, packet.getStateId(), slotData, packet.getCarriedItem());
|
||||
}
|
||||
|
||||
private Packet<?> handleSlotChange(ClientboundContainerSetSlotPacket packet) {
|
||||
MessagesUtil.sendDebugMessages("SetSlot Initial ");
|
||||
|
||||
int windowId = packet.getContainerId();
|
||||
if (windowId != 0) return packet;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null || user.isInWardrobe()) return packet;
|
||||
|
||||
int slot = packet.getSlot();
|
||||
MessagesUtil.sendDebugMessages("SetSlot Slot " + slot);
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slot);
|
||||
EquipmentSlot equipmentSlot = HMCCInventoryUtils.getPacketArmorSlot(slot);
|
||||
if (cosmeticSlot == null || equipmentSlot == null) return packet;
|
||||
if (!user.hasCosmeticInSlot(cosmeticSlot)) return packet;
|
||||
if (Settings.getSlotOption(equipmentSlot).isRequireEmpty()) {
|
||||
if (!player.getInventory().getItem(equipmentSlot).getType().isAir()) return packet;
|
||||
}
|
||||
|
||||
ItemStack item = CraftItemStack.asNMSCopy(user.getUserCosmeticItem(cosmeticSlot));
|
||||
return new ClientboundContainerSetSlotPacket(0, packet.getStateId(), slot, item);
|
||||
}
|
||||
|
||||
private Packet<?> handlePlayerEquipment(ClientboundSetEquipmentPacket packet) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(packet.getEntity());
|
||||
if (user == null || user.isInWardrobe()) return packet;
|
||||
|
||||
List<Pair<net.minecraft.world.entity.EquipmentSlot, ItemStack>> armor = packet.getSlots();
|
||||
|
||||
for (int i = 0; i < armor.size(); i++) {
|
||||
Pair<net.minecraft.world.entity.EquipmentSlot, ItemStack> pair = armor.get(i);
|
||||
if (pair.getFirst() == net.minecraft.world.entity.EquipmentSlot.MAINHAND) {
|
||||
if (user.getPlayer().getUniqueId() == player.getUniqueId())
|
||||
continue; // When a player scrolls real fast, it messes up the mainhand. This fixes it
|
||||
if (user.getPlayer() != null && user.getPlayer().isInvisible())
|
||||
continue; // Fixes integration with GSit still showing mainhand even when hidden
|
||||
armor.set(i, new Pair<>(pair.getFirst(), CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand())));
|
||||
} else {
|
||||
EquipmentSlot slot = CraftEquipmentSlot.getSlot(pair.getFirst());
|
||||
if (slot == null) continue;
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.BukkitCosmeticSlot(slot);
|
||||
if (cosmeticSlot == null) continue;
|
||||
if (Settings.getSlotOption(slot).isRequireEmpty() && player.getInventory().getItem(slot).getType().isAir())
|
||||
continue;
|
||||
|
||||
CosmeticArmorType cosmeticArmor = (CosmeticArmorType) user.getCosmetic(cosmeticSlot);
|
||||
if (cosmeticArmor == null) continue;
|
||||
ItemStack item = CraftItemStack.asNMSCopy(user.getUserCosmeticItem(cosmeticSlot));
|
||||
if (item == null) continue;
|
||||
armor.set(i, new Pair<>(pair.getFirst(), item));
|
||||
}
|
||||
}
|
||||
|
||||
MessagesUtil.sendDebugMessages("Equipment for " + user.getPlayer().getName() + " has been updated for " + player.getName());
|
||||
return new ClientboundSetEquipmentPacket(packet.getEntity(), armor);
|
||||
}
|
||||
|
||||
private Packet<?> handlePassengerSet(ClientboundSetPassengersPacket packet) {
|
||||
CosmeticUser viewerUser = CosmeticUsers.getUser(player);
|
||||
if (viewerUser == null || viewerUser.isInWardrobe()) return packet;
|
||||
|
||||
int ownerId = packet.getVehicle();
|
||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId);
|
||||
Entity entity = HMCCServerUtils.getEntity(ownerId);
|
||||
if (entity == null) return packet;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(entity.getUniqueId());
|
||||
if (user == null) return packet;
|
||||
MessagesUtil.sendDebugMessages("Mount Packet Sent - " + user.getUniqueId());
|
||||
|
||||
if (!user.hasCosmeticInSlot(CosmeticSlot.BACKPACK)) return packet;
|
||||
if (user.getUserBackpackManager() == null) return packet;
|
||||
|
||||
List<Integer> passengers = new ArrayList<>(user.getUserBackpackManager().getEntityManager().getIds());
|
||||
for (int passenger : packet.getPassengers()) passengers.add(passenger);
|
||||
|
||||
int[] passengerIds = passengers.stream().mapToInt(Integer::intValue).toArray();
|
||||
return (Packet<?>) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengerIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
if (!(msg instanceof Packet packet)) {
|
||||
super.channelRead(ctx, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (packet) {
|
||||
case ServerboundContainerClickPacket clickPacket -> handleInventoryClick(clickPacket);
|
||||
case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket);
|
||||
case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket);
|
||||
case ServerboundUseItemOnPacket useItemOnPacket -> msg = handleEntityUse(useItemOnPacket);
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
if (msg == null) return;
|
||||
else super.channelRead(ctx, msg);
|
||||
|
||||
}
|
||||
|
||||
private void handleInventoryClick(ServerboundContainerClickPacket packet) {
|
||||
ClickType clickType = packet.getClickType();
|
||||
int slotClicked = packet.getSlotNum();
|
||||
|
||||
if (clickType != ClickType.PICKUP || slotClicked == -999) return;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null || user.isInWardrobe()) return;
|
||||
CosmeticSlot cosmeticSlot = HMCCInventoryUtils.NMSCosmeticSlot(slotClicked);
|
||||
if (cosmeticSlot == null || !user.hasCosmeticInSlot(cosmeticSlot)) return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(HMCCosmeticsPlugin.getInstance(), () -> user.updateCosmetic(cosmeticSlot), 1);
|
||||
MessagesUtil.sendDebugMessages("Packet fired, updated cosmetic " + cosmeticSlot);
|
||||
}
|
||||
|
||||
private Packet<?> handlePlayerAction(ServerboundPlayerActionPacket packet) {
|
||||
ServerboundPlayerActionPacket.Action action = packet.getAction();
|
||||
|
||||
MessagesUtil.sendDebugMessages("EntityStatus Initial " + player.getEntityId() + " - " + action);
|
||||
if (action != ServerboundPlayerActionPacket.Action.SWAP_ITEM_WITH_OFFHAND) return packet;
|
||||
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null) {
|
||||
MessagesUtil.sendDebugMessages("EntityStatus User is null");
|
||||
return packet;
|
||||
}
|
||||
if (!user.hasCosmeticInSlot(CosmeticSlot.OFFHAND)) return packet;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Packet<?> handlePlayerArm(ServerboundSwingPacket packet) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null || !user.isInWardrobe() || !user.getWardrobeManager().getWardrobeStatus().equals(UserWardrobeManager.WardrobeStatus.RUNNING)) return packet;
|
||||
|
||||
Menu menu = user.getWardrobeManager().getLastOpenMenu();
|
||||
if (menu == null) return packet;
|
||||
menu.openMenu(user);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Packet<?> handleEntityUse(ServerboundUseItemOnPacket packet) {
|
||||
CosmeticUser user = CosmeticUsers.getUser(player);
|
||||
if (user == null || !user.isInWardrobe()) return packet;
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,14 @@ 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;
|
||||
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.packets.HMCCPacketManager;
|
||||
import com.ticxo.modelengine.api.nms.NMSHandler;
|
||||
import lombok.Getter;
|
||||
import me.lojosho.hibiscuscommons.hooks.Hooks;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.util.InventoryUtils;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -54,8 +55,6 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
private UserBalloonManager userBalloonManager;
|
||||
@Getter
|
||||
private UserBackpackManager userBackpackManager;
|
||||
@Getter
|
||||
private final UserEmoteManager userEmoteManager;
|
||||
|
||||
// Cosmetic Settings/Toggles
|
||||
private final ArrayList<HiddenReason> hiddenReason = new ArrayList<>();
|
||||
@@ -74,7 +73,6 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
|
||||
public CosmeticUser(@NotNull UUID uuid) {
|
||||
this.uniqueId = uuid;
|
||||
this.userEmoteManager = new UserEmoteManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,7 +192,7 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
|
||||
this.updateCosmetic();
|
||||
|
||||
if(isHidden() && !getUserEmoteManager().isPlayingEmote() && !playerCosmetics.isEmpty()) {
|
||||
if(isHidden() && !playerCosmetics.isEmpty()) {
|
||||
MessagesUtil.sendActionBar(getPlayer(), "hidden-cosmetics");
|
||||
}
|
||||
}
|
||||
@@ -282,9 +280,6 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
if (slot == CosmeticSlot.BALLOON) {
|
||||
despawnBalloon();
|
||||
}
|
||||
if (slot == CosmeticSlot.EMOTE) {
|
||||
if (getUserEmoteManager().isPlayingEmote()) getUserEmoteManager().stopEmote(UserEmoteManager.StopEmoteReason.UNEQUIP);
|
||||
}
|
||||
colors.remove(slot);
|
||||
playerCosmetics.remove(slot);
|
||||
removeArmor(slot);
|
||||
@@ -317,7 +312,7 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
|
||||
for (Cosmetic cosmetic : playerCosmetics.values()) {
|
||||
if (cosmetic instanceof CosmeticArmorType armorType) {
|
||||
if (getUserEmoteManager().isPlayingEmote() || isInWardrobe()) return;
|
||||
if (isInWardrobe()) return;
|
||||
if (!(getEntity() instanceof HumanEntity humanEntity)) return;
|
||||
|
||||
boolean requireEmpty = Settings.getSlotOption(armorType.getEquipSlot()).isRequireEmpty();
|
||||
@@ -412,29 +407,15 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
}
|
||||
|
||||
|
||||
if (colors.containsKey(cosmetic.getSlot())) {
|
||||
Color color = colors.get(cosmetic.getSlot());
|
||||
if (itemMeta instanceof LeatherArmorMeta leatherMeta) {
|
||||
leatherMeta.setColor(color);
|
||||
} else if (itemMeta instanceof PotionMeta potionMeta) {
|
||||
potionMeta.setColor(color);
|
||||
} else if (itemMeta instanceof MapMeta mapMeta) {
|
||||
mapMeta.setColor(color);
|
||||
} else if (itemMeta instanceof FireworkEffectMeta fireworkMeta) {
|
||||
fireworkMeta.setEffect(
|
||||
FireworkEffect.builder()
|
||||
.with(FireworkEffect.Type.BALL)
|
||||
.withColor(color)
|
||||
.trail(false)
|
||||
.flicker(false)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
itemMeta.getPersistentDataContainer().set(HMCCInventoryUtils.getCosmeticKey(), PersistentDataType.STRING, cosmetic.getId());
|
||||
itemMeta.getPersistentDataContainer().set(InventoryUtils.getOwnerKey(), PersistentDataType.STRING, getEntity().getUniqueId().toString());
|
||||
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
if (colors.containsKey(cosmetic.getSlot())) {
|
||||
Color color = colors.get(cosmetic.getSlot());
|
||||
item = NMSHandlers.getHandler().getUtilHandler().setColor(item, color);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@@ -630,13 +611,13 @@ public class CosmeticUser implements CosmeticHolder {
|
||||
}
|
||||
|
||||
public List<CosmeticSlot> getDyeableSlots() {
|
||||
ArrayList<CosmeticSlot> dyableSlots = new ArrayList<>();
|
||||
ArrayList<CosmeticSlot> dyeableSlots = new ArrayList<>();
|
||||
|
||||
for (Cosmetic cosmetic : playerCosmetics.values()) {
|
||||
if (cosmetic.isDyable()) dyableSlots.add(cosmetic.getSlot());
|
||||
if (cosmetic.isDyeable()) dyeableSlots.add(cosmetic.getSlot());
|
||||
}
|
||||
|
||||
return dyableSlots;
|
||||
return dyeableSlots;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,7 +84,7 @@ public class UserBackpackManager {
|
||||
if (i == 0) HMCCPacketManager.sendRidingPacket(entity.getEntityId(), particleCloud.get(i), owner);
|
||||
else HMCCPacketManager.sendRidingPacket(particleCloud.get(i - 1), particleCloud.get(i) , owner);
|
||||
}
|
||||
HMCCPacketManager.sendRidingPacket(particleCloud.get(particleCloud.size() - 1), user.getUserBackpackManager().getFirstArmorStandId(), owner);
|
||||
HMCCPacketManager.sendRidingPacket(particleCloud.getLast(), user.getUserBackpackManager().getFirstArmorStandId(), owner);
|
||||
if (!user.isHidden()) PacketManager.equipmentSlotUpdate(user.getUserBackpackManager().getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(cosmeticBackpackType, cosmeticBackpackType.getFirstPersonBackpack()), owner);
|
||||
}
|
||||
PacketManager.equipmentSlotUpdate(getFirstArmorStandId(), EquipmentSlot.HEAD, user.getUserCosmeticItem(cosmeticBackpackType), outsideViewers);
|
||||
|
||||
@@ -11,7 +11,6 @@ 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;
|
||||
@@ -82,7 +81,7 @@ public class UserBalloonManager {
|
||||
|
||||
if (color != null) {
|
||||
modeledEntity.getModels().forEach((d, singleModel) -> {
|
||||
if (cosmeticBalloonType.isDyablePart(d)) {
|
||||
if (cosmeticBalloonType.isDyeablePart(d)) {
|
||||
singleModel.setDefaultTint(color);
|
||||
singleModel.getModelRenderer().sendToClient(ModelEngineAPI.getNMSHandler().createParsers());
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStartEvent;
|
||||
import com.hibiscusmc.hmccosmetics.api.events.PlayerEmoteStopEvent;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType;
|
||||
import com.hibiscusmc.hmccosmetics.emotes.EmoteManager;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UserEmoteManager {
|
||||
|
||||
private CosmeticUser user;
|
||||
private UserEmoteModel model;
|
||||
private Entity textEntity;
|
||||
|
||||
public UserEmoteManager(CosmeticUser user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void playEmote(String animationId) {
|
||||
MessagesUtil.sendDebugMessages("playEmote " + animationId);
|
||||
playEmote(EmoteManager.get(animationId), null);
|
||||
}
|
||||
|
||||
public void playEmote(@NotNull CosmeticEmoteType cosmeticEmoteType) {
|
||||
MessagesUtil.sendDebugMessages("playEmote " + cosmeticEmoteType.getAnimationId());
|
||||
playEmote(EmoteManager.get(cosmeticEmoteType.getAnimationId()), cosmeticEmoteType.getText());
|
||||
}
|
||||
|
||||
public void playEmote(String emoteAnimation, String text) {
|
||||
if (isPlayingEmote()) return;
|
||||
if (user.isInWardrobe()) return;
|
||||
// API
|
||||
PlayerEmoteStartEvent event = new PlayerEmoteStartEvent(user, emoteAnimation);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
// Internal
|
||||
try {
|
||||
model = new UserEmoteModel(user);
|
||||
// Play animation id
|
||||
if (emoteAnimation != null) {
|
||||
model.playAnimation(emoteAnimation);
|
||||
}
|
||||
// Show the text
|
||||
if (text != null && textEntity == null) {
|
||||
// removed in 2.7.0
|
||||
//textEntity = HMCCNMSHandlers.getHandler().spawnDisplayEntity(user.getPlayer().getLocation().add(0, 3, 0), text);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlayingEmote() {
|
||||
if (model == null) return false;
|
||||
return model.isPlayingAnimation();
|
||||
}
|
||||
|
||||
public void stopEmote(StopEmoteReason emoteReason) {
|
||||
if (!isPlayingEmote()) return;
|
||||
// API
|
||||
PlayerEmoteStopEvent event = new PlayerEmoteStopEvent(user, emoteReason);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
// Internal
|
||||
model.stopAnimation();
|
||||
if (textEntity != null) {
|
||||
textEntity.remove();
|
||||
textEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void despawnTextEntity() {
|
||||
if (textEntity != null) {
|
||||
textEntity.remove();
|
||||
textEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum StopEmoteReason {
|
||||
SNEAK,
|
||||
DAMAGE,
|
||||
CONNECTION,
|
||||
TELEPORT,
|
||||
UNEQUIP
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCServerUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.MessagesUtil;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager;
|
||||
import com.ticxo.playeranimator.api.model.player.PlayerModel;
|
||||
import me.lojosho.hibiscuscommons.util.ServerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserEmoteModel extends PlayerModel {
|
||||
|
||||
private final CosmeticUser user;
|
||||
private String emotePlaying;
|
||||
private final int armorStandId;
|
||||
private GameMode originalGamemode;
|
||||
|
||||
public UserEmoteModel(@NotNull CosmeticUser user) {
|
||||
super(user.getPlayer());
|
||||
this.user = user;
|
||||
armorStandId = ServerUtils.getNextEntityId();
|
||||
getRangeManager().setRenderDistance(Settings.getViewDistance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playAnimation(@NotNull String id) {
|
||||
super.playAnimation(id);
|
||||
|
||||
emotePlaying = id;
|
||||
|
||||
// Add config option that either allows player to move or forces them into a spot.
|
||||
Player player = user.getPlayer();
|
||||
List<Player> viewer = Collections.singletonList(user.getPlayer());
|
||||
List<Player> outsideViewers = HMCCPacketManager.getViewers(player.getLocation());
|
||||
// Send equipment packet to the player as well (Fixes Optifine still rendering armor when emoting)
|
||||
HMCCPacketManager.equipmentSlotUpdate(player, true, outsideViewers);
|
||||
outsideViewers.remove(player);
|
||||
|
||||
user.getPlayer().setInvisible(true);
|
||||
user.hideCosmetics(CosmeticUser.HiddenReason.EMOTE);
|
||||
|
||||
originalGamemode = player.getGameMode();
|
||||
|
||||
if (Settings.isEmoteCameraEnabled()) {
|
||||
Location newLocation = player.getLocation().clone();
|
||||
newLocation.setPitch(0);
|
||||
|
||||
double DISTANCE = Settings.getEmoteDistance();
|
||||
|
||||
Location thirdPersonLocation = newLocation.add(newLocation.getDirection().normalize().multiply(DISTANCE));
|
||||
if (DISTANCE > 0) {
|
||||
MessagesUtil.sendDebugMessages("Yaw " + (int) thirdPersonLocation.getYaw());
|
||||
MessagesUtil.sendDebugMessages("New Yaw " + ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
|
||||
thirdPersonLocation.setYaw(ServerUtils.getNextYaw((int) thirdPersonLocation.getYaw(), 180));
|
||||
}
|
||||
if (Settings.isCosmeticEmoteBlockCheck() && thirdPersonLocation.getBlock().getType().isOccluding()) {
|
||||
stopAnimation();
|
||||
MessagesUtil.sendMessage(player, "emote-blocked");
|
||||
return;
|
||||
}
|
||||
// Check if block below player is an air block
|
||||
if (Settings.isEmoteAirCheck() && newLocation.clone().subtract(0, 1, 0).getBlock().getType().isAir()) {
|
||||
stopAnimation();
|
||||
MessagesUtil.sendMessage(player, "emote-blocked");
|
||||
}
|
||||
|
||||
HMCCPacketManager.sendEntitySpawnPacket(thirdPersonLocation, armorStandId, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
|
||||
HMCCPacketManager.sendInvisibilityPacket(armorStandId, viewer);
|
||||
HMCCPacketManager.sendLookPacket(armorStandId, thirdPersonLocation, viewer);
|
||||
|
||||
HMCCPacketManager.gamemodeChangePacket(player, 3);
|
||||
HMCCPacketManager.sendCameraPacket(armorStandId, viewer);
|
||||
}
|
||||
|
||||
|
||||
MessagesUtil.sendDebugMessages("playAnimation run");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
if (super.getAnimationProperty() == null) {
|
||||
stopAnimation();
|
||||
return false;
|
||||
}
|
||||
boolean update = (super.update() && isPlayingAnimation());
|
||||
if (!update) {
|
||||
stopAnimation();
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
public void stopAnimation() {
|
||||
emotePlaying = null;
|
||||
despawn();
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
|
||||
List<Player> viewer = Collections.singletonList(player);
|
||||
List<Player> outsideViewers = HMCCPacketManager.getViewers(player.getLocation());
|
||||
// Send Equipment packet to all (Fixes Optifine Issue)
|
||||
HMCCPacketManager.equipmentSlotUpdate(player, false, outsideViewers);
|
||||
outsideViewers.remove(player);
|
||||
|
||||
int entityId = player.getEntityId();
|
||||
HMCCPacketManager.sendCameraPacket(entityId, viewer);
|
||||
HMCCPacketManager.sendEntityDestroyPacket(armorStandId, viewer);
|
||||
if (this.originalGamemode != null) {
|
||||
HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(this.originalGamemode));
|
||||
player.setGameMode(this.originalGamemode);
|
||||
}
|
||||
|
||||
if (user.getPlayer() != null) player.setInvisible(false);
|
||||
user.getUserEmoteManager().despawnTextEntity();
|
||||
user.showPlayer();
|
||||
user.showCosmetics(CosmeticUser.HiddenReason.EMOTE);
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isPlayingAnimation() {
|
||||
return emotePlaying != null;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.user.manager;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
||||
@@ -80,7 +79,7 @@ public class UserEntity {
|
||||
if (this.getLocation() != null && this.getLocation().getWorld() == location.getWorld()) {
|
||||
// Was thinking about using schedulers to just send the packet later... but that would be a lot of tasks and
|
||||
// would probably cause more lag. Furthermore, the server "ticks" the cosmetics every second by defualt. So it's fine like this.
|
||||
if (System.currentTimeMillis() - getLastPositionUpdate() <= Settings.getPacketEntityTeleportCooldown()) return;
|
||||
//if (System.currentTimeMillis() - getLastPositionUpdate() <= Settings.getPacketEntityTeleportCooldown()) return;
|
||||
}
|
||||
this.location = location;
|
||||
for (Integer entity : ids) {
|
||||
@@ -99,7 +98,7 @@ public class UserEntity {
|
||||
// First person backpacks need both packets to rotate properly, otherwise they look off
|
||||
// Regular backpacks just need the look packet
|
||||
if (additonalPacket) HMCCPacketManager.sendRotationPacket(entity, yaw, false, getViewers());
|
||||
HMCCPacketManager.sendLookPacket(entity, location, getViewers());
|
||||
HMCCPacketManager.sendRotateHeadPacket(entity, location, getViewers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,12 +117,12 @@ public class UserWardrobeManager {
|
||||
// Armorstand
|
||||
HMCCPacketManager.sendEntitySpawnPacket(viewingLocation, ARMORSTAND_ID, EntityType.ARMOR_STAND, UUID.randomUUID(), viewer);
|
||||
HMCCPacketManager.sendArmorstandMetadata(ARMORSTAND_ID, viewer);
|
||||
HMCCPacketManager.sendLookPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
||||
HMCCPacketManager.sendRotateHeadPacket(ARMORSTAND_ID, viewingLocation, viewer);
|
||||
|
||||
// Player
|
||||
player.teleport(viewingLocation, PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
player.setInvisible(true);
|
||||
HMCCPacketManager.gamemodeChangePacket(player, 3);
|
||||
HMCCPacketManager.gamemodeChangePacket(player, GameMode.SPECTATOR);
|
||||
HMCCPacketManager.sendCameraPacket(ARMORSTAND_ID, viewer);
|
||||
|
||||
// NPC
|
||||
@@ -142,7 +142,7 @@ public class UserWardrobeManager {
|
||||
}, 4);
|
||||
|
||||
// Location
|
||||
HMCCPacketManager.sendLookPacket(NPC_ID, npcLocation, viewer);
|
||||
HMCCPacketManager.sendRotateHeadPacket(NPC_ID, npcLocation, viewer);
|
||||
HMCCPacketManager.sendRotationPacket(NPC_ID, npcLocation, true, viewer);
|
||||
|
||||
// Misc
|
||||
@@ -234,7 +234,7 @@ public class UserWardrobeManager {
|
||||
// NPC
|
||||
if (user.isBalloonSpawned()) user.getBalloonManager().sendRemoveLeashPacket();
|
||||
HMCCPacketManager.sendEntityDestroyPacket(NPC_ID, viewer); // Success
|
||||
HMCCPacketManager.sendRemovePlayerPacket(player, WARDROBE_UUID, viewer); // Success
|
||||
HMCCPacketManager.sendRemovePlayerPacket(WARDROBE_UUID, viewer); // Success
|
||||
|
||||
// Player
|
||||
HMCCPacketManager.sendCameraPacket(player.getEntityId(), viewer);
|
||||
@@ -247,11 +247,11 @@ public class UserWardrobeManager {
|
||||
if (WardrobeSettings.isForceExitGamemode()) {
|
||||
MessagesUtil.sendDebugMessages("Force Exit Gamemode " + WardrobeSettings.getExitGamemode());
|
||||
player.setGameMode(WardrobeSettings.getExitGamemode());
|
||||
HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(WardrobeSettings.getExitGamemode())); // Success
|
||||
HMCCPacketManager.gamemodeChangePacket(player, WardrobeSettings.getExitGamemode()); // Success
|
||||
} else {
|
||||
MessagesUtil.sendDebugMessages("Original Gamemode " + this.originalGamemode);
|
||||
player.setGameMode(this.originalGamemode);
|
||||
HMCCPacketManager.gamemodeChangePacket(player, HMCCServerUtils.convertGamemode(this.originalGamemode)); // Success
|
||||
HMCCPacketManager.gamemodeChangePacket(player, this.originalGamemode); // Success
|
||||
}
|
||||
user.showPlayer();
|
||||
|
||||
@@ -311,7 +311,7 @@ public class UserWardrobeManager {
|
||||
int yaw = data.get();
|
||||
location.setYaw(yaw);
|
||||
|
||||
HMCCPacketManager.sendLookPacket(NPC_ID, location, viewer);
|
||||
HMCCPacketManager.sendRotateHeadPacket(NPC_ID, location, viewer);
|
||||
user.hidePlayer();
|
||||
int rotationSpeed = WardrobeSettings.getRotationSpeed();
|
||||
location.setYaw(HMCCServerUtils.getNextYaw(yaw - 30, rotationSpeed));
|
||||
@@ -323,10 +323,11 @@ public class UserWardrobeManager {
|
||||
HMCCPacketManager.equipmentSlotUpdate(NPC_ID, user, slot, viewer);
|
||||
}
|
||||
|
||||
// Handle backpacks
|
||||
if (user.hasCosmeticInSlot(CosmeticSlot.BACKPACK) && user.getUserBackpackManager() != null) {
|
||||
HMCCPacketManager.sendTeleportPacket(user.getUserBackpackManager().getFirstArmorStandId(), location, false, viewer);
|
||||
HMCCPacketManager.ridingMountPacket(NPC_ID, user.getUserBackpackManager().getFirstArmorStandId(), viewer);
|
||||
user.getUserBackpackManager().getEntityManager().setRotation(nextyaw);
|
||||
//user.getUserBackpackManager().getEntityManager().setRotation(nextyaw);
|
||||
HMCCPacketManager.sendEntityDestroyPacket(user.getUserBackpackManager().getFirstArmorStandId(), outsideViewers);
|
||||
}
|
||||
|
||||
@@ -358,5 +359,4 @@ public class UserWardrobeManager {
|
||||
RUNNING,
|
||||
STOPPING,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.hibiscusmc.hmccosmetics.util;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@@ -28,22 +27,6 @@ public class HMCCInventoryUtils {
|
||||
SLOT_MAP.put(CosmeticSlot.MAINHAND, EquipmentSlot.HAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from the Bukkit item slots to ProtocolLib item slots. Will produce a null if an improper bukkit item slot is sent through
|
||||
* @param slot The BUKKIT item slot to convert.
|
||||
* @return The ProtocolLib item slot that is returned
|
||||
*/
|
||||
public static EnumWrappers.ItemSlot itemBukkitSlot(final EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> EnumWrappers.ItemSlot.HEAD;
|
||||
case CHEST -> EnumWrappers.ItemSlot.CHEST;
|
||||
case LEGS -> EnumWrappers.ItemSlot.LEGS;
|
||||
case FEET -> EnumWrappers.ItemSlot.FEET;
|
||||
case HAND -> EnumWrappers.ItemSlot.MAINHAND;
|
||||
case OFF_HAND -> EnumWrappers.ItemSlot.OFFHAND;
|
||||
};
|
||||
}
|
||||
|
||||
public static int getPacketArmorSlot(final EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> 5;
|
||||
@@ -67,17 +50,17 @@ public class HMCCInventoryUtils {
|
||||
};
|
||||
}
|
||||
|
||||
public static CosmeticSlot getItemSlotToCosmeticSlot(final EnumWrappers.ItemSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> CosmeticSlot.HELMET;
|
||||
case CHEST -> CosmeticSlot.CHESTPLATE;
|
||||
case LEGS -> CosmeticSlot.LEGGINGS;
|
||||
case FEET -> CosmeticSlot.BOOTS;
|
||||
case OFFHAND -> CosmeticSlot.OFFHAND;
|
||||
case MAINHAND -> CosmeticSlot.MAINHAND;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
// public static CosmeticSlot getItemSlotToCosmeticSlot(final EnumWrappers.ItemSlot slot) {
|
||||
// return switch (slot) {
|
||||
// case HEAD -> CosmeticSlot.HELMET;
|
||||
// case CHEST -> CosmeticSlot.CHESTPLATE;
|
||||
// case LEGS -> CosmeticSlot.LEGGINGS;
|
||||
// case FEET -> CosmeticSlot.BOOTS;
|
||||
// case OFFHAND -> CosmeticSlot.OFFHAND;
|
||||
// case MAINHAND -> CosmeticSlot.MAINHAND;
|
||||
// default -> null;
|
||||
// };
|
||||
// }
|
||||
|
||||
public static CosmeticSlot BukkitCosmeticSlot(EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
@@ -147,31 +130,31 @@ public class HMCCInventoryUtils {
|
||||
return SLOT_MAP.get(slot);
|
||||
}
|
||||
|
||||
public static EquipmentSlot getEquipmentSlot(@NotNull EnumWrappers.ItemSlot slot) {
|
||||
switch (slot) {
|
||||
case HEAD -> {
|
||||
return EquipmentSlot.HEAD;
|
||||
}
|
||||
case CHEST -> {
|
||||
return EquipmentSlot.CHEST;
|
||||
}
|
||||
case LEGS -> {
|
||||
return EquipmentSlot.LEGS;
|
||||
}
|
||||
case FEET -> {
|
||||
return EquipmentSlot.FEET;
|
||||
}
|
||||
case OFFHAND -> {
|
||||
return EquipmentSlot.OFF_HAND;
|
||||
}
|
||||
case MAINHAND -> {
|
||||
return EquipmentSlot.HAND;
|
||||
}
|
||||
default -> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// public static EquipmentSlot getEquipmentSlot(@NotNull EnumWrappers.ItemSlot slot) {
|
||||
// switch (slot) {
|
||||
// case HEAD -> {
|
||||
// return EquipmentSlot.HEAD;
|
||||
// }
|
||||
// case CHEST -> {
|
||||
// return EquipmentSlot.CHEST;
|
||||
// }
|
||||
// case LEGS -> {
|
||||
// return EquipmentSlot.LEGS;
|
||||
// }
|
||||
// case FEET -> {
|
||||
// return EquipmentSlot.FEET;
|
||||
// }
|
||||
// case OFFHAND -> {
|
||||
// return EquipmentSlot.OFF_HAND;
|
||||
// }
|
||||
// case MAINHAND -> {
|
||||
// return EquipmentSlot.HAND;
|
||||
// }
|
||||
// default -> {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public static boolean isCosmeticItem(ItemStack itemStack) {
|
||||
if (itemStack == null) return false;
|
||||
|
||||
@@ -1,29 +1,15 @@
|
||||
package com.hibiscusmc.hmccosmetics.util;
|
||||
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HMCCPlayerUtils {
|
||||
|
||||
@Nullable
|
||||
public static WrappedSignedProperty getSkin(Player player) {
|
||||
WrappedSignedProperty skinData = WrappedGameProfile.fromPlayer(player).getProperties()
|
||||
.get("textures").stream().findAny().orElse(null);
|
||||
|
||||
if (skinData == null) {
|
||||
return null;
|
||||
}
|
||||
return new WrappedSignedProperty("textures", skinData.getValue(), skinData.getSignature());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nearby players. {@link com.hibiscusmc.hmccosmetics.util.packets.HMCCPacketManager#getViewers(Location)}
|
||||
* @param player
|
||||
|
||||
@@ -18,20 +18,6 @@ public class HMCCServerUtils {
|
||||
|
||||
private static String COLOR_CHAR = "&";
|
||||
|
||||
/**
|
||||
* Converts a bukkit gamemode into an integer for use in packets
|
||||
* @param gamemode Bukkit gamemode to convert.
|
||||
* @return int of the gamemode
|
||||
*/
|
||||
public static int convertGamemode(final GameMode gamemode) {
|
||||
return switch (gamemode) {
|
||||
case SURVIVAL -> 0;
|
||||
case CREATIVE -> 1;
|
||||
case ADVENTURE -> 2;
|
||||
case SPECTATOR -> 3;
|
||||
};
|
||||
}
|
||||
|
||||
public static org.bukkit.entity.Entity getEntity(int entityId) {
|
||||
return NMSHandlers.getHandler().getUtilHandler().getEntity(entityId);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.packets;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
|
||||
import com.hibiscusmc.hmccosmetics.config.Settings;
|
||||
import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUser;
|
||||
import com.hibiscusmc.hmccosmetics.user.CosmeticUsers;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCInventoryUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.HMCCPlayerUtils;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerNamedEntitySpawn;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerPlayerInfo;
|
||||
import com.hibiscusmc.hmccosmetics.util.packets.wrappers.WrapperPlayServerRelEntityMove;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.nms.NMSHandlers;
|
||||
import me.lojosho.hibiscuscommons.util.packets.PacketManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class HMCCPacketManager extends PacketManager {
|
||||
|
||||
@@ -46,16 +43,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final UUID uuid,
|
||||
final @NotNull List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getUUIDs().write(0, uuid);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getEntityTypeModifier().write(0, entityType);
|
||||
packet.getDoubles().
|
||||
write(0, location.getX()).
|
||||
write(1, location.getY()).
|
||||
write(2, location.getZ());
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendSpawnEntityPacket(entityId, uuid, entityType, location, sendTo);
|
||||
}
|
||||
|
||||
public static void equipmentSlotUpdate(
|
||||
@@ -97,53 +85,20 @@ public class HMCCPacketManager extends PacketManager {
|
||||
equipmentSlotUpdate(entityId, HMCCInventoryUtils.getEquipmentSlot(cosmeticSlot), user.getUserCosmeticItem(cosmeticSlot), sendTo);
|
||||
}
|
||||
|
||||
public static void sendArmorstandMetadata(
|
||||
int entityId,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
|
||||
public static void sendArmorstandMetadata(int entityId, List<Player> sendTo) {
|
||||
// 0x21 = Invisible + Fire (Aka, burns to make it not take the light of the block its in, avoiding turning it black)
|
||||
byte mask = 0x20;
|
||||
if (Settings.isBackpackPreventDarkness()) mask = 0x21;
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), mask));
|
||||
wrappedDataValueList.add(new WrappedDataValue(15, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x10));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
byte mask = (byte) (Settings.isBackpackPreventDarkness() ? 0x21 : 0x20);
|
||||
Map<Integer, Number> dataValues = Map.of(0, mask, 15, (byte) 0x10);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(entityId, dataValues, sendTo);
|
||||
}
|
||||
|
||||
public static void sendInvisibilityPacket(
|
||||
int entityId,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
public static void sendInvisibilityPacket(int entityId, List<Player> sendTo) {
|
||||
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(entityId, Map.of(0, (byte) 0x20), sendTo);
|
||||
}
|
||||
|
||||
public static void sendCloudEffect(
|
||||
int entityId,
|
||||
List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, entityId);
|
||||
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(0, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0x20));
|
||||
wrappedDataValueList.add(new WrappedDataValue(8, WrappedDataWatcher.Registry.get(Float.class), 0f));
|
||||
//wrappedDataValueList.add(new WrappedDataValue(11, WrappedDataWatcher.Registry.get(Integer.class), 21));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
public static void sendCloudEffect(int entityId, List<Player> sendTo) {
|
||||
Map<Integer, Number> dataValues = Map.of(0, (byte) 0x20, 8, 0f);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(entityId, dataValues, sendTo);
|
||||
}
|
||||
|
||||
public static void sendRotationPacket(
|
||||
@@ -161,16 +116,10 @@ public class HMCCPacketManager extends PacketManager {
|
||||
@NotNull List<Player> sendTo
|
||||
) {
|
||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
float yaw = location.getYaw() * ROTATION_FACTOR;
|
||||
float pitch = location.getPitch() * ROTATION_FACTOR;
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getBytes().write(0, (byte) yaw);
|
||||
packet.getBytes().write(1, (byte) pitch);
|
||||
byte yaw = (byte) (location.getYaw() * ROTATION_FACTOR);
|
||||
byte pitch = (byte) (location.getPitch() * ROTATION_FACTOR);
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
||||
packet.getBooleans().write(0, onGround);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, yaw, pitch, onGround, sendTo);
|
||||
}
|
||||
|
||||
public static void sendRotationPacket(
|
||||
@@ -180,15 +129,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
@NotNull List<Player> sendTo
|
||||
) {
|
||||
float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
float yaw2 = yaw * ROTATION_FACTOR;
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
|
||||
packet.getIntegers().write(0, entityId);
|
||||
packet.getBytes().write(0, (byte) yaw2);
|
||||
packet.getBytes().write(1, (byte) 0);
|
||||
|
||||
//Bukkit.getLogger().info("DEBUG: Yaw: " + (location.getYaw() * ROTATION_FACTOR) + " | Original Yaw: " + location.getYaw());
|
||||
packet.getBooleans().write(0, onGround);
|
||||
for (Player p : sendTo) sendPacket(p, packet);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendRotationPacket(entityId, yaw * ROTATION_FACTOR, 0, onGround, sendTo);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,12 +157,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final int[] passengerIds,
|
||||
final @NotNull List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
|
||||
packet.getIntegers().write(0, mountId);
|
||||
packet.getIntegerArrays().write(0, passengerIds);
|
||||
for (final Player p : sendTo) {
|
||||
sendPacket(p, packet);
|
||||
}
|
||||
NMSHandlers.getHandler().getPacketHandler().sendMountPacket(mountId, passengerIds, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,17 +187,7 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final int entityId,
|
||||
final @NotNull List<Player> sendTo
|
||||
) {
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R3") || HMCCosmeticsAPI.getNMSVersion().contains("v1_20_R1")) {
|
||||
WrapperPlayServerNamedEntitySpawn wrapper = new WrapperPlayServerNamedEntitySpawn();
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setPlayerUUID(uuid);
|
||||
wrapper.setPosition(location.toVector());
|
||||
wrapper.setPitch(location.getPitch());
|
||||
wrapper.setYaw(location.getYaw());
|
||||
for (final Player p : sendTo) sendPacket(p, wrapper.getHandle());
|
||||
return;
|
||||
}
|
||||
sendEntitySpawnPacket(location, entityId, EntityType.PLAYER, uuid);
|
||||
sendEntitySpawnPacket(location, entityId, EntityType.PLAYER, uuid, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,28 +200,10 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final Player skinnedPlayer,
|
||||
final int entityId,
|
||||
final UUID uuid,
|
||||
final String NPCName,
|
||||
final String npcName,
|
||||
final List<Player> sendTo
|
||||
) {
|
||||
WrapperPlayServerPlayerInfo info = new WrapperPlayServerPlayerInfo();
|
||||
info.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
|
||||
|
||||
String name = NPCName;
|
||||
while (name.length() > 16) {
|
||||
name = name.substring(16);
|
||||
}
|
||||
|
||||
WrappedGameProfile wrappedGameProfile = new WrappedGameProfile(uuid, name);
|
||||
WrappedSignedProperty skinData = HMCCPlayerUtils.getSkin(skinnedPlayer);
|
||||
if (skinData != null) wrappedGameProfile.getProperties().put("textures", skinData);
|
||||
|
||||
info.getHandle().getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData(
|
||||
wrappedGameProfile,
|
||||
0,
|
||||
EnumWrappers.NativeGameMode.CREATIVE,
|
||||
WrappedChatComponent.fromText(name)
|
||||
)));
|
||||
for (final Player p : sendTo) sendPacket(p, info.getHandle());
|
||||
NMSHandlers.getHandler().getPacketHandler().sendFakePlayerInfoPacket(skinnedPlayer, entityId, uuid, npcName, sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,32 +227,20 @@ public class HMCCPacketManager extends PacketManager {
|
||||
https://wiki.vg/Entity_metadata#Entity
|
||||
*/
|
||||
final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40;
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
|
||||
packet.getModifier().writeDefaults();
|
||||
packet.getIntegers().write(0, playerId);
|
||||
|
||||
final List<WrappedDataValue> wrappedDataValueList = Lists.newArrayList();
|
||||
wrappedDataValueList.add(new WrappedDataValue(17, WrappedDataWatcher.Registry.get(Byte.class), mask));
|
||||
packet.getDataValueCollectionModifier().write(0, wrappedDataValueList);
|
||||
|
||||
for (final Player p : sendTo) sendPacket(p, packet);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendSharedEntityData(playerId, Map.of(17, mask), sendTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a fake player from being seen by players.
|
||||
* @param player Which gameprofile to wrap for removing the player.
|
||||
* @param uuid What is the fake player UUID
|
||||
* @param sendTo Whom to send the packet to
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void sendRemovePlayerPacket(
|
||||
final Player player,
|
||||
final UUID uuid,
|
||||
final List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE);
|
||||
packet.getUUIDLists().write(0, List.of(uuid));
|
||||
for (final Player p : sendTo) sendPacket(p, packet);
|
||||
NMSHandlers.getHandler().getPacketHandler().sendPlayerInfoRemovePacket(uuid, sendTo);
|
||||
}
|
||||
|
||||
public static void sendLeashPacket(
|
||||
@@ -370,16 +266,39 @@ public class HMCCPacketManager extends PacketManager {
|
||||
final boolean onGround,
|
||||
@NotNull List<Player> sendTo
|
||||
) {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
|
||||
WrapperPlayServerRelEntityMove wrapper = new WrapperPlayServerRelEntityMove(packet);
|
||||
wrapper.setEntityID(entityId);
|
||||
wrapper.setDx(to.getX() - from.getX());
|
||||
wrapper.setDy(to.getY() - from.getY());
|
||||
wrapper.setDz(to.getZ() - from.getZ());
|
||||
wrapper.setOnGround(onGround);
|
||||
for (final Player p : sendTo) {
|
||||
sendPacket(p, wrapper.getHandle());
|
||||
NMSHandlers.getHandler().getPacketHandler().sendMovePacket(entityId, from, to, onGround, sendTo);
|
||||
}
|
||||
|
||||
public static void sendDisplayEntityMetadataPacket(int entityid, ItemStack backpackItem, List<Player> sendTo) {
|
||||
// TODO: Make the default values adjustable
|
||||
Vector3f translation = new Vector3f(0, 3, 0);
|
||||
Vector3f scale = new Vector3f(1, 1, 1);
|
||||
Quaternionf rotationLeft = new Quaternionf();
|
||||
Quaternionf rotationRight = new Quaternionf();
|
||||
Display.Billboard billboard = Display.Billboard.FIXED;
|
||||
int blockLight = 15;
|
||||
int skylight = 15;
|
||||
int viewRange = Settings.getViewDistance();
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
ItemDisplay.ItemDisplayTransform transform = ItemDisplay.ItemDisplayTransform.HEAD;
|
||||
|
||||
NMSHandlers.getHandler().getPacketHandler().sendItemDisplayMetadata(
|
||||
entityid,
|
||||
translation,
|
||||
scale,
|
||||
rotationLeft,
|
||||
rotationRight,
|
||||
billboard,
|
||||
blockLight,
|
||||
skylight,
|
||||
viewRange,
|
||||
width,
|
||||
height,
|
||||
transform,
|
||||
backpackItem,
|
||||
sendTo
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,9 +310,4 @@ public class HMCCPacketManager extends PacketManager {
|
||||
public static List<Player> getViewers(@NotNull Location location) {
|
||||
return PacketManager.getViewers(location, Settings.getViewDistance());
|
||||
}
|
||||
|
||||
public static void sendPacket(Player player, PacketContainer packet) {
|
||||
if (player == null) return;
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, null,false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.google.common.base.Objects;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
// Courtesy of Packet Wrapper
|
||||
public class AbstractPacket {
|
||||
|
||||
// The packet we will be modifying
|
||||
protected PacketContainer handle;
|
||||
|
||||
/**
|
||||
* Constructs a new strongly typed wrapper for the given packet.
|
||||
*
|
||||
* @param handle - handle to the raw packet data.
|
||||
* @param type - the packet type.
|
||||
*/
|
||||
protected AbstractPacket(PacketContainer handle, PacketType type) {
|
||||
// Make sure we're given a valid packet
|
||||
if (handle == null)
|
||||
throw new IllegalArgumentException("Packet handle cannot be NULL.");
|
||||
if (!Objects.equal(handle.getType(), type))
|
||||
throw new IllegalArgumentException(handle.getHandle()
|
||||
+ " is not a packet of type " + type);
|
||||
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a handle to the raw packet data.
|
||||
*
|
||||
* @return Raw packet data.
|
||||
*/
|
||||
public PacketContainer getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the current packet to the given receiver.
|
||||
*
|
||||
* @param receiver - the receiver.
|
||||
* @throws RuntimeException If the packet cannot be sent.
|
||||
*/
|
||||
public void sendPacket(Player receiver) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver,
|
||||
getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the current packet to all online players.
|
||||
*/
|
||||
public void broadcastPacket() {
|
||||
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate receiving the current packet from the given sender.
|
||||
*
|
||||
* @param sender - the sender.
|
||||
* @throws RuntimeException If the packet cannot be received.
|
||||
* @deprecated Misspelled. recieve to receive
|
||||
* @see #receivePacket(Player)
|
||||
*/
|
||||
@Deprecated
|
||||
public void recievePacket(Player sender) {
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
||||
getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot recieve packet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate receiving the current packet from the given sender.
|
||||
*
|
||||
* @param sender - the sender.
|
||||
* @throws RuntimeException if the packet cannot be received.
|
||||
*/
|
||||
public void receivePacket(Player sender) {
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
|
||||
getHandle());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot receive packet.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.NAMED_ENTITY_SPAWN;
|
||||
|
||||
public WrapperPlayServerNamedEntitySpawn() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerNamedEntitySpawn(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(@NotNull PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Player UUID.
|
||||
* <p>
|
||||
* Notes: player's UUID
|
||||
*
|
||||
* @return The current Player UUID
|
||||
*/
|
||||
public UUID getPlayerUUID() {
|
||||
return handle.getUUIDs().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Player UUID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setPlayerUUID(UUID value) {
|
||||
handle.getUUIDs().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the position of the spawned entity as a vector.
|
||||
*
|
||||
* @return The position as a vector.
|
||||
*/
|
||||
public Vector getPosition() {
|
||||
return new Vector(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the position of the spawned entity using a vector.
|
||||
*
|
||||
* @param position - the new position.
|
||||
*/
|
||||
public void setPosition(@NotNull Vector position) {
|
||||
setX(position.getX());
|
||||
setY(position.getY());
|
||||
setZ(position.getZ());
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return handle.getDoubles().read(0);
|
||||
}
|
||||
|
||||
public void setX(double value) {
|
||||
handle.getDoubles().write(0, value);
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return handle.getDoubles().read(1);
|
||||
}
|
||||
|
||||
public void setY(double value) {
|
||||
handle.getDoubles().write(1, value);
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return handle.getDoubles().read(2);
|
||||
}
|
||||
|
||||
public void setZ(double value) {
|
||||
handle.getDoubles().write(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw of the spawned entity.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the spawned entity.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch of the spawned entity.
|
||||
*
|
||||
* @return The current pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch of the spawned entity.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.hibiscusmc.hmccosmetics.api.HMCCosmeticsAPI;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class WrapperPlayServerPlayerInfo extends AbstractPacket {
|
||||
public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO;
|
||||
|
||||
public WrapperPlayServerPlayerInfo() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerPlayerInfo(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
public PlayerInfoAction getAction() {
|
||||
return handle.getPlayerInfoAction().read(0);
|
||||
}
|
||||
|
||||
public void setAction(PlayerInfoAction value) {
|
||||
if (HMCCosmeticsAPI.getNMSVersion().contains("v1_17_R1") || HMCCosmeticsAPI.getNMSVersion().contains("v1_18_R2") || HMCCosmeticsAPI.getNMSVersion().contains("v1_19_R1")) {
|
||||
handle.getPlayerInfoAction().write(0, value);
|
||||
return;
|
||||
}
|
||||
// New way of handling it 1.19.3+
|
||||
handle.getPlayerInfoActions().write(0, Set.of(value));
|
||||
}
|
||||
|
||||
public List<PlayerInfoData> getData() {
|
||||
return handle.getPlayerInfoDataLists().read(0);
|
||||
}
|
||||
|
||||
public void setData(List<PlayerInfoData> value) {
|
||||
handle.getPlayerInfoDataLists().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
package com.hibiscusmc.hmccosmetics.util.packets.wrappers;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class WrapperPlayServerRelEntityMove extends AbstractPacket {
|
||||
public static final PacketType TYPE =
|
||||
PacketType.Play.Server.REL_ENTITY_MOVE;
|
||||
|
||||
public WrapperPlayServerRelEntityMove() {
|
||||
super(new PacketContainer(TYPE), TYPE);
|
||||
handle.getModifier().writeDefaults();
|
||||
}
|
||||
|
||||
public WrapperPlayServerRelEntityMove(PacketContainer packet) {
|
||||
super(packet, TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Entity ID.
|
||||
* <p>
|
||||
* Notes: entity's ID
|
||||
*
|
||||
* @return The current Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
return handle.getIntegers().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Entity ID.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setEntityID(int value) {
|
||||
handle.getIntegers().write(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param world - the current world of the entity.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(World world) {
|
||||
return handle.getEntityModifier(world).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity of the painting that will be spawned.
|
||||
*
|
||||
* @param event - the packet event.
|
||||
* @return The spawned entity.
|
||||
*/
|
||||
public Entity getEntity(@NotNull PacketEvent event) {
|
||||
return getEntity(event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DX.
|
||||
*
|
||||
* @return The current DX
|
||||
*/
|
||||
public double getDx() {
|
||||
return handle.getShorts().read(0) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DX.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDx(double value) {
|
||||
handle.getShorts().write(0, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DY.
|
||||
*
|
||||
* @return The current DY
|
||||
*/
|
||||
public double getDy() {
|
||||
return handle.getShorts().read(1) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DY.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDy(double value) {
|
||||
handle.getShorts().write(1, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve DZ.
|
||||
*
|
||||
* @return The current DZ
|
||||
*/
|
||||
public double getDz() {
|
||||
return handle.getShorts().read(2) / 4096D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DZ.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setDz(double value) {
|
||||
handle.getShorts().write(2, (short) (value * 4096));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the yaw of the current entity.
|
||||
*
|
||||
* @return The current Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return (handle.getBytes().read(0) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the yaw of the current entity.
|
||||
*
|
||||
* @param value - new yaw.
|
||||
*/
|
||||
public void setYaw(float value) {
|
||||
handle.getBytes().write(0, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the pitch of the current entity.
|
||||
*
|
||||
* @return The current pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return (handle.getBytes().read(1) * 360.F) / 256.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch of the current entity.
|
||||
*
|
||||
* @param value - new pitch.
|
||||
*/
|
||||
public void setPitch(float value) {
|
||||
handle.getBytes().write(1, (byte) (value * 256.0F / 360.0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve On Ground.
|
||||
*
|
||||
* @return The current On Ground
|
||||
*/
|
||||
public boolean getOnGround() {
|
||||
return handle.getBooleans().read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set On Ground.
|
||||
*
|
||||
* @param value - new value.
|
||||
*/
|
||||
public void setOnGround(boolean value) {
|
||||
handle.getBooleans().write(0, value);
|
||||
}
|
||||
}
|
||||
@@ -40,17 +40,6 @@ cosmetic-settings:
|
||||
gamemodes:
|
||||
- "SPECTATOR"
|
||||
|
||||
# This disables the entire internal emote system within the plugin. This option requires a restart.
|
||||
emote-enable: true
|
||||
emote-distance: -3 # This shows how far away the camera should be while a player is doing an emote. Negative is behind player.
|
||||
emote-block-check: true # If the server should check if the block is open where the camera is placed (prevents players viewing through blocks)
|
||||
emote-air-check: true # Check if there is air under a player, if there is, don't play emote
|
||||
emote-damage-leave: true # If the player should leave the emote when they take damage
|
||||
emote-invincible: false # If the player should not take damage while doing an emote
|
||||
# If a player should be put into camera mode when looking at an emote. Highly recommend keeping it as true.
|
||||
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 prevents the backpack from being dark when the player is below a block at the expense of making the backpack bright
|
||||
|
||||
@@ -108,15 +108,6 @@ kite:
|
||||
model-data: 7
|
||||
name: "<blue>Kite"
|
||||
amount: 1
|
||||
handstand:
|
||||
slot: EMOTE
|
||||
animation: handstand
|
||||
meditate:
|
||||
slot: EMOTE
|
||||
animation: meditate
|
||||
thinking:
|
||||
slot: EMOTE
|
||||
animation: thinking
|
||||
explorer_backpack:
|
||||
slot: BACKPACK
|
||||
permission: "hmccosmetics.explorer_backpack"
|
||||
|
||||
@@ -134,31 +134,6 @@ items:
|
||||
- "<gray>Allowed: <#6D9DC5>%HMCCosmetics_unlocked_kite%"
|
||||
type: cosmetic
|
||||
cosmetic: kite
|
||||
# EMOTES DO NOT WORK IN RECENT HMCCOSMETICS VERSIONS.
|
||||
# handstand:
|
||||
# slots:
|
||||
# - 12
|
||||
# item:
|
||||
# material: PAPER
|
||||
# name: "<blue>Handstand Emote"
|
||||
# type: cosmetic
|
||||
# cosmetic: handstand
|
||||
# meditate:
|
||||
# slots:
|
||||
# - 13
|
||||
# item:
|
||||
# material: PAPER
|
||||
# name: "<blue>Meditate Emote"
|
||||
# type: cosmetic
|
||||
# cosmetic: meditate
|
||||
# thinking:
|
||||
# slots:
|
||||
# - 14
|
||||
# item:
|
||||
# material: PAPER
|
||||
# name: "<blue>Thinking Emote"
|
||||
# type: cosmetic
|
||||
# cosmetic: thinking
|
||||
explorer_backpack:
|
||||
slots:
|
||||
- 12
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Binary file not shown.
BIN
lib/HMCColor-2.4-all.jar
Normal file
BIN
lib/HMCColor-2.4-all.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user