Changed the packet listener api, allowing for listener override

This commit is contained in:
Felix Cravic 2020-05-24 17:11:21 +02:00
parent 883e7eb80f
commit b8f2afa4c3
10 changed files with 77 additions and 21 deletions

View File

@ -106,10 +106,9 @@ public class PlayerInit {
} }
}, new UpdateOption(5, TimeUnit.TICK)); }, new UpdateOption(5, TimeUnit.TICK));
connectionManager.addPacketConsumer((player, packet) -> { connectionManager.addPacketConsumer((player, packetController, packet) -> {
// Listen to all received packet // Listen to all received packet
// Returning true means cancelling the packet packetController.setCancel(false);
return false;
}); });
connectionManager.addPlayerInitialization(player -> { connectionManager.addPlayerInitialization(player -> {

View File

@ -12,7 +12,8 @@ public class AnimationListener {
player.callCancellableEvent(AnimationEvent.class, animationEvent, () -> { player.callCancellableEvent(AnimationEvent.class, animationEvent, () -> {
EntityAnimationPacket entityAnimationPacket = new EntityAnimationPacket(); EntityAnimationPacket entityAnimationPacket = new EntityAnimationPacket();
entityAnimationPacket.entityId = player.getEntityId(); entityAnimationPacket.entityId = player.getEntityId();
entityAnimationPacket.animation = animationEvent.getHand() == Player.Hand.MAIN ? EntityAnimationPacket.Animation.SWING_MAIN_ARM : EntityAnimationPacket.Animation.SWING_OFF_HAND; entityAnimationPacket.animation = animationEvent.getHand() == Player.Hand.MAIN ?
EntityAnimationPacket.Animation.SWING_MAIN_ARM : EntityAnimationPacket.Animation.SWING_OFF_HAND;
player.sendPacketToViewers(entityAnimationPacket); player.sendPacketToViewers(entityAnimationPacket);
}); });
} }

View File

@ -16,5 +16,4 @@ public class KeepAliveListener {
int latency = (int) (System.currentTimeMillis() - packet.id); int latency = (int) (System.currentTimeMillis() - packet.id);
player.refreshLatency(latency); player.refreshLatency(latency);
} }
} }

View File

@ -115,8 +115,10 @@ public class PlayerDiggingListener {
case SWAP_ITEM_HAND: case SWAP_ITEM_HAND:
PlayerSwapItemEvent swapItemEvent = new PlayerSwapItemEvent(offHand.clone(), mainHand.clone()); PlayerSwapItemEvent swapItemEvent = new PlayerSwapItemEvent(offHand.clone(), mainHand.clone());
player.callCancellableEvent(PlayerSwapItemEvent.class, swapItemEvent, () -> { player.callCancellableEvent(PlayerSwapItemEvent.class, swapItemEvent, () -> {
playerInventory.setItemInMainHand(swapItemEvent.getMainHandItem()); synchronized (playerInventory) {
playerInventory.setItemInOffHand(swapItemEvent.getOffHandItem()); playerInventory.setItemInMainHand(swapItemEvent.getMainHandItem());
playerInventory.setItemInOffHand(swapItemEvent.getOffHandItem());
}
}); });
break; break;
} }

View File

@ -14,6 +14,11 @@ public class UseEntityListener {
if (entity == null) if (entity == null)
return; return;
ClientInteractEntityPacket.Type type = packet.type; ClientInteractEntityPacket.Type type = packet.type;
// Player cannot interact entities that he cannot see
if (!entity.isViewer(player))
return;
if (type == ClientInteractEntityPacket.Type.ATTACK) { if (type == ClientInteractEntityPacket.Type.ATTACK) {
if (entity instanceof LivingEntity && ((LivingEntity) entity).isDead()) // Can't attack dead entities if (entity instanceof LivingEntity && ((LivingEntity) entity).isDead()) // Can't attack dead entities
return; return;

View File

@ -21,6 +21,7 @@ public class UseItemListener {
Material material = Material.fromId(itemStack.getMaterialId()); Material material = Material.fromId(itemStack.getMaterialId());
// Equip armor with right click
if (material.isArmor()) { if (material.isArmor()) {
PlayerInventory playerInventory = player.getInventory(); PlayerInventory playerInventory = player.getInventory();
if (useItemEvent.isCancelled()) { if (useItemEvent.isCancelled()) {

View File

@ -1,10 +1,10 @@
package net.minestom.server.listener.manager; package net.minestom.server.listener.manager;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.client.ClientPacket; import net.minestom.server.network.packet.client.ClientPlayPacket;
@FunctionalInterface @FunctionalInterface
public interface PacketConsumer { public interface PacketConsumer {
// Cancel the packet if return true // Cancel the packet if return true
boolean accept(Player player, ClientPacket packet); void accept(Player player, PacketController packetController, ClientPlayPacket packet);
} }

View File

@ -0,0 +1,33 @@
package net.minestom.server.listener.manager;
public class PacketController {
private boolean cancel;
private PacketListenerConsumer packetListenerConsumer;
protected PacketController(PacketListenerConsumer packetListenerConsumer) {
this.packetListenerConsumer = packetListenerConsumer;
}
public boolean isCancel() {
return cancel;
}
/**
* @param cancel true if the packet should be cancelled
*/
public void setCancel(boolean cancel) {
this.cancel = cancel;
}
public PacketListenerConsumer getPacketListenerConsumer() {
return packetListenerConsumer;
}
/**
* @param packetListenerConsumer the new listener (do not override the default listener)
*/
public void setPacketListenerConsumer(PacketListenerConsumer packetListenerConsumer) {
this.packetListenerConsumer = packetListenerConsumer;
}
}

View File

@ -0,0 +1,9 @@
package net.minestom.server.listener.manager;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.client.ClientPlayPacket;
@FunctionalInterface
public interface PacketListenerConsumer<T extends ClientPlayPacket> {
void accept(T packet, Player player);
}

View File

@ -9,13 +9,12 @@ import net.minestom.server.network.packet.client.play.*;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
public class PacketListenerManager { public class PacketListenerManager {
private static ConnectionManager connectionManager = MinecraftServer.getConnectionManager(); private static ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
private Map<Class<? extends ClientPlayPacket>, BiConsumer<? extends ClientPlayPacket, Player>> listeners = new ConcurrentHashMap<>(); private Map<Class<? extends ClientPlayPacket>, PacketListenerConsumer> listeners = new ConcurrentHashMap<>();
public PacketListenerManager() { public PacketListenerManager() {
addListener(ClientKeepAlivePacket.class, KeepAliveListener::listener); addListener(ClientKeepAlivePacket.class, KeepAliveListener::listener);
@ -46,22 +45,30 @@ public class PacketListenerManager {
public <T extends ClientPlayPacket> void process(T packet, Player player) { public <T extends ClientPlayPacket> void process(T packet, Player player) {
boolean cancel = false; PacketListenerConsumer<T> packetListenerConsumer = listeners.get(packet.getClass());
for (PacketConsumer packetConsumer : connectionManager.getPacketConsumers()) {
cancel = packetConsumer.accept(player, packet); // Listener can be null if none has been set before, call PacketConsumer anyway
if (packetListenerConsumer == null) {
System.err.println("Packet " + packet.getClass() + " does not have any listener!");
} }
if (cancel)
PacketController packetController = new PacketController(packetListenerConsumer);
for (PacketConsumer packetConsumer : connectionManager.getPacketConsumers()) {
packetConsumer.accept(player, packetController, packet);
}
if (packetController.isCancel())
return; return;
BiConsumer<T, Player> biConsumer = (BiConsumer<T, Player>) listeners.get(packet.getClass()); // Call the listener if not null
if (biConsumer == null) { // (can be null because no listener is set, or because it has been changed by the controller)
System.err.println("Packet " + packet.getClass() + " does not have any listener!"); if (packetListenerConsumer != null) {
return; packetListenerConsumer.accept(packet, player);
} }
biConsumer.accept(packet, player);
} }
public <T extends ClientPlayPacket> void addListener(Class<T> packetClass, BiConsumer<T, Player> consumer) { public <T extends ClientPlayPacket> void addListener(Class<T> packetClass, PacketListenerConsumer<T> consumer) {
this.listeners.put(packetClass, consumer); this.listeners.put(packetClass, consumer);
} }