diff --git a/src/main/java/team/ebi/epicbanitem/EBIRegistries.java b/src/main/java/team/ebi/epicbanitem/EBIRegistries.java index e8b122f..4e85dd4 100644 --- a/src/main/java/team/ebi/epicbanitem/EBIRegistries.java +++ b/src/main/java/team/ebi/epicbanitem/EBIRegistries.java @@ -90,7 +90,8 @@ public void onRegisterRegistry(RegisterRegistryEvent.EngineScoped event) .put(EpicBanItem.key("equip"), injector.getInstance(EquipRestrictionTrigger.class)) // .put(EpicBanItem.key("be_equipped"), // injector.getInstance(BeEquippedRestrictionTrigger.class)) - .put(EpicBanItem.key("craft"), injector.getInstance(BeCraftedRestrictionTrigger.class)) + .put(EpicBanItem.key("be_crafted"), injector.getInstance(BeCraftedRestrictionTrigger.class)) + .put(EpicBanItem.key("craft"), injector.getInstance(CraftRestrictionTrigger.class)) .put(EpicBanItem.key("store"), injector.getInstance(StoreRestrictionTrigger.class)) // .put(EpicBanItem.key("click"), new RestrictionTriggerImpl()) .build()); diff --git a/src/main/java/team/ebi/epicbanitem/trigger/CraftRestrictionTrigger.java b/src/main/java/team/ebi/epicbanitem/trigger/CraftRestrictionTrigger.java new file mode 100644 index 0000000..ba77cce --- /dev/null +++ b/src/main/java/team/ebi/epicbanitem/trigger/CraftRestrictionTrigger.java @@ -0,0 +1,77 @@ +/* + * Copyright 2022 EpicBanItem Team. All Rights Reserved. + * + * This file is part of EpicBanItem, licensed under the GNU GENERAL PUBLIC LICENSE Version 3 (GPL-3.0) + */ +package team.ebi.epicbanitem.trigger; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.filter.Getter; +import org.spongepowered.api.event.filter.cause.First; +import org.spongepowered.api.event.item.inventory.CraftItemEvent; +import org.spongepowered.api.item.inventory.Carrier; +import org.spongepowered.api.item.inventory.Container; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.item.inventory.crafting.CraftingInventory; +import org.spongepowered.api.item.inventory.transaction.SlotTransaction; +import org.spongepowered.api.service.permission.Subject; +import org.spongepowered.api.world.Locatable; + +import com.google.inject.Singleton; +import net.kyori.adventure.audience.Audience; +import net.minecraft.world.inventory.CraftingContainer; +import team.ebi.epicbanitem.EpicBanItem; +import team.ebi.epicbanitem.util.InventoryUtils; +import team.ebi.epicbanitem.util.ItemUtils; + +@Singleton +public class CraftRestrictionTrigger extends EBIRestrictionTrigger { + + public CraftRestrictionTrigger() { + super(EpicBanItem.key("craft")); + } + + @Listener + public void onCraftItemPreview( + final CraftItemEvent.Preview event, + final @Getter("preview") SlotTransaction preview, + final @Getter("craftingInventory") CraftingInventory craftingInventory, + final @First Locatable locatable) { + final var cause = event.cause(); + final var audience = cause.first(Audience.class).orElse(null); + final var subject = cause.first(Subject.class).orElse(null); + final var inventory = cause.allOf(Carrier.class).stream() + .map(Carrier::inventory) + .distinct() + .filter(it -> !(it instanceof Container container) + || container.viewed().stream().noneMatch(CraftingContainer.class::isInstance)) + .findAny(); + final var location = locatable.serverLocation(); + final var world = location.world(); + final var gridInventory = craftingInventory.craftingGrid(); + gridInventory.slots().stream().filter(it -> it.freeCapacity() == 0).forEach(it -> { + final var cancelled = new AtomicBoolean(false); + final var processed = this.processItemCancellable( + event, world, subject, audience, it.peek().createSnapshot(), ignored -> { + cancelled.set(true); + preview.invalidate(); + }); + if (processed.isPresent()) { + if (cancelled.get()) { + it.set(ItemStack.empty()); + if (inventory.isPresent()) + location.spawnEntities(InventoryUtils.offerOrDrop( + inventory.get(), location, processed.get().createStack())); + else location.spawnEntity(ItemUtils.droppedItem(processed.get(), location)); + } else it.set(processed.get().createStack()); + } else if (cancelled.get()) { + if (inventory.isPresent()) + location.spawnEntities(InventoryUtils.offerOrDrop(inventory.get(), location, it.peek())); + else location.spawnEntity(ItemUtils.droppedItem(it.peek().createSnapshot(), location)); + it.set(ItemStack.empty()); + } + }); + } +} diff --git a/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_en_us.properties b/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_en_us.properties index a284b1d..35c6032 100644 --- a/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_en_us.properties +++ b/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_en_us.properties @@ -8,7 +8,8 @@ epicbanitem.trigger.epicbanitem\:use=Use epicbanitem.trigger.epicbanitem\:throw=Throw epicbanitem.trigger.epicbanitem\:pickup=Pickup epicbanitem.trigger.epicbanitem\:drop=Drop -epicbanitem.trigger.epicbanitem\:be_crafted=Cratted +epicbanitem.trigger.epicbanitem\:craft=Craft +epicbanitem.trigger.epicbanitem\:be_crafted=Crafted epicbanitem.trigger.epicbanitem\:click=Click epicbanitem.trigger.epicbanitem\:store=Store epicbanitem.trigger.epicbanitem\:equip=Equip @@ -22,6 +23,7 @@ epicbanitem.trigger.epicbanitem\:use.description=Item(s) is used epicbanitem.trigger.epicbanitem\:throw.description=Item(s) is thrown epicbanitem.trigger.epicbanitem\:pickup.description=Item(s) are picked epicbanitem.trigger.epicbanitem\:drop.description=Item(s) are dropped +epicbanitem.trigger.epicbanitem\:craft.description=Item(s) used for crafting epicbanitem.trigger.epicbanitem\:be_crafted.description=Item(s) is crafted epicbanitem.trigger.epicbanitem\:click.description=Item(s) is clicked epicbanitem.trigger.epicbanitem\:store.description=Item(s) is store to container diff --git a/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_zh_cn.properties b/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_zh_cn.properties index 70a7250..bc9d49e 100644 --- a/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_zh_cn.properties +++ b/src/main/resources/data/plugin-epicbanitem/assets/messages/messages_zh_cn.properties @@ -8,6 +8,7 @@ epicbanitem.trigger.epicbanitem\:use=使用 epicbanitem.trigger.epicbanitem\:throw=丢弃 epicbanitem.trigger.epicbanitem\:pickup=拾取 epicbanitem.trigger.epicbanitem\:drop=掉落 +epicbanitem.trigger.epicbanitem\:craft=合成 epicbanitem.trigger.epicbanitem\:be_crafted=被合成 epicbanitem.trigger.epicbanitem\:click=点击 epicbanitem.trigger.epicbanitem\:store=存入 @@ -22,6 +23,7 @@ epicbanitem.trigger.epicbanitem\:use.description=被使用的物品 epicbanitem.trigger.epicbanitem\:throw.description=被丢弃的物品 epicbanitem.trigger.epicbanitem\:pickup.description=被拾取的掉落物 epicbanitem.trigger.epicbanitem\:drop.description=掉落的物品 +epicbanitem.trigger.epicbanitem\:craft.description=用于合成的物品 epicbanitem.trigger.epicbanitem\:be_crafted.description=被合成的物品 epicbanitem.trigger.epicbanitem\:click.description=鼠标点击的物品 epicbanitem.trigger.epicbanitem\:store.description=存入容器内的物品