diff --git a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java index 711bab09..f2a237aa 100644 --- a/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java +++ b/VelocityCore/Persistent/src/de/steamwar/persistent/Subserver.java @@ -22,6 +22,7 @@ package de.steamwar.persistent; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.ServerInfo; +import com.velocitypowered.api.scheduler.ScheduledTask; import lombok.Getter; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -32,7 +33,10 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.logging.Level; @@ -98,7 +102,13 @@ public class Subserver { @Getter private boolean started; - private final List cachedPlayers = new LinkedList<>(); + private static final int MAX_PROGRESS = 10; + private static final Pattern PLUGIN_COUNT = Pattern.compile("Bukkit plugins \\((\\d+)\\)"); + + private final List cachedPlayers = new CopyOnWriteArrayList<>(); + private volatile int progress = 0; + private int pluginCount = 0; + private int enabledPlugins = 0; @Getter private final Map tablistNames = new HashMap<>(); @@ -127,7 +137,7 @@ public class Subserver { public void sendPlayer(Player p) { if (!started) { - p.sendActionBar(generateBar(0)); + p.sendActionBar(generateBar(progress)); cachedPlayers.add(p); } else { p.createConnectionRequest(registeredServer).connect(); @@ -246,31 +256,32 @@ public class Subserver { private void run() { Exception ex = null; try { - if (checkpoint) { - start(process.getErrorStream(), line -> line.contains("Restore finished successfully.")); - start(process.getInputStream(), line -> line.contains("Checkpoint restored")); - Thread.sleep(100); - } else { - sendProgress(0); - start(process.getInputStream(), line -> { - if (line.contains("Loading libraries, please wait")) { - sendProgress(2); - } else if (line.contains("Starting Minecraft server on")) { - sendProgress(5); - } else if (line.contains("Preparing start region")) { - sendProgress(8); - } - return line.contains("Done ("); - }); - } + ScheduledTask refresh = Persistent.getInstance().getProxy().getScheduler() + .buildTask(Persistent.getInstance(), () -> sendProgress(progress)) + .repeat(2, TimeUnit.SECONDS).schedule(); - if (!started) return; + try { + if (checkpoint) { + start(process.getErrorStream(), line -> line.contains("Restore finished successfully.")); + start(process.getInputStream(), line -> line.contains("Checkpoint restored")); + Thread.sleep(100); + } else { + start(process.getInputStream(), line -> { + updateProgress(line); + return line.contains("Done ("); + }); + } - sendProgress(10); - for (Player cachedPlayer : cachedPlayers) { - sendPlayer(cachedPlayer); + if (!started) return; + + setProgress(MAX_PROGRESS); + for (Player cachedPlayer : cachedPlayers) { + sendPlayer(cachedPlayer); + } + cachedPlayers.clear(); + } finally { + refresh.cancel(); } - cachedPlayers.clear(); process.waitFor(); } catch (IOException e) { @@ -285,6 +296,39 @@ public class Subserver { } } + private void updateProgress(String line) { + if (line.startsWith("Loading Paper")) { + setProgress(1); + } else if (line.startsWith("Bukkit plugins (")) { + Matcher matcher = PLUGIN_COUNT.matcher(line); + if (matcher.find()) pluginCount = Integer.parseInt(matcher.group(1)); + } else if (line.startsWith("Starting minecraft server version")) { + setProgress(2); + } else if (line.contains("Starting Minecraft server on")) { + setProgress(3); + } else if (line.contains("libraries... please wait")) { + setProgress(4); + } else if (line.startsWith("Loading server plugin")) { + setProgress(5); + } else if (line.startsWith("Preparing level")) { + setProgress(6); + } else if (line.startsWith("Preparing start region")) { + setProgress(7); + } else if (line.startsWith("Enabling ")) { + enabledPlugins++; + // 7 -> 9 over all plugins, 9 is reached with the last plugin + setProgress(7 + (pluginCount > 0 ? Math.min(2, 2 * enabledPlugins / pluginCount) : 0)); + } else if (line.startsWith("Done preparing level")) { + setProgress(9); + } + } + + private void setProgress(int newProgress) { + if (newProgress <= progress) return; + progress = newProgress; + sendProgress(newProgress); + } + private Component generateBar(int progress) { return Component.text("⬛".repeat(Math.max(0, progress))).color(NamedTextColor.YELLOW) .append(Component.text("⬛".repeat(Math.max(0, 10 - progress))).color(NamedTextColor.DARK_GRAY));