From 5c8d9903a1f70056621e34c086f17cefea577fc2 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Mon, 31 Oct 2022 19:14:29 +0100 Subject: [PATCH] Work on customizable queue types --- .../placeholder/PAPIExpansion.java | 30 +++---- .../placeholder/PistonQueuePlaceholder.java | 32 ++++--- .../pistonqueue/data/PluginData.java | 4 +- .../pistonqueue/bungee/PistonQueueBungee.java | 10 +-- .../bungee/listeners/QueueListenerBungee.java | 1 + .../hooks/PistonMOTDPlaceholder.java | 10 ++- .../pistonqueue/shared/Config.java | 11 ++- .../pistonqueue/shared/MainCommandShared.java | 12 +-- .../pistonqueue/shared/PistonQueuePlugin.java | 88 +++++++++++++------ .../pistonqueue/shared/QueueAPI.java | 38 -------- .../shared/QueueListenerShared.java | 30 +++---- .../pistonqueue/shared/QueueType.java | 64 +++++--------- .../pistonqueue/shared/SharedChatUtils.java | 6 +- .../pistonqueue/shared/StorageTool.java | 31 +++---- .../velocity/PistonQueueVelocity.java | 5 +- .../{proxyconfig.yml => proxy_config.yml} | 19 ++-- 16 files changed, 182 insertions(+), 209 deletions(-) delete mode 100644 src/main/java/net/pistonmaster/pistonqueue/shared/QueueAPI.java rename src/main/resources/{proxyconfig.yml => proxy_config.yml} (95%) diff --git a/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PAPIExpansion.java b/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PAPIExpansion.java index 827ad8f..4ca2908 100644 --- a/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PAPIExpansion.java +++ b/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PAPIExpansion.java @@ -5,6 +5,8 @@ import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; +import java.util.Map; + @RequiredArgsConstructor public final class PAPIExpansion extends PlaceholderExpansion { private final PistonQueuePlaceholder plugin; @@ -31,28 +33,16 @@ public boolean canRegister() { @Override public String onRequest(OfflinePlayer player, String identifier) { - if (identifier.equals("online_queue_regular")) { - return String.valueOf(plugin.getOnlineQueueRegular()); - } - - if (identifier.equals("online_queue_priority")) { - return String.valueOf(plugin.getOnlineQueuePriority()); - } - - if (identifier.equals("online_queue_veteran")) { - return String.valueOf(plugin.getOnlineQueueVeteran()); - } - - if (identifier.equals("online_main_regular")) { - return String.valueOf(plugin.getOnlineMainRegular()); - } - - if (identifier.equals("online_main_priority")) { - return String.valueOf(plugin.getOnlineMainPriority()); + for (Map.Entry entry : plugin.getOnlineQueue().entrySet()) { + if (identifier.equalsIgnoreCase("online_queue_" + entry.getKey())) { + return String.valueOf(entry.getValue()); + } } - if (identifier.equals("online_main_veteran")) { - return String.valueOf(plugin.getOnlineMainVeteran()); + for (Map.Entry entry : plugin.getOnlineMain().entrySet()) { + if (identifier.equalsIgnoreCase("online_main_" + entry.getKey())) { + return String.valueOf(entry.getValue()); + } } return null; diff --git a/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PistonQueuePlaceholder.java b/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PistonQueuePlaceholder.java index 3bc185c..9518989 100644 --- a/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PistonQueuePlaceholder.java +++ b/PistonQueuePlaceholder/src/main/java/net/pistonmaster/pistonqueue/placeholder/PistonQueuePlaceholder.java @@ -10,16 +10,14 @@ import org.bukkit.plugin.messaging.PluginMessageListener; import org.jetbrains.annotations.NotNull; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; @Getter public final class PistonQueuePlaceholder extends JavaPlugin implements PluginMessageListener { - private int onlineQueueRegular = 0; - private int onlineQueuePriority = 0; - private int onlineQueueVeteran = 0; - private int onlineMainRegular = 0; - private int onlineMainPriority = 0; - private int onlineMainVeteran = 0; + private final Map onlineQueue = new ConcurrentHashMap<>(); + private final Map onlineMain = new ConcurrentHashMap<>(); @Override public void onEnable() { @@ -47,13 +45,23 @@ public void onPluginMessageReceived(String channel, @NotNull Player player, byte String subChannel = in.readUTF(); if (subChannel.equalsIgnoreCase("onlineQueue")) { - onlineQueueRegular = in.readInt(); - onlineQueuePriority = in.readInt(); - onlineQueueVeteran = in.readInt(); + int count = in.readInt(); + + for (int i = 0; i < count; i++) { + String queue = in.readUTF(); + int online = in.readInt(); + + onlineQueue.put(queue, online); + } } else if (subChannel.equalsIgnoreCase("onlineMain")) { - onlineMainRegular = in.readInt(); - onlineMainPriority = in.readInt(); - onlineMainVeteran = in.readInt(); + int count = in.readInt(); + + for (int i = 0; i < count; i++) { + String queue = in.readUTF(); + int online = in.readInt(); + + onlineMain.put(queue, online); + } } } diff --git a/src/main/java-templates/net/pistonmaster/pistonqueue/data/PluginData.java b/src/main/java-templates/net/pistonmaster/pistonqueue/data/PluginData.java index 6b22f4c..91b8c3f 100644 --- a/src/main/java-templates/net/pistonmaster/pistonqueue/data/PluginData.java +++ b/src/main/java-templates/net/pistonmaster/pistonqueue/data/PluginData.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/main/java/net/pistonmaster/pistonqueue/bungee/PistonQueueBungee.java b/src/main/java/net/pistonmaster/pistonqueue/bungee/PistonQueueBungee.java index fec7800..cf082dd 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/bungee/PistonQueueBungee.java +++ b/src/main/java/net/pistonmaster/pistonqueue/bungee/PistonQueueBungee.java @@ -38,7 +38,7 @@ import net.pistonmaster.pistonqueue.shared.utils.UpdateChecker; import org.bstats.bungeecord.Metrics; -import java.io.File; +import java.nio.file.Path; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -56,9 +56,9 @@ public void onEnable() { PluginManager manager = getProxy().getPluginManager(); info(ChatColor.BLUE + "Loading config"); - processConfig(getDataFolder()); + processConfig(getDataDirectory()); - StorageTool.setupTool(getDataFolder()); + StorageTool.setupTool(getDataDirectory()); initializeReservationSlots(); info(ChatColor.BLUE + "Looking for hooks"); @@ -146,8 +146,8 @@ public String getVersion() { } @Override - public File getDataDirectory() { - return getDataFolder(); + public Path getDataDirectory() { + return getDataFolder().toPath(); } private ServerInfoWrapper wrapServer(ServerInfo serverInfo) { diff --git a/src/main/java/net/pistonmaster/pistonqueue/bungee/listeners/QueueListenerBungee.java b/src/main/java/net/pistonmaster/pistonqueue/bungee/listeners/QueueListenerBungee.java index 8b54c49..d1944b4 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/bungee/listeners/QueueListenerBungee.java +++ b/src/main/java/net/pistonmaster/pistonqueue/bungee/listeners/QueueListenerBungee.java @@ -59,6 +59,7 @@ public void onSend(ServerConnectEvent event) { public void onQueueSend(ServerSwitchEvent event) { onConnected(wrap(event)); } + @EventHandler public void onKick(ServerKickEvent event) { onKick(wrap(event)); diff --git a/src/main/java/net/pistonmaster/pistonqueue/hooks/PistonMOTDPlaceholder.java b/src/main/java/net/pistonmaster/pistonqueue/hooks/PistonMOTDPlaceholder.java index dc0e133..5ac6ecf 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/hooks/PistonMOTDPlaceholder.java +++ b/src/main/java/net/pistonmaster/pistonqueue/hooks/PistonMOTDPlaceholder.java @@ -21,7 +21,8 @@ import net.pistonmaster.pistonmotd.api.PlaceholderParser; import net.pistonmaster.pistonmotd.api.PlaceholderUtil; -import net.pistonmaster.pistonqueue.shared.QueueAPI; +import net.pistonmaster.pistonqueue.shared.Config; +import net.pistonmaster.pistonqueue.shared.QueueType; public final class PistonMOTDPlaceholder implements PlaceholderParser { public PistonMOTDPlaceholder() { @@ -30,8 +31,9 @@ public PistonMOTDPlaceholder() { @Override public String parseString(String s) { - return s.replace("%pistonqueue_regular%", String.valueOf(QueueAPI.getRegularSize())) - .replace("%pistonqueue_priority%", String.valueOf(QueueAPI.getPrioritySize())) - .replace("%pistonqueue_veteran%", String.valueOf(QueueAPI.getVeteranSize())); + for (QueueType type : Config.QUEUE_TYPES) { + s = s.replace("%pistonqueue_" + type.getName().toLowerCase() + "%", String.valueOf(type.getQueueMap().size())); + } + return s; } } diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/Config.java b/src/main/java/net/pistonmaster/pistonqueue/shared/Config.java index 228d829..e2e40a4 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/Config.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/Config.java @@ -25,9 +25,9 @@ public final class Config { public static String SERVER_NAME, SERVER_IS_FULL_MESSAGE, QUEUE_POSITION, JOINING_MAIN_SERVER, - QUEUE_BYPASS_PERMISSION, QUEUE_SERVER, QUEUE_PRIORITY_PERMISSION, USERNAME_REGEX, + QUEUE_BYPASS_PERMISSION, QUEUE_SERVER, USERNAME_REGEX, KICK_MESSAGE, ADMIN_PERMISSION, MAIN_SERVER, AUTH_SERVER, SERVER_DOWN_KICK_MESSAGE, - QUEUE_VETERAN_PERMISSION, USERNAME_REGEX_MESSAGE, PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE, + USERNAME_REGEX_MESSAGE, PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE, SHADOW_BAN_MESSAGE, IF_MAIN_DOWN_SEND_TO_QUEUE_MESSAGE, RECOVERY_MESSAGE; public static boolean POSITION_MESSAGE_HOT_BAR, ENABLE_KICK_MESSAGE, @@ -36,12 +36,11 @@ public final class Config { IF_MAIN_DOWN_SEND_TO_QUEUE, RECOVERY, ENABLE_USERNAME_REGEX, SEND_XP_SOUND; public static int QUEUE_MOVE_DELAY, SERVER_ONLINE_CHECK_DELAY, POSITION_MESSAGE_DELAY, - START_TIME, REGULAR_SLOTS, PRIORITY_SLOTS, VETERAN_SLOTS, CUSTOM_PERCENT_PERCENTAGE, + START_TIME, CUSTOM_PERCENT_PERCENTAGE, MAX_PLAYERS_PER_MOVE; - public static List HEADER, FOOTER, HEADER_PRIORITY, FOOTER_PRIORITY, - HEADER_VETERAN, FOOTER_VETERAN, DOWN_WORD_LIST; - + public static List DOWN_WORD_LIST; + public static QueueType[] QUEUE_TYPES; // Not allowed to be resized due to data corruption public static BanType SHADOW_BAN_TYPE; private Config() { diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/MainCommandShared.java b/src/main/java/net/pistonmaster/pistonqueue/shared/MainCommandShared.java index f315496..a7c180e 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/MainCommandShared.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/MainCommandShared.java @@ -41,18 +41,18 @@ default void onCommand(CommandSourceWrapper sender, String[] args, PistonQueuePl case "stats": sendLine(sender); sender.sendMessage(getWrapperFactory().text("Queue stats").color(TextColorWrapper.GOLD)); - sender.sendMessage(getWrapperFactory().text("Regular: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(String.valueOf(QueueAPI.getRegularSize())).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); - sender.sendMessage(getWrapperFactory().text("Priority: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(String.valueOf(QueueAPI.getPrioritySize())).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); - sender.sendMessage(getWrapperFactory().text("Veteran: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(String.valueOf(QueueAPI.getVeteranSize())).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); + for (QueueType type : Config.QUEUE_TYPES) { + sender.sendMessage(getWrapperFactory().text(type.getName() + ": ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(String.valueOf(type.getQueueMap().size())).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); + } sendLine(sender); break; case "slotstats": if (sender.hasPermission(Config.ADMIN_PERMISSION)) { sendLine(sender); sender.sendMessage(getWrapperFactory().text("Main slot stats").color(TextColorWrapper.GOLD)); - sender.sendMessage(getWrapperFactory().text("Regular: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(QueueType.REGULAR.getPlayersWithTypeInMain().get() + "/" + QueueType.REGULAR.getReservedSlots()).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); - sender.sendMessage(getWrapperFactory().text("Priority: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(QueueType.PRIORITY.getPlayersWithTypeInMain().get() + "/" + QueueType.PRIORITY.getReservedSlots()).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); - sender.sendMessage(getWrapperFactory().text("Veteran: ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(QueueType.VETERAN.getPlayersWithTypeInMain().get() + "/" + QueueType.VETERAN.getReservedSlots()).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); + for (QueueType type : Config.QUEUE_TYPES) { + sender.sendMessage(getWrapperFactory().text(type.getName() + ": ").color(TextColorWrapper.GOLD).append(getWrapperFactory().text(type.getPlayersWithTypeInMain().get() + " / " + type.getReservedSlots()).color(TextColorWrapper.GOLD).decorate(TextDecorationWrapper.BOLD))); + } sendLine(sender); } else { noPermission(sender); diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/PistonQueuePlugin.java b/src/main/java/net/pistonmaster/pistonqueue/shared/PistonQueuePlugin.java index ddbca42..820f0ef 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/PistonQueuePlugin.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/PistonQueuePlugin.java @@ -21,15 +21,16 @@ import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; +import lombok.val; import net.pistonmaster.pistonqueue.shared.utils.ConfigOutdatedException; import net.pistonmaster.pistonqueue.shared.utils.MessageType; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; -import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -60,7 +61,7 @@ public interface PistonQueuePlugin { String getVersion(); - File getDataDirectory(); + Path getDataDirectory(); default void scheduleTasks(QueueListenerShared queueListener) { // Sends the position message and updates tab on an interval in chat @@ -68,7 +69,7 @@ default void scheduleTasks(QueueListenerShared queueListener) { if (!queueListener.isMainOnline()) return; - for (QueueType type : QueueType.values()) { + for (QueueType type : Config.QUEUE_TYPES) { sendMessage(type, Config.POSITION_MESSAGE_CHAT, MessageType.CHAT); } }, Config.POSITION_MESSAGE_DELAY, Config.POSITION_MESSAGE_DELAY, TimeUnit.MILLISECONDS); @@ -78,23 +79,26 @@ default void scheduleTasks(QueueListenerShared queueListener) { if (!queueListener.isMainOnline()) return; - for (QueueType type : QueueType.values()) { + for (QueueType type : Config.QUEUE_TYPES) { sendMessage(type, Config.POSITION_MESSAGE_HOT_BAR, MessageType.ACTION_BAR); } }, Config.POSITION_MESSAGE_DELAY, Config.POSITION_MESSAGE_DELAY, TimeUnit.MILLISECONDS); // Updates the tab schedule(() -> { - updateTab(QueueType.VETERAN, Config.HEADER_VETERAN, Config.FOOTER_VETERAN); - updateTab(QueueType.PRIORITY, Config.HEADER_PRIORITY, Config.FOOTER_PRIORITY); - updateTab(QueueType.REGULAR, Config.HEADER, Config.FOOTER); + for (QueueType type : Config.QUEUE_TYPES) { + updateTab(type); + } }, Config.QUEUE_MOVE_DELAY, Config.QUEUE_MOVE_DELAY, TimeUnit.MILLISECONDS); schedule(() -> { - if (Config.PAUSE_QUEUE_IF_MAIN_DOWN && !queueListener.isMainOnline()) { - QueueType.VETERAN.getQueueMap().forEach((UUID id, String str) -> getPlayer(id).ifPresent(value -> value.sendMessage(Config.PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE))); - QueueType.PRIORITY.getQueueMap().forEach((UUID id, String str) -> getPlayer(id).ifPresent(value -> value.sendMessage(Config.PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE))); - QueueType.REGULAR.getQueueMap().forEach((UUID id, String str) -> getPlayer(id).ifPresent(value -> value.sendMessage(Config.PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE))); + if (!Config.PAUSE_QUEUE_IF_MAIN_DOWN || queueListener.isMainOnline()) { + return; + } + + for (QueueType type : Config.QUEUE_TYPES) { + type.getQueueMap().forEach((UUID id, String str) -> + getPlayer(id).ifPresent(value -> value.sendMessage(Config.PAUSE_QUEUE_IF_MAIN_DOWN_MESSAGE))); } }, Config.POSITION_MESSAGE_DELAY, Config.POSITION_MESSAGE_DELAY, TimeUnit.MILLISECONDS); @@ -175,7 +179,7 @@ default void sendMessage(QueueType queue, boolean bool, MessageType type) { } } - default void updateTab(QueueType queue, List header, List footer) { + default void updateTab(QueueType queue) { AtomicInteger position = new AtomicInteger(); for (Map.Entry entry : new LinkedHashMap<>(queue.getQueueMap()).entrySet()) { @@ -183,8 +187,8 @@ default void updateTab(QueueType queue, List header, List footer int incrementedPosition = position.incrementAndGet(); player.sendPlayerListHeaderAndFooter( - header.stream().map(str -> replacePosition(str, incrementedPosition, queue)).collect(Collectors.toList()), - footer.stream().map(str -> replacePosition(str, incrementedPosition, queue)).collect(Collectors.toList())); + queue.getHeader().stream().map(str -> replacePosition(str, incrementedPosition, queue)).collect(Collectors.toList()), + queue.getFooter().stream().map(str -> replacePosition(str, incrementedPosition, queue)).collect(Collectors.toList())); }); } } @@ -247,16 +251,19 @@ default void sendCustomData() { ByteArrayDataOutput outOnlineQueue = ByteStreams.newDataOutput(); outOnlineQueue.writeUTF("onlineQueue"); - outOnlineQueue.writeInt(QueueType.REGULAR.getQueueMap().size()); - outOnlineQueue.writeInt(QueueType.PRIORITY.getQueueMap().size()); - outOnlineQueue.writeInt(QueueType.VETERAN.getQueueMap().size()); + outOnlineQueue.writeInt(Config.QUEUE_TYPES.length); + for (QueueType queueType : Config.QUEUE_TYPES) { + outOnlineQueue.writeUTF(queueType.getName().toLowerCase()); + outOnlineQueue.writeInt(queueType.getQueueMap().size()); + } ByteArrayDataOutput outOnlineMain = ByteStreams.newDataOutput(); outOnlineMain.writeUTF("onlineMain"); - outOnlineMain.writeInt(QueueType.REGULAR.getPlayersWithTypeInMain().get()); - outOnlineMain.writeInt(QueueType.PRIORITY.getPlayersWithTypeInMain().get()); - outOnlineMain.writeInt(QueueType.VETERAN.getPlayersWithTypeInMain().get()); + outOnlineQueue.writeInt(Config.QUEUE_TYPES.length); + for (QueueType queueType : Config.QUEUE_TYPES) { + outOnlineQueue.writeInt(queueType.getPlayersWithTypeInMain().get()); + } Set servers = new HashSet<>(); networkPlayers.forEach(player -> player.getCurrentServer().ifPresent(servers::add)); @@ -269,16 +276,17 @@ default void sendCustomData() { } } - default void processConfig(File dataDirectory) { + default void processConfig(Path dataDirectory) { try { - if (!dataDirectory.exists() && !dataDirectory.mkdir()) - return; + if (!Files.exists(dataDirectory)) { + Files.createDirectories(dataDirectory); + } - File file = new File(dataDirectory, "config.yml"); + Path file = dataDirectory.resolve("config.yml"); - if (!file.exists()) { + if (!Files.exists(file)) { try { - Files.copy(Objects.requireNonNull(PistonQueuePlugin.class.getClassLoader().getResourceAsStream("proxyconfig.yml")), file.toPath()); + Files.copy(Objects.requireNonNull(PistonQueuePlugin.class.getClassLoader().getResourceAsStream("proxy_config.yml")), file); loadConfig(dataDirectory); return; } catch (IOException ie) { @@ -286,14 +294,14 @@ default void processConfig(File dataDirectory) { } } - loadConfig(dataDirectory); + loadConfig(file); } catch (IOException e) { e.printStackTrace(); } } - default void loadConfig(File dataDirectory) throws IOException { - ConfigurationNode config = YamlConfigurationLoader.builder().path(new File(dataDirectory, "config.yml").toPath()).build().load(); + default void loadConfig(Path file) throws IOException { + ConfigurationNode config = YamlConfigurationLoader.builder().path(file).build().load(); Arrays.asList(Config.class.getDeclaredFields()).forEach(it -> { try { @@ -302,6 +310,28 @@ default void loadConfig(File dataDirectory) throws IOException { String fieldName = it.getName(); if (List.class.isAssignableFrom(it.getType())) { it.set(Config.class, config.node(fieldName).getList(String.class)); + } else if (QueueType.class.isAssignableFrom(it.getType())) { + if (it.get(Config.class) == null) { // We will never replace on reload + val queueTypes = config.node("QUEUE_TYPES").childrenMap(); + val array = new QueueType[queueTypes.size()]; + int i = 0; + for (Map.Entry entry : queueTypes.entrySet()) { + Object key = entry.getKey(); + ConfigurationNode typeData = entry.getValue(); + QueueType queueType = new QueueType( + key.toString(), + typeData.node("ORDER").getInt(), + typeData.node("PERMISSION").getString(), + typeData.node("SLOTS").getInt(), + typeData.node("HEADER").getList(String.class), + typeData.node("FOOTER").getList(String.class)); + + array[i] = queueType; + i++; + } + Arrays.sort(array, Comparator.comparingInt(QueueType::getOrder)); + it.set(Config.class, array); + } } else { it.set(Config.class, config.node(fieldName).get(it.getType())); } diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueAPI.java b/src/main/java/net/pistonmaster/pistonqueue/shared/QueueAPI.java deleted file mode 100644 index 95dec92..0000000 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueAPI.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * #%L - * PistonQueue - * %% - * Copyright (C) 2021 AlexProgrammerDE - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ -package net.pistonmaster.pistonqueue.shared; - -@SuppressWarnings({"unused"}) -public final class QueueAPI { - private QueueAPI() { - } - - public static int getVeteranSize() { - return QueueType.VETERAN.getQueueMap().size(); - } - - public static int getPrioritySize() { - return QueueType.PRIORITY.getQueueMap().size(); - } - - public static int getRegularSize() { - return QueueType.REGULAR.getQueueMap().size(); - } -} diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueListenerShared.java b/src/main/java/net/pistonmaster/pistonqueue/shared/QueueListenerShared.java index 74a8b31..48e5a90 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueListenerShared.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/QueueListenerShared.java @@ -110,7 +110,7 @@ protected void onPreConnect(PQServerPreConnectEvent event) { } } - protected void putQueue(PlayerWrapper player, PQServerPreConnectEvent event) { + private void putQueue(PlayerWrapper player, PQServerPreConnectEvent event) { QueueType type = QueueType.getQueueType(player::hasPermission); preQueueAdding(player, type.getHeader(), type.getFooter()); @@ -159,40 +159,40 @@ public void putQueueAuthFirst(PlayerWrapper player) { type.getQueueMap().put(player.getUniqueId(), Config.MAIN_SERVER); } - protected void preQueueAdding(PlayerWrapper player, List header, List footer) { + private void preQueueAdding(PlayerWrapper player, List header, List footer) { player.sendPlayerListHeaderAndFooter(header, footer); if (isServerFull(player)) player.sendMessage(Config.SERVER_IS_FULL_MESSAGE); } - protected boolean isServerFull(PlayerWrapper player) { + private boolean isServerFull(PlayerWrapper player) { return isPlayerMainFull(player) || isAnyoneQueuedOfType(player); } - protected boolean isPlayerMainFull(PlayerWrapper player) { + private boolean isPlayerMainFull(PlayerWrapper player) { return isMainFull(QueueType.getQueueType(player::hasPermission)); } - protected int getFreeSlots(QueueType type) { + private int getFreeSlots(QueueType type) { return type.getReservedSlots() - type.getPlayersWithTypeInMain().get(); } - protected boolean isMainFull(QueueType type) { + private boolean isMainFull(QueueType type) { return getFreeSlots(type) <= 0; } - protected boolean isAnyoneQueuedOfType(PlayerWrapper player) { + private boolean isAnyoneQueuedOfType(PlayerWrapper player) { return !QueueType.getQueueType(player::hasPermission).getQueueMap().isEmpty(); } - protected boolean isAuthToQueue(PQServerConnectedEvent event) { + private boolean isAuthToQueue(PQServerConnectedEvent event) { Optional previousServer = event.getPreviousServer(); return previousServer.isPresent() && previousServer.get().equals(Config.AUTH_SERVER) && event.getServer().equals(Config.QUEUE_SERVER); } public void moveQueue() { - for (QueueType type : QueueType.values()) { + for (QueueType type : Config.QUEUE_TYPES) { for (Map.Entry entry : new LinkedHashMap<>(type.getQueueMap()).entrySet()) { Optional player = plugin.getPlayer(entry.getKey()); @@ -221,10 +221,10 @@ public void moveQueue() { } } - Arrays.stream(QueueType.values()).forEachOrdered(this::connectPlayer); + Arrays.stream(Config.QUEUE_TYPES).forEachOrdered(this::connectPlayer); } - protected void doRecovery(PlayerWrapper player) { + private void doRecovery(PlayerWrapper player) { QueueType type = QueueType.getQueueType(player::hasPermission); Optional currentServer = player.getCurrentServer(); @@ -235,7 +235,7 @@ protected void doRecovery(PlayerWrapper player) { } } - protected void connectPlayer(QueueType type) { + private void connectPlayer(QueueType type) { int freeSlots = getFreeSlots(type); if (freeSlots <= 0) @@ -287,7 +287,7 @@ protected void connectPlayer(QueueType type) { sendXPSoundToQueueType(type); } - protected void sendXPSoundToQueueType(QueueType type) { + private void sendXPSoundToQueueType(QueueType type) { @SuppressWarnings("UnstableApiUsage") ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("xp"); @@ -303,8 +303,8 @@ protected void sendXPSoundToQueueType(QueueType type) { server.sendPluginMessage("piston:queue", out.toByteArray())); } - protected void indexPositionTime() { - for (QueueType type : QueueType.values()) { + private void indexPositionTime() { + for (QueueType type : Config.QUEUE_TYPES) { int position = 0; for (UUID uuid : new LinkedHashMap<>(type.getQueueMap()).keySet()) { diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueType.java b/src/main/java/net/pistonmaster/pistonqueue/shared/QueueType.java index db8df42..721853e 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/QueueType.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/QueueType.java @@ -19,7 +19,9 @@ */ package net.pistonmaster.pistonqueue.shared; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.Setter; import java.time.Duration; import java.time.Instant; @@ -28,57 +30,31 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; +@Getter +@AllArgsConstructor public class QueueType { - public static final QueueType REGULAR = new QueueType(); - public static final QueueType PRIORITY = new QueueType(); - public static final QueueType VETERAN = new QueueType(); - @Getter private final Map queueMap = Collections.synchronizedMap(new LinkedHashMap<>()); - @Getter private final Map durationToPosition = Collections.synchronizedMap(new LinkedHashMap<>()); - @Getter private final Map> positionCache = new ConcurrentHashMap<>(); - @Getter private final AtomicInteger playersWithTypeInMain = new AtomicInteger(); - - public static QueueType[] values() { - return new QueueType[]{REGULAR, PRIORITY, VETERAN}; - } + private final String name; + @Setter + private int order; + @Setter + private String permission; + @Setter + private int reservedSlots; + @Setter + private List header; + @Setter + private List footer; public static QueueType getQueueType(Predicate player) { - if (player.test(Config.QUEUE_VETERAN_PERMISSION)) { - return VETERAN; - } else if (player.test(Config.QUEUE_PRIORITY_PERMISSION)) { - return PRIORITY; - } else { - return REGULAR; - } - } - - public List getHeader() { - if (VETERAN.equals(this)) { - return Config.HEADER_VETERAN; - } else if (PRIORITY.equals(this)) { - return Config.HEADER_PRIORITY; - } - return Config.HEADER; - } - - public List getFooter() { - if (VETERAN.equals(this)) { - return Config.FOOTER_VETERAN; - } else if (PRIORITY.equals(this)) { - return Config.FOOTER_PRIORITY; - } - return Config.FOOTER; - } - - public int getReservedSlots() { - if (VETERAN.equals(this)) { - return Config.VETERAN_SLOTS; - } else if (PRIORITY.equals(this)) { - return Config.PRIORITY_SLOTS; + for (QueueType type : Config.QUEUE_TYPES) { + if (type.getPermission().equals("default") || player.test(type.getPermission())) { + return type; + } } - return Config.REGULAR_SLOTS; + throw new RuntimeException("No queue type found for player! (There is no default queue type)"); } } diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/SharedChatUtils.java b/src/main/java/net/pistonmaster/pistonqueue/shared/SharedChatUtils.java index 6764df1..fb2fb8b 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/SharedChatUtils.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/SharedChatUtils.java @@ -36,9 +36,9 @@ public static String formatDuration(String str, Duration duration, int position) public static String parseText(String text) { text = text.replace("%server%", Config.SERVER_NAME); - text = text.replace("%veteran%", String.valueOf(QueueAPI.getVeteranSize())); - text = text.replace("%priority%", String.valueOf(QueueAPI.getPrioritySize())); - text = text.replace("%regular%", String.valueOf(QueueAPI.getRegularSize())); + for (QueueType type : Config.QUEUE_TYPES) { + text = text.replace("%" + type.getName().toLowerCase() + "%", String.valueOf(type.getQueueMap().size())); + } text = text.replace("%position%", "None"); text = text.replace("%wait%", "None"); diff --git a/src/main/java/net/pistonmaster/pistonqueue/shared/StorageTool.java b/src/main/java/net/pistonmaster/pistonqueue/shared/StorageTool.java index 5017ba4..a819b87 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/shared/StorageTool.java +++ b/src/main/java/net/pistonmaster/pistonqueue/shared/StorageTool.java @@ -23,8 +23,9 @@ import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; -import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -32,9 +33,9 @@ import java.util.UUID; public final class StorageTool { - private static File dataDirectory; + private static Path dataDirectory; private static ConfigurationNode dataConfig; - private static File dataFile; + private static Path dataFile; private StorageTool() { } @@ -114,7 +115,7 @@ private static void loadData() { generateFile(); try { - dataConfig = YamlConfigurationLoader.builder().path(dataFile.toPath()).build().load(); + dataConfig = YamlConfigurationLoader.builder().path(dataFile).build().load(); } catch (IOException e) { e.printStackTrace(); } @@ -124,29 +125,29 @@ private static void saveData() { generateFile(); try { - YamlConfigurationLoader.builder().path(dataFile.toPath()).build().save(dataConfig); + YamlConfigurationLoader.builder().path(dataFile).build().save(dataConfig); } catch (IOException e) { e.printStackTrace(); } } private static void generateFile() { - if (!dataDirectory.exists() && !dataDirectory.mkdir()) - return; + try { + if (!Files.exists(dataDirectory)) { + Files.createDirectories(dataDirectory); + } - if (!dataFile.exists()) { - try { - if (!dataFile.createNewFile()) - throw new IOException("Couldn't create file " + dataFile.getPath()); - } catch (IOException e) { - e.printStackTrace(); + if (!Files.exists(dataFile)) { + Files.createFile(dataFile); } + } catch (IOException e) { + e.printStackTrace(); } } - public static void setupTool(File dataDirectory) { + public static void setupTool(Path dataDirectory) { StorageTool.dataDirectory = dataDirectory; - StorageTool.dataFile = new File(dataDirectory, "data.yml"); + StorageTool.dataFile = dataDirectory.resolve("data.yml"); loadData(); } diff --git a/src/main/java/net/pistonmaster/pistonqueue/velocity/PistonQueueVelocity.java b/src/main/java/net/pistonmaster/pistonqueue/velocity/PistonQueueVelocity.java index f8a3f81..10ff622 100644 --- a/src/main/java/net/pistonmaster/pistonqueue/velocity/PistonQueueVelocity.java +++ b/src/main/java/net/pistonmaster/pistonqueue/velocity/PistonQueueVelocity.java @@ -46,7 +46,6 @@ import org.bstats.velocity.Metrics; import org.slf4j.Logger; -import java.io.File; import java.nio.file.Path; import java.util.List; import java.util.Optional; @@ -60,7 +59,7 @@ url = PluginData.URL, description = PluginData.DESCRIPTION, authors = {"AlexProgrammerDE"}) public final class PistonQueueVelocity implements PistonQueuePlugin { @Getter - private final File dataDirectory; + private final Path dataDirectory; @Getter private final ProxyServer proxyServer; @Getter @@ -75,7 +74,7 @@ public final class PistonQueueVelocity implements PistonQueuePlugin { public PistonQueueVelocity(ProxyServer proxyServer, Logger logger, @DataDirectory Path dataDirectory, PluginContainer pluginContainer, Metrics.Factory metricsFactory) { this.proxyServer = proxyServer; this.logger = logger; - this.dataDirectory = dataDirectory.toFile(); + this.dataDirectory = dataDirectory; this.pluginContainer = pluginContainer; this.metricsFactory = metricsFactory; } diff --git a/src/main/resources/proxyconfig.yml b/src/main/resources/proxy_config.yml similarity index 95% rename from src/main/resources/proxyconfig.yml rename to src/main/resources/proxy_config.yml index da54d16..e452ddf 100644 --- a/src/main/resources/proxyconfig.yml +++ b/src/main/resources/proxy_config.yml @@ -87,11 +87,6 @@ ALLOW_AUTH_SKIP: true # Connecting to server message JOINING_MAIN_SERVER: "&6Connecting to the server..." -# Max players per queue type allowed on the main server -REGULAR_SLOTS: 50 -PRIORITY_SLOTS: 30 -VETERAN_SLOTS: 20 - # Whether you want to set the main server as your target or just want to have BungeeCord to decide. FORCE_MAIN_SERVER: false @@ -131,8 +126,14 @@ SHADOW_BAN_MESSAGE: "&6You have lost connection to the server" QUEUE_BYPASS_PERMISSION: "queue.bypass" ADMIN_PERMISSION: "queue.admin" -QUEUES: - NORMAL: +# Adding or removing queue types requires a full restart!!! +# The order number is checked from first to last. +QUEUE_TYPES: + REGULAR: + ORDER: 3 + # Max players of this type allowed on the main server + SLOTS: 50 + # Special permission for the default queue type PERMISSION: "default" # Queue server tab list configuration use %position% to show the current position of the player # and use %wait% to show the estimated wait time of the player (not very accurate yet) @@ -155,6 +156,8 @@ QUEUES: - " These are the only official SERVERNAME websites and contacts " - "" PRIORITY: + ORDER: 2 + SLOTS: 30 PERMISSION: "queue.priority" # Configs for priority queue tab list HEADER: @@ -175,6 +178,8 @@ QUEUES: - " These are the only official SERVERNAME websites and contacts " - "" VETERAN: + ORDER: 1 + SLOTS: 20 PERMISSION: "queue.veteran" # Configs for veteran queue tab list HEADER: