397 lines
9.9 KiB
Java
397 lines
9.9 KiB
Java
/*
|
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
|
* Copyright (C) 2012 Kristian S. Stangeland
|
|
*
|
|
* 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.events;
|
|
|
|
import java.util.*;
|
|
|
|
import com.comphenix.protocol.PacketType;
|
|
import com.comphenix.protocol.injector.GamePhase;
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.collect.Sets;
|
|
|
|
/**
|
|
* Determines which packets will be observed by a listener, and with what priority.
|
|
*
|
|
* @author Kristian
|
|
*/
|
|
public class ListeningWhitelist {
|
|
|
|
/**
|
|
* A whitelist with no packets - indicates that the listener shouldn't observe any packets.
|
|
*/
|
|
public static final ListeningWhitelist EMPTY_WHITELIST = new ListeningWhitelist(ListenerPriority.LOW);
|
|
|
|
private final ListenerPriority priority;
|
|
private final GamePhase gamePhase;
|
|
private final Set<ListenerOptions> options;
|
|
private final Set<PacketType> types;
|
|
|
|
private ListeningWhitelist(Builder builder) {
|
|
this.priority = builder.priority;
|
|
this.types = builder.types;
|
|
this.gamePhase = builder.gamePhase;
|
|
this.options = builder.options;
|
|
}
|
|
|
|
private ListeningWhitelist(ListenerPriority priority) {
|
|
this.priority = priority;
|
|
this.types = new HashSet<>();
|
|
this.gamePhase = GamePhase.PLAYING;
|
|
this.options = EnumSet.noneOf(ListenerOptions.class);
|
|
}
|
|
|
|
/**
|
|
* Determine if the given whitelist is empty or not.
|
|
*
|
|
* @param whitelist - the whitelist to test.
|
|
* @return TRUE if the whitelist is empty, FALSE otherwise.
|
|
*/
|
|
public static boolean isEmpty(ListeningWhitelist whitelist) {
|
|
if (whitelist == EMPTY_WHITELIST) {
|
|
return true;
|
|
} else if (whitelist == null) {
|
|
return true;
|
|
} else {
|
|
return whitelist.getTypes().isEmpty();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Construct a new builder of whitelists.
|
|
*
|
|
* @return New whitelist builder.
|
|
*/
|
|
public static Builder newBuilder() {
|
|
return new Builder(null);
|
|
}
|
|
|
|
/**
|
|
* Construct a new builder of whitelists initialized to the same values as the template.
|
|
*
|
|
* @param template - the template object.
|
|
* @return New whitelist builder.
|
|
*/
|
|
public static Builder newBuilder(ListeningWhitelist template) {
|
|
return new Builder(template);
|
|
}
|
|
|
|
/**
|
|
* Construct a copy of a given enum.
|
|
*
|
|
* @param options - the options to copy, or NULL to indicate the empty set.
|
|
* @return A copy of the enum set.
|
|
*/
|
|
private static <T extends Enum<T>> EnumSet<T> safeEnumSet(Collection<T> options, Class<T> enumClass) {
|
|
if (options != null && !options.isEmpty()) {
|
|
return EnumSet.copyOf(options);
|
|
} else {
|
|
return EnumSet.noneOf(enumClass);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Construct a copy of a given set.
|
|
*
|
|
* @param set - the set to copy.
|
|
* @return The copied set.
|
|
*/
|
|
private static <T> Set<T> safeSet(Collection<T> set) {
|
|
if (set != null) {
|
|
return new HashSet<>(set);
|
|
} else {
|
|
return Collections.emptySet();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Whether or not this whitelist has any enabled packets.
|
|
*
|
|
* @return TRUE if there are any packets, FALSE otherwise.
|
|
*/
|
|
public boolean isEnabled() {
|
|
return types != null && types.size() > 0;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the priority in the execution order of the packet listener. Highest priority will be executed last.
|
|
*
|
|
* @return Execution order in terms of priority.
|
|
*/
|
|
public ListenerPriority getPriority() {
|
|
return priority;
|
|
}
|
|
|
|
/**
|
|
* Retrieves a set of the packets that will be observed by the listeners.
|
|
*
|
|
* @return Packet whitelist.
|
|
*/
|
|
public Set<PacketType> getTypes() {
|
|
return types;
|
|
}
|
|
|
|
/**
|
|
* Retrieve which game phase this listener is active under.
|
|
*
|
|
* @return The active game phase.
|
|
*/
|
|
public GamePhase getGamePhase() {
|
|
return gamePhase;
|
|
}
|
|
|
|
/**
|
|
* Retrieve every special option associated with this whitelist.
|
|
*
|
|
* @return Every special option.
|
|
*/
|
|
public Set<ListenerOptions> getOptions() {
|
|
return Collections.unmodifiableSet(options);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hashCode(priority, types, gamePhase, options);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object obj) {
|
|
if (obj instanceof ListeningWhitelist) {
|
|
final ListeningWhitelist other = (ListeningWhitelist) obj;
|
|
return Objects.equal(priority, other.priority)
|
|
&& Objects.equal(types, other.types)
|
|
&& Objects.equal(gamePhase, other.gamePhase)
|
|
&& Objects.equal(options, other.options);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
if (this == EMPTY_WHITELIST) {
|
|
return "EMPTY_WHITELIST";
|
|
} else {
|
|
return "ListeningWhitelist[priority=" + priority + ", packets=" + types + ", gamephase=" + gamePhase
|
|
+ ", options=" + options + "]";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents a builder of whitelists.
|
|
*
|
|
* @author Kristian
|
|
*/
|
|
public static class Builder {
|
|
|
|
// Default values
|
|
private ListenerPriority priority = ListenerPriority.NORMAL;
|
|
private Set<PacketType> types = new HashSet<>();
|
|
private GamePhase gamePhase = GamePhase.PLAYING;
|
|
private Set<ListenerOptions> options = new HashSet<>();
|
|
|
|
/**
|
|
* Construct a new listening whitelist template.
|
|
*
|
|
* @param template - the template.
|
|
*/
|
|
private Builder(ListeningWhitelist template) {
|
|
if (template != null) {
|
|
priority(template.getPriority());
|
|
gamePhase(template.getGamePhase());
|
|
types(template.getTypes());
|
|
options(template.getOptions());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the priority to use when constructing new whitelists.
|
|
*
|
|
* @param priority - the priority.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder priority(ListenerPriority priority) {
|
|
this.priority = priority;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to monitor.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder monitor() {
|
|
return priority(ListenerPriority.MONITOR);
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to normal.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder normal() {
|
|
return priority(ListenerPriority.NORMAL);
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to lowest.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder lowest() {
|
|
return priority(ListenerPriority.LOWEST);
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to low.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder low() {
|
|
return priority(ListenerPriority.LOW);
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to highest.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder highest() {
|
|
return priority(ListenerPriority.HIGHEST);
|
|
}
|
|
|
|
/**
|
|
* Set the priority of the whitelist to high.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder high() {
|
|
return priority(ListenerPriority.HIGH);
|
|
}
|
|
|
|
/**
|
|
* Set the whitelist of packet types to copy when constructing new whitelists.
|
|
*
|
|
* @param types - the whitelist of packets.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder types(PacketType... types) {
|
|
this.types = safeSet(Sets.newHashSet(types));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the whitelist of packet types to copy when constructing new whitelists.
|
|
*
|
|
* @param types - the whitelist of packets.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder types(Collection<PacketType> types) {
|
|
this.types = safeSet(types);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the gamephase to use when constructing new whitelists.
|
|
*
|
|
* @param gamePhase - the gamephase.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder gamePhase(GamePhase gamePhase) {
|
|
this.gamePhase = gamePhase;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the gamephase to {@link GamePhase#BOTH}.
|
|
*
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder gamePhaseBoth() {
|
|
return gamePhase(GamePhase.BOTH);
|
|
}
|
|
|
|
/**
|
|
* Set the options to copy when constructing new whitelists.
|
|
*
|
|
* @param options - the options.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder options(Set<ListenerOptions> options) {
|
|
this.options = safeSet(options);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the options to copy when constructing new whitelists.
|
|
*
|
|
* @param options - the options.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder options(Collection<ListenerOptions> options) {
|
|
this.options = safeSet(options);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the options to copy when constructing new whitelists.
|
|
*
|
|
* @param serverOptions - the options array.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder options(ListenerOptions[] serverOptions) {
|
|
this.options = safeSet(Sets.newHashSet(serverOptions));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Options to merge into the current set of options.
|
|
*
|
|
* @param serverOptions - the options array.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder mergeOptions(ListenerOptions... serverOptions) {
|
|
return mergeOptions(Arrays.asList(serverOptions));
|
|
}
|
|
|
|
/**
|
|
* Options to merge into the current set of options.
|
|
*
|
|
* @param serverOptions - the options array.
|
|
* @return This builder, for chaining.
|
|
*/
|
|
public Builder mergeOptions(Collection<ListenerOptions> serverOptions) {
|
|
if (options == null) {
|
|
return options(serverOptions);
|
|
}
|
|
|
|
// Merge the options
|
|
this.options.addAll(serverOptions);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Construct a new whitelist from the values in this builder.
|
|
*
|
|
* @return The new whitelist.
|
|
*/
|
|
public ListeningWhitelist build() {
|
|
return new ListeningWhitelist(this);
|
|
}
|
|
}
|
|
}
|