8000 Dynamic filters! by KingOfSquares · Pull Request #914 · PGMDev/PGM · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Dynamic filters! #914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Oct 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3443a3a
Add dynamic filter support to FilterMatchModule
Pugzy Jan 9, 2021
493b30c
Update portal logic and use dynamic filters
Pugzy Jan 9, 2021
c8d9296
Make MatchPlayer implement Filterable instead of the PlayerQuery
KingOfSquares Jan 12, 2021
4c73f80
Add some documentation
KingOfSquares Mar 20, 2021
371d6a2
Actually follow Filterable implementation spec
Pugzy Apr 5, 2021
1fafac8
Ch-Ch-Ch-Changes
Pugzy Aug 8, 2021
1ef46d1
Formatting and extra portal XML exception
Pugzy Aug 9, 2021
a8a11f3
Throw error when a non-dynamic filter is registered as a dynamic one
KingOfSquares Aug 9, 2021
1e43136
Actually, dont re-introduce that bug
KingOfSquares Aug 9, 2021
d78047b
Some cleanup
KingOfSquares Aug 9, 2021
563d329
default Query#getEvent to null
KingOfSquares Aug 10, 2021
459a882
Suppress some casting warnings
KingOfSquares Aug 10, 2021
76ddc11
Revert changes to MultiFilterFunction
Pugzy Aug 10, 2021
d3d41a3
Resolve issue with empty internalSetParty
Pugzy Aug 10, 2021
416454c
Ensure filter event listeners are registered after everything else is…
KingOfSquares Aug 13, 2021
ea23d04
Use MethodHandles to optimize how Filterables are extracted from arbi…
KingOfSquares Aug 14, 2021
250fbda
Scope MethodHandle creating to Entityy instead of PLayer
KingOfSquares Aug 14, 2021
1a4697a
Add handler parent check and caching and start testing
Pugzy Aug 21, 2021
df5e8b9
Continue fixing
Pugzy Aug 22, 2021
5ea0ad9
Add handlers directly to goal event classes
Pugzy Aug 22, 2021
126e487
Fix getHandle cache exception message and comment
Pugzy Aug 22, 2021
b4c4e57
Remove class as a dynamic filter
Pugzy Aug 22, 2021
4d1b56d
Remove redundant inheritdoc javadoc tags
KingOfSquares Sep 1, 2021
c618a30
Change SingetonImmutableList to native singleton Collection
KingOfSquares Sep 1, 2021
bf3b180
Replace optionals with @Nullable and streams with Collection
KingOfSquares Sep 1, 2021
d64d242
Use PlayerItemTransferEvent in holding and carrying filter
KingOfSquares Sep 1, 2021
8109456
Prefix filterable interface methods with get
Pugzy Sep 5, 2021
73eaffb
Move handler management to MethodHandleUtils
Pugzy Sep 12, 2021
598c197
Change access point of MethodHandleUtils
KingOfSquares Sep 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/main/java/tc/oc/pgm/api/Modules.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import tc.oc.pgm.fallingblocks.FallingBlocksModule;
import tc.oc.pgm.ffa.FreeForAllMatchModule;
import tc.oc.pgm.ffa.FreeForAllModule;
import tc.oc.pgm.filters.FilterMatchModule;
import tc.oc.pgm.filters.FilterModule;
import tc.oc.pgm.filters.dynamic.FilterMatchModule;
import tc.oc.pgm.fireworks.FireworkMatchModule;
import tc.oc.pgm.flag.FlagMatchModule;
import tc.oc.pgm.flag.FlagModule;
Expand Down
39 changes: 39 additions & 0 deletions core/src/main/java/tc/oc/pgm/api/filter/Filter.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,53 @@
package tc.oc.pgm.api.filter;

import com.google.common.collect.ImmutableList;
import java.util.Collection;
import org.bukkit.event.Event;
import tc.oc.pgm.api.feature.Feature;
import tc.oc.pgm.api.feature.FeatureReference;
import tc.oc.pgm.api.filter.query.Query;
import tc.oc.pgm.filters.FilterParser;

/**
* Something that can answer "yes", "no" or "i don't care" to the imagined question: "Can X
* happen?". To be able to answer the question context is provided initially through a {@link Query}
* and then processed by the filter itself before a response is given.
*
* <p>If a filter is connected to a specific {@link Feature} a {@link FeatureReference} should be
* passed at xml parse time (when the filter is created) and {@link FeatureReference#get() fetched}
* at match time
*
* <p>For examples on how to create filters see {@link FilterParser}
*
* @see Query
*/
public interface Filter {

/**
* Filters with children are responsible for returning the events of their children.
*
* <p>Empty list tells us that the filter is not dynamic
*/
default Collection<Class<? extends Event>> getRelevantEvents() {
return ImmutableList.of();
}

/** Least-derived query type that this filter might not abstain from */
Class<? extends Query> getQueryType();

QueryResponse query(Query query);

default boolean response(Query query) {
switch (query(query)) {
case ALLOW:
return true;
case DENY:
return false;
default:
throw new UnsupportedOperationException("Filter did not respond to the query");
}
}

enum QueryResponse {
ALLOW,
DENY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@

/** A query for a player that may or may not be online or participating in the match. */
public interface PlayerQuery extends PartyQuery, EntityTypeQuery, LocationQuery {
UUID getPlayerId();
UUID getId();

/*TODO this is not followed in any implementations or trusted by any other code. If this is fixed change places like
CarryingFlagFilter Line 33/34 at the time of this commit
ParticipantFilter Line 26/27
RegionMatchModule Line 375/376 etc...*/
/** Return the {@link MatchPlayer} for this player if they are online, otherwise null. */
@Nullable
MatchPlayer getPlayer();
Expand Down
26 changes: 25 additions & 1 deletion core/src/main/java/tc/oc/pgm/api/filter/query/Query.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
package tc.oc.pgm.api.filter.query;

import javax.annotation.Nullable;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.entity.CreatureSpawnEvent;
import tc.oc.pgm.api.filter.Filter;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.party.Party;
import tc.oc.pgm.api.player.MatchPlayer;
import tc.oc.pgm.goals.Goal;

/**
* A query can be thought of as context to a question which can be asked to a {@link Filter}. The
* context can include different information like a {@link Match}, a {@link Goal}, a {@link
* MatchPlayer} or a {@link CreatureSpawnEvent.SpawnReason}.
*
* @implSpec a {@link Query} interface should only add <b>one</b> piece of information to the
* context. To increase the amount of information retrievable from the query it can extend other
* queries.
* <p>A {@link PlayerQuery} adds a {@link MatchPlayer} to the context, but can also provide info
* found in other queries like a {@link Party} or a {@link Location}, therefore it extends those
* queries({@link PartyQuery}, {@link LocationQuery}) instead of adding more methods to its own
* interface.
* @see Filter
*/
public interface Query {
/** The event providing the query information, if any */
@Nullable
Event getEvent();
default Event getEvent() {
return null;
}
}
3 changes: 3 additions & 0 deletions core/src/main/java/tc/oc/pgm/api/map/MapProtos.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@ public interface MapProtos {

// Option on objectives to determine if they are required to win the match
Version GOAL_REQUIRED_OPTION = new Version(1, 4, 0);

// Various changes to support dynamic filters
Version DYNAMIC_FILTERS = new Version(1, 4, 2);
}
22 changes: 13 additions & 9 deletions core/src/main/java/tc/oc/pgm/api/match/Match.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import tc.oc.pgm.api.filter.query.MatchQuery;
import tc.oc.pgm.api.map.MapInfo;
import tc.oc.pgm.api.match.event.MatchFinishEvent;
import tc.oc.pgm.api.match.event.MatchLoadEvent;
Expand All @@ -27,7 +28,7 @@
import tc.oc.pgm.api.time.Tick;
import tc.oc.pgm.countdowns.CountdownContext;
import tc.oc.pgm.features.MatchFeatureContext;
import tc.oc.pgm.filters.query.Query;
import tc.oc.pgm.filters.dynamic.Filterable;
import tc.oc.pgm.util.Audience;

/**
Expand All @@ -38,7 +39,12 @@
* {@link Match}. This should allow multiple {@link Match}es to run concurrently on the same {@link
* org.bukkit.Server}, as long as resources are cleaned up after {@link #unload()}.
*/
public interface Match extends MatchPlayerResolver, Audience, ModuleContext<MatchModule> {
public interface Match
extends MatchPlayerResolver,
Audience,
ModuleContext<MatchModule>,
Filterable<MatchQuery>,
MatchQuery {

/**
* Get the global {@link Logger} for the {@link Match}.
Expand Down Expand Up @@ -365,13 +371,6 @@ default boolean finish() {
*/
void removeParty(Party party);

/**
* Get the {@link Query} associated with the {@link Match}.
*
* @return The filter {@link Query}.
*/
Query getQuery();

/**
* Get the {@link Duration} of the {@link Match}, or {@link Duration#ZERO} if not yet started.
*
Expand Down Expand Up @@ -407,4 +406,9 @@ default boolean finish() {
* @return If the {@link Match} was just ended.
*/
boolean calculateVictory();

@Override
default Match getMatch() {
return this;
}
}
21 changes: 20 additions & 1 deletion core/src/main/java/tc/oc/pgm/api/party/Party.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import org.bukkit.ChatColor;
import org.bukkit.Color;
import tc.oc.pgm.api.filter.query.PartyQuery;
import tc.oc.pgm.api.filter.query.PlayerQuery;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.player.MatchPlayer;
import tc.oc.pgm.filters.dynamic.Filterable;
import tc.oc.pgm.util.Audience;
import tc.oc.pgm.util.named.Named;

Expand All @@ -17,7 +19,8 @@
*
* @see Competitor
*/
public interface Party extends Audience, Named {
public interface Party extends Audience, Named, Filterable<PartyQuery>, PartyQuery {

/**
* Gets the match.
*
Expand Down Expand Up @@ -132,4 +135,20 @@ default boolean isParticipating() {
default boolean isObserving() {
return !this.isParticipating();
}

@Override
@Nullable
default Match getFilterableParent() {
return this.getMatch();
}

@Override
default Collection<? extends Filterable<? extends PlayerQuery>> getFilterableChildren() {
return this.getPlayers();
}

@Override
default Party getParty() {
return this;
}
}
24 changes: 15 additions & 9 deletions core/src/main/java/tc/oc/pgm/api/player/MatchPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.UUID;
import javax.annotation.Nullable;
import org.bukkit.GameMode;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.PlayerInventory;
Expand All @@ -12,7 +13,7 @@
import tc.oc.pgm.api.party.Competitor;
import tc.oc.pgm.api.party.Party;
import tc.oc.pgm.api.setting.Settings;
import tc.oc.pgm.filters.query.Query;
import tc.oc.pgm.filters.dynamic.Filterable;
import tc.oc.pgm.kits.Kit;
import tc.oc.pgm.util.Audience;
import tc.oc.pgm.util.attribute.Attribute;
Expand All @@ -27,7 +28,8 @@
* this is used is to check if a {@link MatchPlayer} is involved in an event. If you need to access
* or modify a {@link Player}, there should be a method added to {@link MatchPlayer}.
*/
public interface MatchPlayer extends Audience, Named, Tickable, InventoryHolder {
public interface MatchPlayer
extends Audience, Named, Tickable, InventoryHolder, Filterable<PlayerQuery>, PlayerQuery {

/**
* Get the {@link Match} of the {@link MatchPlayer}.
Expand Down Expand Up @@ -73,13 +75,6 @@ public interface MatchPlayer extends Audience, Named, Tickable, InventoryHolder
@Nullable
ParticipantState getParticipantState();

/**
* Get the filter {@link Query} that exclusively matches the {@link MatchPlayer}.
*
* @return The {@link Query} to match the {@link MatchPlayer}.
*/
PlayerQuery getQuery();

/**
* Get the underlying {@link Player} that is associated with the {@link MatchPlayer}.
*
Expand Down Expand Up @@ -257,4 +252,15 @@ default boolean isLegacy() {

@Deprecated
void internalSetParty(Party party);

@Override
default Class<? extends Entity> getEntityType() {
return Player.class;
}

@Nullable
@Override
default MatchPlayer getPlayer() {
return this;
}
}
4 changes: 4 additions & 0 deletions core/src/main/java/tc/oc/pgm/api/region/Region.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package tc.oc.pgm.api.region;

import java.util.Collection;
import java.util.Iterator;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import tc.oc.pgm.api.filter.Filter;
Expand Down Expand Up @@ -75,4 +77,6 @@ public interface Region extends Filter {
public Iterator<BlockVector> getBlockVectorIterator();

public Iterable<BlockVector> getBlockVectors();

public Collection<Class<? extends Event>> getRelevantEvents();
}
2 changes: 1 addition & 1 deletion core/src/main/java/tc/oc/pgm/blitz/BlitzMatchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public int getNumOfLives(UUID id) {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void handleDeath(final MatchPlayerDeathEvent event) {
MatchPlayer victim = event.getVictim();
if (config.getFilter().query(victim.getQuery()).isDenied()) return;
if (config.getFilter().query(victim).isDenied()) return;
if (victim.getParty() instanceof Competitor) {
Competitor competitor = (Competitor) victim.getParty();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ protected Component formatText() {
public void onEnd(Duration total) {
super.onEnd(total);
for (MatchPlayer player : this.getMatch().getPlayers()) {
if (this.broadcast.filter == null
|| this.broadcast.filter.query(player.getQuery()).isAllowed()) {
if (this.broadcast.filter == null || this.broadcast.filter.query(player).isAllowed()) {
player.sendMessage(this.broadcast.getFormattedMessage());
player.playSound(this.broadcast.getSound());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ private boolean canCapture(Competitor team) {

private boolean canDominate(MatchPlayer player) {
return this.definition.getPlayerFilter() == null
|| this.definition.getPlayerFilter().query(player.getQuery()).isAllowed();
|| this.definition.getPlayerFilter().query(player).isAllowed();
}

public float getEffectivePointsPerSecond() {
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/tc/oc/pgm/ffa/Tribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,13 @@ public boolean isAutomatic() {
}

/**
* If the player is online and participating, this delegates to {@link MatchPlayer#getQuery()}.
* Otherwise it returns an PlayerQuery, which knows about the player's identity, but has no
* properties related to physical presence in the match.
* If the player is online and participating, this delegates to that player. Otherwise it returns
* a PlayerQuery, which knows about the player's identity, but has no properties related to
* physical presence in the match.
*/
@Override
public tc.oc.pgm.api.filter.query.PartyQuery getQuery() {
return player != null ? player.getQuery() : query;
return player != null ? player : query;
}

@Override
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/tc/oc/pgm/filters/CarryingFlagFilter.java
528C
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package tc.oc.pgm.filters;

import java.util.Collection;
import java.util.Collections;
import org.bukkit.event.Event;
import tc.oc.pgm.api.feature.FeatureReference;
import tc.oc.pgm.api.filter.query.PartyQuery;
import tc.oc.pgm.api.filter.query.PlayerQuery;
Expand All @@ -9,6 +12,7 @@
import tc.oc.pgm.api.player.MatchPlayer;
import tc.oc.pgm.flag.Flag;
import tc.oc.pgm.flag.FlagDefinition;
import tc.oc.pgm.flag.event.FlagStateChangeEvent;

public class CarryingFlagFilter extends TypedFilter<PartyQuery> {

Expand All @@ -18,6 +22,11 @@ public CarryingFlagFilter(FeatureReference<? extends FlagDefinition> flag) {
this.flag = flag;
}

@Override
public Collection<Class<? extends Event>> getRelevantEvents() {
return Collections.singleton(FlagStateChangeEvent.class);
}

@Override
public Class<? extends PartyQuery> getQueryType() {
return PartyQuery.class;
Expand All @@ -30,7 +39,7 @@ protected QueryResponse queryTyped(PartyQuery query) {
if (goal == null) return QueryResponse.ABSTAIN;

if (query instanceof PlayerQuery) {
MatchPlayer player = match.getPlayer(((PlayerQuery) query).getPlayerId());
MatchPlayer player = match.getPlayer(((PlayerQuery) query).getId());
return QueryResponse.fromBoolean(player != null && goal.isCarrying(player));
} else {
final Party party = query.getParty();
Expand Down
Loading
0