feat(commands): show player stealth progress
This commit is contained in:
@@ -2,6 +2,7 @@ package games.dmg.spigotstealth;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.time.Clock;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -58,6 +59,8 @@ public final class SpigotStealthPlugin extends JavaPlugin {
|
||||
manager, settings.unlockThreshold(), System::nanoTime, notifier);
|
||||
getServer().getPluginManager().registerEvents(
|
||||
new InvisibilityEffectListener(progression, Clock.systemUTC()), this);
|
||||
Objects.requireNonNull(getCommand("stealth"), "stealth command")
|
||||
.setExecutor(new StealthCommand(manager, progression, settings));
|
||||
getServer().getScheduler().runTaskTimer(this, ignored -> {
|
||||
for (java.util.UUID playerId : progression.activePlayerIds()) {
|
||||
logSaveFailure(progression.checkpoint(playerId));
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package games.dmg.spigotstealth;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/** Player-facing progress command. */
|
||||
public final class StealthCommand implements CommandExecutor {
|
||||
private final StealthStateManager stateManager;
|
||||
private final QualifyingInvisibilityService progression;
|
||||
private final StealthSettings settings;
|
||||
|
||||
public StealthCommand(
|
||||
StealthStateManager stateManager,
|
||||
QualifyingInvisibilityService progression,
|
||||
StealthSettings settings) {
|
||||
this.stateManager = Objects.requireNonNull(stateManager, "stateManager");
|
||||
this.progression = Objects.requireNonNull(progression, "progression");
|
||||
this.settings = Objects.requireNonNull(settings, "settings");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] arguments) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage("Only players can check personal stealth progress.");
|
||||
return true;
|
||||
}
|
||||
if (arguments.length != 1 || !"progress".equals(arguments[0].toLowerCase(Locale.ROOT))) {
|
||||
sender.sendMessage("Usage: /" + label + " progress");
|
||||
return true;
|
||||
}
|
||||
PlayerStealthState state = stateManager.snapshot().player(player.getUniqueId());
|
||||
long accumulated = progression.currentAccumulatedMillis(player.getUniqueId());
|
||||
if (state.unlocked()) {
|
||||
player.sendMessage("Stealth is unlocked.");
|
||||
player.sendMessage("Drink an invisibility potion and log out while invisible to conceal your next login.");
|
||||
return true;
|
||||
}
|
||||
long target = settings.unlockThreshold().toMillis();
|
||||
long remaining = Math.max(0L, target - accumulated);
|
||||
String message = settings.progressMessage()
|
||||
.replace("{progress}", StealthProgressFormatter.duration(accumulated))
|
||||
.replace("{target}", StealthProgressFormatter.duration(target))
|
||||
.replace("{remaining}", StealthProgressFormatter.duration(remaining));
|
||||
player.sendMessage(message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package games.dmg.spigotstealth;
|
||||
|
||||
/** Human-readable duration and progress presentation. */
|
||||
public final class StealthProgressFormatter {
|
||||
private StealthProgressFormatter() { }
|
||||
|
||||
public static String duration(long milliseconds) {
|
||||
long totalSeconds = Math.max(0L, milliseconds) / 1000L;
|
||||
long hours = totalSeconds / 3600L;
|
||||
long minutes = (totalSeconds % 3600L) / 60L;
|
||||
long seconds = totalSeconds % 60L;
|
||||
StringBuilder formatted = new StringBuilder();
|
||||
if (hours > 0L) {
|
||||
formatted.append(hours).append('h');
|
||||
}
|
||||
if (minutes > 0L) {
|
||||
appendSpace(formatted);
|
||||
formatted.append(minutes).append('m');
|
||||
}
|
||||
if (seconds > 0L || formatted.length() == 0) {
|
||||
appendSpace(formatted);
|
||||
formatted.append(seconds).append('s');
|
||||
}
|
||||
return formatted.toString();
|
||||
}
|
||||
|
||||
private static void appendSpace(StringBuilder value) {
|
||||
if (value.length() > 0) {
|
||||
value.append(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user