Add timed boss bars, /near command
This commit is contained in:
parent
f11036a844
commit
8e7244b0b8
8 changed files with 483 additions and 1 deletions
|
@ -9,7 +9,7 @@ yarn_mappings=1.20.1+build.10
|
||||||
loader_version=0.16.7
|
loader_version=0.16.7
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=1.14.3
|
mod_version=1.15.0
|
||||||
maven_group=cc.reconnected
|
maven_group=cc.reconnected
|
||||||
archives_base_name=rcc-server
|
archives_base_name=rcc-server
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,10 @@ public class RccServer implements ModInitializer {
|
||||||
WarpCommand.register(dispatcher, registryAccess, environment);
|
WarpCommand.register(dispatcher, registryAccess, environment);
|
||||||
SetWarpCommand.register(dispatcher, registryAccess, environment);
|
SetWarpCommand.register(dispatcher, registryAccess, environment);
|
||||||
DeleteWarpCommand.register(dispatcher, registryAccess, environment);
|
DeleteWarpCommand.register(dispatcher, registryAccess, environment);
|
||||||
|
|
||||||
|
TimeBarCommand.register(dispatcher, registryAccess, environment);
|
||||||
|
|
||||||
|
NearCommand.register(dispatcher, registryAccess, environment);
|
||||||
});
|
});
|
||||||
|
|
||||||
AfkTracker.register();
|
AfkTracker.register();
|
||||||
|
@ -106,6 +110,7 @@ public class RccServer implements ModInitializer {
|
||||||
BackTracker.register();
|
BackTracker.register();
|
||||||
TabList.register();
|
TabList.register();
|
||||||
HttpApiServer.register();
|
HttpApiServer.register();
|
||||||
|
BossBarManager.register();
|
||||||
|
|
||||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||||
luckPerms = LuckPermsProvider.get();
|
luckPerms = LuckPermsProvider.get();
|
||||||
|
|
|
@ -33,4 +33,13 @@ public class RccServerConfigModel {
|
||||||
));
|
));
|
||||||
|
|
||||||
public String playerTabName = "%rcc-server:afk%%player:displayname_visual%";
|
public String playerTabName = "%rcc-server:afk%%player:displayname_visual%";
|
||||||
|
|
||||||
|
public int nearCommandMaxRange = 48;
|
||||||
|
public int nearCommandDefaultRange = 32;
|
||||||
|
|
||||||
|
public boolean enableAutoRestart = true;
|
||||||
|
public ArrayList<String> restartAt = new ArrayList<>(List.of(
|
||||||
|
"06:00",
|
||||||
|
"18:00"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package cc.reconnected.server.api.events;
|
||||||
|
|
||||||
|
import cc.reconnected.server.core.BossBarManager;
|
||||||
|
import net.fabricmc.fabric.api.event.Event;
|
||||||
|
import net.fabricmc.fabric.api.event.EventFactory;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public class BossBarEvents {
|
||||||
|
public static final Event<Start> START = EventFactory.createArrayBacked(Start.class, callbacks ->
|
||||||
|
(timeBar, server) -> {
|
||||||
|
for (Start callback : callbacks) {
|
||||||
|
callback.onStart(timeBar, server);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static final Event<End> END = EventFactory.createArrayBacked(End.class, callbacks ->
|
||||||
|
(timeBar, server) -> {
|
||||||
|
for (End callback : callbacks) {
|
||||||
|
callback.onEnd(timeBar, server);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static final Event<Cancel> CANCEL = EventFactory.createArrayBacked(Cancel.class, callbacks ->
|
||||||
|
(timeBar, server) -> {
|
||||||
|
for (Cancel callback : callbacks) {
|
||||||
|
callback.onCancel(timeBar, server);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static final Event<Progress> PROGRESS = EventFactory.createArrayBacked(Progress.class, callbacks ->
|
||||||
|
(timeBar, server) -> {
|
||||||
|
for (Progress callback : callbacks) {
|
||||||
|
callback.onProgress(timeBar, server);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Start {
|
||||||
|
void onStart(BossBarManager.TimeBar timeBar, MinecraftServer server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface End {
|
||||||
|
void onEnd(BossBarManager.TimeBar timeBar, MinecraftServer server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Cancel {
|
||||||
|
void onCancel(BossBarManager.TimeBar timeBar, MinecraftServer server);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Progress {
|
||||||
|
void onProgress(BossBarManager.TimeBar timeBar, MinecraftServer server);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package cc.reconnected.server.commands.misc;
|
||||||
|
|
||||||
|
import cc.reconnected.server.RccServer;
|
||||||
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||||
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
|
import net.minecraft.server.command.CommandManager;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import static net.minecraft.server.command.CommandManager.*;
|
||||||
|
|
||||||
|
public class NearCommand {
|
||||||
|
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
|
||||||
|
var rootCommand = literal("near")
|
||||||
|
.requires(Permissions.require("rcc.command.near", 2))
|
||||||
|
.executes(context -> {
|
||||||
|
if (!context.getSource().isExecutedByPlayer()) {
|
||||||
|
context.getSource().sendFeedback(() -> Text.of("This command can only be executed by players!"), false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return execute(context, RccServer.CONFIG.nearCommandDefaultRange(), context.getSource().getPlayer());
|
||||||
|
})
|
||||||
|
.then(argument("radius", IntegerArgumentType.integer(0, RccServer.CONFIG.nearCommandMaxRange()))
|
||||||
|
.executes(context -> {
|
||||||
|
if (!context.getSource().isExecutedByPlayer()) {
|
||||||
|
context.getSource().sendFeedback(() -> Text.of("This command can only be executed by players!"), false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return execute(context, IntegerArgumentType.getInteger(context, "radius"), context.getSource().getPlayer());
|
||||||
|
}));
|
||||||
|
|
||||||
|
dispatcher.register(rootCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int execute(CommandContext<ServerCommandSource> context, int range, ServerPlayerEntity sourcePlayer) {
|
||||||
|
var list = new ArrayList<ClosePlayers>();
|
||||||
|
|
||||||
|
var sourcePos = sourcePlayer.getPos();
|
||||||
|
sourcePlayer.getServerWorld().getPlayers().forEach(targetPlayer -> {
|
||||||
|
var targetPos = targetPlayer.getPos();
|
||||||
|
if (!sourcePlayer.getUuid().equals(targetPlayer.getUuid()) && sourcePos.isInRange(targetPos, range)) {
|
||||||
|
var distance = sourcePos.distanceTo(targetPos);
|
||||||
|
list.add(new ClosePlayers(targetPlayer.getDisplayName(), distance));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(list.isEmpty()) {
|
||||||
|
context.getSource().sendFeedback(() -> Text.literal("There is no one near you.").formatted(Formatting.GOLD), false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.sort(Comparator.comparingDouble(ClosePlayers::distance));
|
||||||
|
|
||||||
|
var text = Text.empty().append(Text.literal("Nearest players: ").formatted(Formatting.GOLD));
|
||||||
|
var comma = Text.literal(", ").formatted(Formatting.GOLD);
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
var player = list.get(i);
|
||||||
|
if (i > 0) {
|
||||||
|
text = text.append(comma);
|
||||||
|
}
|
||||||
|
text = text.append(player.displayName)
|
||||||
|
.append(" ")
|
||||||
|
.append(Text.literal(String.format("(%.1fm)", player.distance)).formatted(Formatting.GREEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
final var finalText = text;
|
||||||
|
context.getSource().sendFeedback(() -> finalText, false);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private record ClosePlayers(Text displayName, double distance) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package cc.reconnected.server.commands.misc;
|
||||||
|
|
||||||
|
import cc.reconnected.server.api.events.BossBarEvents;
|
||||||
|
import cc.reconnected.server.core.BossBarManager;
|
||||||
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||||
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
|
import net.minecraft.command.CommandSource;
|
||||||
|
import net.minecraft.command.argument.UuidArgumentType;
|
||||||
|
import net.minecraft.entity.boss.BossBar;
|
||||||
|
import net.minecraft.server.command.CommandManager;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.text.ClickEvent;
|
||||||
|
import net.minecraft.text.HoverEvent;
|
||||||
|
import net.minecraft.text.Style;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static net.minecraft.server.command.CommandManager.*;
|
||||||
|
|
||||||
|
public class TimeBarCommand {
|
||||||
|
private static final ConcurrentHashMap<UUID, BarCommand> runningBars = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
|
||||||
|
var rootCommand = literal("timebar")
|
||||||
|
.requires(Permissions.require("rcc.command.timebar", 3))
|
||||||
|
.then(literal("start")
|
||||||
|
.then(argument("seconds", IntegerArgumentType.integer(0))
|
||||||
|
.then(argument("color", StringArgumentType.word())
|
||||||
|
.suggests((context, builder) -> {
|
||||||
|
var colors = Arrays.stream(BossBar.Color.values()).map(Enum::toString).toList();
|
||||||
|
return CommandSource.suggestMatching(colors, builder);
|
||||||
|
})
|
||||||
|
.then(argument("style", StringArgumentType.word())
|
||||||
|
.suggests((context, builder) -> {
|
||||||
|
var styles = Arrays.stream(BossBar.Style.values()).map(Enum::toString).toList();
|
||||||
|
return CommandSource.suggestMatching(styles, builder);
|
||||||
|
})
|
||||||
|
.then(argument("countdown", BoolArgumentType.bool())
|
||||||
|
.then(argument("label", StringArgumentType.string())
|
||||||
|
.then(argument("command", StringArgumentType.greedyString())
|
||||||
|
.suggests((context, builder) -> dispatcher.getRoot().listSuggestions(context, builder))
|
||||||
|
.executes(TimeBarCommand::execute))
|
||||||
|
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(literal("cancel")
|
||||||
|
.then(argument("uuid", UuidArgumentType.uuid())
|
||||||
|
.executes(TimeBarCommand::executeCancel)));
|
||||||
|
|
||||||
|
dispatcher.register(rootCommand);
|
||||||
|
|
||||||
|
BossBarEvents.END.register((timeBar, server) -> {
|
||||||
|
if (runningBars.containsKey(timeBar.getUuid())) {
|
||||||
|
var barCommand = runningBars.get(timeBar.getUuid());
|
||||||
|
try {
|
||||||
|
dispatcher.execute(barCommand.command(), barCommand.source);
|
||||||
|
} catch (CommandSyntaxException e) {
|
||||||
|
barCommand.source.sendFeedback(() -> Text.literal(e.toString()).formatted(Formatting.RED), false);
|
||||||
|
}
|
||||||
|
runningBars.remove(timeBar.getUuid());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int execute(CommandContext<ServerCommandSource> context) {
|
||||||
|
var seconds = IntegerArgumentType.getInteger(context, "seconds");
|
||||||
|
var colorName = StringArgumentType.getString(context, "color");
|
||||||
|
var styleName = StringArgumentType.getString(context, "style");
|
||||||
|
var countdown = BoolArgumentType.getBool(context, "countdown");
|
||||||
|
var label = StringArgumentType.getString(context, "label");
|
||||||
|
var command = StringArgumentType.getString(context, "command");
|
||||||
|
|
||||||
|
var color = BossBar.Color.valueOf(colorName);
|
||||||
|
var style = BossBar.Style.valueOf(styleName);
|
||||||
|
|
||||||
|
var bar = BossBarManager.getInstance().startTimeBar(label, seconds, color, style, countdown);
|
||||||
|
|
||||||
|
runningBars.put(bar.getUuid(), new BarCommand(context.getSource(), command));
|
||||||
|
|
||||||
|
|
||||||
|
context.getSource().sendFeedback(() -> Text
|
||||||
|
.literal("New time bar created with UUID ")
|
||||||
|
.append(Text.literal(bar.getUuid().toString()).setStyle(Style.EMPTY
|
||||||
|
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("Click to copy")))
|
||||||
|
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, bar.getUuid().toString())))), true);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int executeCancel(CommandContext<ServerCommandSource> context) {
|
||||||
|
var uuid = UuidArgumentType.getUuid(context, "uuid");
|
||||||
|
|
||||||
|
if (!runningBars.containsKey(uuid)) {
|
||||||
|
context.getSource().sendFeedback(() -> Text.literal("Time bar not found!").formatted(Formatting.RED), false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
runningBars.remove(uuid);
|
||||||
|
BossBarManager.getInstance().cancelTimeBar(uuid);
|
||||||
|
|
||||||
|
context.getSource().sendFeedback(() -> Text.literal("Time bar canceled"), true);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private record BarCommand(ServerCommandSource source, String command) {
|
||||||
|
}
|
||||||
|
}
|
17
src/main/java/cc/reconnected/server/core/AutoRestart.java
Normal file
17
src/main/java/cc/reconnected/server/core/AutoRestart.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package cc.reconnected.server.core;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public class AutoRestart {
|
||||||
|
private static MinecraftServer server;
|
||||||
|
public static void register() {
|
||||||
|
ServerLifecycleEvents.SERVER_STARTING.register(s -> server = s);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void schedule() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
191
src/main/java/cc/reconnected/server/core/BossBarManager.java
Normal file
191
src/main/java/cc/reconnected/server/core/BossBarManager.java
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
package cc.reconnected.server.core;
|
||||||
|
|
||||||
|
import cc.reconnected.server.RccServer;
|
||||||
|
import cc.reconnected.server.api.events.BossBarEvents;
|
||||||
|
import cc.reconnected.server.util.Components;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import net.minecraft.entity.boss.BossBar;
|
||||||
|
import net.minecraft.entity.boss.CommandBossBar;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
|
||||||
|
public class BossBarManager {
|
||||||
|
private static BossBarManager instance;
|
||||||
|
|
||||||
|
public static BossBarManager getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MinecraftServer server;
|
||||||
|
private static ConcurrentLinkedDeque<TimeBar> timeBars = new ConcurrentLinkedDeque<>();
|
||||||
|
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
instance = new BossBarManager();
|
||||||
|
|
||||||
|
ServerLifecycleEvents.SERVER_STARTING.register(s -> server = s);
|
||||||
|
|
||||||
|
ServerTickEvents.END_SERVER_TICK.register(server -> {
|
||||||
|
// every second
|
||||||
|
if (server.getTicks() % 20 == 0) {
|
||||||
|
for (var timeBar : timeBars) {
|
||||||
|
var remove = timeBar.elapse();
|
||||||
|
BossBarEvents.PROGRESS.invoker().onProgress(timeBar, server);
|
||||||
|
|
||||||
|
var players = server.getPlayerManager().getPlayerList();
|
||||||
|
showBar(players, timeBar);
|
||||||
|
|
||||||
|
if (remove) {
|
||||||
|
timeBars.remove(timeBar);
|
||||||
|
BossBarEvents.END.invoker().onEnd(timeBar, server);
|
||||||
|
hideBar(players, timeBar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showBar(Collection<ServerPlayerEntity> players, TimeBar timeBar) {
|
||||||
|
timeBar.getBossBar().addPlayers(players);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void hideBar(Collection<ServerPlayerEntity> players, TimeBar timeBar) {
|
||||||
|
players.forEach(player -> {
|
||||||
|
timeBar.getBossBar().removePlayer(player);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeBar startTimeBar(String label, int seconds, BossBar.Color color, BossBar.Style style, boolean countdown) {
|
||||||
|
var countdownBar = new TimeBar(label, seconds, countdown, color, style);
|
||||||
|
|
||||||
|
timeBars.add(countdownBar);
|
||||||
|
|
||||||
|
var players = server.getPlayerManager().getPlayerList();
|
||||||
|
showBar(players, countdownBar);
|
||||||
|
|
||||||
|
BossBarEvents.START.invoker().onStart(countdownBar, server);
|
||||||
|
|
||||||
|
return countdownBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean cancelTimeBar(TimeBar timeBar) {
|
||||||
|
var success = timeBars.remove(timeBar);
|
||||||
|
if (success) {
|
||||||
|
var players = server.getPlayerManager().getPlayerList();
|
||||||
|
hideBar(players, timeBar);
|
||||||
|
BossBarEvents.CANCEL.invoker().onCancel(timeBar, server);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean cancelTimeBar(UUID uuid) {
|
||||||
|
var progressBar = timeBars.stream().filter(p -> p.uuid.equals(uuid)).findFirst().orElse(null);
|
||||||
|
if (progressBar == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cancelTimeBar(progressBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TimeBar {
|
||||||
|
private final UUID uuid = UUID.randomUUID();
|
||||||
|
private final CommandBossBar bossBar;
|
||||||
|
private final String label;
|
||||||
|
private final int time;
|
||||||
|
private int elapsedSeconds = 0;
|
||||||
|
private final boolean countdown;
|
||||||
|
|
||||||
|
public TimeBar(String label, int time, boolean countdown, BossBar.Color color, BossBar.Style style) {
|
||||||
|
this.bossBar = new CommandBossBar(Identifier.of(RccServer.MOD_ID, uuid.toString()), Text.of(label));
|
||||||
|
this.bossBar.setColor(color);
|
||||||
|
this.bossBar.setStyle(style);
|
||||||
|
this.label = label;
|
||||||
|
this.time = time;
|
||||||
|
this.countdown = countdown;
|
||||||
|
updateName();
|
||||||
|
updateProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatTime(int totalSeconds) {
|
||||||
|
var hours = totalSeconds / 3600;
|
||||||
|
var minutes = (totalSeconds / 60) % 60;
|
||||||
|
var seconds = totalSeconds % 60;
|
||||||
|
if(totalSeconds >= 3600) {
|
||||||
|
return String.format("%dh%dm%ds", hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
return String.format("%dm%ds", minutes, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateName() {
|
||||||
|
var totalTime = formatTime(this.time);
|
||||||
|
var elapsedTime = formatTime(this.elapsedSeconds);
|
||||||
|
|
||||||
|
var remaining = time - elapsedSeconds;
|
||||||
|
var remainingTime = formatTime(remaining);
|
||||||
|
var text = miniMessage.deserialize(label, TagResolver.resolver(
|
||||||
|
Placeholder.parsed("total_time", totalTime),
|
||||||
|
Placeholder.parsed("elapsed_time", elapsedTime),
|
||||||
|
Placeholder.parsed("remaining_time", remainingTime)
|
||||||
|
));
|
||||||
|
|
||||||
|
bossBar.setName(Components.toText(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandBossBar getBossBar() {
|
||||||
|
return bossBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getElapsedSeconds() {
|
||||||
|
return elapsedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCountdown() {
|
||||||
|
return countdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean elapse() {
|
||||||
|
this.elapsedSeconds++;
|
||||||
|
|
||||||
|
updateProgress();
|
||||||
|
updateName();
|
||||||
|
|
||||||
|
return this.elapsedSeconds >= this.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProgress() {
|
||||||
|
float progress = (float) elapsedSeconds / (float) time;
|
||||||
|
if (countdown) {
|
||||||
|
progress = 1f - progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
bossBar.setPercent(Math.min(
|
||||||
|
Math.max(
|
||||||
|
progress,
|
||||||
|
0f),
|
||||||
|
1f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue