mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 21:26:17 +01:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
18d0193288
@ -126,9 +126,9 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
|||||||
private PacketEvent finalEvent;
|
private PacketEvent finalEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag set by the main thread to indiciate that a packet should not be processed.
|
* A queue of packets that were sent with filtered=false
|
||||||
*/
|
*/
|
||||||
private final ThreadLocal<Boolean> scheduleProcessPackets = ThreadLocal.withInitial(() -> true);
|
private final PacketFilterQueue unfilteredProcessedPackets = new PacketFilterQueue();
|
||||||
|
|
||||||
// Other handlers
|
// Other handlers
|
||||||
private ByteToMessageDecoder vanillaDecoder;
|
private ByteToMessageDecoder vanillaDecoder;
|
||||||
@ -328,7 +328,7 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
|||||||
Object original = accessor.get(instance);
|
Object original = accessor.get(instance);
|
||||||
|
|
||||||
// See if we've been instructed not to process packets
|
// See if we've been instructed not to process packets
|
||||||
if (!scheduleProcessPackets.get()) {
|
if (unfilteredProcessedPackets.contains(original)) {
|
||||||
NetworkMarker marker = getMarker(original);
|
NetworkMarker marker = getMarker(original);
|
||||||
|
|
||||||
if (marker != null) {
|
if (marker != null) {
|
||||||
@ -416,7 +416,7 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Skip every kind of non-filtered packet
|
// Skip every kind of non-filtered packet
|
||||||
if (!scheduleProcessPackets.get()) {
|
if (unfilteredProcessedPackets.remove(packet)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,12 +663,11 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
|||||||
public void sendServerPacket(Object packet, NetworkMarker marker, boolean filtered) {
|
public void sendServerPacket(Object packet, NetworkMarker marker, boolean filtered) {
|
||||||
saveMarker(packet, marker);
|
saveMarker(packet, marker);
|
||||||
|
|
||||||
try {
|
if (!filtered) {
|
||||||
scheduleProcessPackets.set(filtered);
|
unfilteredProcessedPackets.add(packet);
|
||||||
invokeSendPacket(packet);
|
|
||||||
} finally {
|
|
||||||
scheduleProcessPackets.set(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invokeSendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
|
* Copyright (C) 2015 dmulloy2
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.comphenix.protocol.injector.netty;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores packets that need to be sent without being handled by the listeners (filtered=false).
|
||||||
|
* When other packets sent after sending the packet are removed, the packet is removed as well
|
||||||
|
* to prevent a memory leak, assuming a consistent send order is in place.
|
||||||
|
*
|
||||||
|
* @author bergerkiller
|
||||||
|
*/
|
||||||
|
public class PacketFilterQueue {
|
||||||
|
private Queue<Object> queue = new ArrayDeque<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a packet to this queue, indicating further on that it should not be filtered.
|
||||||
|
*
|
||||||
|
* @param packet
|
||||||
|
*/
|
||||||
|
public synchronized void add(Object packet) {
|
||||||
|
queue.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a packet is contained inside this queue, indicating
|
||||||
|
* it should not be filtered.
|
||||||
|
*
|
||||||
|
* @param packet
|
||||||
|
* @return True if contained and packet should not be filtered (filtered=false)
|
||||||
|
*/
|
||||||
|
public synchronized boolean contains(Object packet) {
|
||||||
|
return queue.contains(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a packet is contained inside this queue and removes it if so.
|
||||||
|
* Other packets marked in this queue that were sent before this packet are
|
||||||
|
* removed from the queue also, avoiding memory leaks because of dropped packets.
|
||||||
|
*
|
||||||
|
* @param packet
|
||||||
|
* @return True if contained and packet should not be filtered (filtered=false)
|
||||||
|
*/
|
||||||
|
public synchronized boolean remove(Object packet) {
|
||||||
|
if (queue.isEmpty()) {
|
||||||
|
// Nothing in the queue
|
||||||
|
return false;
|
||||||
|
} else if (queue.peek() == packet) {
|
||||||
|
// First in the queue (expected)
|
||||||
|
queue.poll();
|
||||||
|
return true;
|
||||||
|
} else if (!queue.contains(packet)) {
|
||||||
|
// There are unfiltered packets, but this one is not
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// We have skipped over some packets (unexpected)
|
||||||
|
// Poll packets until we find it
|
||||||
|
while (queue.poll() != packet) {
|
||||||
|
if (queue.isEmpty()) {
|
||||||
|
// This should never happen! But to avoid infinite loop.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,9 +22,9 @@ import com.google.common.base.Preconditions;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedAttributeModifier extends AbstractWrapper {
|
public class WrappedAttributeModifier extends AbstractWrapper {
|
||||||
private static final Class<?> OPERATION_CLASS = MinecraftReflection.getMinecraftClass("AttributeModifier$Operation");
|
|
||||||
private static final boolean OPERATION_ENUM = MinecraftVersion.atOrAbove(MinecraftVersion.VILLAGE_UPDATE);
|
private static final boolean OPERATION_ENUM = MinecraftVersion.atOrAbove(MinecraftVersion.VILLAGE_UPDATE);
|
||||||
private static final EquivalentConverter<Operation> OPERATION_CONVERTER = new IndexedEnumConverter<>(Operation.class, OPERATION_CLASS);
|
private static final Class<?> OPERATION_CLASS;
|
||||||
|
private static final EquivalentConverter<Operation> OPERATION_CONVERTER;
|
||||||
|
|
||||||
private static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
private static class IndexedEnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
||||||
private Class<T> specificClass;
|
private Class<T> specificClass;
|
||||||
@ -65,6 +65,11 @@ public class WrappedAttributeModifier extends AbstractWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
OPERATION_CLASS = OPERATION_ENUM ? MinecraftReflection.getMinecraftClass("AttributeModifier$Operation") : null;
|
||||||
|
OPERATION_CONVERTER = OPERATION_ENUM ? new IndexedEnumConverter<>(Operation.class, OPERATION_CLASS) : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the different modifier operations.
|
* Represents the different modifier operations.
|
||||||
* <p>
|
* <p>
|
||||||
|
Loading…
Reference in New Issue
Block a user