vanish impl
This commit is contained in:
@@ -13,6 +13,7 @@ import net.kewwbec.networkcore.api.MetricsService;
|
||||
import net.kewwbec.networkcore.api.PlayerPresence;
|
||||
import net.kewwbec.networkcore.api.RpcClient;
|
||||
import net.kewwbec.networkcore.api.ServerRegistry;
|
||||
import net.kewwbec.networkcore.api.VanishService;
|
||||
import net.kewwbec.networkcore.api.events.ServerLeftNetworkEvent;
|
||||
import net.kewwbec.networkcore.bus.RedisMessageBus;
|
||||
import net.kewwbec.networkcore.command.NetworkCoreCommand;
|
||||
@@ -46,6 +47,11 @@ import net.kewwbec.networkcore.xp.XpSchemaBootstrap;
|
||||
import net.kewwbec.networkcore.presence.PlayerPresenceService;
|
||||
import net.kewwbec.networkcore.registry.RedisServerRegistry;
|
||||
import net.kewwbec.networkcore.rpc.RpcClientImpl;
|
||||
import net.kewwbec.networkcore.vanish.PlayerListVanishFilter;
|
||||
import net.kewwbec.networkcore.vanish.VanishEnforcer;
|
||||
import net.kewwbec.networkcore.vanish.VanishServiceImpl;
|
||||
|
||||
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -75,6 +81,7 @@ public final class NetworkCore extends JavaPlugin {
|
||||
@Nullable private RefRequestService refRequestService;
|
||||
@Nullable private LockService lockService;
|
||||
@Nullable private ShutdownHandoff shutdownHandoff;
|
||||
@Nullable private VanishServiceImpl vanishService;
|
||||
|
||||
public NetworkCore(@Nonnull JavaPluginInit init) {
|
||||
super(init);
|
||||
@@ -164,6 +171,13 @@ public final class NetworkCore extends JavaPlugin {
|
||||
this.alertService = new AlertService(messageBus, serverId);
|
||||
alertService.start();
|
||||
|
||||
this.vanishService = new VanishServiceImpl(messageBus, serverId);
|
||||
vanishService.start();
|
||||
services.register(VanishService.class, vanishService);
|
||||
VanishEnforcer vanishEnforcer = new VanishEnforcer(vanishService);
|
||||
getEventRegistry().registerGlobal(PlayerReadyEvent.class, vanishEnforcer::onPlayerReady);
|
||||
new PlayerListVanishFilter(vanishService).register();
|
||||
|
||||
this.refRequestService = new RefRequestService(messageBus, serverId);
|
||||
refRequestService.start();
|
||||
|
||||
@@ -185,7 +199,7 @@ public final class NetworkCore extends JavaPlugin {
|
||||
});
|
||||
|
||||
getCommandRegistry().registerCommand(new AlertCommand(alertService));
|
||||
getCommandRegistry().registerCommand(new GlistCommand(serverRegistry, presenceService));
|
||||
getCommandRegistry().registerCommand(new GlistCommand(serverRegistry, presenceService, vanishService));
|
||||
getCommandRegistry().registerCommand(new HubCommand(lobbyPicker, refRequestService, serverId));
|
||||
getCommandRegistry().registerCommand(new SendCommand(serverRegistry, presenceService, refRequestService));
|
||||
getCommandRegistry().registerCommand(new SendAllCommand(serverRegistry, presenceService, refRequestService, serverId));
|
||||
@@ -227,6 +241,10 @@ public final class NetworkCore extends JavaPlugin {
|
||||
try { alertService.stop(); } catch (RuntimeException ignored) {}
|
||||
alertService = null;
|
||||
}
|
||||
if (vanishService != null) {
|
||||
try { vanishService.stop(); } catch (RuntimeException ignored) {}
|
||||
vanishService = null;
|
||||
}
|
||||
if (presenceService != null) {
|
||||
try { presenceService.stop(); } catch (RuntimeException ignored) {}
|
||||
presenceService = null;
|
||||
@@ -288,6 +306,8 @@ public final class NetworkCore extends JavaPlugin {
|
||||
@Nullable
|
||||
public NetworkXp getNetworkXp() { return services.get(NetworkXp.class); }
|
||||
@Nullable
|
||||
public VanishService getVanishService() { return services.get(VanishService.class); }
|
||||
@Nullable
|
||||
public RefRequestService getRefRequestService() { return refRequestService; }
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.kewwbec.networkcore.api;
|
||||
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Cross-server vanish state. Source of truth shared via the {@link MessageBus};
|
||||
* each server caches and enforces locally (HiddenPlayersManager + join-broadcast
|
||||
* suppression by consuming plugins).
|
||||
*
|
||||
* <p>Players with the {@code networkstaff.vanish} permission can see vanished
|
||||
* players regardless. Everyone else sees them as if they weren't there.</p>
|
||||
*/
|
||||
public interface VanishService {
|
||||
|
||||
boolean isVanished(@Nonnull UUID playerUuid);
|
||||
|
||||
/**
|
||||
* Toggle vanish state for {@code playerUuid}. Persists to DB (if configured)
|
||||
* and broadcasts to other servers on the bus.
|
||||
*/
|
||||
void setVanished(@Nonnull UUID playerUuid, boolean vanished);
|
||||
|
||||
/** Snapshot of every UUID currently marked vanished, across the network. */
|
||||
@Nonnull
|
||||
Set<UUID> vanishedPlayers();
|
||||
|
||||
/**
|
||||
* Convenience check for "should I pretend this target is offline when showing
|
||||
* results to {@code viewer}?" Returns true iff {@code target} is vanished and
|
||||
* {@code viewer} lacks {@code networkstaff.vanish}. Null viewer is treated as
|
||||
* non-staff (defensive — assume hidden).
|
||||
*/
|
||||
boolean isHiddenFrom(@Nonnull UUID target, @Nullable PlayerRef viewer);
|
||||
|
||||
/**
|
||||
* Subscribe to vanish state changes. Listener receives {@code (uuid, vanishedNow)}
|
||||
* for every toggle, whether the change originated locally or arrived via the bus
|
||||
* from another server. Fires on the bus-handling thread; consumers that need the
|
||||
* world thread must hop themselves.
|
||||
*/
|
||||
void addListener(@Nonnull BiConsumer<UUID, Boolean> listener);
|
||||
}
|
||||
@@ -15,6 +15,8 @@ import net.kewwbec.networkcore.api.PlayerLocation;
|
||||
import net.kewwbec.networkcore.api.PlayerPresence;
|
||||
import net.kewwbec.networkcore.api.ServerInfo;
|
||||
import net.kewwbec.networkcore.api.ServerRegistry;
|
||||
import net.kewwbec.networkcore.api.VanishService;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.awt.Color;
|
||||
@@ -36,12 +38,16 @@ public final class GlistCommand extends AbstractPlayerCommand {
|
||||
|
||||
private final ServerRegistry registry;
|
||||
private final PlayerPresence presence;
|
||||
@Nullable private final VanishService vanish;
|
||||
private final OptionalArg<String> filterArg = withOptionalArg("filter", "Server id or role to filter by", ArgTypes.STRING);
|
||||
|
||||
public GlistCommand(@Nonnull ServerRegistry registry, @Nonnull PlayerPresence presence) {
|
||||
public GlistCommand(@Nonnull ServerRegistry registry,
|
||||
@Nonnull PlayerPresence presence,
|
||||
@Nullable VanishService vanish) {
|
||||
super("glist", "List online players, optionally filtered by server id or role");
|
||||
this.registry = registry;
|
||||
this.presence = presence;
|
||||
this.vanish = vanish;
|
||||
requirePermission(NetworkCorePermissions.GLIST);
|
||||
}
|
||||
|
||||
@@ -60,11 +66,13 @@ public final class GlistCommand extends AbstractPlayerCommand {
|
||||
Set<String> includedIds = new LinkedHashSet<>();
|
||||
for (ServerInfo s : servers) includedIds.add(s.id());
|
||||
|
||||
boolean canSeeVanished = sender.hasPermission(net.kewwbec.networkcore.vanish.VanishEnforcer.PERM_SEE);
|
||||
Map<String, List<PlayerLocation>> grouped = new LinkedHashMap<>();
|
||||
for (ServerInfo s : servers) grouped.put(s.id(), new ArrayList<>());
|
||||
int filteredOnline = 0;
|
||||
for (PlayerLocation loc : presence.all()) {
|
||||
if (!includedIds.contains(loc.serverId())) continue;
|
||||
if (!canSeeVanished && vanish != null && vanish.isVanished(loc.uuid())) continue;
|
||||
grouped.computeIfAbsent(loc.serverId(), k -> new ArrayList<>()).add(loc);
|
||||
filteredOnline++;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package net.kewwbec.networkcore.vanish;
|
||||
|
||||
import com.hypixel.hytale.protocol.Packet;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.AddToServerPlayerList;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.ServerPlayerListPlayer;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.ServerPlayerListUpdate;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.UpdateServerPlayerList;
|
||||
import com.hypixel.hytale.server.core.io.adapter.PacketAdapters;
|
||||
import com.hypixel.hytale.server.core.io.adapter.PlayerPacketFilter;
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
import net.kewwbec.networkcore.api.VanishService;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Outbound packet filter that strips vanished players from the client-visible
|
||||
* tab list. Runs for every outbound {@link AddToServerPlayerList} and
|
||||
* {@link UpdateServerPlayerList}; for non-staff recipients, drops any entries
|
||||
* for vanished UUIDs. If the resulting array is empty the packet is cancelled
|
||||
* entirely.
|
||||
*
|
||||
* <p>For mid-session toggles, see {@link VanishEnforcer#onVanishChanged} —
|
||||
* that side pushes explicit {@code RemoveFromServerPlayerList} /
|
||||
* {@code AddToServerPlayerList} to non-staff clients so the list updates
|
||||
* without waiting for the next engine push.</p>
|
||||
*/
|
||||
public final class PlayerListVanishFilter implements PlayerPacketFilter {
|
||||
|
||||
private final VanishService vanish;
|
||||
|
||||
public PlayerListVanishFilter(@Nonnull VanishService vanish) {
|
||||
this.vanish = vanish;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
PacketAdapters.registerOutbound(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nonnull PlayerRef recipient, @Nonnull Packet packet) {
|
||||
if (recipient.hasPermission(VanishEnforcer.PERM_SEE)) return false;
|
||||
|
||||
if (packet instanceof AddToServerPlayerList add) {
|
||||
return filterAdd(add);
|
||||
}
|
||||
if (packet instanceof UpdateServerPlayerList upd) {
|
||||
return filterUpdate(upd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean filterAdd(@Nonnull AddToServerPlayerList add) {
|
||||
ServerPlayerListPlayer[] players = add.players;
|
||||
if (players == null || players.length == 0) return false;
|
||||
List<ServerPlayerListPlayer> kept = new ArrayList<>(players.length);
|
||||
for (ServerPlayerListPlayer p : players) {
|
||||
if (p == null || p.uuid == null) continue;
|
||||
if (vanish.isVanished(p.uuid)) continue;
|
||||
kept.add(p);
|
||||
}
|
||||
if (kept.isEmpty()) return true;
|
||||
if (kept.size() != players.length) {
|
||||
add.players = kept.toArray(new ServerPlayerListPlayer[0]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean filterUpdate(@Nonnull UpdateServerPlayerList upd) {
|
||||
ServerPlayerListUpdate[] players = upd.players;
|
||||
if (players == null || players.length == 0) return false;
|
||||
List<ServerPlayerListUpdate> kept = new ArrayList<>(players.length);
|
||||
for (ServerPlayerListUpdate u : players) {
|
||||
if (u == null || u.uuid == null) continue;
|
||||
if (vanish.isVanished(u.uuid)) continue;
|
||||
kept.add(u);
|
||||
}
|
||||
if (kept.isEmpty()) return true;
|
||||
if (kept.size() != players.length) {
|
||||
upd.players = kept.toArray(new ServerPlayerListUpdate[0]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.kewwbec.networkcore.vanish;
|
||||
|
||||
/**
|
||||
* Bus payload broadcast on every vanish toggle. Carries enough state for any
|
||||
* server to update its cache and enforce locally.
|
||||
*/
|
||||
public final class VanishChangePayload {
|
||||
|
||||
public static final String CHANNEL = "network:vanish";
|
||||
|
||||
/** UUID being vanished/unvanished. */
|
||||
public String uuid;
|
||||
/** New state — true=vanished, false=unvanished. */
|
||||
public boolean vanished;
|
||||
/** Origin server id (for echo suppression). */
|
||||
public String serverId;
|
||||
/** Timestamp (ms since epoch) for staleness checks if we ever add them. */
|
||||
public long ts;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package net.kewwbec.networkcore.vanish;
|
||||
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.AddToServerPlayerList;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.RemoveFromServerPlayerList;
|
||||
import com.hypixel.hytale.protocol.packets.interface_.ServerPlayerListPlayer;
|
||||
import com.hypixel.hytale.server.core.entity.entities.player.HiddenPlayersManager;
|
||||
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
|
||||
import com.hypixel.hytale.server.core.io.PacketHandler;
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
import com.hypixel.hytale.server.core.universe.Universe;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Per-server enforcement of vanish state via {@link HiddenPlayersManager}.
|
||||
* Wired by NetworkCore: on player join we hide existing vanished players from
|
||||
* non-staff arrivals, and on vanish toggles (local or remote via bus) we update
|
||||
* every online player's visibility set.
|
||||
*/
|
||||
public final class VanishEnforcer {
|
||||
|
||||
/** Anyone with this perm sees vanished players and can use /vanish. */
|
||||
public static final String PERM_SEE = "networkstaff.vanish";
|
||||
|
||||
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||
|
||||
private final VanishServiceImpl vanish;
|
||||
|
||||
public VanishEnforcer(@Nonnull VanishServiceImpl vanish) {
|
||||
this.vanish = vanish;
|
||||
vanish.addListener(this::onVanishChanged);
|
||||
}
|
||||
|
||||
/** Called by NetworkCore on every PlayerReadyEvent. */
|
||||
public void onPlayerReady(@Nonnull PlayerReadyEvent event) {
|
||||
com.hypixel.hytale.component.Ref<com.hypixel.hytale.server.core.universe.world.storage.EntityStore> ref =
|
||||
event.getPlayerRef();
|
||||
if (ref == null || !ref.isValid()) return;
|
||||
com.hypixel.hytale.component.Store<com.hypixel.hytale.server.core.universe.world.storage.EntityStore> store =
|
||||
ref.getStore();
|
||||
if (store == null) return;
|
||||
PlayerRef newcomer = store.getComponent(ref, PlayerRef.getComponentType());
|
||||
if (newcomer == null) return;
|
||||
|
||||
UUID newcomerUuid = newcomer.getUuid();
|
||||
boolean newcomerCanSeeVanished = newcomer.hasPermission(PERM_SEE);
|
||||
|
||||
if (!newcomerCanSeeVanished) {
|
||||
HiddenPlayersManager hpm = newcomer.getHiddenPlayersManager();
|
||||
if (hpm != null) {
|
||||
for (UUID vanishedUuid : vanish.vanishedPlayers()) {
|
||||
if (vanishedUuid.equals(newcomerUuid)) continue;
|
||||
hpm.hidePlayer(vanishedUuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vanish.isVanished(newcomerUuid)) {
|
||||
Universe universe = Universe.get();
|
||||
if (universe == null) return;
|
||||
for (PlayerRef other : universe.getPlayers()) {
|
||||
if (other.getUuid().equals(newcomerUuid)) continue;
|
||||
if (other.hasPermission(PERM_SEE)) continue;
|
||||
HiddenPlayersManager hpm = other.getHiddenPlayersManager();
|
||||
if (hpm != null) hpm.hidePlayer(newcomerUuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onVanishChanged(@Nonnull UUID uuid, boolean vanishedNow) {
|
||||
Universe universe = Universe.get();
|
||||
if (universe == null) return;
|
||||
try {
|
||||
PlayerRef subject = null;
|
||||
for (PlayerRef p : universe.getPlayers()) {
|
||||
if (p.getUuid().equals(uuid)) { subject = p; break; }
|
||||
}
|
||||
for (PlayerRef other : universe.getPlayers()) {
|
||||
if (other.getUuid().equals(uuid)) continue;
|
||||
HiddenPlayersManager hpm = other.getHiddenPlayersManager();
|
||||
if (hpm != null) {
|
||||
if (other.hasPermission(PERM_SEE)) {
|
||||
hpm.showPlayer(uuid);
|
||||
} else if (vanishedNow) {
|
||||
hpm.hidePlayer(uuid);
|
||||
} else {
|
||||
hpm.showPlayer(uuid);
|
||||
}
|
||||
}
|
||||
if (other.hasPermission(PERM_SEE)) continue;
|
||||
PacketHandler ph = other.getPacketHandler();
|
||||
if (ph == null) continue;
|
||||
try {
|
||||
if (vanishedNow) {
|
||||
ph.write(new RemoveFromServerPlayerList(new UUID[]{uuid}));
|
||||
} else if (subject != null) {
|
||||
ServerPlayerListPlayer entry = new ServerPlayerListPlayer(
|
||||
subject.getUuid(),
|
||||
subject.getUsername(),
|
||||
subject.getWorldUuid(),
|
||||
0);
|
||||
ph.write(new AddToServerPlayerList(new ServerPlayerListPlayer[]{entry}));
|
||||
}
|
||||
} catch (RuntimeException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.at(Level.WARNING).log("VanishEnforcer onVanishChanged threw: %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package net.kewwbec.networkcore.vanish;
|
||||
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
import net.kewwbec.networkcore.api.MessageBus;
|
||||
import net.kewwbec.networkcore.api.VanishService;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* In-memory vanish cache, kept consistent across the network via the
|
||||
* {@link MessageBus}. State is not persisted — vanish ends at server restart
|
||||
* (intentional: staff explicitly turn it on each session).
|
||||
*/
|
||||
public final class VanishServiceImpl implements VanishService {
|
||||
|
||||
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||
|
||||
private final MessageBus bus;
|
||||
private final String selfServerId;
|
||||
private final Set<UUID> vanished = ConcurrentHashMap.newKeySet();
|
||||
/** Listeners notified on every change, local or remote-via-bus. */
|
||||
private final List<BiConsumer<UUID, Boolean>> listeners = new CopyOnWriteArrayList<>();
|
||||
@Nullable private MessageBus.Subscription sub;
|
||||
|
||||
public VanishServiceImpl(@Nonnull MessageBus bus, @Nonnull String selfServerId) {
|
||||
this.bus = bus;
|
||||
this.selfServerId = selfServerId;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
sub = bus.subscribe(VanishChangePayload.CHANNEL, VanishChangePayload.class, this::onRemote);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (sub != null) {
|
||||
try { sub.close(); } catch (RuntimeException ignored) {}
|
||||
sub = null;
|
||||
}
|
||||
vanished.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(@Nonnull BiConsumer<UUID, Boolean> listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanished(@Nonnull UUID playerUuid) {
|
||||
return vanished.contains(playerUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVanished(@Nonnull UUID playerUuid, boolean vanishedNow) {
|
||||
boolean changed = vanishedNow ? vanished.add(playerUuid) : vanished.remove(playerUuid);
|
||||
if (!changed) return;
|
||||
fireLocal(playerUuid, vanishedNow);
|
||||
publish(playerUuid, vanishedNow);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Set<UUID> vanishedPlayers() {
|
||||
return Collections.unmodifiableSet(vanished);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHiddenFrom(@Nonnull UUID target, @Nullable PlayerRef viewer) {
|
||||
if (!vanished.contains(target)) return false;
|
||||
if (viewer == null) return true;
|
||||
if (viewer.getUuid().equals(target)) return false;
|
||||
return !viewer.hasPermission(VanishEnforcer.PERM_SEE);
|
||||
}
|
||||
|
||||
private void onRemote(@Nonnull VanishChangePayload p) {
|
||||
if (p.uuid == null || p.serverId == null) return;
|
||||
if (selfServerId.equals(p.serverId)) return;
|
||||
UUID uuid;
|
||||
try { uuid = UUID.fromString(p.uuid); } catch (IllegalArgumentException e) { return; }
|
||||
boolean changed = p.vanished ? vanished.add(uuid) : vanished.remove(uuid);
|
||||
if (changed) fireLocal(uuid, p.vanished);
|
||||
}
|
||||
|
||||
private void publish(@Nonnull UUID uuid, boolean vanishedNow) {
|
||||
try {
|
||||
VanishChangePayload p = new VanishChangePayload();
|
||||
p.uuid = uuid.toString();
|
||||
p.vanished = vanishedNow;
|
||||
p.serverId = selfServerId;
|
||||
p.ts = System.currentTimeMillis();
|
||||
bus.publish(VanishChangePayload.CHANNEL, p);
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.at(Level.WARNING).log("Vanish publish failed: %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void fireLocal(@Nonnull UUID uuid, boolean vanishedNow) {
|
||||
for (BiConsumer<UUID, Boolean> listener : listeners) {
|
||||
try {
|
||||
listener.accept(uuid, vanishedNow);
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.at(Level.WARNING).log("Vanish listener threw: %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user