package com.comphenix.xp.lookup; import java.util.Arrays; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import com.comphenix.xp.parser.Utility; import com.google.common.collect.Lists; public class PlayerQuery implements Query { private List<String> names; private List<String> groups; private List<DamageCause> deathCause; private List<Boolean> murder; // Optimize away object creations private static List<String> noStrings = Utility.getElementList((String) null); private static List<DamageCause> noDamages = Utility.getElementList((DamageCause) null); private static List<Boolean> noKill = Utility.getElementList((Boolean) null); /** * Universal query. */ public static PlayerQuery fromAny() { return new PlayerQuery(noStrings, noStrings, noDamages, noKill); } /** * Creates a query where NULL values match any possible value in that category. * @param name - name to match, or NULL for every possible name. * @param group - group to match, or NULL for every possible group. * @return Resulting query. */ public static PlayerQuery fromAny(String name, String group) { return new PlayerQuery( Utility.getElementList(name), Utility.getElementList(group), noDamages, noKill); } /** * Creates a query where NULL values match any possible value in that category. * @param name - name to match, or NULL for every possible name. * @param group - group to match, or NULL for every possible group. * @param damageCause - damage cause to match, or NULL for every possible damage cause. * @param murder - whether or the player was killed by another player, or NULL if we don't care. * @return Resulting query. */ public static PlayerQuery fromAny(String name, String group, DamageCause damageCause, Boolean murder) { return new PlayerQuery( Utility.getElementList(name), Utility.getElementList(group), Utility.getElementList(damageCause), Utility.getElementList(murder)); } /** * Creates an exact query - where null values only match unspecified "any" queries. * @param name - name to match, or NULL to match unspecified values. * @param group - group to match, or NULL to match unspecified values. * @return Resulting query. */ public static PlayerQuery fromExact(String name, String group) { return new PlayerQuery( Lists.newArrayList(name), Lists.newArrayList(group), noDamages, noKill); } /** * Creates an exact query - where null values only match unspecified "any" queries. * @param player - player to match, or NULL to match every possible player. * @param groups - groups to match. Use a NULL element to match unspecified values. * @param murder - whether or the player was killed by another player, or NULL to match unknown cases. * @return Resulting query. */ public static PlayerQuery fromExact(Player player, String[] groups, Boolean murder) { EntityDamageEvent event = player != null ? player.getLastDamageCause() : null; DamageCause cause = null; if (event != null) { cause = event.getCause(); } // Delegate to a more specific method return fromExact(player != null ? player.getName() : null, groups, cause, murder); } /** * Creates an exact query - where null values only match unspecified "any" queries. * @param name - name to match, or NULL to match unspecified values. * @param groups - groups to match. Use a NULL element to match unspecified values. * @param damageCause - damage cause to match, or NULL to match unspecified values. * @param murder - whether or the player was killed by another player, or NULL to match unknown cases. * @return Resulting query. */ public static PlayerQuery fromExact(String name, String[] groups, DamageCause damageCause, Boolean murder) { return new PlayerQuery( Lists.newArrayList(name), Arrays.asList(groups), Lists.newArrayList(damageCause), Lists.newArrayList(murder)); } /** * Construct a player query by directly supplying the list of parameters. * @param names - list of names to match. * @param groups - list of groups to match. * @param deathCause - list of death causes to match. * @param murder - list of murder states. */ public PlayerQuery(List<String> names, List<String> groups, List<DamageCause> deathCause, List<Boolean> murder) { this.names = names; this.groups = groups; this.deathCause = deathCause; this.murder = murder; } public List<String> getNames() { return names; } public List<String> getGroups() { return groups; } public List<DamageCause> getDeathCause() { return deathCause; } public List<Boolean> getMurder() { return murder; } public boolean hasNames() { return names != null && !names.isEmpty(); } public boolean hasGroups() { return groups != null && !groups.isEmpty(); } public boolean hasDeathCause() { return deathCause != null && !deathCause.isEmpty(); } public boolean hasMurder() { return murder != null && !murder.isEmpty(); } @Override public int hashCode() { return new HashCodeBuilder(17, 31). append(names). append(groups). append(deathCause). append(murder). toHashCode(); } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (obj.getClass() != getClass()) return false; PlayerQuery other = (PlayerQuery) obj; return new EqualsBuilder(). append(names, other.names). append(groups, other.groups). append(deathCause, other.deathCause). append(murder, other.murder). isEquals(); } @Override public Types getQueryType() { return Types.PLAYERS; } @Override public boolean match(Query other) { // Match every parameter if (other instanceof PlayerQuery) { PlayerQuery query = (PlayerQuery) other; // Make sure the current query is the superset of other return QueryMatching.matchParameter(names, query.names) && QueryMatching.matchParameter(groups, query.groups) && QueryMatching.matchParameter(deathCause, query.deathCause) && QueryMatching.matchParameter(murder, query.murder); } // Query must be of the same type return false; } @Override public String toString() { return String.format("%s|%s|%s|%s", hasNames() ? StringUtils.join(names, ", ") : "", hasGroups() ? StringUtils.join(groups, ", ") : "", hasDeathCause() ? StringUtils.join(deathCause, ", ") : "", Utility.formatBoolean("murder", murder)); } }