-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nico Lube
committed
Feb 3, 2025
1 parent
b114785
commit 201042f
Showing
28 changed files
with
2,098 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import org.apache.tools.ant.filters.ReplaceTokens | ||
|
||
plugins { | ||
alias(libs.plugins.shadowjar) | ||
alias(libs.plugins.kotlin) | ||
} | ||
|
||
apply from: '../library.gradle' | ||
apply from: '../publish.gradle' | ||
|
||
dependencies { | ||
api projects.inventoryFrameworkPlatform | ||
runtimeOnly projects.inventoryFrameworkAnvilInput | ||
compileOnly libs.minestom | ||
testCompileOnly libs.minestom | ||
testImplementation projects.inventoryFrameworkApi | ||
testImplementation projects.inventoryFrameworkTest | ||
} | ||
|
||
shadowJar { | ||
archiveBaseName.set('inventory-framework') | ||
archiveAppendix.set('bukkit') | ||
|
||
dependencies { | ||
include(project(":inventory-framework-platform")) | ||
include(project(":inventory-framework-anvil-input")) | ||
} | ||
} | ||
|
||
|
||
java { | ||
targetCompatibility = JavaVersion.VERSION_21 | ||
toolchain { | ||
languageVersion.set(JavaLanguageVersion.of(21)) | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
...k-platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/IFInventoryListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package me.devnatan.inventoryframework | ||
|
||
import me.devnatan.inventoryframework.context.IFCloseContext | ||
import me.devnatan.inventoryframework.context.IFContext | ||
import me.devnatan.inventoryframework.context.IFRenderContext | ||
import me.devnatan.inventoryframework.context.IFSlotClickContext | ||
import me.devnatan.inventoryframework.pipeline.StandardPipelinePhases | ||
import net.minestom.server.MinecraftServer | ||
import net.minestom.server.entity.Player | ||
import net.minestom.server.event.EventFilter | ||
import net.minestom.server.event.EventNode | ||
import net.minestom.server.event.inventory.InventoryCloseEvent | ||
import net.minestom.server.event.inventory.InventoryPreClickEvent | ||
import net.minestom.server.event.item.ItemDropEvent | ||
import net.minestom.server.event.item.PickupItemEvent | ||
import net.minestom.server.inventory.PlayerInventory | ||
|
||
internal class IFInventoryListener( | ||
private val viewFrame: ViewFrame | ||
) { | ||
|
||
init { | ||
val handler = MinecraftServer.getGlobalEventHandler() | ||
val inventoryNode = EventNode.type("IF-inventory", EventFilter.INVENTORY) | ||
.setPriority(10) | ||
.addListener(InventoryPreClickEvent::class.java, this::onInventoryClick) | ||
.addListener(InventoryCloseEvent::class.java, this::onInventoryClose) | ||
val playerNode = EventNode.type("IF-player", EventFilter.PLAYER) | ||
{ _, p -> viewFrame.getViewer(p) != null } | ||
.setPriority(10) | ||
.addListener(ItemDropEvent::class.java, this::onItemDrop) | ||
val entityEvent = EventNode.type("IF-entity", EventFilter.ENTITY) | ||
{ _, e -> e is Player && viewFrame.getViewer(e) != null } | ||
.setPriority(10) | ||
.addListener(PickupItemEvent::class.java, this::onItemPickup) | ||
handler.addChild(inventoryNode) | ||
handler.addChild(playerNode) | ||
handler.addChild(entityEvent) | ||
} | ||
|
||
fun onInventoryClick(event: InventoryPreClickEvent) { | ||
if (event.isCancelled) return | ||
|
||
val player = event.player | ||
val viewer = viewFrame.getViewer(player) ?: return | ||
|
||
val context: IFRenderContext = viewer.activeContext | ||
val clickedComponent: me.devnatan.inventoryframework.component.Component = | ||
context.getComponentsAt(event.slot).stream() | ||
.filter { obj: me.devnatan.inventoryframework.component.Component -> obj.isVisible } | ||
.findFirst() | ||
.orElse(null) | ||
val clickedContainer = if (event.inventory is PlayerInventory) | ||
viewer.selfContainer | ||
else | ||
context.getContainer() | ||
|
||
val root: RootView = context.getRoot() | ||
val clickContext: IFSlotClickContext = root.elementFactory | ||
.createSlotClickContext(event.slot, viewer, clickedContainer, clickedComponent, event, false) | ||
|
||
root.pipeline.execute(StandardPipelinePhases.CLICK, clickContext) | ||
} | ||
|
||
fun onInventoryClose(event: InventoryCloseEvent) { | ||
val player: Player = event.player | ||
val viewer = viewFrame.getViewer(player) ?: return | ||
|
||
val context: IFRenderContext = viewer.activeContext | ||
val root: RootView = context.getRoot() | ||
val closeContext: IFCloseContext = root.elementFactory.createCloseContext(viewer, context) | ||
|
||
root.pipeline.execute(StandardPipelinePhases.CLOSE, closeContext) | ||
} | ||
|
||
fun onItemPickup(event: PickupItemEvent) { | ||
val viewer = viewFrame.getViewer(event.entity as Player) ?: return | ||
|
||
val context: IFContext = viewer.activeContext | ||
if (!context.getConfig().isOptionSet(ViewConfig.CANCEL_ON_PICKUP)) return | ||
|
||
event.isCancelled = context.getConfig().getOptionValue(ViewConfig.CANCEL_ON_PICKUP) | ||
} | ||
|
||
fun onItemDrop(event: ItemDropEvent) { | ||
val viewer = viewFrame.getViewer(event.getPlayer()) ?: return | ||
|
||
val context: IFContext = viewer.activeContext | ||
if (!context.getConfig().isOptionSet(ViewConfig.CANCEL_ON_DROP)) return | ||
|
||
event.isCancelled = context.getConfig().getOptionValue(ViewConfig.CANCEL_ON_DROP) | ||
} | ||
} |
158 changes: 158 additions & 0 deletions
158
...platform-minestom/src/main/kotlin/me/devnatan/inventoryframework/MinestomViewContainer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package me.devnatan.inventoryframework | ||
|
||
import net.kyori.adventure.text.Component | ||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer | ||
import net.minestom.server.entity.Player | ||
import net.minestom.server.inventory.Inventory | ||
import net.minestom.server.inventory.InventoryType | ||
import net.minestom.server.inventory.PlayerInventory | ||
import net.minestom.server.item.ItemStack | ||
import java.util.* | ||
|
||
class MinestomViewContainer( | ||
private val inventory: Inventory, shared: Boolean, private val type: ViewType, | ||
private val proxied: Boolean | ||
) : | ||
ViewContainer { | ||
val isShared: Boolean = shared | ||
|
||
fun getInventory(): Inventory { | ||
return inventory | ||
} | ||
|
||
override fun isProxied(): Boolean { | ||
return proxied | ||
} | ||
|
||
override fun getTitle(): String { | ||
val diffTitle: Boolean = inventory.viewers.stream() | ||
.map { player -> | ||
(player.openInventory as? Inventory)?.title | ||
?.let { PlainTextComponentSerializer.plainText().serialize(it) } ?: "" | ||
} | ||
.distinct() | ||
.findAny() | ||
.isPresent | ||
|
||
check(!(diffTitle && isShared)) { "Cannot get unique title of shared inventory" } | ||
val openInventory = inventory.viewers.first().openInventory | ||
return (openInventory as? Inventory)?.title | ||
?.let { PlainTextComponentSerializer.plainText().serialize(it) } ?: "" | ||
} | ||
|
||
override fun getTitle(viewer: Viewer): String { | ||
return ((viewer as MinestomViewer).player.openInventory as? Inventory)?.title | ||
?.let { PlainTextComponentSerializer.plainText().serialize(it) } ?: "" | ||
} | ||
|
||
override fun getType(): ViewType { | ||
return type | ||
} | ||
|
||
override fun getRowsCount(): Int { | ||
return size / columnsCount | ||
} | ||
|
||
override fun getColumnsCount(): Int { | ||
return type.columns | ||
} | ||
|
||
override fun renderItem(slot: Int, item: Any) { | ||
requireSupportedItem(item) | ||
inventory.setItemStack(slot, item as ItemStack) | ||
} | ||
|
||
override fun removeItem(slot: Int) { | ||
inventory.setItemStack(slot, ItemStack.AIR) | ||
} | ||
|
||
override fun matchesItem(slot: Int, item: Any?, exactly: Boolean): Boolean { | ||
requireSupportedItem(item) | ||
val target: ItemStack = inventory.getItemStack(slot) ?: return item == null | ||
if (item is ItemStack) return if (exactly) target == item else target.isSimilar(item as ItemStack) | ||
|
||
return false | ||
} | ||
|
||
override fun isSupportedItem(item: Any?): Boolean { | ||
return item == null || item is ItemStack | ||
} | ||
|
||
private fun requireSupportedItem(item: Any?) { | ||
if (isSupportedItem(item)) return | ||
|
||
throw IllegalStateException( | ||
"Unsupported item type: " + item!!.javaClass.name | ||
) | ||
} | ||
|
||
override fun hasItem(slot: Int): Boolean { | ||
return !inventory.getItemStack(slot).isAir | ||
} | ||
|
||
override fun getSize(): Int { | ||
return inventory.size | ||
} | ||
|
||
override fun getSlotsCount(): Int { | ||
return size - 1 | ||
} | ||
|
||
override fun getFirstSlot(): Int { | ||
return 0 | ||
} | ||
|
||
override fun getLastSlot(): Int { | ||
val resultSlots = getType().resultSlots | ||
var lastSlot = slotsCount | ||
if (resultSlots != null) { | ||
for (resultSlot in resultSlots) { | ||
if (resultSlot == lastSlot) lastSlot-- | ||
} | ||
} | ||
|
||
return lastSlot | ||
} | ||
|
||
override fun changeTitle(title: String?, target: Viewer) { | ||
changeTitle(title?.let { Component.text(it) } ?: Component.empty(), (target as MinestomViewer).player) | ||
} | ||
|
||
fun changeTitle(title: Component, target: Player) { | ||
val open: Inventory = target.openInventory as? Inventory ?: return | ||
if (inventory.inventoryType == InventoryType.CRAFTING || inventory.inventoryType == InventoryType.CRAFTER_3X3) return | ||
open.setTitle(title) | ||
} | ||
|
||
override fun isEntityContainer(): Boolean { | ||
return inventory is PlayerInventory | ||
} | ||
|
||
override fun open(viewer: Viewer) { | ||
viewer.open(this) | ||
} | ||
|
||
override fun close() { | ||
inventory.viewers.forEach(Player::closeInventory) | ||
} | ||
|
||
override fun close(viewer: Viewer) { | ||
viewer.close() | ||
} | ||
|
||
override fun equals(o: Any?): Boolean { | ||
if (this === o) return true | ||
if (o == null || javaClass != o.javaClass) return false | ||
val that = o as MinestomViewContainer | ||
return isShared == that.isShared && inventory == that.inventory | ||
&& getType() == that.getType() | ||
} | ||
|
||
override fun hashCode(): Int { | ||
return Objects.hash(inventory, isShared, getType()) | ||
} | ||
|
||
override fun toString(): String { | ||
return "BukkitViewContainer{" + "inventory=" + inventory + ", shared=" + isShared + ", type=" + type + '}' | ||
} | ||
} |
Oops, something went wrong.