mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 21:26:17 +01:00
Switch to using PacketType in the built-in commands.
The format is now as follows: /packet add server play 0-255. It may be possible to look up packet types by name later.
This commit is contained in:
parent
6bd8bd2ca2
commit
acea92ef5c
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol;
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
@ -84,27 +88,38 @@ abstract class CommandBase implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a boolean value at a specific location.
|
* Parse a boolean value at the head of the queue.
|
||||||
* @param args - the argument array.
|
* @param arguments - the queue of arguments.
|
||||||
* @param parameterName - the parameter name.
|
* @param parameterName - the parameter name we will match.
|
||||||
* @param index - the argument index.
|
|
||||||
* @return The parsed boolean, or NULL if not valid.
|
* @return The parsed boolean, or NULL if not valid.
|
||||||
*/
|
*/
|
||||||
protected Boolean parseBoolean(String[] args, String parameterName, int index) {
|
protected Boolean parseBoolean(Deque<String> arguments, String parameterName) {
|
||||||
if (index < args.length) {
|
Boolean result = null;
|
||||||
String arg = args[index];
|
|
||||||
|
if (!arguments.isEmpty()) {
|
||||||
|
String arg = arguments.peek();
|
||||||
|
|
||||||
if (arg.equalsIgnoreCase("true") || arg.equalsIgnoreCase("on"))
|
if (arg.equalsIgnoreCase("true") || arg.equalsIgnoreCase("on"))
|
||||||
return true;
|
result = true;
|
||||||
else if (arg.equalsIgnoreCase(parameterName))
|
else if (arg.equalsIgnoreCase(parameterName))
|
||||||
return true;
|
result = true;
|
||||||
else if (arg.equalsIgnoreCase("false") || arg.equalsIgnoreCase("off"))
|
else if (arg.equalsIgnoreCase("false") || arg.equalsIgnoreCase("off"))
|
||||||
return false;
|
result = false;
|
||||||
else
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
arguments.poll();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a queue from a sublist of a given array.
|
||||||
|
* @param args - the source array.
|
||||||
|
* @param start - the starting index.
|
||||||
|
* @return A queue that contains every element in the array, starting at the given index.
|
||||||
|
*/
|
||||||
|
protected Deque<String> toQueue(String[] args, int start) {
|
||||||
|
return new ArrayDeque<String>(Arrays.asList(args).subList(start, args.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.comphenix.protocol;
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.Deque;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -22,14 +22,11 @@ import org.bukkit.conversations.ConversationFactory;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller;
|
import com.comphenix.protocol.MultipleLinesPrompt.MultipleConversationCanceller;
|
||||||
import com.comphenix.protocol.concurrency.IntegerSet;
|
|
||||||
import com.comphenix.protocol.error.ErrorReporter;
|
import com.comphenix.protocol.error.ErrorReporter;
|
||||||
import com.comphenix.protocol.error.Report;
|
import com.comphenix.protocol.error.Report;
|
||||||
import com.comphenix.protocol.error.ReportType;
|
import com.comphenix.protocol.error.ReportType;
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
import com.google.common.collect.DiscreteDomains;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.collect.Range;
|
|
||||||
import com.google.common.collect.Ranges;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A command to apply JavaScript filtering to the packet command.
|
* A command to apply JavaScript filtering to the packet command.
|
||||||
@ -71,19 +68,18 @@ public class CommandFilter extends CommandBase {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final String predicate;
|
private final String predicate;
|
||||||
|
|
||||||
private final IntegerSet ranges;
|
private final Set<PacketType> packets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new immutable filter.
|
* Construct a new immutable filter.
|
||||||
* @param name - the unique name of the filter.
|
* @param name - the unique name of the filter.
|
||||||
* @param predicate - the JavaScript predicate that will be used to filter packet events.
|
* @param predicate - the JavaScript predicate that will be used to filter packet events.
|
||||||
* @param packets - a list of valid packet ID that this filter applies to.
|
* @param packets - a list of packet types this filter applies to.
|
||||||
*/
|
*/
|
||||||
public Filter(String name, String predicate, Set<Integer> packets) {
|
public Filter(String name, String predicate, Set<PacketType> packets) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.ranges = new IntegerSet(Packets.MAXIMUM_PACKET_ID + 1);
|
this.packets = Sets.newHashSet(packets);
|
||||||
this.ranges.addAll(packets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,8 +102,8 @@ public class CommandFilter extends CommandBase {
|
|||||||
* Retrieve a copy of the set of packets this filter applies to.
|
* Retrieve a copy of the set of packets this filter applies to.
|
||||||
* @return Set of packets this filter applies to.
|
* @return Set of packets this filter applies to.
|
||||||
*/
|
*/
|
||||||
public Set<Integer> getRanges() {
|
public Set<PacketType> getRanges() {
|
||||||
return ranges.toSet();
|
return Sets.newHashSet(packets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +112,7 @@ public class CommandFilter extends CommandBase {
|
|||||||
* @return TRUE if it does, FALSE otherwise.
|
* @return TRUE if it does, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean isApplicable(PacketEvent event) {
|
private boolean isApplicable(PacketEvent event) {
|
||||||
return ranges.contains(event.getPacketID());
|
return packets.contains(event.getPacketType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -384,7 +380,11 @@ public class CommandFilter extends CommandBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<Integer> packets = parseRanges(args, 2);
|
// Prepare the input to the packet type parser
|
||||||
|
Deque<String> rangeArguments = toQueue(args, 2);
|
||||||
|
|
||||||
|
final PacketTypeParser parser = new PacketTypeParser();
|
||||||
|
final Set<PacketType> packets = parser.parseTypes(rangeArguments, PacketTypeParser.DEFAULT_MAX_RANGE);
|
||||||
sender.sendMessage("Enter filter program ('}' to complete or CANCEL):");
|
sender.sendMessage("Enter filter program ('}' to complete or CANCEL):");
|
||||||
|
|
||||||
// Make sure we can use the conversable interface
|
// Make sure we can use the conversable interface
|
||||||
@ -455,22 +455,6 @@ public class CommandFilter extends CommandBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Integer> parseRanges(String[] args, int start) {
|
|
||||||
List<Range<Integer>> ranges = RangeParser.getRanges(args, 2, args.length - 1, Ranges.closed(0, 255));
|
|
||||||
Set<Integer> flatten = new HashSet<Integer>();
|
|
||||||
|
|
||||||
if (ranges.isEmpty()) {
|
|
||||||
// Use every packet ID
|
|
||||||
ranges.add(Ranges.closed(0, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, flatten it all
|
|
||||||
for (Range<Integer> range : ranges) {
|
|
||||||
flatten.addAll(range.asSet(DiscreteDomains.integers()));
|
|
||||||
}
|
|
||||||
return flatten;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a filter by its name.
|
* Lookup a filter by its name.
|
||||||
* @param name - the filter name.
|
* @param name - the filter name.
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
package com.comphenix.protocol;
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.Arrays;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -34,26 +36,20 @@ import org.bukkit.command.CommandSender;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import com.comphenix.protocol.concurrency.AbstractIntervalTree;
|
import com.comphenix.protocol.PacketType.Sender;
|
||||||
|
import com.comphenix.protocol.concurrency.PacketTypeSet;
|
||||||
import com.comphenix.protocol.error.ErrorReporter;
|
import com.comphenix.protocol.error.ErrorReporter;
|
||||||
import com.comphenix.protocol.error.Report;
|
import com.comphenix.protocol.error.Report;
|
||||||
import com.comphenix.protocol.error.ReportType;
|
import com.comphenix.protocol.error.ReportType;
|
||||||
import com.comphenix.protocol.events.ConnectionSide;
|
|
||||||
import com.comphenix.protocol.events.ListenerPriority;
|
|
||||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
import com.comphenix.protocol.events.PacketListener;
|
import com.comphenix.protocol.events.PacketListener;
|
||||||
import com.comphenix.protocol.injector.GamePhase;
|
|
||||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
|
||||||
import com.comphenix.protocol.reflect.PrettyPrinter;
|
import com.comphenix.protocol.reflect.PrettyPrinter;
|
||||||
import com.comphenix.protocol.reflect.PrettyPrinter.ObjectPrinter;
|
import com.comphenix.protocol.reflect.PrettyPrinter.ObjectPrinter;
|
||||||
import com.comphenix.protocol.utility.ChatExtensions;
|
import com.comphenix.protocol.utility.ChatExtensions;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||||
import com.google.common.collect.DiscreteDomains;
|
|
||||||
import com.google.common.collect.Range;
|
|
||||||
import com.google.common.collect.Ranges;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,15 +59,7 @@ import com.google.common.collect.Sets;
|
|||||||
*/
|
*/
|
||||||
class CommandPacket extends CommandBase {
|
class CommandPacket extends CommandBase {
|
||||||
public static final ReportType REPORT_CANNOT_SEND_MESSAGE = new ReportType("Cannot send chat message.");
|
public static final ReportType REPORT_CANNOT_SEND_MESSAGE = new ReportType("Cannot send chat message.");
|
||||||
|
|
||||||
private interface DetailedPacketListener extends PacketListener {
|
|
||||||
/**
|
|
||||||
* Determine whether or not the given packet listener is detailed or not.
|
|
||||||
* @return TRUE if it is detailed, FALSE otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isDetailed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum SubCommand {
|
private enum SubCommand {
|
||||||
ADD, REMOVE, NAMES, PAGE;
|
ADD, REMOVE, NAMES, PAGE;
|
||||||
}
|
}
|
||||||
@ -92,12 +80,18 @@ class CommandPacket extends CommandBase {
|
|||||||
|
|
||||||
private ChatExtensions chatter;
|
private ChatExtensions chatter;
|
||||||
|
|
||||||
|
// The main parser
|
||||||
|
private PacketTypeParser typeParser = new PacketTypeParser();
|
||||||
|
|
||||||
// Paged message
|
// Paged message
|
||||||
private Map<CommandSender, List<String>> pagedMessage = new WeakHashMap<CommandSender, List<String>>();
|
private Map<CommandSender, List<String>> pagedMessage = new WeakHashMap<CommandSender, List<String>>();
|
||||||
|
|
||||||
// Registered packet listeners
|
// Current registered packet types
|
||||||
private AbstractIntervalTree<Integer, DetailedPacketListener> clientListeners = createTree(ConnectionSide.CLIENT_SIDE);
|
private PacketTypeSet packetTypes = new PacketTypeSet();
|
||||||
private AbstractIntervalTree<Integer, DetailedPacketListener> serverListeners = createTree(ConnectionSide.SERVER_SIDE);
|
private PacketTypeSet extendedTypes = new PacketTypeSet();
|
||||||
|
|
||||||
|
// The packet listener
|
||||||
|
private PacketListener listener;
|
||||||
|
|
||||||
// Filter packet events
|
// Filter packet events
|
||||||
private CommandFilter filter;
|
private CommandFilter filter;
|
||||||
@ -110,58 +104,7 @@ class CommandPacket extends CommandBase {
|
|||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.chatter = new ChatExtensions(manager);
|
this.chatter = new ChatExtensions(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a packet listener interval tree.
|
|
||||||
* @return Construct the tree.
|
|
||||||
*/
|
|
||||||
private AbstractIntervalTree<Integer, DetailedPacketListener> createTree(final ConnectionSide side) {
|
|
||||||
return new AbstractIntervalTree<Integer, DetailedPacketListener>() {
|
|
||||||
@Override
|
|
||||||
protected Integer decrementKey(Integer key) {
|
|
||||||
return key != null ? key - 1 : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Integer incrementKey(Integer key) {
|
|
||||||
return key != null ? key + 1 : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onEntryAdded(Entry added) {
|
|
||||||
// Ensure that the starting ID and the ending ID is correct
|
|
||||||
// This is necessary because the interval tree may change the range.
|
|
||||||
if (added != null) {
|
|
||||||
Range<Integer> key = added.getKey();
|
|
||||||
DetailedPacketListener listener = added.getValue();
|
|
||||||
DetailedPacketListener corrected = createPacketListener(
|
|
||||||
side, key.lowerEndpoint(), key.upperEndpoint(), listener.isDetailed());
|
|
||||||
|
|
||||||
added.setValue(corrected);
|
|
||||||
|
|
||||||
if (corrected != null) {
|
|
||||||
manager.addPacketListener(corrected);
|
|
||||||
} else {
|
|
||||||
// Never mind
|
|
||||||
remove(key.lowerEndpoint(), key.upperEndpoint());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onEntryRemoved(Entry removed) {
|
|
||||||
// Remove the listener
|
|
||||||
if (removed != null) {
|
|
||||||
DetailedPacketListener listener = removed.getValue();
|
|
||||||
|
|
||||||
if (listener != null) {
|
|
||||||
manager.removePacketListener(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a message without invoking the packet listeners.
|
* Send a message without invoking the packet listeners.
|
||||||
* @param receiver - the player to send it to.
|
* @param receiver - the player to send it to.
|
||||||
@ -223,8 +166,9 @@ class CommandPacket extends CommandBase {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean handleCommand(CommandSender sender, String[] args) {
|
protected boolean handleCommand(CommandSender sender, String[] args) {
|
||||||
try {
|
try {
|
||||||
SubCommand subCommand = parseCommand(args, 0);
|
Deque<String> arguments = new ArrayDeque<String>(Arrays.asList(args));
|
||||||
|
SubCommand subCommand = parseCommand(arguments);
|
||||||
|
|
||||||
// Commands with different parameters
|
// Commands with different parameters
|
||||||
if (subCommand == SubCommand.PAGE) {
|
if (subCommand == SubCommand.PAGE) {
|
||||||
int page = Integer.parseInt(args[1]);
|
int page = Integer.parseInt(args[1]);
|
||||||
@ -236,26 +180,18 @@ class CommandPacket extends CommandBase {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionSide side = parseSide(args, 1, ConnectionSide.BOTH);
|
Set<PacketType> types = typeParser.parseTypes(arguments, PacketTypeParser.DEFAULT_MAX_RANGE);
|
||||||
|
Boolean detailed = parseBoolean(arguments, "detailed");
|
||||||
|
|
||||||
Integer lastIndex = args.length - 1;
|
if (arguments.size() > 0) {
|
||||||
Boolean detailed = parseBoolean(args, "detailed", lastIndex);
|
throw new IllegalArgumentException("Insufficient arguments.");
|
||||||
|
}
|
||||||
// See if the last element is a boolean
|
|
||||||
|
// The last element is optional
|
||||||
if (detailed == null) {
|
if (detailed == null) {
|
||||||
detailed = false;
|
detailed = false;
|
||||||
} else {
|
|
||||||
lastIndex--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the packet IDs are valid
|
|
||||||
List<Range<Integer>> ranges = RangeParser.getRanges(args, 2, lastIndex, Ranges.closed(0, 255));
|
|
||||||
|
|
||||||
if (ranges.isEmpty()) {
|
|
||||||
// Use every packet ID
|
|
||||||
ranges.add(Ranges.closed(0, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform commands
|
// Perform commands
|
||||||
if (subCommand == SubCommand.ADD) {
|
if (subCommand == SubCommand.ADD) {
|
||||||
// The add command is dangerous - don't default on the connection side
|
// The add command is dangerous - don't default on the connection side
|
||||||
@ -264,11 +200,11 @@ class CommandPacket extends CommandBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
executeAddCommand(sender, side, detailed, ranges);
|
executeAddCommand(sender, types, detailed);
|
||||||
} else if (subCommand == SubCommand.REMOVE) {
|
} else if (subCommand == SubCommand.REMOVE) {
|
||||||
executeRemoveCommand(sender, side, detailed, ranges);
|
executeRemoveCommand(sender, types);
|
||||||
} else if (subCommand == SubCommand.NAMES) {
|
} else if (subCommand == SubCommand.NAMES) {
|
||||||
executeNamesCommand(sender, side, ranges);
|
executeNamesCommand(sender, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
@ -279,36 +215,31 @@ class CommandPacket extends CommandBase {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeAddCommand(CommandSender sender, ConnectionSide side, Boolean detailed, List<Range<Integer>> ranges) {
|
private void executeAddCommand(CommandSender sender, Set<PacketType> addition, boolean detailed) {
|
||||||
for (Range<Integer> range : ranges) {
|
packetTypes.addAll(addition);
|
||||||
DetailedPacketListener listener = addPacketListeners(side, range.lowerEndpoint(), range.upperEndpoint(), detailed);
|
|
||||||
sendMessageSilently(sender, ChatColor.BLUE + "Added listener " + getWhitelistInfo(listener));
|
// Also mark these types as "detailed"
|
||||||
|
if (detailed) {
|
||||||
|
extendedTypes.addAll(addition);
|
||||||
}
|
}
|
||||||
|
updatePacketListener();
|
||||||
|
sendMessageSilently(sender, ChatColor.BLUE + "Added listener " + getWhitelistInfo(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeRemoveCommand(CommandSender sender, ConnectionSide side, Boolean detailed, List<Range<Integer>> ranges) {
|
private void executeRemoveCommand(CommandSender sender, Set<PacketType> removal) {
|
||||||
int count = 0;
|
packetTypes.removeAll(removal);
|
||||||
|
extendedTypes.removeAll(removal);
|
||||||
// Remove each packet listener
|
updatePacketListener();
|
||||||
for (Range<Integer> range : ranges) {
|
sendMessageSilently(sender, ChatColor.BLUE + "Removing packet types.");
|
||||||
count += removePacketListeners(side, range.lowerEndpoint(), range.upperEndpoint(), detailed).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessageSilently(sender, ChatColor.BLUE + "Fully removed " + count + " listeners.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeNamesCommand(CommandSender sender, ConnectionSide side, List<Range<Integer>> ranges) {
|
private void executeNamesCommand(CommandSender sender, Set<PacketType> types) {
|
||||||
Set<Integer> named = getNamedPackets(side);
|
|
||||||
List<String> messages = new ArrayList<String>();
|
List<String> messages = new ArrayList<String>();
|
||||||
|
|
||||||
// Print the equivalent name of every given ID
|
// Print the equivalent name of every given ID
|
||||||
for (Range<Integer> range : ranges) {
|
for (PacketType type : types) {
|
||||||
for (int id : range.asSet(DiscreteDomains.integers())) {
|
messages.add(ChatColor.BLUE + type.toString());
|
||||||
if (named.contains(id)) {
|
|
||||||
messages.add(ChatColor.WHITE + "" + id + ": " + ChatColor.BLUE + Packets.getDeclaredName(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender instanceof Player && messages.size() > 0 && messages.size() > PAGE_LINE_COUNT) {
|
if (sender instanceof Player && messages.size() > 0 && messages.size() > PAGE_LINE_COUNT) {
|
||||||
@ -342,90 +273,58 @@ class CommandPacket extends CommandBase {
|
|||||||
else
|
else
|
||||||
return "[None]";
|
return "[None]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Integer> getValidPackets(ConnectionSide side) throws FieldAccessException {
|
|
||||||
HashSet<Integer> supported = Sets.newHashSet();
|
|
||||||
|
|
||||||
if (side.isForClient())
|
private Set<PacketType> filterTypes(Set<PacketType> types, Sender sender) {
|
||||||
supported.addAll(Packets.Client.getSupported());
|
Set<PacketType> result = Sets.newHashSet();
|
||||||
else if (side.isForServer())
|
|
||||||
supported.addAll(Packets.Server.getSupported());
|
|
||||||
|
|
||||||
return supported;
|
for (PacketType type : types) {
|
||||||
}
|
if (type.getSender() == sender) {
|
||||||
|
result.add(type);
|
||||||
private Set<Integer> getNamedPackets(ConnectionSide side) {
|
}
|
||||||
|
|
||||||
Set<Integer> valids = null;
|
|
||||||
Set<Integer> result = Sets.newHashSet();
|
|
||||||
|
|
||||||
try {
|
|
||||||
valids = getValidPackets(side);
|
|
||||||
} catch (FieldAccessException e) {
|
|
||||||
valids = Ranges.closed(0, 255).asSet(DiscreteDomains.integers());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check connection side
|
|
||||||
if (side.isForClient())
|
|
||||||
result.addAll(Packets.Client.getRegistry().values());
|
|
||||||
if (side.isForServer())
|
|
||||||
result.addAll(Packets.Server.getRegistry().values());
|
|
||||||
|
|
||||||
// Remove invalid packets
|
|
||||||
result.retainAll(valids);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketListener createPacketListener(Set<PacketType> type) {
|
||||||
|
final ListeningWhitelist serverList = ListeningWhitelist.newBuilder().
|
||||||
|
types(filterTypes(type, Sender.SERVER)).
|
||||||
|
gamePhaseBoth().
|
||||||
|
monitor().
|
||||||
|
build();
|
||||||
|
|
||||||
public DetailedPacketListener createPacketListener(final ConnectionSide side, int idStart, int idStop, final boolean detailed) {
|
final ListeningWhitelist clientList = ListeningWhitelist.newBuilder(serverList).
|
||||||
Set<Integer> range = Ranges.closed(idStart, idStop).asSet(DiscreteDomains.integers());
|
types(filterTypes(type, Sender.CLIENT)).
|
||||||
Set<Integer> packets;
|
build();
|
||||||
|
|
||||||
try {
|
return new PacketListener() {
|
||||||
// Only use supported packet IDs
|
|
||||||
packets = new HashSet<Integer>(getValidPackets(side));
|
|
||||||
packets.retainAll(range);
|
|
||||||
|
|
||||||
} catch (FieldAccessException e) {
|
|
||||||
// Don't filter anything then
|
|
||||||
packets = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore empty sets
|
|
||||||
if (packets.isEmpty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Create the listener we will be using
|
|
||||||
final ListeningWhitelist whitelist = new ListeningWhitelist(ListenerPriority.MONITOR, packets, GamePhase.BOTH);
|
|
||||||
|
|
||||||
return new DetailedPacketListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketSending(PacketEvent event) {
|
public void onPacketSending(PacketEvent event) {
|
||||||
if (side.isForServer() && filter.filterEvent(event)) {
|
if (filter.filterEvent(event)) {
|
||||||
printInformation(event);
|
printInformation(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketReceiving(PacketEvent event) {
|
public void onPacketReceiving(PacketEvent event) {
|
||||||
if (side.isForClient() && filter.filterEvent(event)) {
|
if (filter.filterEvent(event)) {
|
||||||
printInformation(event);
|
printInformation(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printInformation(PacketEvent event) {
|
private void printInformation(PacketEvent event) {
|
||||||
String verb = side.isForClient() ? "Received" : "Sent";
|
String verb = event.isServerPacket() ? "Sent" : "Received";
|
||||||
String format = side.isForClient() ?
|
String format = event.isServerPacket() ?
|
||||||
"%s %s (%s) from %s" :
|
"%s %s to %s" :
|
||||||
"%s %s (%s) to %s";
|
"%s %s from %s";
|
||||||
|
|
||||||
String shortDescription = String.format(format,
|
String shortDescription = String.format(format,
|
||||||
event.isCancelled() ? "Cancelled" : verb,
|
event.isCancelled() ? "Cancelled" : verb,
|
||||||
Packets.getDeclaredName(event.getPacketID()),
|
event.getPacketType(),
|
||||||
event.getPacketID(),
|
|
||||||
event.getPlayer().getName()
|
event.getPlayer().getName()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Detailed will print the packet's content too
|
// Detailed will print the packet's content too
|
||||||
if (detailed) {
|
if (extendedTypes.contains(event.getPacketType())) {
|
||||||
try {
|
try {
|
||||||
Object packet = event.getPacket().getHandle();
|
Object packet = event.getPacket().getHandle();
|
||||||
Class<?> clazz = packet.getClass();
|
Class<?> clazz = packet.getClass();
|
||||||
@ -463,56 +362,34 @@ class CommandPacket extends CommandBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListeningWhitelist getSendingWhitelist() {
|
public ListeningWhitelist getSendingWhitelist() {
|
||||||
return side.isForServer() ? whitelist : ListeningWhitelist.EMPTY_WHITELIST;
|
return serverList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListeningWhitelist getReceivingWhitelist() {
|
public ListeningWhitelist getReceivingWhitelist() {
|
||||||
return side.isForClient() ? whitelist : ListeningWhitelist.EMPTY_WHITELIST;
|
return clientList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Plugin getPlugin() {
|
public Plugin getPlugin() {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDetailed() {
|
|
||||||
return detailed;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public DetailedPacketListener addPacketListeners(ConnectionSide side, int idStart, int idStop, boolean detailed) {
|
public PacketListener updatePacketListener() {
|
||||||
DetailedPacketListener listener = createPacketListener(side, idStart, idStop, detailed);
|
|
||||||
|
|
||||||
// The trees will manage the listeners for us
|
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
if (side.isForClient())
|
manager.removePacketListener(listener);
|
||||||
clientListeners.put(idStart, idStop, listener);
|
|
||||||
if (side.isForServer())
|
|
||||||
serverListeners.put(idStart, idStop, listener);
|
|
||||||
return listener;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("No packets found in the range " + idStart + " - " + idStop + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a new listener instead
|
||||||
|
listener = createPacketListener(packetTypes.values());
|
||||||
|
manager.addPacketListener(listener);
|
||||||
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<AbstractIntervalTree<Integer, DetailedPacketListener>.Entry> removePacketListeners(
|
private SubCommand parseCommand(Deque<String> arguments) {
|
||||||
ConnectionSide side, int idStart, int idStop, boolean detailed) {
|
String text = arguments.poll().toLowerCase();
|
||||||
|
|
||||||
HashSet<AbstractIntervalTree<Integer, DetailedPacketListener>.Entry> result = Sets.newHashSet();
|
|
||||||
|
|
||||||
// The interval tree will automatically remove the listeners for us
|
|
||||||
if (side.isForClient())
|
|
||||||
result.addAll(clientListeners.remove(idStart, idStop, true));
|
|
||||||
if (side.isForServer())
|
|
||||||
result.addAll(serverListeners.remove(idStart, idStop, true));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SubCommand parseCommand(String[] args, int index) {
|
|
||||||
String text = args[index].toLowerCase();
|
|
||||||
|
|
||||||
// Parse this too
|
// Parse this too
|
||||||
if ("add".startsWith(text))
|
if ("add".startsWith(text))
|
||||||
@ -526,21 +403,4 @@ class CommandPacket extends CommandBase {
|
|||||||
else
|
else
|
||||||
throw new IllegalArgumentException(text + " is not a valid sub command. Must be add or remove.");
|
throw new IllegalArgumentException(text + " is not a valid sub command. Must be add or remove.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConnectionSide parseSide(String[] args, int index, ConnectionSide defaultValue) {
|
|
||||||
if (index < args.length) {
|
|
||||||
String text = args[index].toLowerCase();
|
|
||||||
|
|
||||||
// Parse the side gracefully
|
|
||||||
if ("client".startsWith(text))
|
|
||||||
return ConnectionSide.CLIENT_SIDE;
|
|
||||||
else if ("server".startsWith(text))
|
|
||||||
return ConnectionSide.SERVER_SIDE;
|
|
||||||
else
|
|
||||||
throw new IllegalArgumentException(text + " is not a connection side.");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ class CommandProtocol extends CommandBase {
|
|||||||
|
|
||||||
// Parse the boolean parameter
|
// Parse the boolean parameter
|
||||||
if (args.length == 2) {
|
if (args.length == 2) {
|
||||||
Boolean parsed = parseBoolean(args, "start", 2);
|
Boolean parsed = parseBoolean(toQueue(args, 2), "start");
|
||||||
|
|
||||||
if (parsed != null) {
|
if (parsed != null) {
|
||||||
state = parsed;
|
state = parsed;
|
||||||
|
@ -588,6 +588,16 @@ public class PacketType implements Serializable {
|
|||||||
throw new IllegalArgumentException("Cannot find legacy packet " + packetId);
|
throw new IllegalArgumentException("Cannot find legacy packet " + packetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given legacy packet exists.
|
||||||
|
* @param packetId - the legacy packet ID.
|
||||||
|
* @param preference - the sender preference.
|
||||||
|
* @return TRUE if it does, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean hasLegacy(int packetId) {
|
||||||
|
return getLookup().getFromLegacy(packetId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a packet type from a protocol, sender and packet ID.
|
* Retrieve a packet type from a protocol, sender and packet ID.
|
||||||
* <p>
|
* <p>
|
||||||
@ -610,6 +620,17 @@ public class PacketType implements Serializable {
|
|||||||
"(Protocol: " + protocol + ", Sender: " + sender + ")");
|
"(Protocol: " + protocol + ", Sender: " + sender + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given packet exists.
|
||||||
|
* @param protocol - the protocol.
|
||||||
|
* @param sender - the sender.
|
||||||
|
* @param packetId - the packet ID.
|
||||||
|
* @return TRUE if it exists, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean hasCurrent(Protocol protocol, Sender sender, int packetId) {
|
||||||
|
return getLookup().getFromCurrent(protocol, sender, packetId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a packet type from a protocol, sender and packet ID.
|
* Retrieve a packet type from a protocol, sender and packet ID.
|
||||||
* <p>
|
* <p>
|
||||||
@ -822,7 +843,10 @@ public class PacketType implements Serializable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
Class<?> clazz = getPacketClass();;
|
Class<?> clazz = getPacketClass();;
|
||||||
return (clazz != null ? clazz.getSimpleName() : "UNREGISTERED") +
|
|
||||||
" [" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + "]";
|
if (clazz == null)
|
||||||
|
return "UNREGISTERED [" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + "]";
|
||||||
|
else
|
||||||
|
return clazz.getSimpleName() + "[" + currentId + ", legacy: " + legacyId + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType.Protocol;
|
||||||
|
import com.comphenix.protocol.PacketType.Sender;
|
||||||
|
import com.comphenix.protocol.events.ConnectionSide;
|
||||||
|
import com.google.common.collect.DiscreteDomains;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Range;
|
||||||
|
import com.google.common.collect.Ranges;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
class PacketTypeParser {
|
||||||
|
public final static Range<Integer> DEFAULT_MAX_RANGE = Ranges.closed(0, 255);
|
||||||
|
|
||||||
|
public Set<PacketType> parseTypes(Deque<String> arguments, Range<Integer> defaultRange) {
|
||||||
|
Sender side = null;
|
||||||
|
Protocol protocol = null;
|
||||||
|
Set<PacketType> result = Sets.newHashSet();
|
||||||
|
|
||||||
|
// Find these first
|
||||||
|
while (protocol == null || side == null) {
|
||||||
|
String arg = arguments.poll();
|
||||||
|
|
||||||
|
// Attempt to parse a side or protocol first
|
||||||
|
if (side == null) {
|
||||||
|
ConnectionSide connection = parseSide(arg);
|
||||||
|
|
||||||
|
if (connection != null) {
|
||||||
|
side = connection.getSender();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (protocol == null) {
|
||||||
|
if ((protocol = parseProtocol(arg)) != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No side and protocol specified.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then we move on to parsing IDs (named packet types soon to come)
|
||||||
|
List<Range<Integer>> ranges = RangeParser.getRanges(arguments, DEFAULT_MAX_RANGE);
|
||||||
|
|
||||||
|
// Supply a default integer range
|
||||||
|
if (ranges.size() == 0) {
|
||||||
|
ranges = Lists.newArrayList();
|
||||||
|
ranges.add(defaultRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Range<Integer> range : ranges) {
|
||||||
|
for (Integer id : range.asSet(DiscreteDomains.integers())) {
|
||||||
|
// Deprecated packets
|
||||||
|
if (protocol == null) {
|
||||||
|
if (PacketType.hasLegacy(id)) {
|
||||||
|
result.add(PacketType.findLegacy(id, side));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (PacketType.hasCurrent(protocol, side, id)) {
|
||||||
|
result.add(PacketType.findCurrent(protocol, side, id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a connection sides from a string.
|
||||||
|
* @param text - the possible connection side.
|
||||||
|
* @return The connection side, or NULL if not found.
|
||||||
|
*/
|
||||||
|
public ConnectionSide parseSide(String text) {
|
||||||
|
if (text == null)
|
||||||
|
return null;
|
||||||
|
String candidate = text.toLowerCase();
|
||||||
|
|
||||||
|
// Parse the side gracefully
|
||||||
|
if ("client".startsWith(candidate))
|
||||||
|
return ConnectionSide.CLIENT_SIDE;
|
||||||
|
else if ("server".startsWith(candidate))
|
||||||
|
return ConnectionSide.SERVER_SIDE;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a protocol from a string.
|
||||||
|
* @param text - the possible protocol.
|
||||||
|
* @return The protocol, or NULL if not found.
|
||||||
|
*/
|
||||||
|
public Protocol parseProtocol(String text) {
|
||||||
|
if (text == null)
|
||||||
|
return null;
|
||||||
|
String candidate = text.toLowerCase();
|
||||||
|
|
||||||
|
if ("handshake".equals(candidate) || "handshaking".equals(candidate))
|
||||||
|
return Protocol.HANDSHAKING;
|
||||||
|
else if ("login".equals(candidate))
|
||||||
|
return Protocol.LOGIN;
|
||||||
|
else if ("play".equals(candidate) || "game".equals(candidate))
|
||||||
|
return Protocol.PLAY;
|
||||||
|
else if ("status".equals(candidate))
|
||||||
|
return Protocol.STATUS;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
package com.comphenix.protocol;
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.DiscreteDomains;
|
import com.google.common.collect.DiscreteDomains;
|
||||||
@ -37,7 +40,7 @@ class RangeParser {
|
|||||||
* @return The parsed ranges.
|
* @return The parsed ranges.
|
||||||
*/
|
*/
|
||||||
public static List<Range<Integer>> getRanges(String text, Range<Integer> legalRange) {
|
public static List<Range<Integer>> getRanges(String text, Range<Integer> legalRange) {
|
||||||
return getRanges(new String[] { text }, 0, 0, legalRange);
|
return getRanges(new ArrayDeque<String>(Arrays.asList(text)), legalRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,8 +51,8 @@ class RangeParser {
|
|||||||
* @param legalRange - range of legal values.
|
* @param legalRange - range of legal values.
|
||||||
* @return The parsed ranges.
|
* @return The parsed ranges.
|
||||||
*/
|
*/
|
||||||
public static List<Range<Integer>> getRanges(String[] args, int offset, int lastIndex, Range<Integer> legalRange) {
|
public static List<Range<Integer>> getRanges(Deque<String> input, Range<Integer> legalRange) {
|
||||||
List<String> tokens = tokenizeInput(args, offset, lastIndex);
|
List<String> tokens = tokenizeInput(input);
|
||||||
List<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
|
List<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
|
||||||
|
|
||||||
for (int i = 0; i < tokens.size(); i++) {
|
for (int i = 0; i < tokens.size(); i++) {
|
||||||
@ -121,13 +124,13 @@ class RangeParser {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> tokenizeInput(String[] args, int offset, int lastIndex) {
|
private static List<String> tokenizeInput(Deque<String> input) {
|
||||||
List<String> tokens = new ArrayList<String>();
|
List<String> tokens = new ArrayList<String>();
|
||||||
|
|
||||||
// Tokenize the input
|
// Tokenize the input
|
||||||
for (int i = offset; i <= lastIndex; i++) {
|
while (!input.isEmpty()) {
|
||||||
String text = args[i];
|
|
||||||
StringBuilder number = new StringBuilder();
|
StringBuilder number = new StringBuilder();
|
||||||
|
String text = input.peek();
|
||||||
|
|
||||||
for (int j = 0; j < text.length(); j++) {
|
for (int j = 0; j < text.length(); j++) {
|
||||||
char current = text.charAt(j);
|
char current = text.charAt(j);
|
||||||
@ -145,13 +148,15 @@ class RangeParser {
|
|||||||
|
|
||||||
tokens.add(Character.toString(current));
|
tokens.add(Character.toString(current));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Illegal character '" + current + "' found.");
|
// We're no longer dealing with integers - quit
|
||||||
|
return tokens;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the number token, if it hasn't already
|
// Add the number token, if it hasn't already
|
||||||
if (number.length() > 0)
|
if (number.length() > 0)
|
||||||
tokens.add(number.toString());
|
tokens.add(number.toString());
|
||||||
|
input.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
|
@ -40,6 +40,16 @@ public class PacketTypeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given types to the set of packet types.
|
||||||
|
* @param types - the types to add.
|
||||||
|
*/
|
||||||
|
public synchronized void addAll(Iterable<? extends PacketType> types) {
|
||||||
|
for (PacketType type : types) {
|
||||||
|
addType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a particular type to the set.
|
* Remove a particular type to the set.
|
||||||
* @param type - the type to remove.
|
* @param type - the type to remove.
|
||||||
@ -53,6 +63,16 @@ public class PacketTypeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given types from the set.
|
||||||
|
* @param type - the types to remove.
|
||||||
|
*/
|
||||||
|
public synchronized void removeAll(Iterable<? extends PacketType> types) {
|
||||||
|
for (PacketType type : types) {
|
||||||
|
removeType(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the packet class associated with a particular type.
|
* Retrieve the packet class associated with a particular type.
|
||||||
* @param type - the packet type.
|
* @param type - the packet type.
|
||||||
|
@ -295,9 +295,9 @@ public class ListeningWhitelist {
|
|||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private ListenerPriority priority;
|
private ListenerPriority priority;
|
||||||
private Set<PacketType> types;
|
private Set<PacketType> types = Sets.newHashSet();
|
||||||
private GamePhase gamePhase;
|
private GamePhase gamePhase;
|
||||||
private Set<ListenerOptions> options;
|
private Set<ListenerOptions> options = Sets.newHashSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new listening whitelist template.
|
* Construct a new listening whitelist template.
|
||||||
|
Loading…
Reference in New Issue
Block a user