add vanish to here

This commit is contained in:
2026-06-04 16:49:20 -04:00
parent fc5d0639b8
commit e7e92cb8c3
6 changed files with 196 additions and 0 deletions
@@ -17,6 +17,7 @@ public final class StaffPermissionsNodes {
public static final String LOOKUP = ROOT + ".lookup";
public static final String HISTORY = ROOT + ".history";
public static final String UI = ROOT + ".ui";
public static final String VANISH = ROOT + ".vanish";
private StaffPermissionsNodes() {
}
@@ -143,6 +143,18 @@ public final class StaffPlugin extends JavaPlugin {
StaffUIContext uiContext = new StaffUIContext(permissions, punishmentService, staffChat, resolver, punishmentRepo, seenRepo);
getCommandRegistry().registerCommand(new StaffUICommand(uiContext));
net.kewwbec.networkcore.api.VanishService vanish = core.getVanishService();
if (vanish != null) {
getCommandRegistry().registerCommand(new net.kewwbec.staff.command.VanishCommand(vanish));
net.kewwbec.staff.listener.VanishHudController hudController =
new net.kewwbec.staff.listener.VanishHudController(vanish);
vanish.addListener(hudController::onVanishChanged);
getEventRegistry().registerGlobal(PlayerReadyEvent.class, hudController::onPlayerReady);
getEventRegistry().registerGlobal(PlayerDisconnectEvent.class, hudController::onPlayerDisconnect);
} else {
LOGGER.at(Level.WARNING).log("Staff: NetworkCore VanishService unavailable, skipping /vanish + HUD");
}
LOGGER.at(Level.INFO).log("Staff started");
}
@@ -0,0 +1,47 @@
package net.kewwbec.staff.command;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import net.kewwbec.networkcore.api.VanishService;
import net.kewwbec.staff.StaffPermissionsNodes;
import javax.annotation.Nonnull;
import java.awt.Color;
/**
* Toggles vanish for the sender. Cross-server via {@link VanishService}'s bus
* channel — if the sender hops to another server, they remain vanished there.
*/
public final class VanishCommand extends AbstractPlayerCommand {
private final VanishService vanish;
public VanishCommand(@Nonnull VanishService vanish) {
super("vanish", "Toggle vanish: hide yourself from non-staff players network-wide");
this.vanish = vanish;
requirePermission(StaffPermissionsNodes.VANISH);
}
@Override protected boolean canGeneratePermission() { return false; }
@Override
protected void execute(@Nonnull CommandContext ctx,
@Nonnull Store<EntityStore> store,
@Nonnull Ref<EntityStore> ref,
@Nonnull PlayerRef sender,
@Nonnull World world) {
boolean now = !vanish.isVanished(sender.getUuid());
vanish.setVanished(sender.getUuid(), now);
if (now) {
ctx.sendMessage(Message.raw("You are now vanished. Non-staff can't see you.").color(Color.GREEN));
} else {
ctx.sendMessage(Message.raw("You are no longer vanished.").color(Color.YELLOW));
}
}
}
@@ -0,0 +1,95 @@
package net.kewwbec.staff.listener;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.event.events.player.PlayerDisconnectEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import net.kewwbec.networkcore.api.VanishService;
import net.kewwbec.staff.ui.VanishStatusHud;
import javax.annotation.Nonnull;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
/**
* Owns the per-player {@link VanishStatusHud} lifecycle: shows it when the local
* player vanishes (including remote-origin toggles), hides on unvanish or disconnect,
* shows on initial join if already vanished.
*/
public final class VanishHudController {
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
private final VanishService vanish;
private final ConcurrentMap<UUID, VanishStatusHud> active = new ConcurrentHashMap<>();
public VanishHudController(@Nonnull VanishService vanish) {
this.vanish = vanish;
}
public void onPlayerReady(@Nonnull PlayerReadyEvent event) {
Ref<EntityStore> ref = event.getPlayerRef();
if (ref == null || !ref.isValid()) return;
Store<EntityStore> store = ref.getStore();
if (store == null) return;
PlayerRef player = store.getComponent(ref, PlayerRef.getComponentType());
if (player == null) return;
if (vanish.isVanished(player.getUuid())) {
showFor(player);
}
}
public void onPlayerDisconnect(@Nonnull PlayerDisconnectEvent event) {
PlayerRef ref = event.getPlayerRef();
if (ref == null) return;
active.remove(ref.getUuid());
}
public void onVanishChanged(@Nonnull UUID uuid, @Nonnull Boolean vanishedNow) {
PlayerRef target = findOnline(uuid);
if (target == null) return;
World world = target.getReference() == null
? null
: target.getReference().getStore().getExternalData().getWorld();
Runnable apply = () -> {
try {
if (vanishedNow) showFor(target);
else hideFor(target.getUuid());
} catch (RuntimeException e) {
((HytaleLogger.Api) LOGGER.at(Level.WARNING).withCause(e))
.log("VanishHud apply failed for %s", target.getUsername());
}
};
if (world != null) world.execute(apply);
else apply.run();
}
private void showFor(@Nonnull PlayerRef player) {
active.computeIfAbsent(player.getUuid(), uuid -> {
VanishStatusHud hud = new VanishStatusHud(player);
hud.update();
return hud;
});
}
private void hideFor(@Nonnull UUID uuid) {
VanishStatusHud hud = active.remove(uuid);
if (hud != null) hud.clear();
}
private static PlayerRef findOnline(@Nonnull UUID uuid) {
Universe universe = Universe.get();
if (universe == null) return null;
for (PlayerRef p : universe.getPlayers()) {
if (p.getUuid().equals(uuid)) return p;
}
return null;
}
}
@@ -0,0 +1,29 @@
package net.kewwbec.staff.ui;
import com.hypixel.hytale.server.core.entity.entities.player.hud.CustomUIHud;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import javax.annotation.Nonnull;
/**
* Persistent bottom-right "VANISHED" indicator shown to the local staff member
* while their vanish state is on. Toggled by {@link net.kewwbec.staff.listener.VanishHudController}.
*/
public final class VanishStatusHud extends CustomUIHud {
private static final String UI_FILE = "KweebecNet_Staff/Hud/VanishStatusHud.ui";
public VanishStatusHud(@Nonnull PlayerRef playerRef) {
super(playerRef, "KweebecNetVanishStatus", 0);
}
@Override
protected void build(@Nonnull UICommandBuilder ui) {
ui.append(UI_FILE);
}
public void clear() {
update(true, new UICommandBuilder());
}
}
@@ -0,0 +1,12 @@
Group #VanishStatusHud {
Anchor: (Bottom: 50, Right: 50, Width: 140, Height: 28);
Background: #1A0808;
OutlineColor: #FF4444;
OutlineSize: 1;
Label #VanishStatusText {
Anchor: (Full: 0);
Style: (FontSize: 12, TextColor: #FF6666, HorizontalAlignment: Center, VerticalAlignment: Center, RenderBold: true);
Text: "VANISHED";
}
}