diff --git a/pom.xml b/pom.xml index ba0d6f3..36fb50e 100644 --- a/pom.xml +++ b/pom.xml @@ -23,8 +23,8 @@ maven-compiler-plugin 3.8.1 - ${java.version} - ${java.version} + 11 + 11 diff --git a/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java b/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java index 397a71e..ea621d4 100644 --- a/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java +++ b/src/main/java/org/aleabodo/fireworksmc/Commands/Fireworkshow.java @@ -3,6 +3,7 @@ package org.aleabodo.fireworksmc.Commands; import org.aleabodo.fireworksmc.Direction; import org.aleabodo.fireworksmc.Fireworks_Mc; import org.aleabodo.fireworksmc.Message; +import org.aleabodo.fireworksmc.Tempo; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -28,33 +29,68 @@ public class Fireworkshow implements CommandExecutor, TabCompleter { switch (args[0]) { case "setlocation": //Set location - Fireworks_Mc.show.setLocation(player.getLocation()); + Fireworks_Mc.config.location = player.getLocation(); + Fireworks_Mc.config.save(); Message.sendInfo(player, "Location successfully set to your position."); - break; + return true; case "setdirection": - //Set direction - switch (args[1]) { - case "north": - Fireworks_Mc.show.setDirection(Direction.NORTH); - break; - case "east": - Fireworks_Mc.show.setDirection(Direction.EAST); - break; - case "south": - Fireworks_Mc.show.setDirection(Direction.SOUTH); - break; - case "west": - Fireworks_Mc.show.setDirection(Direction.WEST); - break; - default: - Message.sendWarning(player, "Please enter either 'north', 'east', 'south', or 'west'!"); + //Compute direction based on player yaw + if (args.length < 2) { + float yaw = player.getLocation().getYaw(); + if (yaw < 0) { + yaw += 360; + } + yaw = (yaw % 360 + 360) % 360; // true modulo, as javas modulo is weird for negative values + Direction direction; + if (yaw >= 315 || yaw < 45) { + direction = Direction.SOUTH; + } else if (yaw < 135) { + direction = Direction.WEST; + } else if (yaw < 225) { + direction = Direction.NORTH; + } else if (yaw < 315) { + direction = Direction.EAST; + } else { + direction = Direction.NORTH; + } + Fireworks_Mc.config.direction = direction; + Message.sendInfo(player, "Direction successfully set to " + direction); + Fireworks_Mc.config.save(); + return true; + } + + //Set direction manually + switch (args[1]) { + case "NORTH": + Fireworks_Mc.config.direction = Direction.NORTH; + Message.sendInfo(player, "Direction successfully set to " + Direction.NORTH); + Fireworks_Mc.config.save(); + return true; + case "EAST": + Fireworks_Mc.config.direction = Direction.EAST; + Message.sendInfo(player, "Direction successfully set to " + Direction.EAST); + Fireworks_Mc.config.save(); + return true; + case "SOUTH": + Fireworks_Mc.config.direction = Direction.SOUTH; + Message.sendInfo(player, "Direction successfully set to " + Direction.SOUTH); + Fireworks_Mc.config.save(); + return true; + case "WEST": + Fireworks_Mc.config.direction = Direction.WEST; + Message.sendInfo(player, "Direction successfully set to " + Direction.WEST); + Fireworks_Mc.config.save(); + return true; + default: + Message.sendWarning(player, "Please enter either 'NORTH', 'EAST', 'SOUTH', 'WEST', or leave empty!"); + return false; } - break; case "setduration": //Set duration try { int duration = Integer.parseInt(args[1]); - Fireworks_Mc.show.setDuration(duration); + Fireworks_Mc.config.duration = duration; + Fireworks_Mc.config.save(); Message.sendInfo(player, "Duration successfully set to " + duration); return true; } catch (NumberFormatException e) { @@ -66,11 +102,118 @@ public class Fireworkshow implements CommandExecutor, TabCompleter { for (int i = 1; i highlights; + public SortedMap tempo; + + public Config() { + reload(); + } + + private void load() { + Fireworks_Mc.getPlugin().reloadConfig(); + FileConfiguration config = Fireworks_Mc.getPlugin().getConfig(); + this.bpm = config.getInt("bpm", 80); + this.duration = config.getInt("duration", 60); + this.seed = config.getString("seed", "Survival-Pi"); + this.highlights = new TreeSet<>(config.getIntegerList("highlights")); + + // Parse and set location + this.location = new Location( + Fireworks_Mc.getWorld(config.getString("location.world","world")), + config.getInt("location.x",0), + config.getInt("location.y",80), + config.getInt("location.z",0) + ); + + // Parse and set direction + String direction = config.getString("direction", "WEST"); + if(direction != null) { + switch (direction) { + case "NORTH": + this.direction = Direction.NORTH; + case "EAST": + this.direction = Direction.EAST; + case "SOUTH": + this.direction = Direction.SOUTH; + default: + this.direction = Direction.WEST; + } + } + + // Parse and set tempo + SortedMap tempo = new TreeMap<>(); + List tempoArray = config.getStringList("tempo"); + tempo.put(0, Tempo.NORMAL); //Have at least one tempo configuration in the map + for (String tempoString : tempoArray) { + String[] args = tempoString.split(","); + if (args.length == 2) { + try { + Tempo t; + switch (args[1]) { + case "QUIET": + t = Tempo.QUIET; + case "SLOW": + t = Tempo.SLOW; + case "FAST": + t = Tempo.FAST; + case "FASTEST": + t = Tempo.FASTEST; + default: + t = Tempo.NORMAL; + } + tempo.put(Integer.parseInt(args[0]), t); + } catch (NumberFormatException e) { + Fireworks_Mc.getPlugin().getLogger().log(Level.SEVERE, "Config in section 'tempo' is expecting an integer!"); + return; + } + } + } + this.tempo = tempo; + } + + public void save() { + FileConfiguration config = Fireworks_Mc.getPlugin().getConfig(); + + config.set("bpm", this.bpm); + config.set("seed", this.seed); + config.set("duration", this.duration); + config.set("direction", this.direction.toString()); + config.set("highlights", new ArrayList<>(this.highlights)); + + //Convert tempo map to ArrayList and set tempo in config to this list + ArrayList tempoStringList = new ArrayList<>(); + for (Integer key : this.tempo.keySet()) { + Tempo value = this.tempo.get(key); + tempoStringList.add(key + "," + value.toString()); + } + config.set("tempo", tempoStringList); + + ConfigurationSection locationSection = config.createSection("location"); + locationSection.set("world", this.location.getWorld().getName()); + locationSection.set("x", this.location.getX()); + locationSection.set("y", this.location.getY()); + locationSection.set("z", this.location.getZ()); + + Fireworks_Mc.getPlugin().saveConfig(); + } + + public void print() { + //Compute string of all highlights. Use this string to append to the text component + StringBuilder highlight = new StringBuilder(); + for (Integer h : this.highlights) { + highlight.append("\n") + .append(" - ") + .append(".".repeat(Message.getNumberOfDotsToAlign(" - " + h))) + .append(h); + } + + //Compute string of all tempos + StringBuilder tempos = new StringBuilder(); + for (Integer key : this.tempo.keySet()) { + Tempo value = this.tempo.get(key); + tempos.append("\n") + .append(" - ") + .append(".".repeat(Message.getNumberOfDotsToAlign(" - " + key + "," + value.toString()))) + .append(key).append(",").append(value.toString()); + } + + Message.sendDebug( + Component.text("Config:\n").color(NamedTextColor.GOLD), + Component.text( + "direction: " + + ".".repeat(Message.getNumberOfDotsToAlign("direction: " + this.direction.toString())) + + this.direction.toString() + + "\n" + + + "bpm: " + + ".".repeat(Message.getNumberOfDotsToAlign("bpm: " + this.bpm)) + + this.bpm + + "\n" + + + "duration: " + + ".".repeat(Message.getNumberOfDotsToAlign("duration: " + this.duration)) + + this.duration + + "\n" + + + "seed: " + + ".".repeat(Message.getNumberOfDotsToAlign("seed: " + this.seed)) + + this.seed + + "\n" + + + "location:" + + "\n" + + " - world: " + + ".".repeat(Message.getNumberOfDotsToAlign(" - world: " + this.location.getWorld().getName())) + + this.location.getWorld().getName() + + "\n" + + " - x: " + + ".".repeat(Message.getNumberOfDotsToAlign(" - x: " + this.location.getX())) + + this.location.getX() + + "\n" + + " - y: " + + ".".repeat(Message.getNumberOfDotsToAlign(" - y: " + this.location.getY())) + + this.location.getY() + + "\n" + + " - z: " + + ".".repeat(Message.getNumberOfDotsToAlign(" - z: " + this.location.getZ())) + + this.location.getZ() + + "\n" + + + "highlights:" + + highlight + + "\n" + + + "tempo:" + + tempos + ) + ); + } + + public void reload() { + load(); + } +} diff --git a/src/main/java/org/aleabodo/fireworksmc/Direction.java b/src/main/java/org/aleabodo/fireworksmc/Direction.java index 3a806ae..41c9f57 100644 --- a/src/main/java/org/aleabodo/fireworksmc/Direction.java +++ b/src/main/java/org/aleabodo/fireworksmc/Direction.java @@ -4,5 +4,20 @@ public enum Direction { NORTH, EAST, SOUTH, - WEST + WEST; + + @Override + public String toString() { + switch (this) { + case NORTH: + return "NORTH"; + case EAST: + return "EAST"; + case SOUTH: + return "SOUTH"; + case WEST: + return "WEST"; + } + return null; + } } diff --git a/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java b/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java index 2008f37..6893c18 100644 --- a/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java +++ b/src/main/java/org/aleabodo/fireworksmc/Fireworks_Mc.java @@ -22,6 +22,7 @@ public final class Fireworks_Mc extends JavaPlugin { private static Fireworks_Mc plugin; public static Show show; + public static Config config; @Override public void onEnable() { @@ -40,16 +41,22 @@ public final class Fireworks_Mc extends JavaPlugin { } particlesAPI = ParticleNativePlugin.getAPI(); + /* + * Initilize config + */ + Fireworks_Mc.config = new Config(); + //Initialize show with default values - Fireworks_Mc.show = new Show("Survival-Pi", + /*Fireworks_Mc.show = new Show("Survival-Pi", new Location(Fireworks_Mc.getWorld("world"), 0, 80, 0), Direction.NORTH, - 60); - + 60,76); +*/ /* * Initialize command executors */ Objects.requireNonNull(getCommand("fireworkshow")).setExecutor(new Fireworkshow()); + Objects.requireNonNull(getCommand("fs")).setExecutor(new Fireworkshow()); //Command alias for fireworkshow } @Override diff --git a/src/main/java/org/aleabodo/fireworksmc/Message.java b/src/main/java/org/aleabodo/fireworksmc/Message.java index 0535dbe..f7ad340 100644 --- a/src/main/java/org/aleabodo/fireworksmc/Message.java +++ b/src/main/java/org/aleabodo/fireworksmc/Message.java @@ -6,6 +6,7 @@ import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import org.bukkit.map.MinecraftFont; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -13,7 +14,7 @@ import java.util.Collection; public class Message { public static void sendInfo(@NotNull Player player, Component ... content) { - Component textComponent = Component.text().color(NamedTextColor.GRAY).build() + Component textComponent = Component.text().color(NamedTextColor.WHITE).build() .append(Component.text("[Fireworks] ") .color(TextColor.color(0,213,255)) .decoration(TextDecoration.BOLD, true)); @@ -46,7 +47,7 @@ public class Message { */ public static void sendWarning(@NotNull Player player, Component ... content) { - Component textComponent = Component.text().color(NamedTextColor.GRAY).build() + Component textComponent = Component.text().color(NamedTextColor.WHITE).build() .append(Component.text("[Fireworks] ") .color(TextColor.color(255, 3, 4)) .decoration(TextDecoration.BOLD, true)); @@ -80,7 +81,7 @@ public class Message { */ public static void sendBroadcast(Component ... content) { - Component textComponent = Component.text().color(NamedTextColor.GRAY).build() + Component textComponent = Component.text().color(NamedTextColor.WHITE).build() .append(Component.text("[Fireworks] ") .color(TextColor.color(255, 153, 0)) .decoration(TextDecoration.BOLD, true)); @@ -104,7 +105,7 @@ public class Message { */ public static void sendDebug(Component ... content) { - Component textComponent = Component.text().color(NamedTextColor.GRAY).build() + Component textComponent = Component.text().color(NamedTextColor.WHITE).build() .append(Component.text("[Fireworks] ") .color(TextColor.color(255, 0, 245)) .decoration(TextDecoration.BOLD, true)); @@ -114,7 +115,7 @@ public class Message { } for (Player p : Bukkit.getOnlinePlayers()) { - if (p.hasPermission("beacon.debug")) + if (p.hasPermission("fireworksmc.debug")) p.sendMessage(textComponent); } } @@ -122,4 +123,13 @@ public class Message { public static void sendDebug(String content) { sendDebug(Component.text(content)); } + + /* + * ############################################################################# + * Utils + */ + + public static int getNumberOfDotsToAlign(String displayText) { + return (int) Math.round((130.0 - MinecraftFont.Font.getWidth(displayText))/2); + } } \ No newline at end of file diff --git a/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java b/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java new file mode 100644 index 0000000..39d784f --- /dev/null +++ b/src/main/java/org/aleabodo/fireworksmc/Patterns/Pattern.java @@ -0,0 +1,17 @@ +package org.aleabodo.fireworksmc.Patterns; + +public class Pattern { + private int duration = 10; + + public Pattern(int duration) { + + } + + /* + * ################### GETTER ################### + */ + + public int getDuration() { + return duration; + } +} diff --git a/src/main/java/org/aleabodo/fireworksmc/Show.java b/src/main/java/org/aleabodo/fireworksmc/Show.java index 2469bcd..3246d08 100644 --- a/src/main/java/org/aleabodo/fireworksmc/Show.java +++ b/src/main/java/org/aleabodo/fireworksmc/Show.java @@ -1,13 +1,11 @@ package org.aleabodo.fireworksmc; -import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.FireworkEffect; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.Firework; import org.bukkit.inventory.meta.FireworkMeta; -import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; import java.security.MessageDigest; @@ -15,16 +13,25 @@ import java.security.NoSuchAlgorithmException; import java.util.Random; public class Show { - private String seed; + private long seed; private Location location; private Direction direction; private int duration; //in seconds + private int bpm; - public Show(String seed, Location location, Direction direction, int duration) { + public Show(long seed, Location location, Direction direction, int duration, int bpm) { this.seed = seed; this.location = location; this.direction = direction; this.duration = duration; + this.bpm = bpm; + } + + /* + * Generate the firework show according to the random seed and the timings/highlights configured + */ + public void generate() { + } /** @@ -60,34 +67,11 @@ public class Show { }.runTaskLater(Fireworks_Mc.getPlugin(), 20); // 20 ticks = 1 second } - /** - * - * @param seedString Random seed as string - * @return Random number between 0 and based on the seed - */ - private double generateRandomValueFromSeed(String seedString) { - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - byte[] hashBytes = md.digest(seedString.getBytes()); - - // Convert the first 8 bytes of the hash to a long value - long hashValue = 0; - for (int i = 0; i < 8; i++) { - hashValue = (hashValue << 8) | (hashBytes[i]); - } - - //Convert long (hastValue) into random number between 0 and 1. - return new Random(hashValue).nextDouble(); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Hashing algorithm not available. (Have to check or Intellij complains.", e); - } - } - /* * ################### GETTER ################### */ - public String getSeed() { + public long getSeed() { return seed; } @@ -103,13 +87,15 @@ public class Show { return duration; } - + public int getBpm() { + return bpm; + } /* * ################### SETTER ################### */ - public void setSeed(String seed) { + public void setSeed(long seed) { this.seed = seed; } @@ -124,4 +110,8 @@ public class Show { public void setDuration(int duration) { this.duration = duration; } + + public void setBpm(int bpm) { + this.bpm = bpm; + } } diff --git a/src/main/java/org/aleabodo/fireworksmc/Tempo.java b/src/main/java/org/aleabodo/fireworksmc/Tempo.java new file mode 100644 index 0000000..21a5056 --- /dev/null +++ b/src/main/java/org/aleabodo/fireworksmc/Tempo.java @@ -0,0 +1,26 @@ +package org.aleabodo.fireworksmc; + +public enum Tempo { + QUIET, + SLOW, + NORMAL, + FAST, + FASTEST; + + @Override + public String toString() { + switch (this) { + case QUIET: + return "QUIET"; + case SLOW: + return "SLOW"; + case NORMAL: + return "NORMAL"; + case FAST: + return "FAST"; + case FASTEST: + return "FASTEST"; + } + return null; + } +} diff --git a/src/main/java/org/aleabodo/fireworksmc/Utils.java b/src/main/java/org/aleabodo/fireworksmc/Utils.java new file mode 100644 index 0000000..d8258bb --- /dev/null +++ b/src/main/java/org/aleabodo/fireworksmc/Utils.java @@ -0,0 +1,38 @@ +package org.aleabodo.fireworksmc; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Random; + +public class Utils { + /** + * + * @param seed as long + * @return Random number between 0 and based on the seed + */ + public static double generateRandomValueFromSeed(long seed) { + return new Random(seed).nextDouble(); + } + + /** + * + * @param seedString Random seed as string + * @return Seed converted as long + */ + public static long generateLongFromSeed(String seedString) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] hashBytes = md.digest(seedString.getBytes()); + + // Convert the first 8 bytes of the hash to a long value + long hashValue = 0; + for (int i = 0; i < 8; i++) { + hashValue = (hashValue << 8) | (hashBytes[i]); + } + + return hashValue; + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Hashing algorithm not available. (Have to check or Intellij complains.", e); + } + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 050cd68..89766a6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,6 +5,7 @@ api-version: '1.20' commands: fireworkshow: description: All fireworks show related commands + aliases: [fs] depend: [ParticleNativeAPI] permissions: fireworksmc.setseed: