Skip to content

Commit

Permalink
Add new event and API for PlayerFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Apr 16, 2023
1 parent 0c15f92 commit bfcdea3
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 30 deletions.
43 changes: 43 additions & 0 deletions src/main/java/net/citizensnpcs/api/event/NPCSeenByPlayerEvent.java
@@ -0,0 +1,43 @@
package net.citizensnpcs.api.event;

import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;

import net.citizensnpcs.api.npc.NPC;

public class NPCSeenByPlayerEvent extends NPCEvent implements Cancellable {
private boolean cancel;
private final Player player;

public NPCSeenByPlayerEvent(NPC npc, Player player) {
super(npc);
this.player = player;
}

@Override
public HandlerList getHandlers() {
return handlers;
}

public Player getPlayer() {
return player;
}

@Override
public boolean isCancelled() {
return cancel;
}

@Override
public void setCancelled(boolean cancel) {
this.cancel = cancel;
}

public static HandlerList getHandlerList() {
return handlers;
}

private static final HandlerList handlers = new HandlerList();

}
136 changes: 107 additions & 29 deletions src/main/java/net/citizensnpcs/api/trait/trait/PlayerFilter.java
@@ -1,10 +1,13 @@
package net.citizensnpcs.api.trait.trait;

import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Function;

import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;

Expand All @@ -18,36 +21,47 @@
public class PlayerFilter extends Trait {
@Persist
private Set<UUID> allowlist = null;
private Function<Player, Boolean> filter;
@Persist
private Set<String> groupAllowlist = null;
@Persist
private Set<String> groupHidden = null;
@Persist
private Set<UUID> hidden = null;
private Function<Player, Boolean> hideFunction = (p) -> {
if (allowlist != null && !allowlist.contains(p.getUniqueId()))
return true;
if (hidden != null && hidden.contains(p.getUniqueId()))
return true;
if (groupAllowlist != null || groupHidden != null) {
RegisteredServiceProvider<net.milkbowl.vault.permission.Permission> groups = Bukkit.getServicesManager()
.getRegistration(net.milkbowl.vault.permission.Permission.class);
if (groups != null
&& !groupAllowlist.stream().anyMatch(group -> groups.getProvider().playerInGroup(p, group))) {
return true;
}
if (groups != null
&& groupHidden.stream().anyMatch(group -> groups.getProvider().playerInGroup(p, group))) {
return true;
}
}
return false;
};
private final Set<UUID> hiddenPlayers = Sets.newHashSet();
private BiConsumer<Player, Entity> hideFunction;
private BiConsumer<Player, Entity> viewFunction;
private final Set<UUID> viewingPlayers = Sets.newHashSet();

public PlayerFilter() {
super("playerfilter");
}

public PlayerFilter(BiConsumer<Player, Entity> hideFunction, BiConsumer<Player, Entity> viewFunction) {
this();
this.filter = p -> {
if (allowlist != null && !allowlist.contains(p.getUniqueId()))
return true;
if (hidden != null && hidden.contains(p.getUniqueId()))
return true;
if (groupAllowlist != null || groupHidden != null) {
RegisteredServiceProvider<net.milkbowl.vault.permission.Permission> groups = Bukkit.getServicesManager()
.getRegistration(net.milkbowl.vault.permission.Permission.class);
if (groups != null
&& !groupAllowlist.stream().anyMatch(group -> groups.getProvider().playerInGroup(p, group))) {
return true;
}
if (groups != null
&& groupHidden.stream().anyMatch(group -> groups.getProvider().playerInGroup(p, group))) {
return true;
}
}
return false;
};
this.hideFunction = hideFunction;
this.viewFunction = viewFunction;
}

public void clear() {
hidden = allowlist = null;
groupAllowlist = groupHidden = null;
Expand All @@ -58,60 +72,124 @@ public void hide(UUID uuid) {
hidden = Sets.newHashSet();
}
hidden.add(uuid);
viewingPlayers.add(uuid);
recalculate();
}

public void hideGroup(String group) {
if (groupHidden == null) {
groupHidden = Sets.newHashSet();
}
groupHidden.add(group);
recalculate();
}

public boolean isHidden(Player player) {
if (hideFunction == null)
return false;
return hideFunction.apply(player);
return filter == null ? false : filter.apply(player);
}

@Override
public void onDespawn() {
hiddenPlayers.clear();
viewingPlayers.clear();
}

/**
* Only the given {@link Player} identified by their {@link UUID} should see the {@link NPC}.
*/
public void only(UUID uuid) {
if (allowlist == null) {
allowlist = Sets.newHashSet();
}
allowlist.add(uuid);
recalculate();
}

public void onlyGroup(String group) {
if (groupAllowlist == null) {
groupAllowlist = Sets.newHashSet();
}
groupAllowlist.add(group);
recalculate();
}

/**
* For internal use. Method signature may be changed at any time.
*/
public boolean onSeenByPlayer(Player player) {
if (isHidden(player)) {
this.hiddenPlayers.add(player.getUniqueId());
return true;
}
this.viewingPlayers.add(player.getUniqueId());
return false;
}

/**
* Explicit recalculation of which {@link Player}s should be viewing the {@link NPC}. Sends hide packets for players
* that should no longer view the NPC.
*/
public void recalculate() {
System.out.println(viewingPlayers + " " + hiddenPlayers);
for (Iterator<UUID> itr = viewingPlayers.iterator(); itr.hasNext();) {
UUID uuid = itr.next();
Player player = Bukkit.getPlayer(uuid);
if (player == null) {
itr.remove();
continue;
}
if (hideFunction != null && filter.apply(player)) {
hideFunction.accept(player, npc.getEntity());
itr.remove();
}
}
for (Iterator<UUID> itr = hiddenPlayers.iterator(); itr.hasNext();) {
UUID uuid = itr.next();
Player player = Bukkit.getPlayer(uuid);
if (player == null) {
itr.remove();
continue;
}
if (viewFunction != null && !filter.apply(player)) {
viewFunction.accept(player, npc.getEntity());
itr.remove();
}
}
}

/**
* Sets the filter function, which returns {@code true} if the {@link NPC} should be hidden from the given
* {@link Player}.
*/
public void setPlayerFilter(Function<Player, Boolean> filter) {
this.hideFunction = filter;
this.filter = filter;
recalculate();
}

public void unhide(UUID uuid) {
if (hidden != null) {
hidden.remove(uuid);
}
if (hidden.size() == 0) {
hidden = null;
if (hidden.size() == 0) {
hidden = null;
}
}
if (allowlist != null) {
allowlist.remove(uuid);
}
hiddenPlayers.add(uuid);
recalculate();
}

public void unhideGroup(String group) {
if (groupHidden != null) {
groupHidden.remove(group);
}
if (groupHidden.size() == 0) {
groupHidden = null;
if (groupHidden.size() == 0) {
groupHidden = null;
}
}
if (groupAllowlist != null) {
groupAllowlist = null;
}
recalculate();
}
}
3 changes: 2 additions & 1 deletion src/main/java/net/citizensnpcs/api/util/Translator.java
Expand Up @@ -77,8 +77,9 @@ private MessageFormat getFormatter(String unreplaced) {

private String translate(String key, Locale locale) {
ResourceBundle bundle = preferredBundle;
if (locale != defaultLocale)
if (locale != defaultLocale) {
bundle = getBundle(locale);
}
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
Expand Down

0 comments on commit bfcdea3

Please sign in to comment.