diff --git a/api/src/main/java/com/alttd/boosterapi/Booster.java b/api/src/main/java/com/alttd/boosterapi/Booster.java index 705a45c..601e668 100644 --- a/api/src/main/java/com/alttd/boosterapi/Booster.java +++ b/api/src/main/java/com/alttd/boosterapi/Booster.java @@ -2,7 +2,7 @@ package com.alttd.boosterapi; import java.util.UUID; -public interface Booster { +public interface Booster extends Comparable { boolean isActive(); @@ -20,6 +20,8 @@ public interface Booster { void setStartingTime(long startingTime); + Long getEndTime(); + Long getDuration(); void setDuration(long duration); diff --git a/api/src/main/java/com/alttd/boosterapi/config/BoosterStorage.java b/api/src/main/java/com/alttd/boosterapi/config/BoosterStorage.java index 71598fc..43f54cb 100644 --- a/api/src/main/java/com/alttd/boosterapi/config/BoosterStorage.java +++ b/api/src/main/java/com/alttd/boosterapi/config/BoosterStorage.java @@ -1,6 +1,7 @@ package com.alttd.boosterapi.config; import com.alttd.boosterapi.Booster; +import com.alttd.boosterapi.BoosterType; import com.alttd.boosterapi.util.ALogger; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; @@ -12,6 +13,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import java.io.File; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; public abstract class BoosterStorage { @@ -21,6 +23,11 @@ public abstract class BoosterStorage { ALogger.info("Loading boosters..."); init(); boosters = loadBoosters(); + if (Config.DEBUG) { + for (Booster value : boosters.values()) { + ALogger.info(value.getType().BoosterName); + } + } } private void init() { File CONFIG_PATH = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "Boosters"); @@ -87,6 +94,8 @@ public abstract class BoosterStorage { try { JsonGenerator generator = new JsonFactory().createGenerator(CONFIG_FILE, JsonEncoding.UTF8); for (Booster booster : boosters) { + if (booster.finished()) + continue; saveBooster(booster, generator); } generator.close(); @@ -110,4 +119,7 @@ public abstract class BoosterStorage { generator.writeEndObject(); } + public Collection getBoosters(BoosterType type) { + return boosters.values().stream().filter(booster -> booster.getType().equals(type)).collect(Collectors.toList()); + } } diff --git a/plugin/src/main/java/com/alttd/boosters/data/Booster.java b/plugin/src/main/java/com/alttd/boosters/data/ServerBooster.java similarity index 76% rename from plugin/src/main/java/com/alttd/boosters/data/Booster.java rename to plugin/src/main/java/com/alttd/boosters/data/ServerBooster.java index 0c18aa5..d741c27 100644 --- a/plugin/src/main/java/com/alttd/boosters/data/Booster.java +++ b/plugin/src/main/java/com/alttd/boosters/data/ServerBooster.java @@ -1,11 +1,13 @@ package com.alttd.boosters.data; +import com.alttd.boosterapi.Booster; import com.alttd.boosterapi.BoosterType; import com.alttd.boosterapi.util.ALogger; +import org.jetbrains.annotations.NotNull; import java.util.UUID; -public class Booster implements com.alttd.boosterapi.Booster { +public class ServerBooster implements Booster { private UUID uuid; private String activator; @@ -16,7 +18,7 @@ public class Booster implements com.alttd.boosterapi.Booster { private Boolean active; private Boolean finished; - public Booster(UUID uuid, BoosterType boosterType, String reason, long duration, double multiplier) { + public ServerBooster(UUID uuid, BoosterType boosterType, String reason, long duration, double multiplier) { this.uuid = uuid; this.boosterType = boosterType; this.activator = reason; @@ -26,11 +28,11 @@ public class Booster implements com.alttd.boosterapi.Booster { this.finished = false; } - public Booster(BoosterType type, String playerName, long duration, double multiplier) { + public ServerBooster(BoosterType type, String playerName, long duration, double multiplier) { this(UUID.randomUUID(), type, playerName, duration, multiplier); } - public Booster(UUID uuid, String activator, BoosterType boosterType, long startingTime, long duration, double multiplier, boolean active, boolean finished) { + public ServerBooster(UUID uuid, String activator, BoosterType boosterType, long startingTime, long duration, double multiplier, boolean active, boolean finished) { this.uuid = uuid; this.activator = activator; this.boosterType = boosterType; @@ -81,6 +83,11 @@ public class Booster implements com.alttd.boosterapi.Booster { this.startingTime = startingTime; } + @Override + public Long getEndTime() { + return startingTime = duration; + } + @Override public Long getDuration() { return duration; @@ -137,5 +144,13 @@ public class Booster implements com.alttd.boosterapi.Booster { } - + @Override + public int compareTo(@NotNull Object o) { + Booster booster = (Booster) o; + if (booster.getMultiplier() < getMultiplier()) + return -1; + if (booster.getMultiplier() > getMultiplier()) + return 1; + return booster.isActive() ? 1 : -1; + } } diff --git a/plugin/src/main/java/com/alttd/boosters/listeners/PluginMessage.java b/plugin/src/main/java/com/alttd/boosters/listeners/PluginMessage.java index d075665..782badf 100644 --- a/plugin/src/main/java/com/alttd/boosters/listeners/PluginMessage.java +++ b/plugin/src/main/java/com/alttd/boosters/listeners/PluginMessage.java @@ -18,12 +18,19 @@ public class PluginMessage implements PluginMessageListener { if(!channel.equals(Config.pluginMessageChannel)) return; ByteArrayDataInput in = ByteStreams.newDataInput(bytes); String subChannel = in.readUTF(); - // Listen to plugin messages from velocity to either activate or deactive a booster. switch (subChannel) { case "activate" -> { - ServerBoosterStorage.getServerBoosterStorage().reload(); - //TODO maybe make this add one thing to the map without resetting it to avoid having to clear it - // (still need to load it all to get that one booster though) + UUID uuid = UUID.fromString(in.readUTF()); + Booster booster = ServerBoosterStorage.getServerBoosterStorage().getBoosters().get(uuid); + if (booster == null) { + ServerBoosterStorage.getServerBoosterStorage().reload(); + booster = ServerBoosterStorage.getServerBoosterStorage().getBoosters().get(uuid); + } + if (booster == null) { + ALogger.warn("Unable to load and activate booster [" + uuid + "]"); + break; + } + booster.setActive(true); } case "finish" -> { UUID uuid = UUID.fromString(in.readUTF()); @@ -43,6 +50,9 @@ public class PluginMessage implements PluginMessageListener { } booster.stopBooster(); } + case "reload" -> { + ServerBoosterStorage.getServerBoosterStorage().reload(); + } default -> {} } } diff --git a/plugin/src/main/java/com/alttd/boosters/managers/BoosterManager.java b/plugin/src/main/java/com/alttd/boosters/managers/BoosterManager.java index 62c5254..a754afb 100644 --- a/plugin/src/main/java/com/alttd/boosters/managers/BoosterManager.java +++ b/plugin/src/main/java/com/alttd/boosters/managers/BoosterManager.java @@ -2,15 +2,15 @@ package com.alttd.boosters.managers; import com.alttd.boosterapi.Booster; import com.alttd.boosterapi.BoosterType; +import com.alttd.boosterapi.config.BoosterStorage; +import com.alttd.boosters.storage.ServerBoosterStorage; import java.util.List; public class BoosterManager { - private static List activeBoosters; - public boolean isBoosted(BoosterType type) { - for (Booster b : activeBoosters) { + for (Booster b : ServerBoosterStorage.getServerBoosterStorage().getBoosters().values()) { if (b.getType() == type && b.isActive()) { return true; } @@ -19,7 +19,7 @@ public class BoosterManager { } public Booster getBooster(BoosterType type) { - for (Booster b : activeBoosters) { + for (Booster b : ServerBoosterStorage.getServerBoosterStorage().getBoosters().values()) { if (b.getType() == type && b.isActive()) { return b; } diff --git a/plugin/src/main/java/com/alttd/boosters/storage/ServerBoosterStorage.java b/plugin/src/main/java/com/alttd/boosters/storage/ServerBoosterStorage.java index 2911a57..80d2620 100644 --- a/plugin/src/main/java/com/alttd/boosters/storage/ServerBoosterStorage.java +++ b/plugin/src/main/java/com/alttd/boosters/storage/ServerBoosterStorage.java @@ -4,6 +4,7 @@ import com.alttd.boosterapi.Booster; import com.alttd.boosterapi.BoosterType; import com.alttd.boosterapi.config.BoosterStorage; import com.alttd.boosterapi.util.ALogger; +import com.alttd.boosters.data.ServerBooster; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; @@ -77,7 +78,7 @@ public class ServerBoosterStorage extends BoosterStorage { return error("Didn't find finished at expected location"); parser.nextValue(); boolean finished = parser.getValueAsBoolean(); - return new com.alttd.boosters.data.Booster(uuid, activator, boosterType, startingTime, duration, multiplier, active, finished); + return new ServerBooster(uuid, activator, boosterType, startingTime, duration, multiplier, active, finished); } private static Booster error(String error) { diff --git a/velocity/src/main/java/com/alttd/vboosters/commands/BoosterCommand.java b/velocity/src/main/java/com/alttd/vboosters/commands/BoosterCommand.java index 0dc431f..a2ccef9 100755 --- a/velocity/src/main/java/com/alttd/vboosters/commands/BoosterCommand.java +++ b/velocity/src/main/java/com/alttd/vboosters/commands/BoosterCommand.java @@ -29,6 +29,7 @@ import net.kyori.adventure.text.minimessage.Template; import java.text.DateFormat; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class BoosterCommand { @@ -72,7 +73,7 @@ public class BoosterCommand { templates.add(Template.of("end_time", "unknown")); if (booster.isActive()) activeBoosterComponents.add(miniMessage.parse(activeBooster, templates)); - else + else if (!booster.finished()) queuedBoosterComponents.add(miniMessage.parse(queuedBooster, templates)); } Component separator = miniMessage.parse("\n"); @@ -100,7 +101,7 @@ public class BoosterCommand { .executes(context -> { //TODO make messages configurable String username = context.getArgument("username", String.class); BoosterType boosterType = BoosterType.getByName(context.getArgument("booster", String.class)); - long duration = context.getArgument("time", Integer.class) * 60; + long duration = TimeUnit.MINUTES.toMillis(context.getArgument("time", Integer.class)); double multiplier = context.getArgument("multiplier", Double.class); VelocityBoosters.getPlugin().getBoosterManager().addBooster(new VelocityBooster(boosterType, username, duration, multiplier)); long expiryTime = new Date().getTime() + duration; diff --git a/velocity/src/main/java/com/alttd/vboosters/data/VelocityBooster.java b/velocity/src/main/java/com/alttd/vboosters/data/VelocityBooster.java index 317a03a..12a26f0 100644 --- a/velocity/src/main/java/com/alttd/vboosters/data/VelocityBooster.java +++ b/velocity/src/main/java/com/alttd/vboosters/data/VelocityBooster.java @@ -2,12 +2,18 @@ package com.alttd.vboosters.data; import com.alttd.boosterapi.Booster; import com.alttd.boosterapi.BoosterType; +import com.alttd.vboosters.VelocityBoosters; import com.alttd.vboosters.storage.VelocityBoosterStorage; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; import java.util.Date; import java.util.UUID; +import java.util.stream.Collectors; public class VelocityBooster implements Booster { @@ -88,6 +94,11 @@ public class VelocityBooster implements Booster { this.startingTime = startingTime; } + @Override + public Long getEndTime() { + return startingTime + duration; + } + @Override public Long getDuration() { return duration; @@ -127,7 +138,11 @@ public class VelocityBooster implements Booster { setActive(false); saveBooster(); if (!finished) { - //TODO send plugin message that its stopped + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("finish"); + out.writeUTF(uuid.toString()); + VelocityBoosters.getPlugin().getProxy().getAllServers() + .forEach(registeredServer -> registeredServer.sendPluginMessage(VelocityBoosters.getPlugin().getChannelIdentifier(), out.toByteArray())); } } @@ -136,11 +151,27 @@ public class VelocityBooster implements Booster { VelocityBoosterStorage vbs = VelocityBoosterStorage.getVelocityBoosterStorage(); vbs.getBoosters().put(uuid, this); vbs.saveBoosters(vbs.getBoosters().values()); + updateQueue(); + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("reload"); + VelocityBoosters.getPlugin().getProxy().getAllServers() + .forEach(registeredServer -> registeredServer.sendPluginMessage(VelocityBoosters.getPlugin().getChannelIdentifier(), out.toByteArray())); } public void finish() { //TODO finish it on the servers as well finished = true; stopBooster(); + saveBooster(); //Deletes inactive boosters + List collect = VelocityBoosterStorage.getVelocityBoosterStorage().getBoosters(boosterType).stream().sorted().collect(Collectors.toList()); + if (collect.size() <= 1) + return; + Booster booster = collect.get(1); + booster.setActive(true); + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("activate"); + out.writeUTF(booster.getUUID().toString()); + VelocityBoosters.getPlugin().getProxy().getAllServers() + .forEach(registeredServer -> registeredServer.sendPluginMessage(VelocityBoosters.getPlugin().getChannelIdentifier(), out.toByteArray())); //TODO send plugin message that this is finished } @@ -149,4 +180,38 @@ public class VelocityBooster implements Booster { return finished; } + private void updateQueue() { + Collection boosters = VelocityBoosterStorage.getVelocityBoosterStorage().getBoosters(getType()); + if (boosters.isEmpty()) + return; + List collect = boosters.stream().sorted().collect(Collectors.toList()); + Booster booster = collect.get(0); + if (!booster.isActive()) { + booster.setActive(true); + booster.setStartingTime(new Date().getTime()); + } + if (collect.size() > 1) + fixTimes(collect); + } + + private void fixTimes(List sorted) { + for (int i = 0; i < sorted.size() - 1; i++) { + Booster booster = sorted.get(i + 1); + if (booster.isActive()) { //Disable active boosters that shouldn't be active and update their duration + booster.setActive(false); + booster.setDuration(booster.getEndTime() - booster.getStartingTime()); + } + booster.setStartingTime(sorted.get(i).getEndTime()); + } + } + + @Override + public int compareTo(@NotNull Object o) { + Booster booster = (Booster) o; + if (booster.getMultiplier() < getMultiplier()) + return -1; + if (booster.getMultiplier() > getMultiplier()) + return 1; + return booster.isActive() ? 1 : -1; + } }