diff --git a/build.gradle.kts b/build.gradle.kts
index 25838c89e..870101f3e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -29,18 +29,18 @@ subprojects {
filesMatching(arrayListOf("commands.yml", "config.yml")) {
expand(
- Pair("project_version", rootProject.properties["project_version"]),
- Pair("config_version", rootProject.properties["config_version"]),
- Pair("lang_version", rootProject.properties["lang_version"])
+ Pair("project_version", rootProject.properties["project_version"]!!),
+ Pair("config_version", rootProject.properties["config_version"]!!),
+ Pair("lang_version", rootProject.properties["lang_version"]!!)
)
}
}
}
-fun versionBanner() = project.providers.exec {
+fun versionBanner(): String = project.providers.exec {
commandLine("git", "rev-parse", "--short=8", "HEAD")
}.standardOutput.asText.map { it.trim() }.getOrElse("Unknown")
-fun builder() = project.providers.exec {
+fun builder(): String = project.providers.exec {
commandLine("git", "config", "user.name")
}.standardOutput.asText.map { it.trim() }.getOrElse("Unknown")
\ No newline at end of file
diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts
index 2067a6a4a..0d7569af6 100644
--- a/bukkit/build.gradle.kts
+++ b/bukkit/build.gradle.kts
@@ -80,7 +80,7 @@ tasks.withType {
}
artifacts {
- archives(tasks.shadowJar)
+ implementation(tasks.shadowJar)
}
tasks {
diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts
index df485034a..933d60862 100644
--- a/bukkit/compatibility/build.gradle.kts
+++ b/bukkit/compatibility/build.gradle.kts
@@ -17,6 +17,7 @@ repositories {
maven("https://repo.hiusers.com/releases") // zaphkiel
maven("https://jitpack.io") // sxitem slimefun
maven("https://repo.codemc.io/repository/maven-public/") // quickshop
+ maven("https://repo.nexomc.com/releases/") // nexo
}
dependencies {
@@ -41,6 +42,8 @@ dependencies {
// MMOItems
compileOnly("net.Indyuce:MMOItems-API:6.10-SNAPSHOT")
compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT")
+ // Nexo
+ compileOnly("com.nexomc:nexo:1.13.0")
// LuckPerms
compileOnly("net.luckperms:api:5.4")
// viaversion
@@ -63,6 +66,8 @@ dependencies {
compileOnly("com.github.Zrips:Jobs:v5.2.2.3")
// CustomFishing
compileOnly("net.momirealms:custom-fishing:2.3.3")
+ // CustomNameplates
+ compileOnly("net.momirealms:custom-nameplates:3.0.33")
// eco
compileOnly("com.willfp:eco:6.70.1")
compileOnly("com.willfp:EcoJobs:3.56.1")
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java
index 2e17e977f..e21594b35 100644
--- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/BukkitCompatibilityManager.java
@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.compatibility;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.compatibility.item.*;
import net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld.LegacySlimeFormatStorageAdaptor;
@@ -16,6 +17,7 @@ import net.momirealms.craftengine.bukkit.compatibility.quickshop.QuickShopItemEx
import net.momirealms.craftengine.bukkit.compatibility.region.WorldGuardRegionCondition;
import net.momirealms.craftengine.bukkit.compatibility.skript.SkriptHook;
import net.momirealms.craftengine.bukkit.compatibility.slimeworld.SlimeFormatStorageAdaptor;
+import net.momirealms.craftengine.bukkit.compatibility.tag.CustomNameplateProviders;
import net.momirealms.craftengine.bukkit.compatibility.viaversion.ViaVersionUtils;
import net.momirealms.craftengine.bukkit.compatibility.worldedit.WorldEditBlockRegister;
import net.momirealms.craftengine.bukkit.font.BukkitFontManager;
@@ -28,9 +30,12 @@ import net.momirealms.craftengine.core.loot.LootConditions;
import net.momirealms.craftengine.core.plugin.compatibility.CompatibilityManager;
import net.momirealms.craftengine.core.plugin.compatibility.LevelerProvider;
import net.momirealms.craftengine.core.plugin.compatibility.ModelProvider;
+import net.momirealms.craftengine.core.plugin.compatibility.TagResolverProvider;
import net.momirealms.craftengine.core.plugin.config.Config;
+import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.condition.AlwaysFalseCondition;
import net.momirealms.craftengine.core.plugin.context.event.EventConditions;
+import net.momirealms.craftengine.core.plugin.text.minimessage.FormattedLine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.WorldManager;
@@ -43,6 +48,8 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
private final BukkitCraftEngine plugin;
private final Map modelProviders;
private final Map levelerProviders;
+ private final Map tagResolverProviders;
+ private TagResolverProvider[] tagResolverProviderArray = null;
private boolean hasPlaceholderAPI;
public BukkitCompatibilityManager(BukkitCraftEngine plugin) {
@@ -52,6 +59,7 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
"BetterModel", BetterModelModel::new
));
this.levelerProviders = new HashMap<>();
+ this.tagResolverProviders = new HashMap<>();
}
@Override
@@ -146,6 +154,12 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
new QuickShopItemExpressionHandler(this.plugin).register();
logHook("QuickShop-Hikari");
}
+ if (this.isPluginEnabled("CustomNameplates")) {
+ registerTagResolverProvider(new CustomNameplateProviders.Background());
+ registerTagResolverProvider(new CustomNameplateProviders.Nameplate());
+ registerTagResolverProvider(new CustomNameplateProviders.Bubble());
+ logHook("CustomNameplates");
+ }
}
@Override
@@ -158,6 +172,13 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
this.levelerProviders.put(plugin, provider);
}
+ @Override
+ public void registerTagResolverProvider(TagResolverProvider provider) {
+ this.tagResolverProviders.put(provider.name(), provider);
+ this.tagResolverProviderArray = this.tagResolverProviders.values().toArray(new TagResolverProvider[0]);
+ FormattedLine.Companion.resetWithCustomResolvers(new ArrayList<>(this.tagResolverProviders.keySet()));
+ }
+
private void logHook(String plugin) {
this.plugin.logger().info("[Compatibility] " + plugin + " hooked");
}
@@ -291,6 +312,10 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
itemManager.registerExternalItemSource(new SlimefunSource());
logHook("Slimefun");
}
+ if (this.isPluginEnabled("Nexo")) {
+ itemManager.registerExternalItemSource(new NexoItemSource());
+ logHook("Nexo");
+ }
}
private Plugin getPlugin(String name) {
@@ -314,7 +339,9 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
@Override
public String parse(Player player, String text) {
- return PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player.platformPlayer(), text);
+ return player == null
+ ? PlaceholderAPIUtils.parse(null, text)
+ : PlaceholderAPIUtils.parse((org.bukkit.entity.Player) player.platformPlayer(), text);
}
@Override
@@ -326,4 +353,15 @@ public class BukkitCompatibilityManager implements CompatibilityManager {
public int getPlayerProtocolVersion(UUID uuid) {
return ViaVersionUtils.getPlayerProtocolVersion(uuid);
}
+
+ @Override
+ public TagResolver[] createExternalTagResolvers(Context context) {
+ if (this.tagResolverProviderArray == null) return null;
+ int length = this.tagResolverProviderArray.length;
+ TagResolver[] resolvers = new TagResolver[length];
+ for (int i = 0; i < length; i++) {
+ resolvers[i] = this.tagResolverProviderArray[i].getTagResolver(context);
+ }
+ return resolvers;
+ }
}
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/NexoItemSource.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/NexoItemSource.java
new file mode 100644
index 000000000..fbe3452e9
--- /dev/null
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/NexoItemSource.java
@@ -0,0 +1,29 @@
+package net.momirealms.craftengine.bukkit.compatibility.item;
+
+import com.nexomc.nexo.api.NexoItems;
+import com.nexomc.nexo.items.ItemBuilder;
+import net.momirealms.craftengine.core.item.ExternalItemSource;
+import net.momirealms.craftengine.core.item.ItemBuildContext;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.Nullable;
+
+public class NexoItemSource implements ExternalItemSource {
+
+ @Override
+ public String plugin() {
+ return "nexo";
+ }
+
+ @Nullable
+ @Override
+ public ItemStack build(String id, ItemBuildContext context) {
+ ItemBuilder itemBuilder = NexoItems.itemFromId(id);
+ if (itemBuilder == null) return null;
+ return itemBuilder.build();
+ }
+
+ @Override
+ public String id(ItemStack item) {
+ return NexoItems.idFromItem(item);
+ }
+}
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/quickshop/QuickShopItemExpressionHandler.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/quickshop/QuickShopItemExpressionHandler.java
index 0eb528a33..f41ff7ee8 100644
--- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/quickshop/QuickShopItemExpressionHandler.java
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/quickshop/QuickShopItemExpressionHandler.java
@@ -1,7 +1,6 @@
package net.momirealms.craftengine.bukkit.compatibility.quickshop;
import com.ghostchu.quickshop.api.QuickShopAPI;
-import com.ghostchu.quickshop.api.event.QSConfigurationReloadEvent;
import com.ghostchu.quickshop.api.registry.BuiltInRegistry;
import com.ghostchu.quickshop.api.registry.Registry;
import com.ghostchu.quickshop.api.registry.builtin.itemexpression.ItemExpressionHandler;
@@ -9,9 +8,6 @@ import com.ghostchu.quickshop.api.registry.builtin.itemexpression.ItemExpression
import net.momirealms.craftengine.bukkit.api.CraftEngineItems;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.core.util.Key;
-import org.bukkit.Bukkit;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BackgroundTag.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BackgroundTag.java
new file mode 100644
index 000000000..7fcdee579
--- /dev/null
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BackgroundTag.java
@@ -0,0 +1,47 @@
+package net.momirealms.craftengine.bukkit.compatibility.tag;
+
+import net.kyori.adventure.text.minimessage.Context;
+import net.kyori.adventure.text.minimessage.ParsingException;
+import net.kyori.adventure.text.minimessage.tag.Tag;
+import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import net.momirealms.craftengine.core.plugin.CraftEngine;
+import net.momirealms.craftengine.core.plugin.context.PlayerContext;
+import net.momirealms.craftengine.core.util.AdventureHelper;
+import net.momirealms.customnameplates.api.CustomNameplatesAPI;
+import net.momirealms.customnameplates.api.feature.background.Background;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Optional;
+
+public class BackgroundTag implements TagResolver {
+ private final net.momirealms.craftengine.core.plugin.context.Context context;
+
+ public BackgroundTag(net.momirealms.craftengine.core.plugin.context.Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException {
+ if (!this.has(name)) {
+ return null;
+ }
+ String id = arguments.popOr("No background id provided").toString();
+ Optional background = CustomNameplatesAPI.getInstance().getBackground(id);
+ if (background.isEmpty()) {
+ return null;
+ }
+ double left = arguments.popOr("No argument left provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ double right = arguments.popOr("No argument right provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ String content = arguments.popOr("No argument content provided").toString();
+ String parsed = this.context instanceof PlayerContext playerContext ? CraftEngine.instance().compatibilityManager().parse(playerContext.player(), content) : CraftEngine.instance().compatibilityManager().parse(null, content);
+ String textWithImage = CustomNameplatesAPI.getInstance().createTextWithImage(parsed, background.get(), (float) left, (float) right);
+ return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(textWithImage, this.context.tagResolvers()));
+ }
+
+ @Override
+ public boolean has(@NotNull String name) {
+ return "background".equals(name);
+ }
+}
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BubbleTag.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BubbleTag.java
new file mode 100644
index 000000000..8891d0d55
--- /dev/null
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/BubbleTag.java
@@ -0,0 +1,47 @@
+package net.momirealms.craftengine.bukkit.compatibility.tag;
+
+import net.kyori.adventure.text.minimessage.Context;
+import net.kyori.adventure.text.minimessage.ParsingException;
+import net.kyori.adventure.text.minimessage.tag.Tag;
+import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import net.momirealms.craftengine.core.plugin.CraftEngine;
+import net.momirealms.craftengine.core.plugin.context.PlayerContext;
+import net.momirealms.craftengine.core.util.AdventureHelper;
+import net.momirealms.customnameplates.api.CustomNameplatesAPI;
+import net.momirealms.customnameplates.api.feature.bubble.Bubble;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Optional;
+
+public class BubbleTag implements TagResolver {
+ private final net.momirealms.craftengine.core.plugin.context.Context context;
+
+ public BubbleTag(net.momirealms.craftengine.core.plugin.context.Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException {
+ if (!this.has(name)) {
+ return null;
+ }
+ String id = arguments.popOr("No bubble id provided").toString();
+ Optional bubble = CustomNameplatesAPI.getInstance().getBubble(id);
+ if (bubble.isEmpty()) {
+ return null;
+ }
+ double left = arguments.popOr("No argument left provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ double right = arguments.popOr("No argument right provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ String content = arguments.popOr("No argument content provided").toString();
+ String parsed = this.context instanceof PlayerContext playerContext ? CraftEngine.instance().compatibilityManager().parse(playerContext.player(), content) : CraftEngine.instance().compatibilityManager().parse(null, content);
+ String textWithImage = CustomNameplatesAPI.getInstance().createTextWithImage(parsed, bubble.get(), (float) left, (float) right);
+ return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(textWithImage, this.context.tagResolvers()));
+ }
+
+ @Override
+ public boolean has(@NotNull String name) {
+ return "bubble".equals(name);
+ }
+}
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateProviders.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateProviders.java
new file mode 100644
index 000000000..5f6aae796
--- /dev/null
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/CustomNameplateProviders.java
@@ -0,0 +1,44 @@
+package net.momirealms.craftengine.bukkit.compatibility.tag;
+
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import net.momirealms.craftengine.core.plugin.compatibility.TagResolverProvider;
+import net.momirealms.craftengine.core.plugin.context.Context;
+
+public class CustomNameplateProviders {
+
+ public static class Background implements TagResolverProvider {
+ @Override
+ public String name() {
+ return "background";
+ }
+
+ @Override
+ public TagResolver getTagResolver(Context context) {
+ return new BackgroundTag(context);
+ }
+ }
+
+ public static class Nameplate implements TagResolverProvider {
+ @Override
+ public String name() {
+ return "nameplate";
+ }
+
+ @Override
+ public TagResolver getTagResolver(Context context) {
+ return new NameplateTag(context);
+ }
+ }
+
+ public static class Bubble implements TagResolverProvider {
+ @Override
+ public String name() {
+ return "bubble";
+ }
+
+ @Override
+ public TagResolver getTagResolver(Context context) {
+ return new BubbleTag(context);
+ }
+ }
+}
diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/NameplateTag.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/NameplateTag.java
new file mode 100644
index 000000000..aefdf0e5b
--- /dev/null
+++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/tag/NameplateTag.java
@@ -0,0 +1,47 @@
+package net.momirealms.craftengine.bukkit.compatibility.tag;
+
+import net.kyori.adventure.text.minimessage.Context;
+import net.kyori.adventure.text.minimessage.ParsingException;
+import net.kyori.adventure.text.minimessage.tag.Tag;
+import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import net.momirealms.craftengine.core.plugin.CraftEngine;
+import net.momirealms.craftengine.core.plugin.context.PlayerContext;
+import net.momirealms.craftengine.core.util.AdventureHelper;
+import net.momirealms.customnameplates.api.CustomNameplatesAPI;
+import net.momirealms.customnameplates.api.feature.nameplate.Nameplate;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Optional;
+
+public class NameplateTag implements TagResolver {
+ private final net.momirealms.craftengine.core.plugin.context.Context context;
+
+ public NameplateTag(net.momirealms.craftengine.core.plugin.context.Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments, @NotNull Context ctx) throws ParsingException {
+ if (!this.has(name)) {
+ return null;
+ }
+ String id = arguments.popOr("No nameplate id provided").toString();
+ Optional nameplate = CustomNameplatesAPI.getInstance().getNameplate(id);
+ if (nameplate.isEmpty()) {
+ return null;
+ }
+ double left = arguments.popOr("No argument left provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ double right = arguments.popOr("No argument right provided").asDouble().orElseThrow(() -> ctx.newException("Invalid argument number", arguments));
+ String content = arguments.popOr("No argument content provided").toString();
+ String parsed = this.context instanceof PlayerContext playerContext ? CraftEngine.instance().compatibilityManager().parse(playerContext.player(), content) : CraftEngine.instance().compatibilityManager().parse(null, content);
+ String textWithImage = CustomNameplatesAPI.getInstance().createTextWithImage(parsed, nameplate.get(), (float) left, (float) right);
+ return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(textWithImage, this.context.tagResolvers()));
+ }
+
+ @Override
+ public boolean has(@NotNull String name) {
+ return "nameplate".equals(name);
+ }
+}
diff --git a/bukkit/legacy/build.gradle.kts b/bukkit/legacy/build.gradle.kts
index 0434654d8..75ecb2c84 100644
--- a/bukkit/legacy/build.gradle.kts
+++ b/bukkit/legacy/build.gradle.kts
@@ -29,5 +29,5 @@ tasks.withType {
}
artifacts {
- archives(tasks.shadowJar)
+ implementation(tasks.shadowJar)
}
\ No newline at end of file
diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/DismountListener1_20.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/DismountListener1_20.java
index 98fd4deea..50db9bcec 100644
--- a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/DismountListener1_20.java
+++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/DismountListener1_20.java
@@ -7,7 +7,7 @@ import org.bukkit.event.Listener;
import java.util.function.BiConsumer;
-public class DismountListener1_20 implements Listener {
+public final class DismountListener1_20 implements Listener {
private final BiConsumer consumer;
public DismountListener1_20(BiConsumer consumer) {
diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAttributeUtils.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAttributeUtils.java
index 639c83553..720b75e89 100644
--- a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAttributeUtils.java
+++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAttributeUtils.java
@@ -8,7 +8,8 @@ import org.bukkit.entity.Player;
import java.util.Objects;
import java.util.Optional;
-public class LegacyAttributeUtils {
+public final class LegacyAttributeUtils {
+ private LegacyAttributeUtils() {}
public static void setMaxHealth(ArmorStand entity) {
Objects.requireNonNull(entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)).setBaseValue(0.01);
diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java
index 63a00b16e..7a7701d71 100644
--- a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java
+++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyAuthLibUtils.java
@@ -4,7 +4,8 @@ import com.mojang.authlib.GameProfile;
import java.util.UUID;
-public class LegacyAuthLibUtils {
+public final class LegacyAuthLibUtils {
+ private LegacyAuthLibUtils() {}
public static String getName(GameProfile profile) {
return profile.getName();
diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyEntityUtils.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyEntityUtils.java
index 35a23f0ad..15425cc8e 100644
--- a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyEntityUtils.java
+++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyEntityUtils.java
@@ -8,7 +8,8 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import java.util.function.Consumer;
-public class LegacyEntityUtils {
+public final class LegacyEntityUtils {
+ private LegacyEntityUtils() {}
public static Entity spawnEntity(World world, Location loc, EntityType type, Consumer function) {
return world.spawnEntity(loc, type, CreatureSpawnEvent.SpawnReason.CUSTOM, function::accept);
diff --git a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyInventoryUtils.java b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyInventoryUtils.java
index 9692a7953..5fa59cef1 100644
--- a/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyInventoryUtils.java
+++ b/bukkit/legacy/src/main/java/net/momirealms/craftengine/bukkit/util/LegacyInventoryUtils.java
@@ -1,14 +1,18 @@
package net.momirealms.craftengine.bukkit.util;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.Merchant;
import org.jetbrains.annotations.Nullable;
-public class LegacyInventoryUtils {
+public final class LegacyInventoryUtils {
+ private LegacyInventoryUtils() {}
public static Inventory getTopInventory(Player player) {
return player.getOpenInventory().getTopInventory();
@@ -67,7 +71,20 @@ public class LegacyInventoryUtils {
player.openWorkbench(null, true);
}
+ public static void openMerchant(Player player, Merchant merchant) {
+ player.openMerchant(merchant, true);
+ }
+
+ @SuppressWarnings("deprecation")
+ public static Merchant createMerchant() {
+ return Bukkit.createMerchant("Villager");
+ }
+
public static Player getPlayerFromInventoryEvent(InventoryEvent event) {
return (Player) event.getView().getPlayer();
}
+
+ public static boolean isHotBarSwapAndReadd(InventoryAction action) {
+ return action == InventoryAction.HOTBAR_MOVE_AND_READD;
+ }
}
diff --git a/bukkit/loader/build.gradle.kts b/bukkit/loader/build.gradle.kts
index 547fbb2b0..fa0ddd0d9 100644
--- a/bukkit/loader/build.gradle.kts
+++ b/bukkit/loader/build.gradle.kts
@@ -56,7 +56,7 @@ bukkit {
}
artifacts {
- archives(tasks.shadowJar)
+ implementation(tasks.shadowJar)
}
tasks {
diff --git a/bukkit/paper-loader/build.gradle.kts b/bukkit/paper-loader/build.gradle.kts
index 9b04d929d..6f4b05f8e 100644
--- a/bukkit/paper-loader/build.gradle.kts
+++ b/bukkit/paper-loader/build.gradle.kts
@@ -77,6 +77,9 @@ paper {
register("ViaVersion") { required = false }
register("QuickShop-Hikari") { required = false }
+ // external tag
+ register("CustomNameplates") { required = false }
+
// external models
register("ModelEngine") { required = false }
register("BetterModel") { required = false }
@@ -90,6 +93,7 @@ paper {
register("HeadDatabase") { required = false }
register("SX-Item") { required = false }
register("Slimefun") { required = false }
+ register("Nexo") { required = false }
// leveler
register("AuraSkills") { required = false }
@@ -126,11 +130,12 @@ paper {
register("PreciousStones") { required = false }
register("hClaims") { required = false }
register("Factions") { required = false }
+ register("NoBuildPlus") { required = false }
}
}
artifacts {
- archives(tasks.shadowJar)
+ implementation(tasks.shadowJar)
}
tasks {
diff --git a/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEngineBootstrap.java b/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEngineBootstrap.java
index 45eb0a35d..3487acf09 100644
--- a/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEngineBootstrap.java
+++ b/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEngineBootstrap.java
@@ -17,7 +17,7 @@ import java.lang.reflect.Method;
import java.util.Objects;
@SuppressWarnings("UnstableApiUsage")
-public class PaperCraftEngineBootstrap implements PluginBootstrap {
+public final class PaperCraftEngineBootstrap implements PluginBootstrap {
private static final Class> clazz$PluginProviderContext = PluginProviderContext.class;
private static final Class> clazz$ComponentLogger = Objects.requireNonNull(
ReflectionUtils.getClazz(
@@ -29,7 +29,8 @@ public class PaperCraftEngineBootstrap implements PluginBootstrap {
clazz$PluginProviderContext, clazz$ComponentLogger, new String[] { "getLogger" }
)
);
- protected BukkitCraftEngine plugin;
+
+ BukkitCraftEngine plugin;
@Override
public void bootstrap(@NotNull BootstrapContext context) {
diff --git a/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEnginePlugin.java b/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEnginePlugin.java
index ee3ac717b..0840c777b 100644
--- a/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEnginePlugin.java
+++ b/bukkit/paper-loader/src/main/java/net/momirealms/craftengine/bukkit/plugin/PaperCraftEnginePlugin.java
@@ -2,7 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin;
import org.bukkit.plugin.java.JavaPlugin;
-public class PaperCraftEnginePlugin extends JavaPlugin {
+public final class PaperCraftEnginePlugin extends JavaPlugin {
private final PaperCraftEngineBootstrap bootstrap;
public PaperCraftEnginePlugin(PaperCraftEngineBootstrap bootstrap) {
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java
index e42a03083..9a5f8acc3 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/advancement/BukkitAdvancementManager.java
@@ -22,7 +22,7 @@ import net.momirealms.craftengine.core.util.VersionHelper;
import java.nio.file.Path;
import java.util.*;
-public class BukkitAdvancementManager extends AbstractAdvancementManager {
+public final class BukkitAdvancementManager extends AbstractAdvancementManager {
private final BukkitCraftEngine plugin;
private final AdvancementParser advancementParser;
private final Map advancements = new HashMap<>();
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java
index d7367e5cd..4a47cd615 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineFurniture.java
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.api;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager;
+import net.momirealms.craftengine.bukkit.entity.seat.BukkitSeatManager;
import net.momirealms.craftengine.bukkit.nms.CollisionEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
@@ -18,6 +19,7 @@ import net.momirealms.craftengine.core.plugin.context.parameter.DirectContextPar
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldPosition;
+import net.momirealms.sparrow.nbt.CompoundTag;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@@ -159,8 +161,7 @@ public final class CraftEngineFurniture {
* @return is seat or not
*/
public static boolean isSeat(@NotNull Entity entity) {
- Integer baseEntityId = entity.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
- return baseEntityId != null;
+ return entity.getPersistentDataContainer().has(BukkitSeatManager.SEAT_KEY);
}
/**
@@ -182,9 +183,12 @@ public final class CraftEngineFurniture {
*/
@Nullable
public static BukkitFurniture getLoadedFurnitureBySeat(@NotNull Entity seat) {
- Integer baseEntityId = seat.getPersistentDataContainer().get(BukkitFurnitureManager.FURNITURE_SEAT_BASE_ENTITY_KEY, PersistentDataType.INTEGER);
- if (baseEntityId == null) return null;
- return BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(baseEntityId);
+ if (isSeat(seat)) {
+ CompoundTag seatExtraData = BukkitSeatManager.instance().getSeatExtraData(seat);
+ int entityId = seatExtraData.getInt("entity_id");
+ BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId);
+ }
+ return null;
}
/**
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackCacheEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackCacheEvent.java
index 35f1cdd4f..dfa064fa3 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackCacheEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackCacheEvent.java
@@ -21,7 +21,7 @@ import java.nio.file.Path;
* if you need the cache to recognize updates.
*
*/
-public class AsyncResourcePackCacheEvent extends Event {
+public final class AsyncResourcePackCacheEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PackCacheData cacheData;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackGenerateEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackGenerateEvent.java
index efca827ba..4a058e76b 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackGenerateEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/AsyncResourcePackGenerateEvent.java
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
-public class AsyncResourcePackGenerateEvent extends Event {
+public final class AsyncResourcePackGenerateEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Path generatedPackPath;
private final Path zipFilePath;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CraftEngineReloadEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CraftEngineReloadEvent.java
index 949299b48..d3d078099 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CraftEngineReloadEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CraftEngineReloadEvent.java
@@ -5,7 +5,7 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
-public class CraftEngineReloadEvent extends Event {
+public final class CraftEngineReloadEvent extends Event {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final BukkitCraftEngine plugin;
private static boolean firstFlag = true;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockAttemptPlaceEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockAttemptPlaceEvent.java
index af3683f71..320bd5552 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockAttemptPlaceEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockAttemptPlaceEvent.java
@@ -12,7 +12,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class CustomBlockAttemptPlaceEvent extends PlayerEvent implements Cancellable {
+public final class CustomBlockAttemptPlaceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final CustomBlock customBlock;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java
index 4034c8dea..e6f6a3451 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockBreakEvent.java
@@ -10,7 +10,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class CustomBlockBreakEvent extends PlayerEvent implements Cancellable {
+public final class CustomBlockBreakEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final CustomBlock customBlock;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java
index f9c9eccf2..cc37edb93 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockInteractEvent.java
@@ -15,7 +15,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class CustomBlockInteractEvent extends PlayerEvent implements Cancellable {
+public final class CustomBlockInteractEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final CustomBlock customBlock;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockPlaceEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockPlaceEvent.java
index 53ce67e2a..cffe6a3bf 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockPlaceEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/CustomBlockPlaceEvent.java
@@ -11,7 +11,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class CustomBlockPlaceEvent extends PlayerEvent implements Cancellable {
+public final class CustomBlockPlaceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final CustomBlock customBlock;
private final ImmutableBlockState state;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java
index 6a26aab44..901c6f032 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java
@@ -8,7 +8,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class FurnitureAttemptBreakEvent extends PlayerEvent implements Cancellable {
+public final class FurnitureAttemptBreakEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final BukkitFurniture furniture;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptPlaceEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptPlaceEvent.java
index f77c77e12..6d0a54209 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptPlaceEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptPlaceEvent.java
@@ -12,7 +12,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class FurnitureAttemptPlaceEvent extends PlayerEvent implements Cancellable {
+public final class FurnitureAttemptPlaceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final CustomFurniture furniture;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureBreakEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureBreakEvent.java
index 087004c50..20dd2a80a 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureBreakEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureBreakEvent.java
@@ -8,7 +8,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class FurnitureBreakEvent extends PlayerEvent implements Cancellable {
+public final class FurnitureBreakEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final BukkitFurniture furniture;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureInteractEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureInteractEvent.java
index a9a523484..1e1adcf47 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureInteractEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureInteractEvent.java
@@ -1,6 +1,7 @@
package net.momirealms.craftengine.bukkit.api.event;
import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture;
+import net.momirealms.craftengine.core.entity.furniture.HitBox;
import net.momirealms.craftengine.core.entity.player.InteractionHand;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -9,21 +10,29 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class FurnitureInteractEvent extends PlayerEvent implements Cancellable {
+public final class FurnitureInteractEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final BukkitFurniture furniture;
private final InteractionHand hand;
private final Location interactionPoint;
+ private final HitBox hitBox;
public FurnitureInteractEvent(@NotNull Player player,
@NotNull BukkitFurniture furniture,
@NotNull InteractionHand hand,
- @NotNull Location interactionPoint) {
+ @NotNull Location interactionPoint,
+ @NotNull HitBox hitBox) {
super(player);
this.furniture = furniture;
this.hand = hand;
this.interactionPoint = interactionPoint;
+ this.hitBox = hitBox;
+ }
+
+ @NotNull
+ public HitBox hitBox() {
+ return hitBox;
}
@NotNull
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurniturePlaceEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurniturePlaceEvent.java
index 8ea0c9645..9f495d317 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurniturePlaceEvent.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurniturePlaceEvent.java
@@ -9,7 +9,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class FurniturePlaceEvent extends PlayerEvent implements Cancellable {
+public final class FurniturePlaceEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location location;
private final BukkitFurniture furniture;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
index abcf5d08f..b650e0a57 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
@@ -6,6 +6,9 @@ import net.momirealms.craftengine.bukkit.block.behavior.UnsafeCompositeBlockBeha
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.BlockGenerator;
+import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager;
+import net.momirealms.craftengine.bukkit.plugin.network.payload.PayloadHelper;
+import net.momirealms.craftengine.bukkit.plugin.network.payload.protocol.VisualBlockStatePacket;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.*;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
@@ -18,15 +21,17 @@ import net.momirealms.craftengine.core.block.parser.BlockStateParser;
import net.momirealms.craftengine.core.loot.LootTable;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
-import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
+import net.momirealms.craftengine.core.plugin.context.Context;
import net.momirealms.craftengine.core.plugin.context.event.EventTrigger;
import net.momirealms.craftengine.core.plugin.context.function.Function;
import net.momirealms.craftengine.core.plugin.logger.Debugger;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.sound.SoundData;
import net.momirealms.craftengine.core.sound.SoundSet;
-import net.momirealms.craftengine.core.util.*;
-import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
+import net.momirealms.craftengine.core.util.Key;
+import net.momirealms.craftengine.core.util.ObjectHolder;
+import net.momirealms.craftengine.core.util.Tristate;
+import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.event.HandlerList;
@@ -61,6 +66,8 @@ public final class BukkitBlockManager extends AbstractBlockManager {
private Set