From 9f34bea77ae225673977a5beb30372c62f2f2825 Mon Sep 17 00:00:00 2001 From: ScarletRedMan Date: Thu, 31 Oct 2024 01:55:55 +0700 Subject: [PATCH] feat: implemented item prefabs --- .../dragonestia/msb3/api/ServerBootstrap.java | 5 ++ .../msb3/api/item/ItemPrefabManager.java | 33 ++++++++ .../msb3/api/item/prefab/ItemPrefab.java | 84 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 api/src/main/java/ru/dragonestia/msb3/api/item/ItemPrefabManager.java create mode 100644 api/src/main/java/ru/dragonestia/msb3/api/item/prefab/ItemPrefab.java diff --git a/api/src/main/java/ru/dragonestia/msb3/api/ServerBootstrap.java b/api/src/main/java/ru/dragonestia/msb3/api/ServerBootstrap.java index 20f42e4..e63b5f9 100644 --- a/api/src/main/java/ru/dragonestia/msb3/api/ServerBootstrap.java +++ b/api/src/main/java/ru/dragonestia/msb3/api/ServerBootstrap.java @@ -3,6 +3,7 @@ package ru.dragonestia.msb3.api; import lombok.Getter; import lombok.extern.log4j.Log4j2; import net.minestom.server.MinecraftServer; +import ru.dragonestia.msb3.api.item.ItemPrefabManager; import ru.dragonestia.msb3.api.resource.ResourcePackManager; import java.net.InetSocketAddress; @@ -26,9 +27,11 @@ public class ServerBootstrap { }; @Getter private static ServerBootstrap instance; + @Getter private static boolean started = false; private final MinecraftServer server; @Getter private final ResourcePackManager resourcePackManager; + @Getter private final ItemPrefabManager itemPrefabManager; public ServerBootstrap() { instance = this; @@ -40,11 +43,13 @@ public class ServerBootstrap { MinecraftServer.setBrandName("Dragonestia"); resourcePackManager = new ResourcePackManager(); + itemPrefabManager = new ItemPrefabManager(); init(); } public void start(String address, int port) { + started = true; server.start(new InetSocketAddress(address, port)); } diff --git a/api/src/main/java/ru/dragonestia/msb3/api/item/ItemPrefabManager.java b/api/src/main/java/ru/dragonestia/msb3/api/item/ItemPrefabManager.java new file mode 100644 index 0000000..575f2b3 --- /dev/null +++ b/api/src/main/java/ru/dragonestia/msb3/api/item/ItemPrefabManager.java @@ -0,0 +1,33 @@ +package ru.dragonestia.msb3.api.item; + +import lombok.extern.log4j.Log4j2; +import ru.dragonestia.msb3.api.ServerBootstrap; +import ru.dragonestia.msb3.api.item.prefab.ItemPrefab; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Log4j2 +public final class ItemPrefabManager { + + private final Map prefabs = new HashMap<>(); + + public ItemPrefabManager() {} + + public synchronized void register(ItemPrefab prefab) { + if (ServerBootstrap.isStarted()) { + throw new IllegalStateException("Server is already started"); + } + + if (prefabs.containsKey(prefab.getIdentifier())) { + throw new IllegalArgumentException("Prefab already registered: " + prefab.getIdentifier()); + } + + prefabs.put(prefab.getIdentifier(), prefab); + } + + public Optional getPrefab(String identifier) { + return Optional.ofNullable(prefabs.get(identifier)); + } +} diff --git a/api/src/main/java/ru/dragonestia/msb3/api/item/prefab/ItemPrefab.java b/api/src/main/java/ru/dragonestia/msb3/api/item/prefab/ItemPrefab.java new file mode 100644 index 0000000..465537d --- /dev/null +++ b/api/src/main/java/ru/dragonestia/msb3/api/item/prefab/ItemPrefab.java @@ -0,0 +1,84 @@ +package ru.dragonestia.msb3.api.item.prefab; + +import net.kyori.adventure.nbt.BinaryTag; +import net.minestom.server.item.ItemStack; +import net.minestom.server.tag.Tag; +import ru.dragonestia.msb3.api.ServerBootstrap; + +import java.util.Optional; +import java.util.function.Supplier; + +public class ItemPrefab { + + private static final Tag TAG_IDENTIFIER = Tag.String("msb3_prefab_id"); + private static final Tag TAG_DATA = Tag.NBT("msb3_prefab_data"); + + private final String identifier; + protected final Supplier factory; + + public ItemPrefab(String identifier, Supplier factory) { + this.identifier = identifier; + this.factory = factory; + } + + public static Optional of(String identifier) { + return ServerBootstrap.getInstance().getItemPrefabManager().getPrefab(identifier); + } + + public static Optional of(ItemStack item) { + if (item == null || item.hasTag(TAG_IDENTIFIER)) return Optional.empty(); + return ServerBootstrap.getInstance().getItemPrefabManager().getPrefab(item.getTag(TAG_IDENTIFIER)); + } + + public final String getIdentifier() { + return identifier; + } + + public final boolean isOwn(ItemStack item) { + return item.hasTag(TAG_IDENTIFIER) && identifier.equals(item.getTag(TAG_IDENTIFIER)); + } + + public final ItemStack create(int amount, BinaryTag data) { + var builder = factory.get().builder() + .amount(amount) + .set(TAG_IDENTIFIER, identifier); + + if (data != null) builder.set(TAG_DATA, data); + + return builder.build(); + } + + public final ItemStack create(int amount) { + return create(amount, null); + } + + public final ItemStack create() { + return create(1); + } + + public final BinaryTag extractData(ItemStack item) { + if (item.hasTag(TAG_DATA)) return item.getTag(TAG_DATA); + return null; + } + + public static SerializedPrefab serialize(ItemStack item) { + if (item == null || item.isAir()) return null; + + var prefabOpt = of(item); + if (prefabOpt.isEmpty()) return null; + var prefab = prefabOpt.get(); + + return new SerializedPrefab(prefab.getIdentifier(), item.amount()); + } + + public record SerializedPrefab(String id, int amount) { + + public ItemStack deserialize(SerializedPrefab serialized) { + var prefabOpt = of(serialized.id); + if (prefabOpt.isEmpty()) return null; + var prefab = prefabOpt.get(); + + return prefab.create(serialized.amount); + } + } +}