Compare commits

..

16 Commits

Author SHA1 Message Date
Auxilor
28b268e175 Added %player% to configslot 2022-09-28 12:38:38 +01:00
Auxilor
33937d1ce7 Switched Crunch to fork 2022-09-28 11:04:59 +01:00
Auxilor
e971778cc3 Updated to 6.42.0 2022-09-28 10:47:51 +01:00
Auxilor
f99612ded3 Added CustomSlot, improved various GUI elements, added GUI components. 2022-09-28 10:47:42 +01:00
Auxilor
50272bbbcf Improved skull texture API backend 2022-09-28 08:44:16 +01:00
Auxilor
9a703f6190 One more held item slot fix 2022-09-26 14:02:20 +01:00
Auxilor
f8fec7eec4 Updated to 6.41.3 2022-09-26 13:57:50 +01:00
Auxilor
f6aadda4ed Fixed PacketHeldItemSlot 2022-09-26 13:57:39 +01:00
Auxilor
d8fca0f348 Switched KingdomsX to local jar 2022-09-26 12:52:46 +01:00
Auxilor
65ff4c4a31 PR Codestyle 2022-09-26 12:36:34 +01:00
Auxilor
90702bc7aa Merge remote-tracking branch 'origin/develop' into develop 2022-09-26 12:34:53 +01:00
Will FP
e81b788a1b Merge pull request #199 from mani1232/master
Update KingdomsX dependence
2022-09-26 12:34:46 +01:00
Auxilor
ebc0ee7940 Updated to 6.41.2 2022-09-26 12:33:25 +01:00
Auxilor
82d269daf1 Improved PacketWindowItems and DisplayFrame 2022-09-26 12:32:07 +01:00
Auxilor
9d5300d6ae Began display system fixes 2022-09-26 12:10:22 +01:00
mani1232
8870e4d6fb Update KingdomsX dependence 2022-09-25 21:26:21 +02:00
23 changed files with 460 additions and 199 deletions

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.gui.component;
import com.willfp.eco.core.gui.slot.Slot;
import org.jetbrains.annotations.Nullable;
/**
* A GUI Component is a 2-dimensional set of slots that can be
* placed in a menu.
*/
public interface GUIComponent {
/**
* Get the amount of rows in the component.
*
* @return The rows.
*/
int getRows();
/**
* Get the amount of columns in the component.
*
* @return The columns.
*/
int getColumns();
/**
* Get the slot at a certain position in the component.
*
* @param row The row (1-indexed).
* @param column The column (1-indexed).
* @return The slot, or null if no slot at the location.
*/
@Nullable
Slot getSlotAt(final int row,
final int column);
}

View File

@@ -1,7 +1,9 @@
package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.slot.FillerMask;
import com.willfp.eco.core.gui.slot.Slot;
import org.apache.commons.lang3.Validate;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull;
@@ -13,6 +15,13 @@ import java.util.function.Consumer;
* Builder to create menus.
*/
public interface MenuBuilder {
/**
* Get the amount of rows.
*
* @return The amount of rows.
*/
int getRows();
/**
* Set the menu title.
*
@@ -33,6 +42,32 @@ public interface MenuBuilder {
int column,
@NotNull Slot slot);
/**
* Add a component.
*
* @param row The row of the top left corner.
* @param column The column of the top left corner.
* @param component The component.
* @return The builder.
*/
default MenuBuilder addComponent(final int row,
final int column,
@NotNull GUIComponent component) {
Validate.isTrue(column + component.getColumns() - 1 <= 9, "Component is too large to be placed here!");
Validate.isTrue(row + component.getRows() - 1 <= this.getRows(), "Component is too large to be placed here!");
for (int currentRow = row; currentRow < row + component.getRows(); currentRow++) {
for (int currentCol = column; currentCol < column + component.getColumns(); currentCol++) {
Slot slot = component.getSlotAt(currentRow, currentCol);
if (slot != null) {
setSlot(currentRow, currentCol, slot);
}
}
}
return this;
}
/**
* Run function to modify the builder.
*

View File

@@ -0,0 +1,115 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A slot loaded in from config.
*/
public class ConfigSlot extends CustomSlot {
/**
* The config of the slot.
*/
private final Config config;
/**
* Cached handlers, for performance.
*/
private final Map<String, List<CommandToDispatch>> handlers = new HashMap<>();
/**
* Create a new config slot.
*
* @param config The config.
*/
public ConfigSlot(@NotNull final Config config) {
this.config = config;
init(
Slot.builder(Items.lookup(config.getString("item")))
.onLeftClick(dispatchCommandHandler("left-click"))
.onRightClick(dispatchCommandHandler("right-click"))
.onShiftLeftClick(dispatchCommandHandler("shift-left-click"))
.onShiftRightClick(dispatchCommandHandler("shift-right-click"))
.build()
);
}
/**
* Create a slot handler for dispatching commands.
*
* @param configKey The config key.
* @return The handler.
*/
private SlotHandler dispatchCommandHandler(@NotNull final String configKey) {
if (!handlers.containsKey(configKey)) {
List<CommandToDispatch> commands = new ArrayList<>();
for (String command : config.getStrings(configKey)) {
if (command.startsWith("console:")) {
commands.add(new CommandToDispatch(
StringUtils.removePrefix("console:", command),
true
));
} else {
commands.add(new CommandToDispatch(
command,
false
));
}
}
handlers.put(configKey, commands);
}
List<CommandToDispatch> toDispatch = handlers.get(configKey);
return (event, slot, menu) -> {
Player player = (Player) event.getWhoClicked();
for (CommandToDispatch dispatch : toDispatch) {
dispatch.dispatch(player);
}
};
}
/**
* Signifies a command to dispatch.
*
* @param command The command.
* @param console If the command should be run as console.
*/
private record CommandToDispatch(
@NotNull String command,
boolean console
) {
/**
* Dispatch command.
*
* @param player The player.
*/
void dispatch(@NotNull final Player player) {
if (console()) {
Bukkit.dispatchCommand(
Bukkit.getConsoleSender(),
command().replace("%player%", player.getName())
);
} else {
Bukkit.dispatchCommand(
player,
command().replace("%player%", player.getName())
);
}
}
}
}

View File

@@ -0,0 +1,97 @@
package com.willfp.eco.core.gui.slot;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Base class for custom slot implementations.
*/
public abstract class CustomSlot implements Slot {
/**
* The internal slot to delegate to.
*/
private Slot delegate = null;
/**
* Create a new custom slot.
*/
protected CustomSlot() {
}
/**
* Initialize the slot with the delegate.
*
* @param slot The slot to delegate to.
*/
protected void init(@NotNull final Slot slot) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
this.delegate = slot;
}
/**
* Get the delegate slot.
* <p>
* This is not required to add the slot to a menu, but is instead used internally.
*
* @return The slot.
*/
public Slot getDelegate() {
return this.delegate;
}
@Override
public ItemStack getItemStack(@NotNull final Player player) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.getItemStack(player);
}
@Override
public boolean isCaptive() {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.isCaptive();
}
@Override
public boolean isNotCaptiveFor(@NotNull final Player player) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.isNotCaptiveFor(player);
}
@Override
public boolean isCaptiveFromEmpty() {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.isCaptiveFromEmpty();
}
@Override
public final int getRows() {
return Slot.super.getRows();
}
@Override
public final int getColumns() {
return Slot.super.getColumns();
}
@Override
public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column);
}
}

View File

@@ -1,7 +1,9 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -11,8 +13,11 @@ import java.util.function.Function;
/**
* A slot is an item in a GUI that can handle clicks.
* <p>
* Don't create custom Slot implementations directly from this class,
* rather extend {@link CustomSlot}.
*/
public interface Slot {
public interface Slot extends GUIComponent {
/**
* Get the ItemStack that would be shown to a player.
*
@@ -48,6 +53,22 @@ public interface Slot {
return false;
}
@Override
default int getRows() {
return 1;
}
@Override
default int getColumns() {
return 1;
}
@Override
default Slot getSlotAt(final int row,
final int column) {
return this;
}
/**
* Create a builder for an ItemStack.
*
@@ -67,6 +88,16 @@ public interface Slot {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
}
/**
* Create a builder for a TestableItem.
*
* @param item The item.
* @return The builder.
*/
static SlotBuilder builder(@NotNull final TestableItem item) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> item.getItem());
}
/**
* Create a builder for a player-specific ItemStack.
*

View File

@@ -85,6 +85,16 @@ fun slot(
item: ItemStack
): Slot = Slot.builder(item).build()
/** Kotlin builder for slots. */
fun slot(
item: TestableItem,
init: SlotBuilder.() -> Unit
): Slot {
val builder = Slot.builder(item)
init(builder)
return builder.build()
}
/** Kotlin builder for slots. */
fun slot(
item: TestableItem

View File

@@ -17,7 +17,7 @@ import org.bukkit.inventory.ItemStack
import java.util.function.BiConsumer
import java.util.function.Consumer
class EcoMenuBuilder(private val rows: Int ) : MenuBuilder {
class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
private var title = "Menu"
private var maskSlots: List<MutableList<Slot?>>
private val slots: List<MutableList<Slot?>> = ListUtils.create2DList(rows, 9)
@@ -25,6 +25,8 @@ class EcoMenuBuilder(private val rows: Int ) : MenuBuilder {
private var onOpen = OpenHandler { _, _ -> }
private var onRender: (Player, Menu) -> Unit = { _, _ -> }
override fun getRows() = rows
override fun setTitle(title: String): MenuBuilder {
this.title = StringUtils.format(title)
return this

View File

@@ -0,0 +1,43 @@
package com.willfp.eco.internal.spigot.proxy.common
import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
private lateinit var setProfile: Method
private lateinit var profile: Field
var SkullMeta.texture: String?
get() {
if (!::profile.isInitialized) {
// Assumes instance of CraftMetaSkull; package-private class so can't do manual type check
profile = this.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[this] as GameProfile? ?: return null
val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.value
}
set(base64) {
if (!::setProfile.isInitialized) {
// Same here; that's why I can't delegate to a lazy initializer
setProfile = this.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile.isAccessible = true
}
if (base64 == null) {
setProfile.invoke(this, null)
} else {
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(this, profile)
}
}

View File

@@ -1,48 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.texture
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
class Skull : SkullProxy {
private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
if (!this::setProfile.isInitialized) {
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile.isAccessible = true
}
if (base64.length < 20) {
return
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name
}
}
): String? = meta.texture
}

View File

@@ -1,48 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.texture
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
class Skull : SkullProxy {
private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
if (!this::setProfile.isInitialized) {
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile.isAccessible = true
}
if (base64.length < 20) {
return
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name
}
}
): String? = meta.texture
}

View File

@@ -1,48 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.texture
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
class Skull : SkullProxy {
private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
if (!this::setProfile.isInitialized) {
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile.isAccessible = true
}
if (base64.length < 20) {
return
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name
}
}
): String? = meta.texture
}

View File

@@ -1,48 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.texture
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID
class Skull : SkullProxy {
private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
if (!this::setProfile.isInitialized) {
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile.isAccessible = true
}
if (base64.length < 20) {
return
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name
}
}
): String? = meta.texture
}

View File

@@ -6,7 +6,7 @@ dependencies {
compileOnly project(":eco-core:core-backend")
// Libraries
implementation 'com.github.Redempt:Crunch:master-SNAPSHOT'
implementation 'com.github.WillFP:Crunch:1.1.3'
implementation 'mysql:mysql-connector-java:8.0.25'
implementation 'org.jetbrains.exposed:exposed-core:0.37.3'
implementation 'org.jetbrains.exposed:exposed-dao:0.37.3'
@@ -25,7 +25,6 @@ dependencies {
compileOnly 'com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.7-SNAPSHOT'
compileOnly 'com.github.TechFortress:GriefPrevention:16.17.1'
compileOnly 'com.github.cryptomorin:kingdoms:1.12.3'
compileOnly('com.github.TownyAdvanced:Towny:0.97.2.6') {
exclude group: 'com.zaxxer', module: 'HikariCP'
}

View File

@@ -56,7 +56,7 @@ import com.willfp.eco.internal.spigot.data.PlayerBlockListener
import com.willfp.eco.internal.spigot.data.storage.ProfileSaver
import com.willfp.eco.internal.spigot.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.display.PacketChat
import com.willfp.eco.internal.spigot.display.PacketHeldWindowItems
import com.willfp.eco.internal.spigot.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.display.PacketSetSlot
@@ -357,7 +357,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
PacketSetCreativeSlot(this),
PacketSetSlot(this),
PacketWindowItems(this),
PacketHeldWindowItems(this),
PacketHeldItemSlot(this),
PacketOpenWindowMerchant(this)
)
}

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.internal.spigot.display
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.events.PacketContainer
import com.comphenix.protocol.events.PacketEvent
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame
import org.bukkit.entity.Player
class PacketHeldItemSlot(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin, PacketType.Play.Server.HELD_ITEM_SLOT, false) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}
override fun onReceive(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -1,25 +0,0 @@
package com.willfp.eco.internal.spigot.display
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.events.PacketContainer
import com.comphenix.protocol.events.PacketEvent
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
class PacketHeldWindowItems(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
packet.itemModifier.modify(0) { item: ItemStack? ->
Display.display(
item!!, player
)
}
}
}

View File

@@ -9,7 +9,6 @@ import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
class PacketSetSlot(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.SET_SLOT, false) {
override fun onSend(
@@ -17,14 +16,13 @@ class PacketSetSlot(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketTyp
player: Player,
event: PacketEvent
) {
packet.itemModifier.modify(0, object : VersionCompatiblePLibFunction<ItemStack> {
override fun apply(item: ItemStack) =
Display.display(
item,
player
)
})
packet.itemModifier.modify(0) {
Display.display(
it,
player
)
}
player.lastDisplayFrame = DisplayFrame.EMPTY
}
}
}

View File

@@ -14,21 +14,32 @@ import org.bukkit.inventory.ItemStack
import java.util.concurrent.ConcurrentHashMap
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) {
private val ignorePacketList = ConcurrentHashMap.newKeySet<String>()
private val lastKnownWindowIDs = ConcurrentHashMap<String, Int>()
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
if (ignorePacketList.contains(player.name)) {
ignorePacketList.remove(player.name)
return
packet.itemModifier.modify(0) {
Display.display(
it, player
)
}
val windowId = packet.integers.read(0)
if (windowId != 0) {
// Using name because UUID is unreliable with ProtocolLib players.
val name = player.name
val lastKnownID = lastKnownWindowIDs[name]
lastKnownWindowIDs[name] = windowId
// If there is any change in window ID at any point,
// Remove the last display frame to prevent any potential conflicts.
// If the window ID is not zero (not a player inventory), then remove too,
// as GUIs are not player inventories.
if (lastKnownID != windowId || windowId != 0) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}

View File

@@ -1,8 +0,0 @@
package com.willfp.eco.internal.spigot.display
import com.google.common.base.Function
import java.util.function.UnaryOperator
interface VersionCompatiblePLibFunction<T> : Function<T, T>, UnaryOperator<T> {
}

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.internal.spigot.gui
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.gui.slot.CustomSlot
import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.internal.gui.menu.EcoMenu
import com.willfp.eco.internal.gui.menu.MenuHandler
import com.willfp.eco.internal.gui.menu.asRenderedInventory
@@ -16,6 +18,13 @@ import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.event.player.PlayerItemHeldEvent
class GUIListener(private val plugin: EcoPlugin) : Listener {
private fun Slot.handle(event: InventoryClickEvent, menu: EcoMenu) {
when (this) {
is EcoSlot -> this.handleInventoryClick(event, menu)
is CustomSlot -> this.delegate.handle(event, menu)
}
}
@EventHandler(priority = EventPriority.HIGH)
fun handleSlotClick(event: InventoryClickEvent) {
val rendered = event.clickedInventory?.asRenderedInventory() ?: return
@@ -24,9 +33,7 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
val (row, column) = MenuUtils.convertSlotToRowColumn(event.slot)
val slot = menu.getSlot(row, column) as? EcoSlot ?: return
slot.handleInventoryClick(event, menu)
menu.getSlot(row, column).handle(event, menu)
plugin.scheduler.run { rendered.render() }
}

View File

@@ -6,10 +6,10 @@ import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import org.kingdoms.constants.group.Kingdom
import org.kingdoms.constants.group.model.KingdomRelation
import org.kingdoms.constants.group.model.relationships.StandardRelationAttribute
import org.kingdoms.constants.land.Land
import org.kingdoms.constants.player.DefaultKingdomPermission
import org.kingdoms.constants.player.KingdomPlayer
import org.kingdoms.constants.player.StandardKingdomPermission
import org.kingdoms.managers.PvPManager
class AntigriefKingdoms : AntigriefIntegration {
@@ -23,11 +23,13 @@ class AntigriefKingdoms : AntigriefIntegration {
}
val kingdom: Kingdom = kp.kingdom ?: return false
val land = Land.getLand(block) ?: return true
val permission: DefaultKingdomPermission =
if (land.isNexusLand) DefaultKingdomPermission.NEXUS_BUILD else DefaultKingdomPermission.BUILD
val permission = if (land.isNexusLand) {
StandardKingdomPermission.NEXUS_BUILD
} else StandardKingdomPermission.BUILD
return if (!kp.hasPermission(permission)) {
false
} else kingdom.hasAttribute(land.kingdom, KingdomRelation.Attribute.BUILD)
} else kingdom.hasAttribute(land.kingdom, StandardRelationAttribute.BUILD)
}
override fun canCreateExplosion(
@@ -84,4 +86,4 @@ class AntigriefKingdoms : AntigriefIntegration {
override fun hashCode(): Int {
return this.pluginName.hashCode()
}
}
}

View File

@@ -1,3 +1,3 @@
version = 6.41.1
version = 6.42.0
plugin-name = eco
kotlin.code.style = official

Binary file not shown.