Moved away from ProtocolLib

This commit is contained in:
Auxilor
2023-02-14 16:49:04 +00:00
parent add5390787
commit a053f512f8
55 changed files with 897 additions and 811 deletions

View File

@@ -13,27 +13,30 @@ import java.util.Collections;
/** /**
* Wrapper class for ProtocolLib packets. * Wrapper class for ProtocolLib packets.
*
* @deprecated ProtocolLib is no longer used by eco. Use {@link com.willfp.eco.core.packet.PacketListener} instead.
*/ */
@Deprecated(since = "6.51.0")
public abstract class AbstractPacketAdapter extends PacketAdapter { public abstract class AbstractPacketAdapter extends PacketAdapter {
/** /**
* The packet type to listen for. * The handle type to listen for.
*/ */
private final PacketType type; private final PacketType type;
/** /**
* Whether the packet adapter should be registered after the server has loaded. * Whether the handle adapter should be registered after the server has loaded.
* <p> * <p>
* Useful for monitor priority adapters that <b>must</b> be ran last. * Useful for monitor priority adapters that <b>must</b> be ran last.
*/ */
private final boolean postLoad; private final boolean postLoad;
/** /**
* Create a new packet adapter for a specified plugin and type. * Create a new handle adapter for a specified plugin and type.
* *
* @param plugin The plugin that ProtocolLib should mark as the owner. * @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for. * @param type The {@link PacketType} to listen for.
* @param priority The priority at which the adapter should be ran on packet send/receive. * @param priority The priority at which the adapter should be ran on handle send/receive.
* @param postLoad If the packet adapter should be registered after the server has loaded. * @param postLoad If the handle adapter should be registered after the server has loaded.
*/ */
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin, protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
@NotNull final PacketType type, @NotNull final PacketType type,
@@ -45,11 +48,11 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Create a new packet adapter for a specified plugin and type. * Create a new handle adapter for a specified plugin and type.
* *
* @param plugin The plugin that ProtocolLib should mark as the owner. * @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for. * @param type The {@link PacketType} to listen for.
* @param postLoad If the packet adapter should be registered after the server has loaded. * @param postLoad If the handle adapter should be registered after the server has loaded.
*/ */
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin, protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
@NotNull final PacketType type, @NotNull final PacketType type,
@@ -58,9 +61,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* The code that should be executed once the packet has been received. * The code that should be executed once the handle has been received.
* *
* @param packet The packet. * @param packet The handle.
* @param player The player. * @param player The player.
* @param event The event. * @param event The event.
*/ */
@@ -71,9 +74,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* THe code that should be executed once the packet has been sent. * THe code that should be executed once the handle has been sent.
* *
* @param packet The packet. * @param packet The handle.
* @param player The player. * @param player The player.
* @param event The event. * @param event The event.
*/ */
@@ -84,7 +87,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Boilerplate to assert that the packet is of the specified type. * Boilerplate to assert that the handle is of the specified type.
* *
* @param event The ProtocolLib event. * @param event The ProtocolLib event.
*/ */
@@ -102,7 +105,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Boilerplate to assert that the packet is of the specified type. * Boilerplate to assert that the handle is of the specified type.
* *
* @param event The ProtocolLib event. * @param event The ProtocolLib event.
*/ */
@@ -125,7 +128,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Register the packet adapter with ProtocolLib. * Register the handle adapter with ProtocolLib.
*/ */
public final void register() { public final void register() {
if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) { if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) {
@@ -134,7 +137,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Get if the packet adapter should be loaded last. * Get if the handle adapter should be loaded last.
* *
* @return If post load. * @return If post load.
*/ */

View File

@@ -13,6 +13,7 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory; import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory; import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader; import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.packet.PacketListener;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
@@ -52,7 +53,7 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will * <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b> * be cancelled.</b>
*/ */
@SuppressWarnings("unused") @SuppressWarnings({"unused", "DeprecatedIsStillUsed"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike { public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The polymart resource ID of the plugin. * The polymart resource ID of the plugin.
@@ -422,13 +423,16 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Prerequisite.update(); Prerequisite.update();
if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
this.loadPacketAdapters().forEach(abstractPacketAdapter -> { this.loadPacketAdapters().forEach(abstractPacketAdapter -> {
if (!abstractPacketAdapter.isPostLoad()) { if (!abstractPacketAdapter.isPostLoad()) {
abstractPacketAdapter.register(); abstractPacketAdapter.register();
} }
}); });
}
this.loadListeners().forEach(listener -> this.getEventManager().registerListener(listener)); this.loadListeners().forEach(listener -> this.getEventManager().registerListener(listener));
this.loadPacketListeners().forEach(listener -> this.getEventManager().registerPacketListener(listener));
this.loadPluginCommands().forEach(PluginCommand::register); this.loadPluginCommands().forEach(PluginCommand::register);
@@ -683,16 +687,27 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/** /**
* ProtocolLib packet adapters to be registered. * ProtocolLib handle adapters to be registered.
* <p> * <p>
* If the plugin does not require ProtocolLib this can be left empty. * If the plugin does not require ProtocolLib this can be left empty.
* *
* @return A list of packet adapters. * @return A list of handle adapters.
* @deprecated Use {@link #loadPacketListeners()} instead.
*/ */
@Deprecated(since = "6.51.0")
protected List<AbstractPacketAdapter> loadPacketAdapters() { protected List<AbstractPacketAdapter> loadPacketAdapters() {
return new ArrayList<>(); return new ArrayList<>();
} }
/**
* Packet Listeners to be registered.
*
* @return A list of handle listeners.
*/
protected List<PacketListener> loadPacketListeners() {
return new ArrayList<>();
}
/** /**
* All listeners to be registered. * All listeners to be registered.
* *

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.events; package com.willfp.eco.core.events;
import com.willfp.eco.core.packet.PacketListener;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,4 +26,11 @@ public interface EventManager {
* Unregister all listeners associated with the plugin. * Unregister all listeners associated with the plugin.
*/ */
void unregisterAllListeners(); void unregisterAllListeners();
/**
* Register a packet listener.
*
* @param listener The listener.
*/
void registerPacketListener(@NotNull PacketListener listener);
} }

View File

@@ -0,0 +1,12 @@
package com.willfp.eco.core.packet;
import org.jetbrains.annotations.NotNull;
/**
* Represents a packet.
*
* @param handle The NMS handle.
*/
public record Packet(@NotNull Object handle) {
}

View File

@@ -0,0 +1,67 @@
package com.willfp.eco.core.packet;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.jetbrains.annotations.NotNull;
/**
* Represents a handle being sent or received.
*/
public class PacketEvent implements Cancellable {
/**
* The handle.
*/
private final Packet packet;
/**
* The player.
*/
private final Player player;
/**
* If the event should be cancelled.
*/
private boolean cancelled = false;
/**
* Create a new handle event.
*
* @param packet The handle.
* @param player The player.
*/
public PacketEvent(@NotNull final Packet packet,
@NotNull final Player player) {
this.packet = packet;
this.player = player;
}
/**
* Get the NMS handle.
*
* @return The handle.
*/
@NotNull
public Packet getPacket() {
return packet;
}
/**
* Get the player.
*
* @return The player.
*/
@NotNull
public Player getPlayer() {
return player;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.packet;
import org.jetbrains.annotations.NotNull;
/**
* Listens to packets.
*/
public interface PacketListener {
/**
* Called when a handle is sent.
*
* @param event The event.
*/
default void onSend(@NotNull final PacketEvent event) {
// Override when needed.
}
/**
* Called when a handle is received.
*
* @param event The event.
*/
default void onReceive(@NotNull final PacketEvent event) {
// Override when needed.
}
/**
* Get the priority of the listener.
*
* @return The priority.
*/
default PacketPriority getPriority() {
return PacketPriority.NORMAL;
}
}

View File

@@ -0,0 +1,31 @@
package com.willfp.eco.core.packet;
/**
* The priority (order) of packet listeners.
*/
public enum PacketPriority {
/**
* Ran first.
*/
LOWEST,
/**
* Ran second.
*/
LOW,
/**
* Ran third.
*/
NORMAL,
/**
* Ran fourth.
*/
HIGH,
/**
* Ran last.
*/
HIGHEST
}

View File

@@ -2,11 +2,38 @@ package com.willfp.eco.internal.events
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.events.EventManager import com.willfp.eco.core.events.EventManager
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.core.packet.PacketPriority
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList
import org.bukkit.event.Listener import org.bukkit.event.Listener
class EcoEventManager (private val plugin: EcoPlugin) : EventManager {
private class RegisteredPacketListener(
val plugin: EcoPlugin,
val listener: PacketListener
)
private val listeners = mutableMapOf<PacketPriority, MutableList<RegisteredPacketListener>>()
fun PacketEvent.handleSend() {
for (priority in PacketPriority.values()) {
for (listener in listeners[priority] ?: continue) {
listener.listener.onSend(this)
}
}
}
fun PacketEvent.handleReceive() {
for (priority in PacketPriority.values()) {
for (listener in listeners[priority] ?: continue) {
listener.listener.onReceive(this)
}
}
}
class EcoEventManager(private val plugin: EcoPlugin) : EventManager {
override fun registerListener(listener: Listener) { override fun registerListener(listener: Listener) {
Bukkit.getPluginManager().registerEvents(listener, plugin) Bukkit.getPluginManager().registerEvents(listener, plugin)
} }
@@ -17,5 +44,17 @@ class EcoEventManager (private val plugin: EcoPlugin) : EventManager {
override fun unregisterAllListeners() { override fun unregisterAllListeners() {
HandlerList.unregisterAll(plugin) HandlerList.unregisterAll(plugin)
for (value in listeners.values) {
value.removeIf { it.plugin == plugin }
}
}
override fun registerPacketListener(listener: PacketListener) {
listeners.getOrPut(listener.priority) { mutableListOf() }.add(
RegisteredPacketListener(
plugin,
listener
)
)
} }
} }

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.internal.spigot.proxy.common.packet
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.internal.events.handleReceive
import com.willfp.eco.internal.events.handleSend
import io.netty.channel.ChannelDuplexHandler
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.ChannelPromise
import org.bukkit.Bukkit
import java.util.UUID
class EcoChannelDuplexHandler(
private val uuid: UUID
) : ChannelDuplexHandler() {
override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
val player = Bukkit.getPlayer(uuid)
if (player != null) {
val event = PacketEvent(Packet(msg), player)
event.handleReceive()
if (!event.isCancelled) {
super.channelRead(ctx, msg)
}
} else {
super.channelRead(ctx, msg)
}
}
override fun write(ctx: ChannelHandlerContext, msg: Any, promise: ChannelPromise) {
val player = Bukkit.getPlayer(uuid)
if (player != null) {
val event = PacketEvent(Packet(msg), player)
event.handleSend()
if (!event.isCancelled) {
super.channelRead(ctx, msg)
}
} else {
super.write(ctx, msg, promise)
}
}
}

View File

@@ -0,0 +1,32 @@
package com.willfp.eco.internal.spigot.proxy.common.packet.display
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class PacketAutoRecipe(
private val plugin: EcoPlugin
) : PacketListener {
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundPlaceGhostRecipePacket ?: return
if (!plugin.configYml.getBool("displayed-recipes")) {
return
}
if (!EcoPlugin.getPluginNames().contains(packet.recipe.namespace)) {
return
}
if (packet.recipe.path.contains("_displayed")) {
return
}
val fKey = packet.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[packet] as ResourceLocation
fKey[packet] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.internal.spigot.proxy.common.packet.display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket
object PacketHeldItemSlot : PacketListener {
override fun onReceive(event: PacketEvent) {
if (event.packet.handle !is ServerboundSetCarriedItemPacket) {
return
}
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.common.packet.display
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.asNMSStack
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
object PacketOpenWindowMerchant : PacketListener {
private val field = ClientboundMerchantOffersPacket::class.java.getDeclaredField("b").apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundMerchantOffersPacket ?: return
val offers = mutableListOf<MerchantOffer>()
for (offer in packet.offers) {
val nbt = offer.createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(nms.asBukkitStack(), event.player)
val itemNBT = displayed.asNMSStack().save(CompoundTag())
nbt.put(tag, itemNBT)
}
offers += MerchantOffer(nbt)
}
field.set(packet, offers)
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.internal.spigot.proxy.common.packet.display
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
object PacketSetCreativeSlot : PacketListener {
override fun onReceive(event: PacketEvent) {
val packet = event.packet.handle as? ServerboundSetCreativeModeSlotPacket ?: return
Display.revert(packet.item.asBukkitStack())
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.internal.spigot.proxy.common.packet.display
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket
object PacketSetSlot : PacketListener {
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundContainerSetSlotPacket ?: return
Display.display(packet.item.asBukkitStack(), event.player)
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -1,39 +1,37 @@
package com.willfp.eco.internal.spigot.display package com.willfp.eco.internal.spigot.proxy.common.packet.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.EcoPlugin
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.core.items.HashedItem import com.willfp.eco.core.items.HashedItem
import com.willfp.eco.internal.spigot.display.frame.DisplayFrame import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.WINDOW_ITEMS, false) { class PacketWindowItems(
private val lastKnownWindowIDs = ConcurrentHashMap<String, Int>() private val plugin: EcoPlugin
) : PacketListener {
private val lastKnownWindowIDs = ConcurrentHashMap<UUID, Int>()
override fun onSend( private val field = ClientboundContainerSetContentPacket::class.java.getDeclaredField("c")
packet: PacketContainer, .apply { isAccessible = true }
player: Player,
event: PacketEvent
) {
packet.itemModifier.modify(0) {
Display.display(
it, player
)
}
val windowId = packet.integers.read(0) override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundContainerSetContentPacket ?: return
val player = event.player
// Using name because UUID is unreliable with ProtocolLib players. Display.display(packet.carriedItem.asBukkitStack(), player)
val name = player.name
val lastKnownID = lastKnownWindowIDs[name] val windowId = packet.containerId
lastKnownWindowIDs[name] = windowId
val lastKnownID = lastKnownWindowIDs[player.uniqueId]
lastKnownWindowIDs[player.uniqueId] = windowId
// If there is any change in window ID at any point, // If there is any change in window ID at any point,
// Remove the last display frame to prevent any potential conflicts. // Remove the last display frame to prevent any potential conflicts.
@@ -43,17 +41,20 @@ class PacketWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, Packe
player.lastDisplayFrame = DisplayFrame.EMPTY player.lastDisplayFrame = DisplayFrame.EMPTY
} }
val itemStacks = packet.itemListModifier.read(0) ?: return val itemStacks = packet.items.map { it.asBukkitStack() }
packet.itemListModifier.write(0, modifyWindowItems(itemStacks, windowId, player)) val newItems = modifyWindowItems(itemStacks.toMutableList(), windowId, player)
field.set(packet, newItems)
} }
private fun modifyWindowItems( private fun modifyWindowItems(
itemStacks: MutableList<ItemStack>, itemStacks: MutableList<ItemStack>,
windowId: Int, windowId: Int,
player: Player player: Player
): MutableList<ItemStack> { ): MutableList<ItemStack> {
if (this.getPlugin().configYml.getBool("use-display-frame") && windowId == 0) { if (plugin.configYml.getBool("use-display-frame") && windowId == 0) {
val frameMap = mutableMapOf<Byte, HashedItem>() val frameMap = mutableMapOf<Byte, HashedItem>()
for (index in itemStacks.indices) { for (index in itemStacks.indices) {

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.internal.spigot.display.frame package com.willfp.eco.internal.spigot.proxy.common.packet.display.frame
import com.comphenix.protocol.injector.temporary.TemporaryPlayer
import com.willfp.eco.core.items.HashedItem import com.willfp.eco.core.items.HashedItem
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@@ -33,19 +32,9 @@ private val frames = ConcurrentHashMap<UUID, DisplayFrame>()
var Player.lastDisplayFrame: DisplayFrame var Player.lastDisplayFrame: DisplayFrame
get() { get() {
// ProtocolLib fix
if (this is TemporaryPlayer) {
return DisplayFrame.EMPTY
}
return frames[this.uniqueId] ?: DisplayFrame.EMPTY return frames[this.uniqueId] ?: DisplayFrame.EMPTY
} }
set(value) { set(value) {
// ProtocolLib fix
if (this is TemporaryPlayer) {
return
}
frames[this.uniqueId] = value frames[this.uniqueId] = value
} }

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1 package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
@@ -27,7 +28,7 @@ import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
override fun init() { override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl) CommonsProvider.setIfNeeded(CommonsProviderImpl)
} }
@@ -60,7 +61,7 @@ class CommonsInitializer : CommonsInitializerProxy {
} }
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack { override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asBukkitCopy(itemStack) return CraftItemStack.asCraftMirror(itemStack)
} }
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) { override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {

View File

@@ -0,0 +1,68 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.EcoChannelDuplexHandler
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_17_R1.display.PacketChat
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun addPlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
player.handle.connection.connection.channel.pipeline()
.addBefore("eco_packet_handler", player.name, EcoChannelDuplexHandler(player.uniqueId))
}
override fun removePlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
val channel = player.handle.connection.connection.channel
channel.eventLoop().submit {
channel.pipeline().remove(player.name)
}
}
override fun sendPacket(player: Player, packet: Any) {
if (player !is CraftPlayer) {
return
}
if (packet !is Packet<*>) {
return
}
player.handle.connection.send(packet)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin),
PacketChat
)
}
}

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy {
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe {
recipe as CraftMerchantRecipe
val nbt = getHandle(recipe).createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
nbt.put(tag, itemNBT)
}
return CraftMerchantRecipe(MerchantOffer(nbt))
}
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
return handle[recipe] as MerchantOffer
}
init {
handle.isAccessible = true
}
}

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1 package com.willfp.eco.internal.spigot.proxy.v1_17_R1.display
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import net.kyori.adventure.nbt.api.BinaryTagHolder import net.kyori.adventure.nbt.api.BinaryTagHolder
import net.kyori.adventure.text.BuildableComponent import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
@@ -9,20 +10,28 @@ import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.event.HoverEvent import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.TagParser import net.minecraft.nbt.TagParser
import net.minecraft.network.protocol.game.ClientboundChatPacket
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@Suppress("UNCHECKED_CAST") object PacketChat : PacketListener {
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson() private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any { private val field = ClientboundChatPacket::class.java.declaredFields
if (obj !is net.minecraft.network.chat.Component) { .first { it.type == net.minecraft.network.chat.Component::class.java }
return obj .apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundChatPacket ?: return
val newMessage = modifyComponent(packet.message, event.player)
field.set(packet, newMessage)
} }
private fun modifyComponent(obj: net.minecraft.network.chat.Component, player: Player): Any {
val component = gsonComponentSerializer.deserialize( val component = gsonComponentSerializer.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson( net.minecraft.network.chat.Component.Serializer.toJson(
obj obj
@@ -53,6 +62,7 @@ class ChatComponent : ChatComponentProxy {
} }
component = component.children(children) component = component.children(children)
@Suppress("UNCHECKED_CAST")
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
val showItem = hoverEvent.value() val showItem = hoverEvent.value()

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1 package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
@@ -27,7 +28,7 @@ import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
override fun init() { override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl) CommonsProvider.setIfNeeded(CommonsProviderImpl)
} }
@@ -60,7 +61,7 @@ class CommonsInitializer : CommonsInitializerProxy {
} }
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack { override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asBukkitCopy(itemStack) return CraftItemStack.asCraftMirror(itemStack)
} }
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) { override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {

View File

@@ -0,0 +1,68 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.EcoChannelDuplexHandler
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_18_R1.display.PacketChat
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler: PacketHandlerProxy {
override fun addPlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
player.handle.connection.connection.channel.pipeline()
.addBefore("eco_packet_handler", player.name, EcoChannelDuplexHandler(player.uniqueId))
}
override fun removePlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
val channel = player.handle.connection.connection.channel
channel.eventLoop().submit {
channel.pipeline().remove(player.name)
}
}
override fun sendPacket(player: Player, packet: Any) {
if (player !is CraftPlayer) {
return
}
if (packet !is Packet<*>) {
return
}
player.handle.connection.send(packet)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin),
PacketChat
)
}
}

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy {
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe {
recipe as CraftMerchantRecipe
val nbt = getHandle(recipe).createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
nbt.put(tag, itemNBT)
}
return CraftMerchantRecipe(MerchantOffer(nbt))
}
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
return handle[recipe] as MerchantOffer
}
init {
handle.isAccessible = true
}
}

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1 package com.willfp.eco.internal.spigot.proxy.v1_18_R1.display
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import net.kyori.adventure.nbt.api.BinaryTagHolder import net.kyori.adventure.nbt.api.BinaryTagHolder
import net.kyori.adventure.text.BuildableComponent import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
@@ -9,20 +10,28 @@ import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.event.HoverEvent import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.TagParser import net.minecraft.nbt.TagParser
import net.minecraft.network.protocol.game.ClientboundChatPacket
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@Suppress("UNCHECKED_CAST") object PacketChat : PacketListener {
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson() private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any { private val field = ClientboundChatPacket::class.java.declaredFields
if (obj !is net.minecraft.network.chat.Component) { .first { it.type == net.minecraft.network.chat.Component::class.java }
return obj .apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundChatPacket ?: return
val newMessage = modifyComponent(packet.message, event.player)
field.set(packet, newMessage)
} }
private fun modifyComponent(obj: net.minecraft.network.chat.Component, player: Player): Any {
val component = gsonComponentSerializer.deserialize( val component = gsonComponentSerializer.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson( net.minecraft.network.chat.Component.Serializer.toJson(
obj obj
@@ -53,6 +62,7 @@ class ChatComponent : ChatComponentProxy {
} }
component = component.children(children) component = component.children(children)
@Suppress("UNCHECKED_CAST")
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
val showItem = hoverEvent.value() val showItem = hoverEvent.value()

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2 package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
@@ -27,7 +28,7 @@ import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
override fun init() { override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl) CommonsProvider.setIfNeeded(CommonsProviderImpl)
} }
@@ -60,7 +61,7 @@ class CommonsInitializer : CommonsInitializerProxy {
} }
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack { override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asBukkitCopy(itemStack) return CraftItemStack.asCraftMirror(itemStack)
} }
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) { override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {

View File

@@ -0,0 +1,68 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.EcoChannelDuplexHandler
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_18_R2.display.PacketChat
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler: PacketHandlerProxy {
override fun addPlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
player.handle.connection.connection.channel.pipeline()
.addBefore("eco_packet_handler", player.name, EcoChannelDuplexHandler(player.uniqueId))
}
override fun removePlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
val channel = player.handle.connection.connection.channel
channel.eventLoop().submit {
channel.pipeline().remove(player.name)
}
}
override fun sendPacket(player: Player, packet: Any) {
if (player !is CraftPlayer) {
return
}
if (packet !is Packet<*>) {
return
}
player.handle.connection.send(packet)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin),
PacketChat
)
}
}

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy {
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe {
recipe as CraftMerchantRecipe
val nbt = getHandle(recipe).createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
nbt.put(tag, itemNBT)
}
return CraftMerchantRecipe(MerchantOffer(nbt))
}
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
return handle[recipe] as MerchantOffer
}
init {
handle.isAccessible = true
}
}

View File

@@ -1,7 +1,8 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2 package com.willfp.eco.internal.spigot.proxy.v1_18_R2.display
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import net.kyori.adventure.nbt.api.BinaryTagHolder import net.kyori.adventure.nbt.api.BinaryTagHolder
import net.kyori.adventure.text.BuildableComponent import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
@@ -9,20 +10,28 @@ import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.event.HoverEvent import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.TagParser import net.minecraft.nbt.TagParser
import net.minecraft.network.protocol.game.ClientboundChatPacket
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@Suppress("UNCHECKED_CAST") object PacketChat : PacketListener {
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson() private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any { private val field = ClientboundChatPacket::class.java.declaredFields
if (obj !is net.minecraft.network.chat.Component) { .first { it.type == net.minecraft.network.chat.Component::class.java }
return obj .apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundChatPacket ?: return
val newMessage = modifyComponent(packet.message, event.player)
field.set(packet, newMessage)
} }
private fun modifyComponent(obj: net.minecraft.network.chat.Component, player: Player): Any {
val component = gsonComponentSerializer.deserialize( val component = gsonComponentSerializer.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson( net.minecraft.network.chat.Component.Serializer.toJson(
obj obj
@@ -53,6 +62,7 @@ class ChatComponent : ChatComponentProxy {
} }
component = component.children(children) component = component.children(children)
@Suppress("UNCHECKED_CAST")
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
val showItem = hoverEvent.value() val showItem = hoverEvent.value()
@@ -62,7 +72,8 @@ class ChatComponent : ChatComponentProxy {
} }
val newShowItem = showItem.nbt( val newShowItem = showItem.nbt(
BinaryTagHolder.binaryTagHolder( @Suppress("UnstableApiUsage", "DEPRECATION")
BinaryTagHolder.of(
CraftItemStack.asNMSCopy( CraftItemStack.asNMSCopy(
Display.display( Display.display(
CraftItemStack.asBukkitCopy( CraftItemStack.asBukkitCopy(

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -1,93 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy
import net.kyori.adventure.nbt.api.BinaryTagHolder
import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.TagParser
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
@Suppress("UNCHECKED_CAST")
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any {
if (obj !is net.minecraft.network.chat.Component) {
return obj
}
val component = gsonComponentSerializer.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson(
obj
)
).asComponent() as BuildableComponent<*, *>
val newComponent = modifyBaseComponent(component, player)
return net.minecraft.network.chat.Component.Serializer.fromJson(
gsonComponentSerializer.serialize(newComponent.asComponent())
) ?: obj
}
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
var component = baseComponent
if (component is TranslatableComponent) {
val args = mutableListOf<Component>()
for (arg in component.args()) {
args.add(modifyBaseComponent(arg, player))
}
component = component.args(args)
}
val children = mutableListOf<Component>()
for (child in component.children()) {
children.add(modifyBaseComponent(child, player))
}
component = component.children(children)
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
val showItem = hoverEvent.value()
if (showItem !is HoverEvent.ShowItem) {
return component
}
val newShowItem = showItem.nbt(
BinaryTagHolder.binaryTagHolder(
CraftItemStack.asNMSCopy(
Display.display(
CraftItemStack.asBukkitCopy(
CraftItemStack.asNMSCopy(
ItemStack(
Material.matchMaterial(
showItem.item()
.toString()
) ?: return component,
showItem.count()
)
).apply {
this.tag = TagParser.parseTag(
showItem.nbt()?.string() ?: return component
) ?: return component
}
),
player
)
).orCreateTag.toString()
)
)
val newHover = hoverEvent.value(newShowItem)
val style = component.style().hoverEvent(newHover)
return component.style(style)
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1 package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
@@ -27,7 +28,7 @@ import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
override fun init() { override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl) CommonsProvider.setIfNeeded(CommonsProviderImpl)
} }
@@ -60,7 +61,7 @@ class CommonsInitializer : CommonsInitializerProxy {
} }
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack { override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asBukkitCopy(itemStack) return CraftItemStack.asCraftMirror(itemStack)
} }
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) { override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {

View File

@@ -0,0 +1,66 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.EcoChannelDuplexHandler
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler: PacketHandlerProxy {
override fun addPlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
player.handle.connection.connection.channel.pipeline()
.addBefore("eco_packet_handler", player.name, EcoChannelDuplexHandler(player.uniqueId))
}
override fun removePlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
val channel = player.handle.connection.connection.channel
channel.eventLoop().submit {
channel.pipeline().remove(player.name)
}
}
override fun sendPacket(player: Player, packet: Any) {
if (player !is CraftPlayer) {
return
}
if (packet !is Packet<*>) {
return
}
player.handle.connection.send(packet)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin)
)
}
}

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy {
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe {
recipe as CraftMerchantRecipe
val nbt = getHandle(recipe).createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
nbt.put(tag, itemNBT)
}
return CraftMerchantRecipe(MerchantOffer(nbt))
}
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
return handle[recipe] as MerchantOffer
}
init {
handle.isAccessible = true
}
}

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy
import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket
import net.minecraft.resources.ResourceLocation
class AutoCraft : AutoCraftProxy {
override fun modifyPacket(packet: Any) {
val recipePacket = packet as ClientboundPlaceGhostRecipePacket
val fKey = recipePacket.javaClass.getDeclaredField("b")
fKey.isAccessible = true
val key = fKey[recipePacket] as ResourceLocation
fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed")
}
}

View File

@@ -1,93 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy
import net.kyori.adventure.nbt.api.BinaryTagHolder
import net.kyori.adventure.text.BuildableComponent
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.TagParser
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
@Suppress("UNCHECKED_CAST")
class ChatComponent : ChatComponentProxy {
private val gsonComponentSerializer = GsonComponentSerializer.gson()
override fun modifyComponent(obj: Any, player: Player): Any {
if (obj !is net.minecraft.network.chat.Component) {
return obj
}
val component = gsonComponentSerializer.deserialize(
net.minecraft.network.chat.Component.Serializer.toJson(
obj
)
).asComponent() as BuildableComponent<*, *>
val newComponent = modifyBaseComponent(component, player)
return net.minecraft.network.chat.Component.Serializer.fromJson(
gsonComponentSerializer.serialize(newComponent.asComponent())
) ?: obj
}
private fun modifyBaseComponent(baseComponent: Component, player: Player): Component {
var component = baseComponent
if (component is TranslatableComponent) {
val args = mutableListOf<Component>()
for (arg in component.args()) {
args.add(modifyBaseComponent(arg, player))
}
component = component.args(args)
}
val children = mutableListOf<Component>()
for (child in component.children()) {
children.add(modifyBaseComponent(child, player))
}
component = component.children(children)
val hoverEvent: HoverEvent<Any> = component.style().hoverEvent() as HoverEvent<Any>? ?: return component
val showItem = hoverEvent.value()
if (showItem !is HoverEvent.ShowItem) {
return component
}
val newShowItem = showItem.nbt(
BinaryTagHolder.binaryTagHolder(
CraftItemStack.asNMSCopy(
Display.display(
CraftItemStack.asBukkitCopy(
CraftItemStack.asNMSCopy(
ItemStack(
Material.matchMaterial(
showItem.item()
.toString()
) ?: return component,
showItem.count()
)
).apply {
this.tag = TagParser.parseTag(
showItem.nbt()?.string() ?: return component
) ?: return component
}
),
player
)
).orCreateTag.toString()
)
)
val newHover = hoverEvent.value(newShowItem)
val style = component.style().hoverEvent(newHover)
return component.style(style)
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2 package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
@@ -27,7 +28,7 @@ import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
override fun init() { override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl) CommonsProvider.setIfNeeded(CommonsProviderImpl)
} }
@@ -60,7 +61,7 @@ class CommonsInitializer : CommonsInitializerProxy {
} }
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack { override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asBukkitCopy(itemStack) return CraftItemStack.asCraftMirror(itemStack)
} }
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) { override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {

View File

@@ -0,0 +1,66 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.EcoChannelDuplexHandler
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun addPlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
player.handle.connection.connection.channel.pipeline()
.addBefore("eco_packet_handler", player.name, EcoChannelDuplexHandler(player.uniqueId))
}
override fun removePlayer(player: Player) {
if (player !is CraftPlayer) {
return
}
val channel = player.handle.connection.connection.channel
channel.eventLoop().submit {
channel.pipeline().remove(player.name)
}
}
override fun sendPacket(player: Player, packet: Any) {
if (player !is CraftPlayer) {
return
}
if (packet !is Packet<*>) {
return
}
player.handle.connection.send(packet)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin)
)
}
}

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy {
private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe {
recipe as CraftMerchantRecipe
val nbt = getHandle(recipe).createTag()
for (tag in arrayOf("buy", "buyB", "sell")) {
val nms = ItemStack.of(nbt.getCompound(tag))
val displayed = Display.display(CraftItemStack.asBukkitCopy(nms), player)
val itemNBT = CraftItemStack.asNMSCopy(displayed).save(CompoundTag())
nbt.put(tag, itemNBT)
}
return CraftMerchantRecipe(MerchantOffer(nbt))
}
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
return handle[recipe] as MerchantOffer
}
init {
handle.isAccessible = true
}
}

View File

@@ -6,7 +6,6 @@ import com.willfp.eco.core.PluginLike
import com.willfp.eco.core.PluginProps import com.willfp.eco.core.PluginProps
import com.willfp.eco.core.command.CommandBase import com.willfp.eco.core.command.CommandBase
import com.willfp.eco.core.command.PluginCommandBase import com.willfp.eco.core.command.PluginCommandBase
import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.data.keys.PersistentDataKey import com.willfp.eco.core.data.keys.PersistentDataKey
@@ -55,7 +54,6 @@ import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.TPSProxy import com.willfp.eco.internal.spigot.proxy.TPSProxy
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.command.CommandMap
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.entity.Entity import org.bukkit.entity.Entity
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
@@ -78,7 +76,7 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
) )
init { init {
getProxy(CommonsInitializerProxy::class.java).init() getProxy(CommonsInitializerProxy::class.java).init(this)
} }
@Suppress("RedundantNullableReturnType") @Suppress("RedundantNullableReturnType")

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.internal.spigot package com.willfp.eco.internal.spigot
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.Eco import com.willfp.eco.core.Eco
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.Prerequisite import com.willfp.eco.core.Prerequisite
@@ -17,6 +16,7 @@ import com.willfp.eco.core.integrations.mcmmo.McmmoManager
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
import com.willfp.eco.core.integrations.shop.ShopManager import com.willfp.eco.core.integrations.shop.ShopManager
import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.Items
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.core.particle.Particles import com.willfp.eco.core.particle.Particles
import com.willfp.eco.core.price.Prices import com.willfp.eco.core.price.Prices
import com.willfp.eco.internal.entities.EntityArgParserAdult import com.willfp.eco.internal.entities.EntityArgParserAdult
@@ -57,14 +57,6 @@ import com.willfp.eco.internal.spigot.data.DataYml
import com.willfp.eco.internal.spigot.data.PlayerBlockListener import com.willfp.eco.internal.spigot.data.PlayerBlockListener
import com.willfp.eco.internal.spigot.data.ProfileHandler import com.willfp.eco.internal.spigot.data.ProfileHandler
import com.willfp.eco.internal.spigot.data.storage.ProfileSaver 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.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
import com.willfp.eco.internal.spigot.display.PacketWindowItems
import com.willfp.eco.internal.spigot.display.frame.clearFrames
import com.willfp.eco.internal.spigot.drops.CollatedRunnable import com.willfp.eco.internal.spigot.drops.CollatedRunnable
import com.willfp.eco.internal.spigot.eventlisteners.EntityDeathByEntityListeners import com.willfp.eco.internal.spigot.eventlisteners.EntityDeathByEntityListeners
import com.willfp.eco.internal.spigot.eventlisteners.NaturalExpGainListenersPaper import com.willfp.eco.internal.spigot.eventlisteners.NaturalExpGainListenersPaper
@@ -120,7 +112,9 @@ import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop
import com.willfp.eco.internal.spigot.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.recipes.CraftingRecipeListener import com.willfp.eco.internal.spigot.recipes.CraftingRecipeListener
import com.willfp.eco.internal.spigot.recipes.StackedRecipeListener import com.willfp.eco.internal.spigot.recipes.StackedRecipeListener
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex
@@ -247,7 +241,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
ProfileSaver(this, profileHandler) ProfileSaver(this, profileHandler)
this.scheduler.runTimer( this.scheduler.runTimer(
{ clearFrames() }, { getProxy(PacketHandlerProxy::class.java).clearDisplayFrames() },
this.configYml.getInt("display-frame-ttl").toLong(), this.configYml.getInt("display-frame-ttl").toLong(),
this.configYml.getInt("display-frame-ttl").toLong() this.configYml.getInt("display-frame-ttl").toLong()
) )
@@ -357,18 +351,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
) )
} }
override fun loadPacketAdapters(): List<AbstractPacketAdapter> {
return listOf(
PacketAutoRecipe(this),
PacketChat(this),
PacketSetCreativeSlot(this),
PacketSetSlot(this),
PacketWindowItems(this),
PacketHeldItemSlot(this),
PacketOpenWindowMerchant(this)
)
}
override fun loadListeners(): List<Listener> { override fun loadListeners(): List<Listener> {
val listeners = mutableListOf( val listeners = mutableListOf(
ArmorListener(), ArmorListener(),
@@ -380,6 +362,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
ArmorChangeEventListeners(this), ArmorChangeEventListeners(this),
DataListener(this), DataListener(this),
PlayerBlockListener(this), PlayerBlockListener(this),
PacketInjectorListener(this),
ServerLocking ServerLocking
) )
@@ -393,4 +376,8 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
return listeners return listeners
} }
override fun loadPacketListeners(): List<PacketListener> {
return this.getProxy(PacketHandlerProxy::class.java).getPacketListeners(this)
}
} }

View File

@@ -1,35 +0,0 @@
package com.willfp.eco.internal.spigot.display
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.ProtocolLibrary
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.proxy.AutoCraftProxy
import org.bukkit.entity.Player
class PacketAutoRecipe(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.AUTO_RECIPE, false) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
if (!this.getPlugin().configYml.getBool("displayed-recipes")) {
return
}
if (!EcoPlugin.getPluginNames()
.contains(packet.minecraftKeys.values[0].fullKey.split(":".toRegex()).toTypedArray()[0])
) {
return
}
if (packet.minecraftKeys.values[0].fullKey.split(":".toRegex()).toTypedArray()[1].contains("displayed")) {
return
}
getPlugin().getProxy(AutoCraftProxy::class.java).modifyPacket(packet.handle)
val newAutoRecipe = PacketContainer(PacketType.Play.Server.AUTO_RECIPE)
newAutoRecipe.minecraftKeys.write(0, packet.minecraftKeys.read(0))
ProtocolLibrary.getProtocolManager().sendServerPacket(player, newAutoRecipe)
}
}

View File

@@ -1,36 +0,0 @@
package com.willfp.eco.internal.spigot.display
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.events.ListenerPriority
import com.comphenix.protocol.events.PacketContainer
import com.comphenix.protocol.events.PacketEvent
import com.comphenix.protocol.wrappers.WrappedChatComponent
import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy
import org.bukkit.entity.Player
class PacketChat(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin,
PacketType.Play.Server.CHAT,
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.HIGHEST,
true) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
for (i in 0 until packet.chatComponents.size()) {
val component = packet.chatComponents.read(i) ?: continue
if (component.handle == null) {
return
}
val newComponent = WrappedChatComponent.fromHandle(
getPlugin().getProxy(
ChatComponentProxy::class.java
).modifyComponent(component.handle, player)
)
packet.chatComponents.write(i, newComponent)
}
}
}

View File

@@ -1,29 +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.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,33 +0,0 @@
package com.willfp.eco.internal.spigot.display
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.events.ListenerPriority
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.proxy.VillagerTradeProxy
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
class PacketOpenWindowMerchant(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin,
PacketType.Play.Server.OPEN_WINDOW_MERCHANT,
if (plugin.configYml.getBool("use-lower-protocollib-priority")) ListenerPriority.NORMAL else ListenerPriority.MONITOR,
true) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
val recipes = mutableListOf<MerchantRecipe>()
for (recipe in packet.merchantRecipeLists.read(0)) {
val newRecipe = getPlugin().getProxy(VillagerTradeProxy::class.java).displayTrade(
recipe!!, player
)
recipes.add(newRecipe)
}
packet.merchantRecipeLists.write(0, recipes)
}
}

View File

@@ -1,29 +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 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 PacketSetCreativeSlot(plugin: EcoPlugin) :
AbstractPacketAdapter(plugin, PacketType.Play.Client.SET_CREATIVE_SLOT, false) {
override fun onReceive(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
packet.itemModifier.modify(0) { itemStack: ItemStack? ->
Display.revert(
itemStack!!
)
}
player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -1,28 +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 com.willfp.eco.internal.spigot.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame
import org.bukkit.entity.Player
class PacketSetSlot(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, PacketType.Play.Server.SET_SLOT, false) {
override fun onSend(
packet: PacketContainer,
player: Player,
event: PacketEvent
) {
packet.itemModifier.modify(0) {
Display.display(
it,
player
)
}
player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.internal.spigot.packet
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
class PacketInjectorListener(
private val plugin: EcoPlugin
) : Listener {
@EventHandler
fun onJoin(event: PlayerJoinEvent) {
plugin.getProxy(PacketHandlerProxy::class.java).addPlayer(event.player)
}
@EventHandler
fun onLeave(event: PlayerQuitEvent) {
plugin.getProxy(PacketHandlerProxy::class.java).addPlayer(event.player)
}
}

View File

@@ -1,5 +0,0 @@
package com.willfp.eco.internal.spigot.proxy
interface AutoCraftProxy {
fun modifyPacket(packet: Any)
}

View File

@@ -1,10 +0,0 @@
package com.willfp.eco.internal.spigot.proxy
import org.bukkit.entity.Player
interface ChatComponentProxy {
fun modifyComponent(
obj: Any,
player: Player
): Any
}

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.internal.spigot.proxy package com.willfp.eco.internal.spigot.proxy
import com.willfp.eco.core.EcoPlugin
interface CommonsInitializerProxy { interface CommonsInitializerProxy {
fun init() fun init(plugin: EcoPlugin)
} }

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.internal.spigot.proxy
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import org.bukkit.entity.Player
interface PacketHandlerProxy {
fun addPlayer(player: Player)
fun removePlayer(player: Player)
fun sendPacket(player: Player, packet: Any)
fun clearDisplayFrames()
fun getPacketListeners(plugin: EcoPlugin): List<PacketListener>
}

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.internal.spigot.proxy
import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe
interface VillagerTradeProxy {
fun displayTrade(
recipe: MerchantRecipe,
player: Player
): MerchantRecipe
}