From b18d7d0457ed54f130d227877fb31931d7aa0b05 Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Fri, 1 Oct 2021 10:49:29 -0400 Subject: [PATCH 01/10] =?UTF-8?q?=E2=9C=A8=20Started=20Working=20on=20Pers?= =?UTF-8?q?istent=20Settings=20Support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/DeluxeMediaPlugin.java | 68 +++++++++++-------- .../{VideoType.java => PlaybackType.java} | 8 +-- .../command/video/VideoCommand.java | 2 +- .../command/video/VideoCommandAttributes.java | 50 ++++++++------ .../command/video/VideoCreator.java | 2 +- .../command/video/VideoSettingCommand.java | 6 +- .../config/ConfigurationProvider.java | 4 +- .../deluxemediaplugin/json/DataProvider.java | 53 +++++++++++++++ .../deluxemediaplugin/json/GsonProvider.java | 16 +++++ .../json/MediaAttributesData.java | 14 ++++ 10 files changed, 162 insertions(+), 61 deletions(-) rename deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/{VideoType.java => PlaybackType.java} (89%) create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 9c794df20..43d27b6ba 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -74,8 +74,8 @@ public final class DeluxeMediaPlugin { private CommandHandler handler; private Logger logger; - private PersistentPictureManager manager; private AudioConfiguration audioConfiguration; + private PersistentPictureManager manager; private HttpServer server; private MediaBot mediaBot; private ServerInfo httpAudioServer; @@ -93,17 +93,8 @@ public void enable() { this.log( join(separator(text(" ")), text("Running DeluxeMediaPlugin", AQUA), text("[BETA]", GOLD), text("1.0.0", AQUA))); - this.log( - "Loading MinecraftMediaLibrary instance... this may take a minute depending on your server!"); - try { - this.library = LibraryProvider.builder().plugin(this.plugin).build(); - this.library.initialize(); - } catch (final ExecutionException | InterruptedException e) { - this.log(text("There was a severe issue while loading the EzMediaCore instance!", RED)); - e.printStackTrace(); - this.plugin.getServer().getPluginManager().disablePlugin(this.plugin); - return; - } + this.log("Loading MinecraftMediaLibrary instance... this may take a minute depending on your server!"); + this.startLibrary(); this.log("Finished loading MinecraftMediaLibrary instance!"); this.loadPersistentData(); this.log("Finished loading persistent data!"); @@ -120,6 +111,29 @@ public void enable() { """); } + public void disable() throws Exception { + this.log("DeluxeMediaPlugin is shutting down!"); + this.shutdownLibrary(); + this.unregisterCommands(); + this.disableBot(); + this.cancelNativeTasks(); + this.log("Good Bye :("); + } + + public void load() { + } + + private void startLibrary() { + try { + this.library = LibraryProvider.builder().plugin(this.plugin).build(); + this.library.initialize(); + } catch (final ExecutionException | InterruptedException e) { + this.log(text("There was a severe issue while loading the EzMediaCore instance!", RED)); + e.printStackTrace(); + this.plugin.getServer().getPluginManager().disablePlugin(this.plugin); + } + } + private void startMetrics() { new Metrics(this.plugin, 10229); } @@ -144,37 +158,38 @@ private void printLogo() { } } - public void disable() throws Exception { - this.log("DeluxeMediaPlugin is shutting down!"); - - if (this.library != null) { - this.library.shutdown(); - this.log("Successfully shutdown MinecraftMediaLibrary instance!"); - } else { - this.log(text("EzMediaCore instance is null... something fishy is going on.", RED)); + private void disableBot() { + if (this.mediaBot != null) { + this.mediaBot.getJDA().shutdown(); } + } + private void unregisterCommands() { if (this.handler != null) { for (final BaseCommand cmd : this.handler.getCommands()) { CommandUtils.unRegisterBukkitCommand(this, cmd); } } + } - if (this.mediaBot != null) { - this.mediaBot.getJDA().shutdown(); + private void shutdownLibrary() { + if (this.library != null) { + this.library.shutdown(); + this.log("Successfully shutdown MinecraftMediaLibrary instance!"); + } else { + this.log(text("EzMediaCore instance is null... something fishy is going on.", RED)); } + } + private void cancelNativeTasks() throws Exception { final EnhancedExecution extractor = this.attributes.getExtractor(); if (extractor != null) { extractor.close(); } - final EnhancedExecution streamExtractor = this.attributes.getStreamExtractor(); if (streamExtractor != null) { streamExtractor.close(); } - - this.log("Good Bye :("); } private void loadPersistentData() { @@ -201,9 +216,6 @@ private void loadPersistentData() { } } - public void load() { - } - public void log(@NotNull final String line) { this.log(format(text(line))); } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoType.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/PlaybackType.java similarity index 89% rename from deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoType.java rename to deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/PlaybackType.java index 47ed29bd7..e628ab3a7 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoType.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/PlaybackType.java @@ -28,14 +28,14 @@ import java.util.Optional; import org.jetbrains.annotations.NotNull; -public enum VideoType { +public enum PlaybackType { ITEMFRAME("itemframe-maps"), ARMOR_STAND("armorstands"), CHATBOX("chatbox"), DEBUG_HIGHLIGHTS("debug-highlights"), SCOREBOARD("scoreboard"); - private static final Map KEYS; + private static final Map KEYS; static { KEYS = @@ -49,11 +49,11 @@ public enum VideoType { private final String name; - VideoType(@NotNull final String name) { + PlaybackType(@NotNull final String name) { this.name = name; } - public static @NotNull Optional ofKey(@NotNull final String str) { + public static @NotNull Optional ofKey(@NotNull final String str) { return Optional.ofNullable(KEYS.get(str)); } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java index 891992016..1bc2baa0e 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java @@ -135,7 +135,7 @@ private int playVideo(@NotNull final CommandContext context) { this.releaseIfPlaying(); - final VideoType type = this.attributes.getVideoType(); + final PlaybackType type = this.attributes.getVideoType(); switch (type) { case ITEMFRAME -> this.attributes.setPlayer(this.builder.createMapPlayer(players)); case ARMOR_STAND -> { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java index 7f2534512..62df10c12 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java @@ -24,6 +24,7 @@ package io.github.pulsebeat02.deluxemediaplugin.command.video; +import com.google.gson.annotations.Expose; import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting; import io.github.pulsebeat02.ezmediacore.ffmpeg.EnhancedExecution; import io.github.pulsebeat02.ezmediacore.player.MrlConfiguration; @@ -39,12 +40,26 @@ public final class VideoCommandAttributes { TEMPORARY_PLACEHOLDER = true; } - private final AtomicBoolean completion; + @Expose + private DitherSetting ditherType; - private VideoPlayer player; - private DitherSetting dither; + @Expose private AudioOutputType audioOutputType; - private VideoType mode; + + @Expose + private PlaybackType playbackType; + + @Expose + private int map; + + @Expose + private int frameWidth, frameHeight; + + @Expose + private int pixelWidth, pixelHeight; + + private final AtomicBoolean completion; + private VideoPlayer player; private MrlConfiguration videoMrl; private MrlConfiguration oggMrl; @@ -52,33 +67,26 @@ public final class VideoCommandAttributes { private EnhancedExecution extractor; private EnhancedExecution streamExtractor; - private int map; - - private int frameWidth; - private int frameHeight; - private int pixelWidth; - private int pixelHeight; - private String resourcepackUrl; // for resourcepack url private byte[] resourcepackHash; public VideoCommandAttributes() { - this.dither = DitherSetting.FILTER_LITE; + this.ditherType = DitherSetting.FILTER_LITE; this.audioOutputType = AudioOutputType.RESOURCEPACK; + this.playbackType = PlaybackType.ITEMFRAME; this.frameWidth = 5; this.frameHeight = 5; this.pixelWidth = 640; this.pixelHeight = 360; this.completion = new AtomicBoolean(false); - this.mode = VideoType.ITEMFRAME; } - public DitherSetting getDither() { - return this.dither; + public DitherSetting getDitherType() { + return this.ditherType; } - public void setDither(final DitherSetting dither) { - this.dither = dither; + public void setDitherType(final DitherSetting ditherType) { + this.ditherType = ditherType; } public VideoPlayer getPlayer() { @@ -133,12 +141,12 @@ public void setMap(final int map) { return this.completion; } - public @NotNull VideoType getVideoType() { - return this.mode; + public @NotNull PlaybackType getVideoType() { + return this.playbackType; } - public void setVideoType(final VideoType type) { - this.mode = type; + public void setVideoType(final PlaybackType type) { + this.playbackType = type; } public String getResourcepackUrl() { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java index b4f880dee..ddbd30530 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java @@ -52,7 +52,7 @@ public VideoCreator( return VideoBuilder.unspecified() .callback( CallbackBuilder.map() - .algorithm(this.attributes.getDither().getAlgorithm()) + .algorithm(this.attributes.getDitherType().getAlgorithm()) .blockWidth(this.attributes.getPixelWidth()) .map(Identifier.ofIdentifier(0)) .dims(Dimension.ofDimension(this.attributes.getFrameWidth(), this.attributes.getFrameHeight())) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java index 32d069dc6..adf7999db 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java @@ -109,7 +109,7 @@ public VideoSettingCommand( private @NotNull CompletableFuture suggestVideoModes( final CommandContext context, final @NotNull SuggestionsBuilder builder) { - Arrays.stream(VideoType.values()).forEach(x -> builder.suggest(x.name())); + Arrays.stream(PlaybackType.values()).forEach(x -> builder.suggest(x.name())); return builder.buildFuture(); } @@ -243,7 +243,7 @@ private int setDitherMode(@NotNull final CommandContext context) if (setting.isEmpty()) { red(audience, "Could not find dither type %s".formatted(algorithm)); } else { - this.attributes.setDither(setting.get()); + this.attributes.setDitherType(setting.get()); audience.sendMessage( format(join(noSeparators(), text("Set dither type to ", GOLD), text(algorithm, AQUA)))); } @@ -255,7 +255,7 @@ private int setVideoMode(@NotNull final CommandContext context) { final Audience audience = this.plugin.audience().sender(context.getSource()); final String mode = context.getArgument("video-mode", String.class); - final Optional type = VideoType.ofKey(mode); + final Optional type = PlaybackType.ofKey(mode); if (type.isEmpty()) { red(audience, "Could not find video mode %s".formatted(mode)); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java index 5567ea64c..379cab431 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java @@ -90,9 +90,7 @@ public void saveDefaultConfig() { } public void read() { - if (!Files.exists(this.config)) { - this.saveDefaultConfig(); - } + this.saveDefaultConfig(); this.getConfig(); try { this.serialize(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java new file mode 100644 index 000000000..b9cff9af2 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java @@ -0,0 +1,53 @@ +package io.github.pulsebeat02.deluxemediaplugin.json; + +import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class DataProvider { + + private final DeluxeMediaPlugin plugin; + private final String name; + private final Path path; + private T object; + + public DataProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) + throws IOException { + this.plugin = plugin; + this.name = name; + this.path = plugin.getBootstrap().getDataFolder().toPath().resolve(this.name); + } + + public void deserialize() throws IOException { + GsonProvider.getGson().toJson(this.object, Files.newBufferedWriter(this.path)); + } + + public void serialize() throws IOException { + if (!Files.exists(this.path)) { + this.plugin.getBootstrap().saveResource(this.name, false); + } + this.object = + (T) + GsonProvider.getGson() + .fromJson(Files.newBufferedReader(this.path), this.object.getClass()); + } + + public @Nullable T getSerializedValue() { + return this.object; + } + + public @NotNull DeluxeMediaPlugin getPlugin() { + return this.plugin; + } + + public @NotNull String getFileName() { + return this.name; + } + + public @NotNull Path getConfigFile() { + return this.path; + } +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java new file mode 100644 index 000000000..ffb438d33 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java @@ -0,0 +1,16 @@ +package io.github.pulsebeat02.deluxemediaplugin.json; + +import com.google.gson.Gson; + +public final class GsonProvider { + + private static final Gson GSON; + + static { + GSON = new Gson(); + } + + public static Gson getGson() { + return GSON; + } +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java new file mode 100644 index 000000000..4fae33449 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java @@ -0,0 +1,14 @@ +package io.github.pulsebeat02.deluxemediaplugin.json; + +import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import io.github.pulsebeat02.deluxemediaplugin.command.video.VideoCommandAttributes; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; + +public class MediaAttributesData extends DataProvider { + + public MediaAttributesData( + @NotNull final DeluxeMediaPlugin plugin) throws IOException { + super(plugin, "video-attributes.json"); + } +} From 80454155557d19de00a85bb3e69bbaae78c788aa Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Fri, 1 Oct 2021 20:54:32 -0400 Subject: [PATCH 02/10] =?UTF-8?q?=E2=9C=A8=20Started=20Working=20on=20Loca?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/DeluxeMediaPlugin.java | 53 +++--- .../deluxemediaplugin/message/Locale.java | 155 ++++++++++++++++++ .../deluxemediaplugin/message/Sender.java | 11 ++ 3 files changed, 187 insertions(+), 32 deletions(-) create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 43d27b6ba..8df8a0f72 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -25,13 +25,8 @@ package io.github.pulsebeat02.deluxemediaplugin; import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format; -import static net.kyori.adventure.text.Component.join; import static net.kyori.adventure.text.Component.text; -import static net.kyori.adventure.text.JoinConfiguration.separator; -import static net.kyori.adventure.text.format.NamedTextColor.AQUA; import static net.kyori.adventure.text.format.NamedTextColor.BLUE; -import static net.kyori.adventure.text.format.NamedTextColor.GOLD; -import static net.kyori.adventure.text.format.NamedTextColor.RED; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand; @@ -43,6 +38,7 @@ import io.github.pulsebeat02.deluxemediaplugin.config.HttpConfiguration; import io.github.pulsebeat02.deluxemediaplugin.config.PersistentPictureManager; import io.github.pulsebeat02.deluxemediaplugin.config.ServerInfo; +import io.github.pulsebeat02.deluxemediaplugin.message.Locale; import io.github.pulsebeat02.deluxemediaplugin.update.UpdateChecker; import io.github.pulsebeat02.deluxemediaplugin.utility.CommandUtils; import io.github.pulsebeat02.ezmediacore.LibraryProvider; @@ -57,7 +53,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.logging.Logger; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import org.bstats.bukkit.Metrics; @@ -71,8 +67,8 @@ public final class DeluxeMediaPlugin { private MediaLibraryCore library; private BukkitAudiences audiences; + private Audience console; private CommandHandler handler; - private Logger logger; private AudioConfiguration audioConfiguration; private PersistentPictureManager manager; @@ -87,48 +83,41 @@ public DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { } public void enable() { - this.logger = this.plugin.getLogger(); this.audiences = BukkitAudiences.create(this.plugin); + this.console = this.audiences.console(); this.printLogo(); - this.log( - join(separator(text(" ")), text("Running DeluxeMediaPlugin", AQUA), text("[BETA]", GOLD), - text("1.0.0", AQUA))); - this.log("Loading MinecraftMediaLibrary instance... this may take a minute depending on your server!"); + this.console.sendMessage(Locale.ENABLE_PLUGIN.build()); + this.console.sendMessage(Locale.EMC_INIT.build()); this.startLibrary(); - this.log("Finished loading MinecraftMediaLibrary instance!"); + this.console.sendMessage(Locale.FIN_EMC_INIT.build()); this.loadPersistentData(); - this.log("Finished loading persistent data!"); + this.console.sendMessage(Locale.FIN_PERSISTENT_INIT.build()); this.registerCommands(); - this.log("Finished registering plugin commands!"); + this.console.sendMessage(Locale.FIN_COMMANDS_INIT.build()); this.startMetrics(); - this.log("Finished loading Metrics data!"); + this.console.sendMessage(Locale.FIN_METRICS_INIT.build()); this.checkUpdates(); - this.log("Finished loading DeluxeMediaPlugin!"); - this.log(""" - Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this - is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for - support at my Discord! (https://discord.gg/MgqRKvycMC) - """); + this.console.sendMessage(Locale.FIN_PLUGIN_INIT.build()); + this.console.sendMessage(Locale.WELCOME.build()); } public void disable() throws Exception { - this.log("DeluxeMediaPlugin is shutting down!"); + this.console.sendMessage(Locale.DISABLE_PLUGIN.build()); this.shutdownLibrary(); this.unregisterCommands(); this.disableBot(); this.cancelNativeTasks(); - this.log("Good Bye :("); + this.console.sendMessage(Locale.GOODBYE.build()); } - public void load() { - } + public void load() {} private void startLibrary() { try { this.library = LibraryProvider.builder().plugin(this.plugin).build(); this.library.initialize(); } catch (final ExecutionException | InterruptedException e) { - this.log(text("There was a severe issue while loading the EzMediaCore instance!", RED)); + this.console.sendMessage(Locale.ERR_EMC_INIT.build()); e.printStackTrace(); this.plugin.getServer().getPluginManager().disablePlugin(this.plugin); } @@ -175,9 +164,9 @@ private void unregisterCommands() { private void shutdownLibrary() { if (this.library != null) { this.library.shutdown(); - this.log("Successfully shutdown MinecraftMediaLibrary instance!"); + this.console.sendMessage(Locale.GOOD_EMC_SHUTDOWN.build()); } else { - this.log(text("EzMediaCore instance is null... something fishy is going on.", RED)); + this.console.sendMessage(Locale.ERR_EMC_SHUTDOWN.build()); } } @@ -194,8 +183,8 @@ private void cancelNativeTasks() throws Exception { private void loadPersistentData() { try { - Set.of(this.plugin.getDataFolder().toPath().resolve("configuration")).forEach( - ThrowingConsumer.unchecked(FileUtils::createFolderIfNotExists)); + Set.of(this.plugin.getDataFolder().toPath().resolve("configuration")) + .forEach(ThrowingConsumer.unchecked(FileUtils::createFolderIfNotExists)); final HttpConfiguration httpConfiguration = new HttpConfiguration(this); final EncoderConfiguration encoderConfiguration = new EncoderConfiguration(this); final BotConfiguration botConfiguration = new BotConfiguration(this); @@ -211,7 +200,7 @@ private void loadPersistentData() { this.manager = new PersistentPictureManager(this); this.manager.startTask(); } catch (final IOException e) { - this.logger.severe("A severe issue occurred while reading data from configuration files!"); + this.console.sendMessage(Locale.ERR_PERSISTENT_INIT.build()); e.printStackTrace(); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java new file mode 100644 index 000000000..b23d94090 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java @@ -0,0 +1,155 @@ +package io.github.pulsebeat02.deluxemediaplugin.message; + +import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format; +import static net.kyori.adventure.text.Component.join; +import static net.kyori.adventure.text.Component.text; +import static net.kyori.adventure.text.JoinConfiguration.separator; +import static net.kyori.adventure.text.format.NamedTextColor.AQUA; +import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY; +import static net.kyori.adventure.text.format.NamedTextColor.GOLD; +import static net.kyori.adventure.text.format.NamedTextColor.GRAY; +import static net.kyori.adventure.text.format.NamedTextColor.RED; + +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +public interface Locale { + + Component NEW_LINE = Component.newline(); + Component SPACE = Component.space(); + + UniComponent REQUIRED_ARGUMENT = + argument -> + text() + .color(DARK_GRAY) + .append(text("<")) + .append(text(argument, GRAY)) + .append(text(">")) + .build(); + + UniComponent OPTIONAL_ARGUMENT = + argument -> + text() + .color(DARK_GRAY) + .append(text("[")) + .append(text(argument, GRAY)) + .append(text("]")) + .build(); + + NullComponent + + ENABLE_PLUGIN = () -> join(separator(text(" ")), + text("Running DeluxeMediaPlugin", AQUA), + text("[BETA]", GOLD), + text("1.0.0", AQUA)), + EMC_INIT = () -> text("Loading EzMediaCore instance... this may take some time!"), + WELCOME = () -> text(""" + Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this + is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for + support at my Discord! (https://discord.gg/MgqRKvycMC) + """), + + DISABLE_PLUGIN = () -> text("DeluxeMediaPlugin is shutting down!"), + GOOD_EMC_SHUTDOWN = () -> text("Successfully shutdown MinecraftMediaLibrary instance!"), + GOODBYE = () -> text("Good Bye! :("), + + FIN_EMC_INIT = () -> text("Finished loading MinecraftMediaLibrary instance!"), + FIN_PERSISTENT_INIT = () -> text("Finished loading persistent data!"), + FIN_COMMANDS_INIT = () -> text("Finished registering plugin commands!"), + FIN_METRICS_INIT = () -> text("Finished loading Metrics data!"), + FIN_PLUGIN_INIT = () -> text("Finished loading DeluxeMediaPlugin!"), + + ERR_EMC_INIT = () -> text("There was a severe issue while loading the EzMediaCore instance!", RED), + ERR_PERSISTENT_INIT = () -> text("A severe issue occurred while reading data from configuration files!", RED), + ERR_EMC_SHUTDOWN = () -> text("EzMediaCore instance is null... something fishy is going on.", RED) + + + + + ; + + @FunctionalInterface + interface NullComponent { + Component build(); + + default void send(@NotNull final S sender) { + sender.sendMessage(format(this.build())); + } + } + + @FunctionalInterface + interface UniComponent { + Component build(A0 arg0); + + default void send(@NotNull final S sender, final A0 arg0) { + sender.sendMessage(format(this.build(arg0))); + } + } + + @FunctionalInterface + interface BiComponent { + Component build(A0 arg0, A1 arg1); + + default void send(@NotNull final S sender, @NotNull final A0 arg0, @NotNull final A1 arg1) { + sender.sendMessage(format(this.build(arg0, arg1))); + } + } + + @FunctionalInterface + interface TriComponent { + Component build(A0 arg0, A1 arg1, A2 arg2); + + default void send( + @NotNull final S sender, + @NotNull final A0 arg0, + @NotNull final A1 arg1, + @NotNull final A2 arg2) { + sender.sendMessage(format(this.build(arg0, arg1, arg2))); + } + } + + @FunctionalInterface + interface QuadComponent { + Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3); + + default void send( + @NotNull final S sender, + @NotNull final A0 arg0, + @NotNull final A1 arg1, + @NotNull final A2 arg2, + @NotNull final A3 arg3) { + sender.sendMessage(format(this.build(arg0, arg1, arg2, arg3))); + } + } + + @FunctionalInterface + interface PentaComponent { + Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4); + + default void send( + @NotNull final S sender, + @NotNull final A0 arg0, + @NotNull final A1 arg1, + @NotNull final A2 arg2, + @NotNull final A3 arg3, + @NotNull final A4 arg4) { + sender.sendMessage(format(this.build(arg0, arg1, arg2, arg3, arg4))); + } + } + + @FunctionalInterface + interface HexaComponent { + Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5); + + default void send( + @NotNull final S sender, + @NotNull final A0 arg0, + @NotNull final A1 arg1, + @NotNull final A2 arg2, + @NotNull final A3 arg3, + @NotNull final A4 arg4, + @NotNull final A5 arg5) { + sender.sendMessage(format(this.build(arg0, arg1, arg2, arg3, arg4, arg5))); + } + } +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java new file mode 100644 index 000000000..d45fb3df3 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java @@ -0,0 +1,11 @@ +package io.github.pulsebeat02.deluxemediaplugin.message; + +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +public interface Sender { + + void sendMessage(@NotNull final Component component); + + boolean hasPermission(@NotNull final String permission); +} From 5b262484398415ef628baf9e0a65c6d29a2aa263 Mon Sep 17 00:00:00 2001 From: Brandon Li <40838203+PulseBeat02@users.noreply.github.com> Date: Fri, 1 Oct 2021 23:25:23 -0400 Subject: [PATCH 03/10] =?UTF-8?q?=E2=9C=A8=20Switched=20Messages=20to=20Lo?= =?UTF-8?q?cale=20+=20Refactored=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ezmediacore/analysis/Diagnostic.java | 3 +- .../BlockHighlightCallbackDispatcher.java | 4 +- .../entity/EntityCallbackDispatcher.java | 3 +- .../ezmediacore/dimension/ChatDimension.java | 3 +- .../ezmediacore/dimension/FrameDimension.java | 3 +- .../ezmediacore/dimension/PixelDimension.java | 3 +- .../ezmediacore/dither/DitherAlgorithm.java | 3 +- .../executor/ExecutorProvider.java | 3 +- .../ezmediacore/ffmpeg/AudioExtractor.java | 4 +- .../ezmediacore/format/FormatterProvider.java | 3 +- .../ezmediacore/playlist/spotify/Avatar.java | 4 +- .../ezmediacore/random/AssertingRandom.java | 11 +- .../ezmediacore/random/MurmurHash3.java | 9 +- .../random/Xoroshiro128PlusRandom.java | 3 +- .../pulsebeat02/ezmediacore/search/BNDM.java | 15 +- .../ezmediacore/search/MismatchSearch.java | 156 ++--- .../ezmediacore/search/StringSearch.java | 148 +++-- .../ezmediacore/sneaky/SneakyThrowUtil.java | 3 +- .../throwable/DeadResourceLinkException.java | 3 +- .../throwable/HttpFailureException.java | 3 +- .../throwable/InvalidMRLException.java | 3 +- .../throwable/InvalidPackFormatException.java | 3 +- .../InvalidPackResourceException.java | 3 +- .../throwable/LibraryException.java | 3 +- .../throwable/RequestFailureException.java | 3 +- .../throwable/UnknownArtistException.java | 3 +- .../throwable/UnknownPlaylistException.java | 3 +- .../UnsupportedPlatformException.java | 3 +- .../ezmediacore/utility/ArrayUtils.java | 3 +- .../ezmediacore/utility/CollectionUtils.java | 3 +- .../ezmediacore/utility/FastStringUtils.java | 3 +- .../ezmediacore/utility/FastUUIDUtils.java | 7 +- .../ezmediacore/utility/FileUtils.java | 3 +- .../ezmediacore/utility/HashingUtils.java | 3 +- .../ezmediacore/utility/ImageUtils.java | 3 +- .../ezmediacore/utility/MapUtils.java | 3 +- .../ezmediacore/utility/NetworkUtils.java | 3 +- .../ezmediacore/utility/PathUtils.java | 5 +- .../ezmediacore/utility/ThreadUtils.java | 3 +- .../deluxemediaplugin/DeluxeMediaPlugin.java | 13 +- .../audio/M3uStreamSegmentUrlProvider.java | 8 +- .../bot/audio/MusicManager.java | 10 +- .../bot/audio/MusicSendHandler.java | 2 +- .../bot/audio/TrackScheduler.java | 12 +- .../command/CommandHandler.java | 12 +- .../command/CommandSegment.java | 12 +- .../command/audio/AudioCommand.java | 11 +- .../command/audio/AudioLoadCommand.java | 43 +- .../command/discord/DiscordCommand.java | 15 +- .../command/dither/DitherCommand.java | 9 +- .../ffmpeg/FFmpegAddArgumentCommand.java | 32 +- .../command/ffmpeg/FFmpegCommand.java | 18 +- .../ffmpeg/FFmpegRemoveArgumentCommand.java | 29 +- .../command/gui/ItemBuilder.java | 2 +- .../command/gui/SkullCreator.java | 538 +++++++++--------- .../command/gui/SkullException.java | 3 +- .../command/image/ResetImageCommand.java | 40 +- .../command/image/SetImageCommand.java | 183 +++--- .../command/map/MapCommand.java | 181 +++--- .../command/plugin/PluginCommand.java | 56 +- .../command/screen/ScreenCommand.java | 12 +- .../command/video/VideoCommand.java | 91 +-- .../command/video/VideoCommandAttributes.java | 8 +- .../command/video/VideoCreator.java | 158 ++--- .../command/video/VideoLoadCommand.java | 85 +-- .../command/video/VideoSettingCommand.java | 89 +-- .../config/BotConfiguration.java | 15 +- .../deluxemediaplugin/json/DataProvider.java | 23 + .../deluxemediaplugin/json/GsonProvider.java | 23 + .../json/MediaAttributesData.java | 25 +- .../deluxemediaplugin/message/Locale.java | 316 +++++++++- .../deluxemediaplugin/message/Sender.java | 23 + .../update/UpdateChecker.java | 40 +- .../deluxemediaplugin/utility/ChatUtils.java | 21 +- .../utility/CommandUtils.java | 9 +- .../ezmediacore/LibraryProvider.java | 3 +- .../pulsebeat02/ezmediacore/EzMediaCore.java | 3 +- .../ezmediacore/NativePluginLoader.java | 3 +- .../callback/BlockHighlightCallback.java | 3 +- .../ezmediacore/callback/ChatCallback.java | 3 +- .../ezmediacore/callback/EntityCallback.java | 4 +- .../ezmediacore/callback/FrameCallback.java | 3 +- .../ezmediacore/callback/MapCallback.java | 3 +- .../callback/ScoreboardCallback.java | 3 +- .../ezmediacore/dither/MapPalette.java | 290 +++++----- .../dither/algorithm/FilterLiteDither.java | 3 +- .../dither/algorithm/FloydDither.java | 3 +- .../dither/algorithm/SimpleDither.java | 3 +- .../dither/load/DitherLookupUtil.java | 7 +- .../ezmediacore/dither/load/LoadBlue.java | 3 +- .../ezmediacore/dither/load/LoadGreen.java | 3 +- .../ezmediacore/dither/load/LoadRed.java | 3 +- .../ffmpeg/FFmpegCommandExecutor.java | 6 +- .../ffmpeg/SpotifyTrackExtractor.java | 9 +- .../ffmpeg/YoutubeVideoAudioExtractor.java | 9 +- .../ezmediacore/http/FileRequestHandler.java | 2 +- .../ezmediacore/http/HttpServerDaemon.java | 12 +- .../ezmediacore/image/DynamicImage.java | 3 +- .../pulsebeat02/ezmediacore/image/Image.java | 6 +- .../persistent/PersistentImageStorage.java | 3 +- .../ezmediacore/player/FFmpegMediaPlayer.java | 39 +- .../ezmediacore/player/JCodecMediaPlayer.java | 58 +- .../ezmediacore/player/MediaPlayer.java | 3 +- .../ezmediacore/player/VideoBuilder.java | 6 +- .../ezmediacore/playlist/WebsiteControls.java | 21 +- .../ezmediacore/playlist/WebsitePlayer.java | 24 +- .../playlist/spotify/SpotifyProvider.java | 3 +- .../youtube/SpotifyTrackDownloader.java | 16 +- .../playlist/youtube/YoutubeAudioFormat.java | 6 +- .../playlist/youtube/YoutubeProvider.java | 6 +- .../youtube/YoutubeVideoDownloader.java | 16 +- .../playlist/youtube/YoutubeVideoFormat.java | 6 +- .../ezmediacore/reflect/Reflection.java | 48 +- .../ezmediacore/reflect/TinyProtocol.java | 22 +- .../resourcepack/ResourcepackWrapper.java | 6 +- .../ezmediacore/task/CommandTask.java | 2 +- .../ezmediacore/task/CommandTaskChain.java | 8 +- .../ezmediacore/utility/ArgumentUtils.java | 3 +- .../ezmediacore/utility/DependencyUtils.java | 51 +- .../utility/MediaExtractionUtils.java | 3 +- .../ezmediacore/utility/RequestUtils.java | 3 +- .../ezmediacore/utility/ResourceUtils.java | 3 +- .../utility/ResourcepackUtils.java | 13 +- .../ezmediacore/utility/TaskUtils.java | 3 +- .../ezmediacore/utility/VideoFrameUtils.java | 3 +- .../ezmediacore/vlc/EMCNativeDiscovery.java | 2 +- .../vlc/os/mac/SilentMacInstallation.java | 6 +- .../vlc/os/unix/UnixNativeDiscovery.java | 3 +- .../vlc/os/window/WindowsNativeDiscovery.java | 3 +- .../ezmediacore/FFmpegVideoTest.java | 3 +- .../ezmediacore/VLCDownloadTest.java | 3 +- .../libshout/exception/BadFileException.java | 6 +- .../exception/PushStreamException.java | 6 +- .../exception/ReadStreamException.java | 6 +- 134 files changed, 1823 insertions(+), 1597 deletions(-) diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/analysis/Diagnostic.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/analysis/Diagnostic.java index ee34735eb..be4f7413e 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/analysis/Diagnostic.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/analysis/Diagnostic.java @@ -35,7 +35,8 @@ public interface Diagnostic { /** - * Debugs the information into the Logger class the library uses to debug information for clients. + * Debugs the information into the Logger class the library uses to debug information for + * clients. */ void debugInformation(); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallbackDispatcher.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallbackDispatcher.java index 8b4c7ec68..5b7722f06 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallbackDispatcher.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallbackDispatcher.java @@ -23,4 +23,6 @@ */ package io.github.pulsebeat02.ezmediacore.callback; -public interface BlockHighlightCallbackDispatcher extends Callback, Locatable {} +public interface BlockHighlightCallbackDispatcher extends Callback, Locatable { + +} diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/entity/EntityCallbackDispatcher.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/entity/EntityCallbackDispatcher.java index fbee3151c..b5e1820ea 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/entity/EntityCallbackDispatcher.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/callback/entity/EntityCallbackDispatcher.java @@ -38,6 +38,5 @@ public interface EntityCallbackDispatcher extends Callback, Locatable { @NotNull NamedEntityString getStringName(); - @Nullable - Consumer modifyEntity(); + @Nullable Consumer modifyEntity(); } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/ChatDimension.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/ChatDimension.java index eee880aa8..c10e5e695 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/ChatDimension.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/ChatDimension.java @@ -54,5 +54,6 @@ public final class ChatDimension { X16_92 = ofDimension(16, 92); } - private ChatDimension() {} + private ChatDimension() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/FrameDimension.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/FrameDimension.java index b8443ac3a..ce3e031f1 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/FrameDimension.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/FrameDimension.java @@ -52,5 +52,6 @@ public final class FrameDimension { X10_14 = ofDimension(10, 14); } - private FrameDimension() {} + private FrameDimension() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/PixelDimension.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/PixelDimension.java index 3da7a5b6c..5ff6d91c0 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/PixelDimension.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dimension/PixelDimension.java @@ -55,5 +55,6 @@ public final class PixelDimension { X3840_2160 = ofDimension(3840, 2160); } - private PixelDimension() {} + private PixelDimension() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dither/DitherAlgorithm.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dither/DitherAlgorithm.java index bfdc5ba3c..e55ffdf23 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/dither/DitherAlgorithm.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/dither/DitherAlgorithm.java @@ -32,5 +32,6 @@ public interface DitherAlgorithm { @NotNull ByteBuffer ditherIntoMinecraft(final int @NotNull [] buffer, final int width); - default void dither(final int @NotNull [] buffer, final int width) {} + default void dither(final int @NotNull [] buffer, final int width) { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/executor/ExecutorProvider.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/executor/ExecutorProvider.java index b65fb6e0f..1ff3d97e1 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/executor/ExecutorProvider.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/executor/ExecutorProvider.java @@ -54,5 +54,6 @@ public final class ExecutorProvider { FRAME_HANDLER = Executors.newCachedThreadPool(); } - private ExecutorProvider() {} + private ExecutorProvider() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/AudioExtractor.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/AudioExtractor.java index edf2c0043..9477453e4 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/AudioExtractor.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/AudioExtractor.java @@ -23,4 +23,6 @@ */ package io.github.pulsebeat02.ezmediacore.ffmpeg; -public interface AudioExtractor extends IOProvider {} +public interface AudioExtractor extends IOProvider { + +} diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/format/FormatterProvider.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/format/FormatterProvider.java index fa4beeb47..cb02dd1a8 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/format/FormatterProvider.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/format/FormatterProvider.java @@ -33,5 +33,6 @@ public final class FormatterProvider { FFMPEG_TIME_FORMATTER = new SimpleDateFormat("HH:mm:ss.SSS"); } - private FormatterProvider() {} + private FormatterProvider() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/Avatar.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/Avatar.java index c2d0c77b9..4dfb063ef 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/Avatar.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/Avatar.java @@ -26,4 +26,6 @@ import io.github.pulsebeat02.ezmediacore.dimension.Dimensional; import io.github.pulsebeat02.ezmediacore.playlist.ResourceUrl; -public interface Avatar extends Dimensional, ResourceUrl {} +public interface Avatar extends Dimensional, ResourceUrl { + +} diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/AssertingRandom.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/AssertingRandom.java index f7f8fb685..884aa8ac9 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/AssertingRandom.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/AssertingRandom.java @@ -35,8 +35,11 @@ */ public final class AssertingRandom extends Random { - @Serial private static final long serialVersionUID = -1552213382473062718L; - /** Enable paranoid mode when assertions are enabled. */ + @Serial + private static final long serialVersionUID = -1552213382473062718L; + /** + * Enable paranoid mode when assertions are enabled. + */ private static final boolean assertionsEnabled = AssertingRandom.class.desiredAssertionStatus(); private final Random delegate; @@ -162,7 +165,9 @@ public int hashCode() { return this.delegate.hashCode(); } - /** This object will no longer be usable after this method is called. */ + /** + * This object will no longer be usable after this method is called. + */ public void destroy() { this.valid = false; } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/MurmurHash3.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/MurmurHash3.java index 7ed87a4cf..34a3be431 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/MurmurHash3.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/MurmurHash3.java @@ -31,11 +31,14 @@ * @see "http://sites.google.com/site/murmurhash/" */ public final class MurmurHash3 { + private MurmurHash3() { // no instances. } - /** Hashes a 4-byte sequence (Java int). */ + /** + * Hashes a 4-byte sequence (Java int). + */ public static int hash(int k) { k ^= k >>> 16; k *= 0x85ebca6b; @@ -45,7 +48,9 @@ public static int hash(int k) { return k; } - /** Hashes an 8-byte sequence (Java long). */ + /** + * Hashes an 8-byte sequence (Java long). + */ public static long hash(long k) { k ^= k >>> 33; k *= 0xff51afd7ed558ccdL; diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/Xoroshiro128PlusRandom.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/Xoroshiro128PlusRandom.java index a792d3371..43a9d765d 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/Xoroshiro128PlusRandom.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/random/Xoroshiro128PlusRandom.java @@ -36,7 +36,8 @@ public class Xoroshiro128PlusRandom extends Random { private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53); private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0 / (1L << 24); - @Serial private static final long serialVersionUID = -2223015498326800080L; + @Serial + private static final long serialVersionUID = -2223015498326800080L; private long s0, s1; diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java index 69fb34727..e68670700 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java @@ -64,13 +64,13 @@ * @author Johann Burkard * @version $Id: BNDM.java 6675 2015-01-17 21:02:35Z johann $ * @see StringSearch – - * high-performance pattern matching algorithms in Java + * high-performance pattern matching algorithms in Java * @see - * http://www.dcc.uchile.cl/~gnavarro/ps/cpm98.ps.gz + * http://www.dcc.uchile.cl/~gnavarro/ps/cpm98.ps.gz * @see - * http://www-igm.univ-mlv.fr/~raffinot/ftp/cpm98.ps.gz + * http://www-igm.univ-mlv.fr/~raffinot/ftp/cpm98.ps.gz * @see - * http://citeseer.ist.psu.edu/navarro98bitparallel.html + * http://citeseer.ist.psu.edu/navarro98bitparallel.html */ public class BNDM extends StringSearch { @@ -95,7 +95,8 @@ public Object processBytes(final byte @NotNull [] pattern) { /** * Pre-processing of the pattern. The pattern may not exceed 32 bytes in length. If it does, - * only it's first 32 bytes are processed which might lead to unexpected results. Returns a + * only it's first 32 bytes are processed which might lead to unexpected results. Returns + * a * {@link CharIntMap} which is serializable. */ @Override @@ -112,7 +113,9 @@ public Object processChars(final char @NotNull [] pattern) { return b; } - /** */ + /** + * + */ @Override public int searchBytes( final byte[] text, diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/MismatchSearch.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/MismatchSearch.java index ee8f0a68c..a47610b44 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/MismatchSearch.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/MismatchSearch.java @@ -69,7 +69,7 @@ * @author Johann Burkard * @version $Id: MismatchSearch.java 6675 2015-01-17 21:02:35Z johann $ * @see StringSearch – - * high-performance pattern matching algorithms in Java + * high-performance pattern matching algorithms in Java */ public abstract class MismatchSearch extends StringSearch { @@ -82,7 +82,8 @@ public abstract class MismatchSearch extends StringSearch { * *

Identical to process(pattern, 0) * - * @param pattern the byte array containing the pattern, may not be null + * @param pattern the byte array containing the pattern, may not be + * null * @see #processBytes(byte[], int) */ @Override @@ -93,8 +94,9 @@ public final Object processBytes(final byte[] pattern) { /** * Pre-processes the pattern, allowing k errors. * - * @param pattern the byte array containing the pattern, may not be null - * @param k the editing distance + * @param pattern the byte array containing the pattern, may not be + * null + * @param k the editing distance * @return an Object */ public abstract Object processBytes(byte[] pattern, int k); @@ -117,7 +119,7 @@ public final Object processChars(final char[] pattern) { * Pre-processes a char array, allowing k errors. * * @param pattern a char array containing the pattern, may not be null - * @param k the editing distance + * @param k the editing distance * @return an Object */ public abstract Object processChars(char[] pattern, int k); @@ -127,7 +129,7 @@ public final Object processChars(final char[] pattern) { * is implicitly called in the {@link #searchString(String, String)} methods. * * @param pattern the String containing the pattern, may not be null - * @param k the editing distance + * @param k the editing distance * @return an Object */ public Object processString(final String pattern, final int k) { @@ -138,7 +140,9 @@ public Object processString(final String pattern, final int k) { * Byte searching methods */ - /** @see #searchBytes(byte[], int, int, byte[], Object, int) */ + /** + * @see #searchBytes(byte[], int, int, byte[], Object, int) + */ @Override public final int searchBytes( final byte[] text, @@ -154,9 +158,10 @@ public final int searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null - * @param pattern the byte array containing the pattern, may not be null - * @param k the editing distance + * @param text the byte array containing the text, may not be null + * @param pattern the byte array containing the pattern, may not be + * null + * @param k the editing distance * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object, int) */ @@ -168,11 +173,12 @@ public final int[] searchBytes(final byte[] text, final byte[] pattern, final in * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null - * @param pattern the byte array containing the pattern, may not be null + * @param text the byte array containing the text, may not be null + * @param pattern the byte array containing the pattern, may not be + * null * @param processed an Object as returned from {@link #processBytes(byte[], int)}, may not be - * null - * @param k the editing distance + * null + * @param k the editing distance * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object, int) */ @@ -186,10 +192,11 @@ public final int[] searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null + * @param text the byte array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the byte array containing the pattern, may not be null - * @param k the editing distance + * @param pattern the byte array containing the pattern, may not be + * null + * @param k the editing distance * @return int the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object, int) */ @@ -204,11 +211,11 @@ public final int[] searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null + * @param text the byte array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the pattern to search for, may not be null + * @param pattern the pattern to search for, may not be null * @param processed - * @param k the editing distance + * @param k the editing distance * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object, int) */ @@ -226,11 +233,13 @@ public final int[] searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text text the byte array containing the text, may not be null + * @param text text the byte array containing the text, may not be + * null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the byte array containing the pattern, may not be null - * @param k the editing distance + * @param textEnd at which position in the text comparing should stop + * @param pattern the byte array containing the pattern, may not be + * null + * @param k the editing distance * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object, int) */ @@ -248,13 +257,14 @@ public final int[] searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text text the byte array containing the text, may not be null + * @param text text the byte array containing the text, may not be + * null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the pattern to search for, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processBytes(byte[], int)}, may not be - * null - * @param k the editing distance + * null + * @param k the editing distance * @return the position in the text or -1 if the pattern was not found * @see #processBytes(byte[], int) */ @@ -286,9 +296,9 @@ public final int searchChars( /** * Finder for the given pattern in the text, allowing k errors. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param pattern the pattern to search for, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ @@ -299,11 +309,11 @@ public final int[] searchChars(final char[] text, final char[] pattern, final in /** * Finder for the given pattern in the text, allowing k errors. * - * @param text the String containing the text, may not be null - * @param pattern the pattern to search for, may not be null + * @param text the String containing the text, may not be null + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ @@ -316,10 +326,10 @@ public final int[] searchChars( /** * Finder for the given pattern in the text, starting at textStart, allowing k errors. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the pattern to search for, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param pattern the pattern to search for, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -333,12 +343,12 @@ public final int[] searchChars( /** * Finder for the given pattern in the text, starting at textStart, allowing k errors. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the pattern to search for, may not be null + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ @@ -356,11 +366,11 @@ public final int[] searchChars( * Finder for the given pattern in the text, starting at textStart and comparing to at most * textEnd, allowing k errors. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the pattern to search for, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param textEnd at which position in the text comparing should stop + * @param pattern the pattern to search for, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found */ public final int[] searchChars( @@ -377,13 +387,13 @@ public final int[] searchChars( * Finder for the given pattern in the text, starting at textStart and comparing to at most * textEnd, allowing k errors. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the pattern to search for, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found */ public abstract int[] searchChars( @@ -395,9 +405,9 @@ public abstract int[] searchChars( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param pattern the String containing the pattern, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], int) */ @@ -409,11 +419,11 @@ public final int[] searchString(final String text, final String pattern, final i * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null - * @param pattern the String containing the pattern, may not be null + * @param text the String containing the text, may not be null + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ @@ -427,10 +437,10 @@ public final int[] searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the String containing the pattern, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param pattern the String containing the pattern, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], int) */ @@ -444,12 +454,12 @@ public final int[] searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the String containing the pattern, may not be null + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ @@ -467,11 +477,11 @@ public final int[] searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the String containing the pattern, may not be null - * @param k the maximum number of mismatches (the editing distance) + * @param textEnd at which position in the text comparing should stop + * @param pattern the String containing the pattern, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], int) */ @@ -489,13 +499,13 @@ public final int[] searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the String containing the pattern, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[], int)} or {@link - * #processString(String, int)}, may not be null - * @param k the maximum number of mismatches (the editing distance) + * #processString(String, int)}, may not be null + * @param k the maximum number of mismatches (the editing distance) * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object, int) */ diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/StringSearch.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/StringSearch.java index d46aabcc5..b2d696577 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/StringSearch.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/StringSearch.java @@ -80,12 +80,14 @@ * @author Johann Burkard * @version $Id: StringSearch.java 6675 2015-01-17 21:02:35Z johann $ * @see StringSearch – - * high-performance pattern matching algorithms in Java + * high-performance pattern matching algorithms in Java */ public abstract class StringSearch { private static final int CROSSOVER_MACOSX = 50; - /** The StringAccess instance. */ + /** + * The StringAccess instance. + */ static StringAccess activeStringAccess; /** * The crossover point at which the Reflection based char accessor should be used. The crossover @@ -120,7 +122,7 @@ public abstract class StringSearch { } } } - return new Field[] {val, off}; + return new Field[]{val, off}; }); value = valueOffset[0]; offset = valueOffset[1]; @@ -149,7 +151,8 @@ public abstract class StringSearch { super(); } - public static void init() {} + public static void init() { + } /** * Returns if Reflection is used to access the underlying char array in Strings. @@ -175,7 +178,8 @@ public static char[] getChars(final String s) { * Pre-processes a byte array. This method should be used if a pattern is searched * for more than one time. * - * @param pattern the byte array containing the pattern, may not be null + * @param pattern the byte array containing the pattern, may not be + * null * @return an Object */ public abstract Object processBytes(byte[] pattern); @@ -209,8 +213,9 @@ public Object processString(final String pattern) { * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null - * @param pattern the byte array containing the pattern, may not be null + * @param text the byte array containing the text, may not be null + * @param pattern the byte array containing the pattern, may not be + * null * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object) */ @@ -222,8 +227,8 @@ public final int searchBytes(final byte[] text, final byte[] pattern) { * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null - * @param pattern the pattern to search for, may not be null + * @param text the byte array containing the text, may not be null + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processBytes(byte[])}, may not be * null * @return the position in the text or -1 if the pattern was not found @@ -239,9 +244,10 @@ public final int searchBytes(final byte[] text, final byte[] pattern, final Obje * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null + * @param text the byte array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the byte array containing the pattern, may not be null + * @param pattern the byte array containing the pattern, may not be + * null * @return int the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object) */ @@ -253,9 +259,9 @@ public final int searchBytes(final byte[] text, final int textStart, final byte[ * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the byte array containing the text, may not be null + * @param text the byte array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the pattern to search for, may not be null + * @param pattern the pattern to search for, may not be null * @param processed processed data * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object) @@ -270,10 +276,12 @@ public final int searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text text the byte array containing the text, may not be null + * @param text text the byte array containing the text, may not be + * null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the byte array containing the pattern, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the byte array containing the pattern, may not be + * null * @return the position in the text or -1 if the pattern was not found * @see #searchBytes(byte[], int, int, byte[], Object) */ @@ -287,10 +295,11 @@ public final int searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text text the byte array containing the text, may not be null + * @param text text the byte array containing the text, may not be + * null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the pattern to search for, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processBytes(byte[])}, may not be * null * @return the position in the text or -1 if the pattern was not found @@ -303,8 +312,9 @@ public abstract int searchBytes( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the character array containing the text, may not be null - * @param pattern the char array containing the pattern, may not be null + * @param text the character array containing the text, may not be null + * @param pattern the char array containing the pattern, may not be + * null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -316,10 +326,11 @@ public final int searchChars(final char[] text, final char[] pattern) { * Returns the index of the pattern in the text using the pre-processed Object. Returns -1 if the * pattern was not found. * - * @param text the character array containing the text, may not be null - * @param pattern the char array containing the pattern, may not be null + * @param text the character array containing the text, may not be null + * @param pattern the char array containing the pattern, may not be + * null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -333,9 +344,10 @@ public final int searchChars(final char[] text, final char[] pattern, final Obje * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the character array containing the text, may not be null + * @param text the character array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the char array containing the pattern, may not be null + * @param pattern the char array containing the pattern, may not be + * null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -347,11 +359,12 @@ public final int searchChars(final char[] text, final int textStart, final char[ * Returns the index of the pattern in the text using the pre-processed Object. Returns -1 if the * pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the char array containing the pattern, may not be null + * @param pattern the char array containing the pattern, may not be + * null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -365,10 +378,11 @@ public final int searchChars( * Returns the position in the text at which the pattern was found. Returns -1 if the pattern was * not found. * - * @param text the character array containing the text, may not be null + * @param text the character array containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the char array containing the pattern, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the char array containing the pattern, may not be + * null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -382,12 +396,12 @@ public final int searchChars( * Returns the index of the pattern in the text using the pre-processed Object. Returns -1 if the * pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the pattern to search for, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the pattern to search for, may not be null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found */ public abstract int searchChars( @@ -397,7 +411,7 @@ public abstract int searchChars( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param pattern the String containing the pattern, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) @@ -410,10 +424,10 @@ public final int searchString(final String text, final String pattern) { * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null - * @param pattern the String containing the pattern, may not be null + * @param text the String containing the text, may not be null + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -427,9 +441,9 @@ public final int searchString(final String text, final String pattern, final Obj * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the String containing the pattern, may not be null + * @param pattern the String containing the pattern, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -441,11 +455,11 @@ public final int searchString(final String text, final int textStart, final Stri * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param pattern the String containing the pattern, may not be null + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[], Object) */ @@ -459,10 +473,10 @@ public final int searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the String containing the pattern, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the String containing the pattern, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[]) */ @@ -476,12 +490,12 @@ public final int searchString( * Convenience method to search for patterns in Strings. Returns the position in the text at which * the pattern was found. Returns -1 if the pattern was not found. * - * @param text the String containing the text, may not be null + * @param text the String containing the text, may not be null * @param textStart at which position in the text the comparing should start - * @param textEnd at which position in the text comparing should stop - * @param pattern the String containing the pattern, may not be null + * @param textEnd at which position in the text comparing should stop + * @param pattern the String containing the pattern, may not be null * @param processed an Object as returned from {@link #processChars(char[])} or {@link - * #processString(String)}, may not be null + * #processString(String)}, may not be null * @return the position in the text or -1 if the pattern was not found * @see #searchChars(char[], int, int, char[]) */ @@ -540,7 +554,7 @@ public String toString() { * Returns a {@link CharIntMap} of the extent of the given pattern, using the specified default * value. * - * @param pattern the pattern, may not be null + * @param pattern the pattern, may not be null * @param defaultValue the default value * @return a CharIntMap, never null * @see CharIntMap#CharIntMap(int, char, int) @@ -555,8 +569,8 @@ final CharIntMap createCharIntMap(final char[] pattern, final int defaultValue) * Returns a {@link CharIntMap} of the extent of the given pattern, using the specified default * value. * - * @param pattern the pattern, may not be null - * @param patternEnd where to stop searching for extent values in the pattern + * @param pattern the pattern, may not be null + * @param patternEnd where to stop searching for extent values in the pattern * @param defaultValue the default value * @return a CharIntMap, never null * @see CharIntMap#CharIntMap(int, char, int) @@ -592,7 +606,9 @@ final int index(final byte idx) { */ static class StringAccess { - /** Instances are created in StringSearch only. */ + /** + * Instances are created in StringSearch only. + */ private StringAccess() { super(); } @@ -613,7 +629,9 @@ int searchString( text.toCharArray(), textStart, textEnd, pattern.toCharArray(), processed); } - /** Searches a pattern inside a text, using the given StringSearch instance. */ + /** + * Searches a pattern inside a text, using the given StringSearch instance. + */ int searchString( @NotNull final String text, final int textStart, @@ -679,7 +697,7 @@ static class ReflectionStringAccess extends StringAccess { /** * Instances are created in StringSearch only. * - * @param value the "value" field in String + * @param value the "value" field in String * @param offset the "offset" field in String */ private ReflectionStringAccess(final Field value, final Field offset) { @@ -702,7 +720,7 @@ int searchString( final int o = this.offset.getInt(text); final char[] t = (char[]) this.value.get(text); return instance.searchChars( - t, textStart + o, textEnd + o, this.getChars(pattern), processed) + t, textStart + o, textEnd + o, this.getChars(pattern), processed) - o; } catch (final IllegalAccessException ex) { @@ -712,7 +730,9 @@ int searchString( return super.searchString(text, textStart, textEnd, pattern, processed, instance); } - /** */ + /** + * + */ @Override int searchString( @NotNull final String text, @@ -734,7 +754,9 @@ int searchString( return super.searchString(text, textStart, textEnd, pattern, instance); } - /** */ + /** + * + */ @Override int[] searchString( @NotNull final String text, @@ -762,7 +784,9 @@ int[] searchString( return super.searchString(text, textStart, textEnd, pattern, k, instance); } - /** */ + /** + * + */ @Override int[] searchString( @NotNull final String text, diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/sneaky/SneakyThrowUtil.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/sneaky/SneakyThrowUtil.java index e2f06d36f..e47b0c825 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/sneaky/SneakyThrowUtil.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/sneaky/SneakyThrowUtil.java @@ -27,7 +27,8 @@ public final class SneakyThrowUtil { - private SneakyThrowUtil() {} + private SneakyThrowUtil() { + } static R sneakyThrow(@NotNull final Exception t) throws T { throw (T) t; diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/DeadResourceLinkException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/DeadResourceLinkException.java index 540ef6540..d8e7030c6 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/DeadResourceLinkException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/DeadResourceLinkException.java @@ -28,7 +28,8 @@ public final class DeadResourceLinkException extends LibraryException { - @Serial private static final long serialVersionUID = -6428433369003844013L; + @Serial + private static final long serialVersionUID = -6428433369003844013L; public DeadResourceLinkException(@NotNull final String url) { super("Cannot retrieve resource from %s!".formatted(url)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/HttpFailureException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/HttpFailureException.java index 0a2c9ef7a..dcb6ee738 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/HttpFailureException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/HttpFailureException.java @@ -28,7 +28,8 @@ public final class HttpFailureException extends LibraryException { - @Serial private static final long serialVersionUID = -8317098640373685160L; + @Serial + private static final long serialVersionUID = -8317098640373685160L; public HttpFailureException(@NotNull final String message) { super("HTTP Exception: %s".formatted(message)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidMRLException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidMRLException.java index 8438d67dc..80ae6e656 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidMRLException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidMRLException.java @@ -29,7 +29,8 @@ public class InvalidMRLException extends LibraryException { - @Serial private static final long serialVersionUID = 6350588543681340867L; + @Serial + private static final long serialVersionUID = 6350588543681340867L; public InvalidMRLException(@NotNull final String mrl) { super("Invalid MRL %s".formatted(mrl)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackFormatException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackFormatException.java index bde39ba8e..eecc31c50 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackFormatException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackFormatException.java @@ -27,7 +27,8 @@ public final class InvalidPackFormatException extends LibraryException { - @Serial private static final long serialVersionUID = -4686809703553076358L; + @Serial + private static final long serialVersionUID = -4686809703553076358L; public InvalidPackFormatException(final int id) { super("Pack format %d is not a valid pack format!".formatted(id)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackResourceException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackResourceException.java index fc1c1986a..089456e74 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackResourceException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/InvalidPackResourceException.java @@ -28,7 +28,8 @@ public final class InvalidPackResourceException extends LibraryException { - @Serial private static final long serialVersionUID = 1682368011870345638L; + @Serial + private static final long serialVersionUID = 1682368011870345638L; public InvalidPackResourceException(@NotNull final String message) { super("Resourcepack Exception: %s".formatted(message)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/LibraryException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/LibraryException.java index d5a2c87e9..fafe6077b 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/LibraryException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/LibraryException.java @@ -28,7 +28,8 @@ public class LibraryException extends AssertionError { - @Serial private static final long serialVersionUID = -6914539609629173333L; + @Serial + private static final long serialVersionUID = -6914539609629173333L; public LibraryException(@NotNull final String message) { super(message); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/RequestFailureException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/RequestFailureException.java index f818ee5ae..d8e4fc79d 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/RequestFailureException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/RequestFailureException.java @@ -28,7 +28,8 @@ public class RequestFailureException extends LibraryException { - @Serial private static final long serialVersionUID = 6437787548576716445L; + @Serial + private static final long serialVersionUID = 6437787548576716445L; public RequestFailureException(@NotNull final String message) { super(message); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownArtistException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownArtistException.java index bac7efc4e..dcbe9eadf 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownArtistException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownArtistException.java @@ -28,7 +28,8 @@ public final class UnknownArtistException extends LibraryException { - @Serial private static final long serialVersionUID = 888269687137805842L; + @Serial + private static final long serialVersionUID = 888269687137805842L; public UnknownArtistException(@NotNull final String url) { super("Cannot retrieve artist from %s!".formatted(url)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownPlaylistException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownPlaylistException.java index bb2de4a2f..76d529f7f 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownPlaylistException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnknownPlaylistException.java @@ -28,7 +28,8 @@ public final class UnknownPlaylistException extends LibraryException { - @Serial private static final long serialVersionUID = 6632975059132666888L; + @Serial + private static final long serialVersionUID = 6632975059132666888L; public UnknownPlaylistException(@NotNull final String playlist) { super("Cannot retrieve information on playlist %s!".formatted(playlist)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnsupportedPlatformException.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnsupportedPlatformException.java index 6f098fb0b..cbb2323fd 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnsupportedPlatformException.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/throwable/UnsupportedPlatformException.java @@ -28,7 +28,8 @@ public final class UnsupportedPlatformException extends LibraryException { - @Serial private static final long serialVersionUID = 1682368011870345698L; + @Serial + private static final long serialVersionUID = 1682368011870345698L; public UnsupportedPlatformException(@NotNull final String platform) { super("Platform %s is not supported by EzMediaCore!".formatted(platform)); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArrayUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArrayUtils.java index 7e917e84c..178190154 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArrayUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArrayUtils.java @@ -36,7 +36,8 @@ public final class ArrayUtils { - private ArrayUtils() {} + private ArrayUtils() { + } public static T @NotNull [] trim( final T @NotNull [] array, final int startInclusive, final int endExclusive) { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/CollectionUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/CollectionUtils.java index c84dfbc89..6b15e1bdb 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/CollectionUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/CollectionUtils.java @@ -30,7 +30,8 @@ public final class CollectionUtils { - private CollectionUtils() {} + private CollectionUtils() { + } @NotNull public static Multimap createMultiMap( diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastStringUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastStringUtils.java index 9483f13f4..9690927c2 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastStringUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastStringUtils.java @@ -35,7 +35,8 @@ public final class FastStringUtils { STRING_SEARCHER = new BNDM(); } - private FastStringUtils() {} + private FastStringUtils() { + } public static int fastQuerySearch(@NotNull final String content, @NotNull final String target) { return STRING_SEARCHER.searchString(content, target); diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastUUIDUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastUUIDUtils.java index f4b09a617..9d68fec5b 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastUUIDUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FastUUIDUtils.java @@ -68,7 +68,7 @@ public class FastUUIDUtils { private static final int UUID_STRING_LENGTH = 36; private static final char[] HEX_DIGITS = - new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static final long[] HEX_VALUES = new long[128]; static { @@ -100,7 +100,8 @@ public class FastUUIDUtils { HEX_VALUES['F'] = 0xf; } - private FastUUIDUtils() {} + private FastUUIDUtils() { + } /** * Parses a UUID from the given character sequence. The character sequence must represent a UUID @@ -109,7 +110,7 @@ private FastUUIDUtils() {} * @param uuidSequence the character sequence from which to parse a UUID * @return the UUID represented by the given character sequence * @throws IllegalArgumentException if the given character sequence does not conform to the string - * representation as described in {@link UUID#toString()} + * representation as described in {@link UUID#toString()} */ @Contract("_ -> new") public static @NotNull UUID parseUUID(final @NotNull CharSequence uuidSequence) { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FileUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FileUtils.java index 238da89a9..7ea87da4e 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FileUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/FileUtils.java @@ -39,7 +39,8 @@ public final class FileUtils { - private FileUtils() {} + private FileUtils() { + } public static @NotNull Path downloadImageFile( @NotNull final String url, @NotNull final Path folder) throws IOException { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/HashingUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/HashingUtils.java index 969b3c3ac..b20a48edd 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/HashingUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/HashingUtils.java @@ -34,7 +34,8 @@ public final class HashingUtils { - private HashingUtils() {} + private HashingUtils() { + } public static Optional createHashSHA(@NotNull final Path file) { try { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ImageUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ImageUtils.java index ac67bd448..c03fea792 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ImageUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ImageUtils.java @@ -30,7 +30,8 @@ public final class ImageUtils { - private ImageUtils() {} + private ImageUtils() { + } public static @NotNull BufferedImage resize( @NotNull final BufferedImage img, final int width, final int height) { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MapUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MapUtils.java index e7c5a81b7..3d0c5d508 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MapUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MapUtils.java @@ -36,7 +36,8 @@ public final class MapUtils { - private MapUtils() {} + private MapUtils() { + } @NotNull public static ItemStack getMapFromID(final int id) { diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/NetworkUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/NetworkUtils.java index a55c4731c..976093758 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/NetworkUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/NetworkUtils.java @@ -25,5 +25,6 @@ public final class NetworkUtils { - private NetworkUtils() {} + private NetworkUtils() { + } } diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PathUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PathUtils.java index 40f87f85f..5da86c941 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PathUtils.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PathUtils.java @@ -30,11 +30,10 @@ public final class PathUtils { - private PathUtils() {} + private PathUtils() { + } /** - * - * *

    * Checks if a string is a valid path.
    * Null safe.
diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ThreadUtils.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ThreadUtils.java
index d5c0bf15c..bed8ae6ee 100644
--- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ThreadUtils.java
+++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ThreadUtils.java
@@ -28,7 +28,8 @@
 
 public final class ThreadUtils {
 
-  private ThreadUtils() {}
+  private ThreadUtils() {
+  }
 
   public static void createThreadDump() {
     final ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java
index 8df8a0f72..97a93f93b 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java
@@ -24,7 +24,6 @@
 
 package io.github.pulsebeat02.deluxemediaplugin;
 
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
 import static net.kyori.adventure.text.Component.text;
 import static net.kyori.adventure.text.format.NamedTextColor.BLUE;
 
@@ -55,7 +54,6 @@
 import java.util.concurrent.ExecutionException;
 import net.kyori.adventure.audience.Audience;
 import net.kyori.adventure.platform.bukkit.BukkitAudiences;
-import net.kyori.adventure.text.Component;
 import org.bstats.bukkit.Metrics;
 import org.bukkit.plugin.java.JavaPlugin;
 import org.jetbrains.annotations.NotNull;
@@ -110,7 +108,8 @@ public void disable() throws Exception {
     this.console.sendMessage(Locale.GOODBYE.build());
   }
 
-  public void load() {}
+  public void load() {
+  }
 
   private void startLibrary() {
     try {
@@ -205,12 +204,8 @@ private void loadPersistentData() {
     }
   }
 
-  public void log(@NotNull final String line) {
-    this.log(format(text(line)));
-  }
-
-  public void log(@NotNull final Component line) {
-    this.audiences.console().sendMessage(line);
+  public Audience getLogger() {
+    return this.console;
   }
 
   public @NotNull JavaPlugin getBootstrap() {
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java
index 26970acf2..dbe510dd6 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java
@@ -180,7 +180,11 @@ private boolean shouldWaitForSegment(
     return false;
   }
 
-  record ChannelStreamInfo(String quality, String url) {}
+  record ChannelStreamInfo(String quality, String url) {
 
-  record SegmentInfo(String url, Long duration, String name) {}
+  }
+
+  record SegmentInfo(String url, Long duration, String name) {
+
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java
index c48015ce5..aa57c33b7 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java
@@ -66,7 +66,9 @@ public MusicManager(@NotNull final MediaBot bot) {
     AudioSourceManagers.registerLocalSource(this.playerManager);
   }
 
-  /** Join's Voice Chanel and set's log channel. */
+  /**
+   * Join's Voice Chanel and set's log channel.
+   */
   public void joinVoiceChannel() {
     final Guild guild = this.bot.getGuild();
     final long id = guild.getIdLong();
@@ -80,7 +82,9 @@ public void joinVoiceChannel() {
     audio.openAudioConnection(voiceChannel);
   }
 
-  /** Leave's Voice Channel. */
+  /**
+   * Leave's Voice Channel.
+   */
   public void leaveVoiceChannel() {
     final Guild guild = this.bot.getGuild();
     guild.getAudioManager().closeAudioConnection();
@@ -94,7 +98,7 @@ public void addTrack(@NotNull final String url) {
   /**
    * Adds track.
    *
-   * @param url Load's Song.
+   * @param url     Load's Song.
    * @param channel Channel to send message.
    */
   public void addTrack(@Nullable final MessageChannel channel, @NotNull final String url) {
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java
index 386026a13..564fd3858 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java
@@ -42,7 +42,7 @@ public class MusicSendHandler implements AudioSendHandler {
    * MusicSendHandler Public Constructor.
    *
    * @param musicManager MusicManager Class.
-   * @param audioPlayer AudioPlayer.
+   * @param audioPlayer  AudioPlayer.
    */
   public MusicSendHandler(
       @NotNull final MediaBot bot,
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java
index 8d376ee04..ad6c7d1c5 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java
@@ -30,7 +30,9 @@
 import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot;
 import org.jetbrains.annotations.NotNull;
 
-/** Stolen from itxfrosty Music bot. */
+/**
+ * Stolen from itxfrosty Music bot.
+ */
 public class TrackScheduler extends AudioEventAdapter {
 
   private final MediaBot bot;
@@ -57,12 +59,16 @@ public void queueSong(@NotNull final AudioTrack track) {
     }
   }
 
-  /** Clear's Audio Queue. */
+  /**
+   * Clear's Audio Queue.
+   */
   public void clearQueue() {
     this.audioPlayer.stopTrack();
   }
 
-  /** Skips Song. */
+  /**
+   * Skips Song.
+   */
   public void skip() {
     this.audioPlayer
         .getPlayingTrack()
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java
index 18bb36d01..07b50b529 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java
@@ -97,10 +97,10 @@ public CommandHandler(@NotNull final DeluxeMediaPlugin plugin) {
   /**
    * CommandHandler to read input and execute other commands.
    *
-   * @param sender command sender
+   * @param sender  command sender
    * @param command command sent
-   * @param label label of command
-   * @param args arguments for command
+   * @param label   label of command
+   * @param args    arguments for command
    * @return whether the command usage should be showed up.
    */
   @Override
@@ -123,10 +123,10 @@ public boolean onCommand(
   /**
    * Tab handler to handle tab completer.
    *
-   * @param sender command sender
+   * @param sender  command sender
    * @param command current command
-   * @param alias aliases of command
-   * @param args arguments of the command
+   * @param alias   aliases of command
+   * @param args    arguments of the command
    * @return list of options.
    */
   @Override
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java
index 83dd27853..2ec1b89d8 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java
@@ -51,11 +51,17 @@ default  RequiredArgumentBuilder argument(
   }
 
   @FunctionalInterface
-  interface Root extends CommandSegment> {}
+  interface Root extends CommandSegment> {
+
+  }
 
   @FunctionalInterface
-  interface Literal extends CommandSegment> {}
+  interface Literal extends CommandSegment> {
+
+  }
 
   @FunctionalInterface
-  interface Argument extends CommandSegment> {}
+  interface Argument extends CommandSegment> {
+
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java
index 8b174f280..c2d1ec382 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java
@@ -25,13 +25,12 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.audio;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Map;
 import java.util.function.Consumer;
@@ -79,7 +78,7 @@ private int playAudio(@NotNull final CommandContext context) {
                 100.0F,
                 1.0F));
 
-    gold(audience, "Started playing audio!");
+    audience.sendMessage(Locale.START_AUDIO.build());
 
     return SINGLE_SUCCESS;
   }
@@ -94,7 +93,7 @@ private int stopAudio(@NotNull final CommandContext context) {
 
     this.audioAction(player -> player.stopSound(this.attributes.getKey()));
 
-    red(audience, "Stopped playing audio!");
+    audience.sendMessage(Locale.PAUSE_AUDIO.build());
 
     return SINGLE_SUCCESS;
   }
@@ -105,7 +104,7 @@ private void audioAction(@NotNull final Consumer consumer) {
 
   private boolean checkUnloaded(@NotNull final Audience audience) {
     if (this.attributes.getAudio() == null) {
-      red(audience, "File or URL not specified!");
+      audience.sendMessage(Locale.ERR_NO_MRL.build());
       return true;
     }
     return false;
@@ -113,7 +112,7 @@ private boolean checkUnloaded(@NotNull final Audience audience) {
 
   private boolean checkIncompleteLoad(@NotNull final Audience audience) {
     if (!this.attributes.getCompletion().get()) {
-      red(audience, "Audio is still processing!");
+      audience.sendMessage(Locale.ERR_NO_MRL.build());
       return true;
     }
     return false;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java
index fbcb1449f..74341d479 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java
@@ -25,14 +25,13 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.audio;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
 
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.ezmediacore.MediaLibraryCore;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.YoutubeVideoAudioExtractor;
 import io.github.pulsebeat02.ezmediacore.resourcepack.ResourcepackSoundWrapper;
@@ -42,7 +41,6 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
 import net.kyori.adventure.audience.Audience;
@@ -68,17 +66,14 @@ public AudioLoadCommand(
   }
 
   private void loadSoundMrl(@NotNull final String mrl) {
-
     final MediaLibraryCore core = this.plugin.library();
     final Path audio = core.getAudioPath().resolve("audio.ogg");
-
     try {
       new YoutubeVideoAudioExtractor(core, this.plugin.getAudioConfiguration(), mrl, audio)
           .executeAsync();
     } catch (final IOException e) {
       e.printStackTrace();
     }
-
     this.attributes.setAudio(audio);
   }
 
@@ -87,7 +82,7 @@ private boolean loadSoundFile(@NotNull final String mrl, @NotNull final Audience
     if (Files.exists(file)) {
       this.attributes.setAudio(file);
     } else {
-      red(audience, "The mrl specified is not valid! (Must be Youtube Link or Audio File)");
+      audience.sendMessage(Locale.ERR_INVALID_MRL.build());
       return true;
     }
     return false;
@@ -101,44 +96,36 @@ private void wrapResourcepack() {
       final ResourcepackSoundWrapper wrapper =
           new ResourcepackSoundWrapper(
               daemon.getDaemon().getServerPath().resolve("resourcepack.zip"), "Audio Pack", 6);
-      wrapper.addSound(loader.getName().toLowerCase(Locale.ROOT), this.attributes.getAudio());
+      wrapper.addSound(loader.getName().toLowerCase(java.util.Locale.ROOT),
+          this.attributes.getAudio());
       wrapper.wrap();
       final Path path = wrapper.getResourcepackFilePath();
       this.attributes.setLink(daemon.createUrl(path));
       this.attributes.setHash(HashingUtils.createHashSHA(path).orElseThrow(AssertionError::new));
     } catch (final IOException e) {
-      loader.getLogger().severe("Failed to wrap resourcepack!");
+      this.plugin.getLogger().sendMessage(Locale.ERR_RESOURCEPACK_WRAP.build());
       e.printStackTrace();
     }
     this.attributes.setCompletion(true);
   }
 
   private int loadAudio(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String mrl = context.getArgument("mrl", String.class);
     final AtomicBoolean completion = this.attributes.getCompletion();
-
     if (this.isLoadingSound(audience)) {
       return SINGLE_SUCCESS;
     }
-
-    gold(
-        audience,
-        "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.");
-
+    audience.sendMessage(Locale.CREATE_RESOURCEPACK.build());
     completion.set(false);
-
     if (mrl.startsWith("http")) {
       CompletableFuture.runAsync(() -> this.loadSoundMrl(mrl));
     } else if (this.loadSoundFile(mrl, audience)) {
       return SINGLE_SUCCESS;
     }
-
     CompletableFuture.runAsync(this::wrapResourcepack)
         .thenRunAsync(() -> this.forceResourcepackLoad(audience))
         .whenComplete((result, exception) -> completion.set(true));
-
     return SINGLE_SUCCESS;
   }
 
@@ -146,35 +133,25 @@ private void forceResourcepackLoad(@NotNull final Audience audience) {
     final String url = this.attributes.getLink();
     final byte[] hash = this.attributes.getHash();
     ResourcepackUtils.forceResourcepackLoad(this.plugin.library(), url, hash);
-    gold(
-        audience,
-        "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash)));
+    audience.sendMessage(Locale.FIN_RESOURCEPACK_INIT.build(url, hash));
   }
 
   private int sendResourcepack(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
-
     if (this.attributes.getLink() == null && this.attributes.getHash() == null) {
-      red(audience, "Please load a resourcepack first!");
+      audience.sendMessage(Locale.ERR_NO_RESOURCEPACK.build());
       return SINGLE_SUCCESS;
     }
-
     final String url = this.attributes.getLink();
     final byte[] hash = this.attributes.getHash();
-
     ResourcepackUtils.forceResourcepackLoad(this.plugin.library(), url, hash);
-
-    gold(audience, "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)));
-
+    audience.sendMessage(Locale.SENT_RESOURCEPACK.build(url, hash));
     return SINGLE_SUCCESS;
   }
 
   private boolean isLoadingSound(@NotNull final Audience audience) {
     if (!this.attributes.getCompletion().get()) {
-      red(
-          audience,
-          "Please wait for the previous audio to extract first before loading another one!");
+      audience.sendMessage(Locale.ERR_INVALID_AUDIO_STATE.build());
       return true;
     }
     return false;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/discord/DiscordCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/discord/DiscordCommand.java
index b11ece9f5..db170fa0c 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/discord/DiscordCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/discord/DiscordCommand.java
@@ -24,8 +24,6 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.discord;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
 
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.context.CommandContext;
@@ -33,6 +31,7 @@
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.bot.audio.MusicManager;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Map;
 import net.kyori.adventure.audience.Audience;
@@ -69,7 +68,7 @@ private int disconnect(@NotNull final CommandContext context) {
       return SINGLE_SUCCESS;
     }
     this.plugin().getMediaBot().getMusicManager().leaveVoiceChannel();
-    gold(audience, "Successfully disconnected from voice channel!");
+    audience.sendMessage(Locale.DC_DISCORD.build());
     return SINGLE_SUCCESS;
   }
 
@@ -79,7 +78,7 @@ private int connect(@NotNull final CommandContext context) {
       return SINGLE_SUCCESS;
     }
     this.plugin().getMediaBot().getMusicManager().joinVoiceChannel();
-    gold(audience, "Successfully connected to voice channel!");
+    audience.sendMessage(Locale.C_DISCORD.build());
     return SINGLE_SUCCESS;
   }
 
@@ -92,7 +91,7 @@ private int play(@NotNull final CommandContext context) {
     final MusicManager manager = this.plugin().getMediaBot().getMusicManager();
     manager.joinVoiceChannel();
     manager.addTrack(mrl);
-    gold(audience, "Successfully started audio on MRL %s!".formatted(mrl));
+    audience.sendMessage(Locale.START_TRACK_DISCORD.build(mrl));
     return SINGLE_SUCCESS;
   }
 
@@ -102,7 +101,7 @@ private int pause(@NotNull final CommandContext context) {
       return SINGLE_SUCCESS;
     }
     this.plugin().getMediaBot().getMusicManager().pauseTrack();
-    gold(audience, "Successfully paused track!");
+    audience.sendMessage(Locale.PAUSED_TRACK_DISCORD.build());
     return SINGLE_SUCCESS;
   }
 
@@ -112,13 +111,13 @@ private int resume(@NotNull final CommandContext context) {
       return SINGLE_SUCCESS;
     }
     this.plugin().getMediaBot().getMusicManager().resumeTrack();
-    gold(audience, "Successfully resumed track!");
+    audience.sendMessage(Locale.RESUMED_TRACK_DISCORD.build());
     return SINGLE_SUCCESS;
   }
 
   private boolean checkDiscordStatus(@NotNull final Audience audience) {
     if (this.plugin().getMediaBot() == null) {
-      red(audience, "Discord bot not setup yet or invalid settings in bot.yml!");
+      audience.sendMessage(Locale.ERR_INVALID_DISCORD_BOT.build());
       return true;
     }
     return false;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/dither/DitherCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/dither/DitherCommand.java
index 100d7201e..0a4e5f493 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/dither/DitherCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/dither/DitherCommand.java
@@ -25,13 +25,12 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.dither;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.aqua;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Map;
 import net.kyori.adventure.audience.Audience;
@@ -58,11 +57,7 @@ private int listSettings(@NotNull final CommandContext context) {
 
     final Audience audience = this.audience().sender(context.getSource());
 
-    gold(audience, "Dithering Options ->");
-
-    for (final DitherSetting setting : DitherSetting.values()) {
-      aqua(audience, setting.getName());
-    }
+    audience.sendMessage(Locale.DITHERING_OPTIONS.build());
 
     return SINGLE_SUCCESS;
   }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegAddArgumentCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegAddArgumentCommand.java
index c87a6468c..adea20e90 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegAddArgumentCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegAddArgumentCommand.java
@@ -25,12 +25,6 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.ffmpeg;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static net.kyori.adventure.text.Component.join;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.arguments.StringArgumentType;
@@ -38,6 +32,7 @@
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegCommandExecutor;
 import net.kyori.adventure.audience.Audience;
 import org.bukkit.command.CommandSender;
@@ -67,12 +62,10 @@ public FFmpegAddArgumentCommand(
   }
 
   private int addIndexArgument(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String str = context.getArgument("arguments", String.class);
     final int index = context.getArgument("index", int.class);
     final String[] args = str.split(" ");
-
     for (final String arg : args) {
       if (arg.contains("=")) {
         final String[] split = arg.split("=");
@@ -81,25 +74,14 @@ private int addIndexArgument(@NotNull final CommandContext contex
         this.ffmpeg.addArgument(arg, index);
       }
     }
-
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Added arguments ", GOLD),
-                text(str, AQUA),
-                text(" to the FFmpeg command at index ", GOLD),
-                text(index, AQUA))));
-
+    audience.sendMessage(Locale.ADD_FFMPEG_ARG_INDX.build(str, index));
     return SINGLE_SUCCESS;
   }
 
   private int addArgument(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String str = context.getArgument("arguments", String.class);
     final String[] arguments = str.split(" ");
-
     for (final String argument : arguments) {
       if (argument.contains("=")) {
         final String[] split = argument.split("=");
@@ -108,15 +90,7 @@ private int addArgument(@NotNull final CommandContext context) {
         this.ffmpeg.addArgument(argument);
       }
     }
-
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Added arguments ", GOLD),
-                text(str, AQUA),
-                text(" to the FFmpeg command.", GOLD))));
-
+    audience.sendMessage(Locale.ADD_FFMPEG_ARG.build(str));
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java
index e7bbc2f4a..0749e836a 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java
@@ -26,18 +26,13 @@
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
 import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.ffmpeg;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static net.kyori.adventure.text.Component.join;
 import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegCommandExecutor;
 import java.util.Map;
@@ -69,7 +64,7 @@ public FFmpegCommand(
 
   private int resetFFmpegCommand(@NotNull final CommandContext context) {
     this.ffmpeg.clearArguments();
-    gold(this.audience().sender(context.getSource()), "Reset all FFmpeg arguments!");
+    this.audience().sender(context.getSource()).sendMessage(Locale.RESET_FFMPEG_ARGS.build());
     return SINGLE_SUCCESS;
   }
 
@@ -77,19 +72,14 @@ private int listFFmpegArguments(@NotNull final CommandContext con
     this.plugin()
         .audience()
         .sender(context.getSource())
-        .sendMessage(
-            format(
-                join(
-                    noSeparators(),
-                    text("Current FFmpeg arguments: ", GOLD),
-                    text(this.ffmpeg.getArguments().toString(), AQUA))));
+        .sendMessage(Locale.LIST_FFMPEG_ARGS.build(this.ffmpeg.getArguments()));
     return SINGLE_SUCCESS;
   }
 
   private int runFFmpegProcess(@NotNull final CommandContext context) {
     final Audience audience = this.plugin().audience().sender(context.getSource());
     this.ffmpeg.executeWithLogging(s -> audience.sendMessage(ffmpeg(text(s))));
-    gold(audience, "Executed FFmpeg command!");
+    audience.sendMessage(Locale.FFMPEG_EXEC.build());
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java
index e3666261b..9238d5adf 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java
@@ -25,12 +25,6 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.ffmpeg;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static net.kyori.adventure.text.Component.join;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.arguments.StringArgumentType;
@@ -38,6 +32,7 @@
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegCommandExecutor;
 import net.kyori.adventure.audience.Audience;
 import org.bukkit.command.CommandSender;
@@ -64,38 +59,20 @@ public FFmpegRemoveArgumentCommand(
   }
 
   private int removeIndexArgument(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final int index = context.getArgument("index", int.class);
     final String arg = this.ffmpeg.getArguments().get(index);
-
     this.ffmpeg.removeArgument(index);
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Removed arguments ", GOLD),
-                text(arg, AQUA),
-                text(" from the FFmpeg command at index ", GOLD),
-                text(index, AQUA))));
-
+    audience.sendMessage(Locale.REMOVE_FFMPEG_ARG_INDX.build(arg, index));
     return SINGLE_SUCCESS;
   }
 
   private int removeArgument(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String argument = context.getArgument("argument", String.class);
-
     this.ffmpeg.removeArgument(argument);
     audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Removed arguments ", GOLD),
-                text(argument, AQUA),
-                text(" from the FFmpeg command.", GOLD))));
-
+        Locale.REMOVE_FFMPEG_ARG.build(argument));
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java
index b4a907c05..ae87ed03c 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java
@@ -190,7 +190,7 @@ public ItemBuilder clone() {
    * Add a lore line.
    *
    * @param line The lore line to add.
-   * @param pos The index of where to put it.
+   * @param pos  The index of where to put it.
    */
   public @NotNull ItemBuilder lore(@NotNull final Component line, final int pos) {
     final ItemMeta im = this.is.getItemMeta();
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullCreator.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullCreator.java
index 8ee651e1a..1af9e551d 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullCreator.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullCreator.java
@@ -55,273 +55,273 @@
  */
 public final class SkullCreator {
 
-	private static boolean warningPosted = false;
-	// some reflection stuff to be used when setting a skull's profile
-	private static Field blockProfileField;
-	private static MethodHandle metaSetProfileMethod;
-	private static Field metaProfileField;
-
-	private SkullCreator() {
-	}
-
-	/**
-	 * Creates a player skull, should work in both legacy and new Bukkit APIs.
-	 */
-	public static @NotNull ItemStack createSkull() {
-		checkLegacy();
-		try {
-			return new ItemStack(Material.valueOf("PLAYER_HEAD"));
-		} catch (final IllegalArgumentException e) {
-			return new ItemStack(Material.valueOf("SKULL_ITEM"), 1, (byte) 3);
-		}
-	}
-
-	/**
-	 * Creates a player skull item with the skin based on a player's name.
-	 *
-	 * @param name The Player's name.
-	 * @return The head of the Player.
-	 * @deprecated names don't make for good identifiers.
-	 */
-	public static @NotNull ItemStack itemFromName(final String name) {
-		return itemWithName(createSkull(), name);
-	}
-
-	/**
-	 * Creates a player skull item with the skin based on a player's UUID.
-	 *
-	 * @param id The Player's UUID.
-	 * @return The head of the Player.
-	 */
-	public static @NotNull ItemStack itemFromUuid(final UUID id) {
-		return itemWithUuid(createSkull(), id);
-	}
-
-	/**
-	 * Creates a player skull item with the skin at a Mojang URL.
-	 *
-	 * @param url The Mojang URL.
-	 * @return The head of the Player.
-	 */
-	public static @NotNull ItemStack itemFromUrl(final String url) {
-		return itemWithUrl(createSkull(), url);
-	}
-
-	/**
-	 * Creates a player skull item with the skin based on a base64 string.
-	 *
-	 * @param base64 The Mojang URL.
-	 * @return The head of the Player.
-	 */
-	public static @NotNull ItemStack itemFromBase64(final String base64) {
-		return itemWithBase64(createSkull(), base64).orElseThrow(() -> new SkullException(base64));
-	}
-
-	/**
-	 * Modifies a skull to use the skin of the player with a given name.
-	 *
-	 * @param item The item to apply the name to. Must be a player skull.
-	 * @param name The Player's name.
-	 * @return The head of the Player.
-	 * @deprecated names don't make for good identifiers.
-	 */
-	@Deprecated
-	public static @NotNull ItemStack itemWithName(@NotNull final ItemStack item,
-												  @NotNull final String name) {
-		final SkullMeta meta = Objects.requireNonNull((SkullMeta) item.getItemMeta());
-		meta.setOwner(name);
-		item.setItemMeta(meta);
-
-		return item;
-	}
-
-	/**
-	 * Modifies a skull to use the skin of the player with a given UUID.
-	 *
-	 * @param item The item to apply the name to. Must be a player skull.
-	 * @param id   The Player's UUID.
-	 * @return The head of the Player.
-	 */
-	public static @NotNull ItemStack itemWithUuid(@NotNull final ItemStack item,
-												  @NotNull final UUID id) {
-		final SkullMeta meta = Objects.requireNonNull((SkullMeta) item.getItemMeta());
-		meta.setOwningPlayer(Bukkit.getOfflinePlayer(id));
-		item.setItemMeta(meta);
-
-		return item;
-	}
-
-	/**
-	 * Modifies a skull to use the skin at the given Mojang URL.
-	 *
-	 * @param item The item to apply the skin to. Must be a player skull.
-	 * @param url  The URL of the Mojang skin.
-	 * @return The head associated with the URL.
-	 */
-	public static @NotNull ItemStack itemWithUrl(@NotNull final ItemStack item,
-												 @NotNull final String url) {
-		final String base64 = urlToBase64(url);
-		return itemWithBase64(item, base64).orElseThrow(() -> new SkullException(base64));
-	}
-
-	/**
-	 * Modifies a skull to use the skin based on the given base64 string.
-	 *
-	 * @param item   The ItemStack to put the base64 onto. Must be a player skull.
-	 * @param base64 The base64 string containing the texture.
-	 * @return The head with a custom texture.
-	 */
-	public static Optional itemWithBase64(
-			@NotNull final ItemStack item, @NotNull final String base64) {
-		if (!(item.getItemMeta() instanceof final SkullMeta meta)) {
-			return Optional.empty();
-		}
-		mutateItemMeta(meta, base64);
-		item.setItemMeta(meta);
-
-		return Optional.of(item);
-	}
-
-	/**
-	 * Sets the block to a skull with the given name.
-	 *
-	 * @param block The block to set.
-	 * @param name  The player to set it to.
-	 * @deprecated names don't make for good identifiers.
-	 */
-	@Deprecated
-	public static void blockWithName(@NotNull final Block block, @NotNull final String name) {
-		final Skull state = (Skull) block.getState();
-		state.setOwningPlayer(Bukkit.getOfflinePlayer(name));
-		state.update(false, false);
-	}
-
-	/**
-	 * Sets the block to a skull with the given UUID.
-	 *
-	 * @param block The block to set.
-	 * @param id    The player to set it to.
-	 */
-	public static void blockWithUuid(@NotNull final Block block, @NotNull final UUID id) {
-		setToSkull(block);
-		final Skull state = (Skull) block.getState();
-		state.setOwningPlayer(Bukkit.getOfflinePlayer(id));
-		state.update(false, false);
-	}
-
-	/**
-	 * Sets the block to a skull with the skin found at the provided mojang URL.
-	 *
-	 * @param block The block to set.
-	 * @param url   The mojang URL to set it to use.
-	 */
-	public static void blockWithUrl(@NotNull final Block block, @NotNull final String url) {
-		blockWithBase64(block, urlToBase64(url));
-	}
-
-	/**
-	 * Sets the block to a skull with the skin for the base64 string.
-	 *
-	 * @param block  The block to set.
-	 * @param base64 The base64 to set it to use.
-	 */
-	public static void blockWithBase64(@NotNull final Block block, @NotNull final String base64) {
-		setToSkull(block);
-		final Skull state = (Skull) block.getState();
-		mutateBlockState(state, base64);
-		state.update(false, false);
-	}
-
-	private static void setToSkull(final @NotNull Block block) {
-		checkLegacy();
-		try {
-			block.setType(Material.valueOf("PLAYER_HEAD"), false);
-		} catch (final IllegalArgumentException e) {
-			block.setType(Material.valueOf("SKULL"), false);
-			final Skull state = (Skull) block.getState();
-			state.setSkullType(SkullType.PLAYER);
-			state.update(false, false);
-		}
-	}
-
-	private static @NotNull String urlToBase64(final String url) {
-
-		final URI actualUrl;
-		try {
-			actualUrl = new URI(url);
-		} catch (final URISyntaxException e) {
-			throw new RuntimeException(e);
-		}
-		final String toEncode = "{\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}".formatted(actualUrl);
-		return Base64.getEncoder().encodeToString(toEncode.getBytes());
-	}
-
-	private static @NotNull GameProfile makeProfile(final @NotNull String b64) {
-		// random uuid based on the b64 string
-		final UUID id =
-				new UUID(
-						b64.substring(b64.length() - 20).hashCode(),
-						b64.substring(b64.length() - 10).hashCode());
-		final GameProfile profile = new GameProfile(id, "Player");
-		profile.getProperties().put("textures", new Property("textures", b64));
-		return profile;
-	}
-
-	private static void mutateBlockState(final Skull block, final String b64) {
-		try {
-			if (blockProfileField == null) {
-				blockProfileField = block.getClass().getDeclaredField("profile");
-				blockProfileField.setAccessible(true);
-			}
-			blockProfileField.set(block, makeProfile(b64));
-		} catch (final NoSuchFieldException | IllegalAccessException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private static void mutateItemMeta(final SkullMeta meta, final String b64) {
-		try {
-			if (metaSetProfileMethod == null) {
-				metaSetProfileMethod = MethodHandles.publicLookup()
-						.findVirtual(meta.getClass(), "setProfile",
-								MethodType.methodType(void.class, GameProfile.class));
-			}
-			metaSetProfileMethod.invoke(meta, makeProfile(b64));
-		} catch (final Throwable throwable) {
-
-			// if in an older API where there is no setProfile method,
-			// we set the profile field directly.
-			try {
-				if (metaProfileField == null) {
-					metaProfileField = meta.getClass().getDeclaredField("profile");
-					metaProfileField.setAccessible(true);
-				}
-				metaProfileField.set(meta, makeProfile(b64));
-
-			} catch (final NoSuchFieldException | IllegalAccessException ex2) {
-				ex2.printStackTrace();
-			}
-
-
-		}
-	}
-
-	// suppress warning since PLAYER_HEAD doesn't exist in 1.12.2,
-	// but we expect this and catch the error at runtime.
-	private static void checkLegacy() {
-		try {
-			// if both of these succeed, then we are running
-			// in a legacy api, but on a modern (1.13+) server.
-			Material.class.getDeclaredField("PLAYER_HEAD");
-			Material.valueOf("SKULL");
-
-			if (!warningPosted) {
-				Bukkit.getLogger()
-						.warning(
-								"SKULLCREATOR API - Using the legacy bukkit API with 1.13+ bukkit versions is not supported!");
-				warningPosted = true;
-			}
-		} catch (final NoSuchFieldException | IllegalArgumentException ignored) {
-		}
-	}
+  private static boolean warningPosted = false;
+  // some reflection stuff to be used when setting a skull's profile
+  private static Field blockProfileField;
+  private static MethodHandle metaSetProfileMethod;
+  private static Field metaProfileField;
+
+  private SkullCreator() {
+  }
+
+  /**
+   * Creates a player skull, should work in both legacy and new Bukkit APIs.
+   */
+  public static @NotNull ItemStack createSkull() {
+    checkLegacy();
+    try {
+      return new ItemStack(Material.valueOf("PLAYER_HEAD"));
+    } catch (final IllegalArgumentException e) {
+      return new ItemStack(Material.valueOf("SKULL_ITEM"), 1, (byte) 3);
+    }
+  }
+
+  /**
+   * Creates a player skull item with the skin based on a player's name.
+   *
+   * @param name The Player's name.
+   * @return The head of the Player.
+   * @deprecated names don't make for good identifiers.
+   */
+  public static @NotNull ItemStack itemFromName(final String name) {
+    return itemWithName(createSkull(), name);
+  }
+
+  /**
+   * Creates a player skull item with the skin based on a player's UUID.
+   *
+   * @param id The Player's UUID.
+   * @return The head of the Player.
+   */
+  public static @NotNull ItemStack itemFromUuid(final UUID id) {
+    return itemWithUuid(createSkull(), id);
+  }
+
+  /**
+   * Creates a player skull item with the skin at a Mojang URL.
+   *
+   * @param url The Mojang URL.
+   * @return The head of the Player.
+   */
+  public static @NotNull ItemStack itemFromUrl(final String url) {
+    return itemWithUrl(createSkull(), url);
+  }
+
+  /**
+   * Creates a player skull item with the skin based on a base64 string.
+   *
+   * @param base64 The Mojang URL.
+   * @return The head of the Player.
+   */
+  public static @NotNull ItemStack itemFromBase64(final String base64) {
+    return itemWithBase64(createSkull(), base64).orElseThrow(() -> new SkullException(base64));
+  }
+
+  /**
+   * Modifies a skull to use the skin of the player with a given name.
+   *
+   * @param item The item to apply the name to. Must be a player skull.
+   * @param name The Player's name.
+   * @return The head of the Player.
+   * @deprecated names don't make for good identifiers.
+   */
+  @Deprecated
+  public static @NotNull ItemStack itemWithName(@NotNull final ItemStack item,
+      @NotNull final String name) {
+    final SkullMeta meta = Objects.requireNonNull((SkullMeta) item.getItemMeta());
+    meta.setOwner(name);
+    item.setItemMeta(meta);
+
+    return item;
+  }
+
+  /**
+   * Modifies a skull to use the skin of the player with a given UUID.
+   *
+   * @param item The item to apply the name to. Must be a player skull.
+   * @param id   The Player's UUID.
+   * @return The head of the Player.
+   */
+  public static @NotNull ItemStack itemWithUuid(@NotNull final ItemStack item,
+      @NotNull final UUID id) {
+    final SkullMeta meta = Objects.requireNonNull((SkullMeta) item.getItemMeta());
+    meta.setOwningPlayer(Bukkit.getOfflinePlayer(id));
+    item.setItemMeta(meta);
+
+    return item;
+  }
+
+  /**
+   * Modifies a skull to use the skin at the given Mojang URL.
+   *
+   * @param item The item to apply the skin to. Must be a player skull.
+   * @param url  The URL of the Mojang skin.
+   * @return The head associated with the URL.
+   */
+  public static @NotNull ItemStack itemWithUrl(@NotNull final ItemStack item,
+      @NotNull final String url) {
+    final String base64 = urlToBase64(url);
+    return itemWithBase64(item, base64).orElseThrow(() -> new SkullException(base64));
+  }
+
+  /**
+   * Modifies a skull to use the skin based on the given base64 string.
+   *
+   * @param item   The ItemStack to put the base64 onto. Must be a player skull.
+   * @param base64 The base64 string containing the texture.
+   * @return The head with a custom texture.
+   */
+  public static Optional itemWithBase64(
+      @NotNull final ItemStack item, @NotNull final String base64) {
+    if (!(item.getItemMeta() instanceof final SkullMeta meta)) {
+      return Optional.empty();
+    }
+    mutateItemMeta(meta, base64);
+    item.setItemMeta(meta);
+
+    return Optional.of(item);
+  }
+
+  /**
+   * Sets the block to a skull with the given name.
+   *
+   * @param block The block to set.
+   * @param name  The player to set it to.
+   * @deprecated names don't make for good identifiers.
+   */
+  @Deprecated
+  public static void blockWithName(@NotNull final Block block, @NotNull final String name) {
+    final Skull state = (Skull) block.getState();
+    state.setOwningPlayer(Bukkit.getOfflinePlayer(name));
+    state.update(false, false);
+  }
+
+  /**
+   * Sets the block to a skull with the given UUID.
+   *
+   * @param block The block to set.
+   * @param id    The player to set it to.
+   */
+  public static void blockWithUuid(@NotNull final Block block, @NotNull final UUID id) {
+    setToSkull(block);
+    final Skull state = (Skull) block.getState();
+    state.setOwningPlayer(Bukkit.getOfflinePlayer(id));
+    state.update(false, false);
+  }
+
+  /**
+   * Sets the block to a skull with the skin found at the provided mojang URL.
+   *
+   * @param block The block to set.
+   * @param url   The mojang URL to set it to use.
+   */
+  public static void blockWithUrl(@NotNull final Block block, @NotNull final String url) {
+    blockWithBase64(block, urlToBase64(url));
+  }
+
+  /**
+   * Sets the block to a skull with the skin for the base64 string.
+   *
+   * @param block  The block to set.
+   * @param base64 The base64 to set it to use.
+   */
+  public static void blockWithBase64(@NotNull final Block block, @NotNull final String base64) {
+    setToSkull(block);
+    final Skull state = (Skull) block.getState();
+    mutateBlockState(state, base64);
+    state.update(false, false);
+  }
+
+  private static void setToSkull(final @NotNull Block block) {
+    checkLegacy();
+    try {
+      block.setType(Material.valueOf("PLAYER_HEAD"), false);
+    } catch (final IllegalArgumentException e) {
+      block.setType(Material.valueOf("SKULL"), false);
+      final Skull state = (Skull) block.getState();
+      state.setSkullType(SkullType.PLAYER);
+      state.update(false, false);
+    }
+  }
+
+  private static @NotNull String urlToBase64(final String url) {
+
+    final URI actualUrl;
+    try {
+      actualUrl = new URI(url);
+    } catch (final URISyntaxException e) {
+      throw new RuntimeException(e);
+    }
+    final String toEncode = "{\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}".formatted(actualUrl);
+    return Base64.getEncoder().encodeToString(toEncode.getBytes());
+  }
+
+  private static @NotNull GameProfile makeProfile(final @NotNull String b64) {
+    // random uuid based on the b64 string
+    final UUID id =
+        new UUID(
+            b64.substring(b64.length() - 20).hashCode(),
+            b64.substring(b64.length() - 10).hashCode());
+    final GameProfile profile = new GameProfile(id, "Player");
+    profile.getProperties().put("textures", new Property("textures", b64));
+    return profile;
+  }
+
+  private static void mutateBlockState(final Skull block, final String b64) {
+    try {
+      if (blockProfileField == null) {
+        blockProfileField = block.getClass().getDeclaredField("profile");
+        blockProfileField.setAccessible(true);
+      }
+      blockProfileField.set(block, makeProfile(b64));
+    } catch (final NoSuchFieldException | IllegalAccessException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private static void mutateItemMeta(final SkullMeta meta, final String b64) {
+    try {
+      if (metaSetProfileMethod == null) {
+        metaSetProfileMethod = MethodHandles.publicLookup()
+            .findVirtual(meta.getClass(), "setProfile",
+                MethodType.methodType(void.class, GameProfile.class));
+      }
+      metaSetProfileMethod.invoke(meta, makeProfile(b64));
+    } catch (final Throwable throwable) {
+
+      // if in an older API where there is no setProfile method,
+      // we set the profile field directly.
+      try {
+        if (metaProfileField == null) {
+          metaProfileField = meta.getClass().getDeclaredField("profile");
+          metaProfileField.setAccessible(true);
+        }
+        metaProfileField.set(meta, makeProfile(b64));
+
+      } catch (final NoSuchFieldException | IllegalAccessException ex2) {
+        ex2.printStackTrace();
+      }
+
+
+    }
+  }
+
+  // suppress warning since PLAYER_HEAD doesn't exist in 1.12.2,
+  // but we expect this and catch the error at runtime.
+  private static void checkLegacy() {
+    try {
+      // if both of these succeed, then we are running
+      // in a legacy api, but on a modern (1.13+) server.
+      Material.class.getDeclaredField("PLAYER_HEAD");
+      Material.valueOf("SKULL");
+
+      if (!warningPosted) {
+        Bukkit.getLogger()
+            .warning(
+                "SKULLCREATOR API - Using the legacy bukkit API with 1.13+ bukkit versions is not supported!");
+        warningPosted = true;
+      }
+    } catch (final NoSuchFieldException | IllegalArgumentException ignored) {
+    }
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java
index ec52638a9..c56c4a48a 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java
@@ -29,7 +29,8 @@
 
 public class SkullException extends AssertionError {
 
-  @Serial private static final long serialVersionUID = 2394089956129784304L;
+  @Serial
+  private static final long serialVersionUID = 2394089956129784304L;
 
   public SkullException(@NotNull final String message) {
     super("Invalid Skull Base64 %s!".formatted(message));
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/ResetImageCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/ResetImageCommand.java
index 7b5a95a27..ee1aed8d9 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/ResetImageCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/ResetImageCommand.java
@@ -25,19 +25,13 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.image;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
-import static net.kyori.adventure.text.Component.join;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.ezmediacore.image.Image;
 import java.util.List;
 import java.util.Optional;
@@ -76,68 +70,48 @@ public ResetImageCommand(
   }
 
   private int purgeMap(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final int id = context.getArgument("id", int.class);
-
     final Optional image =
         this.plugin.getPictureManager().getImages().stream()
             .filter(img -> img.getMaps().contains(id))
             .findAny();
     if (image.isEmpty()) {
-      red(audience, "The image you request purge from the map is not loaded!");
+      audience.sendMessage(Locale.ERR_IMAGE_NOT_LOADED.build());
       return SINGLE_SUCCESS;
     }
-
     image.get().resetMaps();
-
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Successfully purged all maps with id ", GOLD),
-                text(id, AQUA))));
-
+    audience.sendMessage(Locale.PURGE_MAP.build(id));
     return SINGLE_SUCCESS;
   }
 
   private int purgeAllMaps(@NotNull final CommandContext context) {
-
     final CommandSender sender = context.getSource();
     final Audience audience = this.plugin.audience().sender(sender);
     if (!(sender instanceof Player)) {
-      red(audience, "You must be a player to execute this command!");
+      audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
       return SINGLE_SUCCESS;
     }
-
     this.attributes.getListen().add(((Player) sender).getUniqueId());
-
-    red(
-        audience,
-        "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...");
-
+    audience.sendMessage(Locale.PURGE_ALL_MAPS_VERIFY.build());
     return SINGLE_SUCCESS;
   }
 
   @EventHandler
   public void onPlayerChat(final AsyncPlayerChatEvent event) {
-
     final Player p = event.getPlayer();
     final UUID uuid = p.getUniqueId();
     final Set listen = this.attributes.getListen();
-
     if (listen.contains(uuid)) {
-
       event.setCancelled(true);
       final Audience audience = this.plugin.audience().player(p);
-
       if (event.getMessage().equals("YES")) {
         final List images = this.plugin.getPictureManager().getImages();
         images.forEach(Image::resetMaps);
         images.clear();
-        red(audience, "Successfully purged all images!");
+        audience.sendMessage(Locale.PURGED_ALL_MAPS.build());
       } else {
-        red(audience, "Cancelled purge of all images!");
+        audience.sendMessage(Locale.CANCELLED_PURGE_ALL_MAPS.build());
       }
       listen.remove(uuid);
     }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java
index 1ad25965e..999d4bd11 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java
@@ -25,14 +25,13 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.image;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
 
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import io.github.pulsebeat02.ezmediacore.MediaLibraryCore;
 import io.github.pulsebeat02.ezmediacore.dimension.Dimension;
@@ -54,101 +53,99 @@
 
 public final class SetImageCommand implements CommandSegment.Literal {
 
-	private final LiteralCommandNode node;
-	private final ImageCommandAttributes attributes;
-	private final DeluxeMediaPlugin plugin;
+  private final LiteralCommandNode node;
+  private final ImageCommandAttributes attributes;
+  private final DeluxeMediaPlugin plugin;
 
-	public SetImageCommand(
-			@NotNull final DeluxeMediaPlugin plugin, @NotNull final ImageCommandAttributes attributes) {
-		this.plugin = plugin;
-		this.attributes = attributes;
-		this.node =
-				this.literal("set")
-						.then(
-								this.literal("map")
-										.then(
-												this.argument("mrl", StringArgumentType.greedyString())
-														.executes(this::setImage)))
-						.then(
-								this.literal("dimensions")
-										.then(
-												this.argument("dims", StringArgumentType.greedyString())
-														.executes(this::setDimensions)))
-						.build();
-	}
+  public SetImageCommand(
+      @NotNull final DeluxeMediaPlugin plugin, @NotNull final ImageCommandAttributes attributes) {
+    this.plugin = plugin;
+    this.attributes = attributes;
+    this.node =
+        this.literal("set")
+            .then(
+                this.literal("map")
+                    .then(
+                        this.argument("mrl", StringArgumentType.greedyString())
+                            .executes(this::setImage)))
+            .then(
+                this.literal("dimensions")
+                    .then(
+                        this.argument("dims", StringArgumentType.greedyString())
+                            .executes(this::setDimensions)))
+            .build();
+  }
 
-	private int setImage(@NotNull final CommandContext context) {
-		final Audience audience = this.plugin.audience().sender(context.getSource());
-		final String mrl = context.getArgument("mrl", String.class);
-		final int width = this.attributes.getWidth();
-		final int height = this.attributes.getHeight();
-		final Optional optional = ImageMrlType.getType(mrl);
-		if (optional.isEmpty()) {
-			red(audience,
-					"Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS));
-			return SINGLE_SUCCESS;
-		}
-		gold(audience, "Loading image...");
-		final ImageMrlType type = optional.get();
-		CompletableFuture.runAsync(() -> {
-			try {
-				switch (type) {
-					case LOCAL_FILE -> this.drawImage(Path.of(mrl), width, height);
-					case DIRECT_LINK -> this.drawImage(
-							FileUtils.downloadImageFile(mrl, this.plugin.library().getLibraryPath()),
-							width, height);
-					default -> throw new IllegalArgumentException("Illegal image type!");
-				}
-				gold(audience, "Successfully drew image with mrl %s".formatted(mrl));
-			} catch (final IOException e) {
-				this.plugin.getBootstrap().getLogger().severe("Failed to set image file!");
-				e.printStackTrace();
-			}
-		});
-		return SINGLE_SUCCESS;
-	}
+  private int setImage(@NotNull final CommandContext context) {
+    final Audience audience = this.plugin.audience().sender(context.getSource());
+    final String mrl = context.getArgument("mrl", String.class);
+    final int width = this.attributes.getWidth();
+    final int height = this.attributes.getHeight();
+    final Optional optional = ImageMrlType.getType(mrl);
+    if (optional.isEmpty()) {
+      audience.sendMessage(Locale.ERR_INVALID_EXTENSION.build());
+      return SINGLE_SUCCESS;
+    }
+    audience.sendMessage(Locale.LOAD_IMG.build());
+    final ImageMrlType type = optional.get();
+    CompletableFuture.runAsync(() -> {
+      try {
+        switch (type) {
+          case LOCAL_FILE -> this.drawImage(Path.of(mrl), width, height);
+          case DIRECT_LINK -> this.drawImage(
+              FileUtils.downloadImageFile(mrl, this.plugin.library().getLibraryPath()),
+              width, height);
+          default -> throw new IllegalArgumentException("Illegal image type!");
+        }
+        audience.sendMessage(Locale.DREW_IMG.build(mrl));
+      } catch (final IOException e) {
+        this.plugin.getLogger().sendMessage(Locale.ERR_IMG_SET.build());
+        e.printStackTrace();
+      }
+    });
+    return SINGLE_SUCCESS;
+  }
 
-	private void drawImage(
-			@NotNull final Path img,
-			final int width, final int height)
-			throws IOException {
-		final MediaLibraryCore core = this.plugin.library();
-		final List maps = this.getMapsFromDimension(width, height);
-		final String name = PathUtils.getName(img).toLowerCase();
-		final Image image =
-				name.endsWith("gif") ? new DynamicImage(core, img, maps, Dimension.ofDimension(width, height)) :
-						new StaticImage(core, img, maps, Dimension.ofDimension(width, height));
-		image.draw(true);
-		this.plugin.getPictureManager().getImages().add(image);
-	}
+  private void drawImage(
+      @NotNull final Path img,
+      final int width, final int height)
+      throws IOException {
+    final MediaLibraryCore core = this.plugin.library();
+    final List maps = this.getMapsFromDimension(width, height);
+    final String name = PathUtils.getName(img).toLowerCase();
+    final Image image =
+        name.endsWith("gif") ? new DynamicImage(core, img, maps,
+            Dimension.ofDimension(width, height)) :
+            new StaticImage(core, img, maps, Dimension.ofDimension(width, height));
+    image.draw(true);
+    this.plugin.getPictureManager().getImages().add(image);
+  }
 
-	private List getMapsFromDimension(final int width, final int height) {
-		final List maps = new ArrayList<>();
-		for (int i = 0; i < width * height; i++) {
-			maps.add(Bukkit.getServer().createMap(Bukkit.getWorld("world")).getId());
-		}
-		return maps;
-	}
+  private List getMapsFromDimension(final int width, final int height) {
+    final List maps = new ArrayList<>();
+    for (int i = 0; i < width * height; i++) {
+      maps.add(Bukkit.getServer().createMap(Bukkit.getWorld("world")).getId());
+    }
+    return maps;
+  }
 
-	private int setDimensions(@NotNull final CommandContext context) {
-		final Audience audience = this.plugin.audience().sender(context.getSource());
-		final Optional optional =
-				ChatUtils.checkDimensionBoundaries(audience, context.getArgument("dims", String.class));
-		if (optional.isEmpty()) {
-			return SINGLE_SUCCESS;
-		}
-		final int[] dims = optional.get();
-		this.attributes.setWidth(dims[0]);
-		this.attributes.setHeight(dims[1]);
-		gold(
-				audience,
-				"Changed itemframe dimensions to %d:%d (width:height)"
-						.formatted(this.attributes.getWidth(), this.attributes.getHeight()));
-		return SINGLE_SUCCESS;
-	}
+  private int setDimensions(@NotNull final CommandContext context) {
+    final Audience audience = this.plugin.audience().sender(context.getSource());
+    final Optional optional =
+        ChatUtils.checkDimensionBoundaries(audience, context.getArgument("dims", String.class));
+    if (optional.isEmpty()) {
+      return SINGLE_SUCCESS;
+    }
+    final int[] dims = optional.get();
+    this.attributes.setWidth(dims[0]);
+    this.attributes.setHeight(dims[1]);
+    audience.sendMessage(
+        Locale.CHANGED_IMG_DIMS.build(this.attributes.getWidth(), this.attributes.getHeight()));
+    return SINGLE_SUCCESS;
+  }
 
-	@Override
-	public @NotNull LiteralCommandNode node() {
-		return this.node;
-	}
+  @Override
+  public @NotNull LiteralCommandNode node() {
+    return this.node;
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/map/MapCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/map/MapCommand.java
index 1c8db06a8..468eda020 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/map/MapCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/map/MapCommand.java
@@ -25,13 +25,6 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.map;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
-import static net.kyori.adventure.text.Component.join;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.arguments.StringArgumentType;
@@ -39,6 +32,7 @@
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import io.github.pulsebeat02.ezmediacore.utility.MapUtils;
 import java.util.Map;
@@ -53,100 +47,81 @@
 
 public final class MapCommand extends BaseCommand {
 
-	private final LiteralCommandNode node;
-
-	public MapCommand(@NotNull final DeluxeMediaPlugin plugin, @NotNull final TabExecutor executor) {
-		super(plugin, "map", executor, "deluxemediaplugin.command.map", "");
-		this.node =
-				this.literal(this.getName())
-						.requires(super::testPermission)
-						.then(
-								this.argument("id", IntegerArgumentType.integer(-2_147_483_647, 2_147_483_647))
-										.executes(this::giveMap))
-						.then(
-								this.argument("ids", StringArgumentType.greedyString())
-										.executes(this::giveMultipleMaps))
-						.build();
-	}
-
-	private int giveMap(@NotNull final CommandContext context) {
-
-		final CommandSender sender = context.getSource();
-		final Audience audience = this.plugin().audience().sender(sender);
-		final int id = context.getArgument("id", int.class);
-
-		if (!(sender instanceof Player)) {
-			red(audience, "You must be a player to execute this command!");
-			return SINGLE_SUCCESS;
-		}
-
-		((Player) sender).getInventory().addItem(MapUtils.getMapFromID(id));
-
-		audience.sendMessage(format(join(
-				noSeparators(), text("Gave map with id ", GOLD), text(id, AQUA))));
-
-		return SINGLE_SUCCESS;
-	}
-
-	private int giveMultipleMaps(@NotNull final CommandContext context) {
-
-		final CommandSender sender = context.getSource();
-		final Audience audience = this.plugin().audience().sender(sender);
-		final String[] bits = context.getArgument("ids", String.class).split("-");
-
-		final int start;
-		final int end;
-		try {
-			start = Integer.parseInt(bits[0]);
-			end = Integer.parseInt(bits[1]);
-		} catch (final NumberFormatException e) {
-			red(audience, "Invalid format! Must follow [starting-id]-[ending-id]");
-			return SINGLE_SUCCESS;
-		}
-
-		if (!(sender instanceof final Player player)) {
-			red(audience, "You must be a player to execute this command!");
-			return SINGLE_SUCCESS;
-		}
-
-		final PlayerInventory inventory = player.getInventory();
-		boolean noSpace = false;
-		for (int id = start; id <= end; id++) {
-			final ItemStack stack = MapUtils.getMapFromID(id);
-			if (inventory.firstEmpty() == -1) {
-				noSpace = true;
-			}
-			if (noSpace) {
-				player.getWorld().dropItem(player.getLocation(), stack);
-			} else {
-				inventory.addItem(stack);
-			}
-		}
-
-		audience.sendMessage(
-				format(
-						join(
-								noSeparators(),
-								text("Gave maps between IDs ", GOLD),
-								text(start, AQUA),
-								text(" and ", GOLD),
-								text(end, AQUA))));
-
-		return SINGLE_SUCCESS;
-	}
-
-	@Override
-	public @NotNull Component usage() {
-		return ChatUtils.getCommandUsage(
-				Map.of(
-						"/map [id]",
-						"Gives a map to the player with the specific id",
-						"/map [starting-id]-[ending-id]",
-						"Gives all maps between starting-id to ending-id (inclusive)"));
-	}
-
-	@Override
-	public @NotNull LiteralCommandNode node() {
-		return this.node;
-	}
+  private final LiteralCommandNode node;
+
+  public MapCommand(@NotNull final DeluxeMediaPlugin plugin, @NotNull final TabExecutor executor) {
+    super(plugin, "map", executor, "deluxemediaplugin.command.map", "");
+    this.node =
+        this.literal(this.getName())
+            .requires(super::testPermission)
+            .then(
+                this.argument("id", IntegerArgumentType.integer(-2_147_483_647, 2_147_483_647))
+                    .executes(this::giveMap))
+            .then(
+                this.argument("ids", StringArgumentType.greedyString())
+                    .executes(this::giveMultipleMaps))
+            .build();
+  }
+
+  private int giveMap(@NotNull final CommandContext context) {
+    final CommandSender sender = context.getSource();
+    final Audience audience = this.plugin().audience().sender(sender);
+    final int id = context.getArgument("id", int.class);
+    if (!(sender instanceof Player)) {
+      audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
+      return SINGLE_SUCCESS;
+    }
+    ((Player) sender).getInventory().addItem(MapUtils.getMapFromID(id));
+    audience.sendMessage(Locale.GIVE_MAP_ID.build(id));
+    return SINGLE_SUCCESS;
+  }
+
+  private int giveMultipleMaps(@NotNull final CommandContext context) {
+    final CommandSender sender = context.getSource();
+    final Audience audience = this.plugin().audience().sender(sender);
+    final String[] bits = context.getArgument("ids", String.class).split("-");
+    final int start;
+    final int end;
+    try {
+      start = Integer.parseInt(bits[0]);
+      end = Integer.parseInt(bits[1]);
+    } catch (final NumberFormatException e) {
+      audience.sendMessage(Locale.ERR_MAP_RANGE.build());
+      return SINGLE_SUCCESS;
+    }
+    if (!(sender instanceof final Player player)) {
+      audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
+      return SINGLE_SUCCESS;
+    }
+    final PlayerInventory inventory = player.getInventory();
+    boolean noSpace = false;
+    for (int id = start; id <= end; id++) {
+      final ItemStack stack = MapUtils.getMapFromID(id);
+      if (inventory.firstEmpty() == -1) {
+        noSpace = true;
+      }
+      if (noSpace) {
+        player.getWorld().dropItem(player.getLocation(), stack);
+      } else {
+        inventory.addItem(stack);
+      }
+    }
+    audience.sendMessage(Locale.GAVE_MAP_RANGE.build(start, end));
+    return SINGLE_SUCCESS;
+  }
+
+  @Override
+  public @NotNull Component usage() {
+    return ChatUtils.getCommandUsage(
+        Map.of(
+            "/map [id]",
+            "Gives a map to the player with the specific id",
+            "/map [starting-id]-[ending-id]",
+            "Gives all maps between starting-id to ending-id (inclusive)"));
+  }
+
+  @Override
+  public @NotNull LiteralCommandNode node() {
+    return this.node;
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/plugin/PluginCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/plugin/PluginCommand.java
index dfb5c02e2..5f142fdce 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/plugin/PluginCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/plugin/PluginCommand.java
@@ -25,73 +25,21 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.plugin;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static net.kyori.adventure.text.Component.newline;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.event.ClickEvent.openUrl;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
-import static net.kyori.adventure.text.format.Style.style;
-import static net.kyori.adventure.text.format.TextDecoration.BOLD;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Map;
 import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.TextComponent;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.TabExecutor;
 import org.jetbrains.annotations.NotNull;
 
 public class PluginCommand extends BaseCommand {
 
-  private static final TextComponent PLUGIN_INFORMATION;
-
-  static {
-    PLUGIN_INFORMATION =
-        text()
-            .append(text("-----------------------------------", GOLD))
-            .append(newline())
-            .append(text("Plugin: ", GOLD, BOLD))
-            .append(text("DeluxeMediaPlugin", AQUA))
-            .append(newline())
-            .append(text("Authors: ", GOLD, BOLD))
-            .append(
-                text(
-                    "PulseBeat_02",
-                    style(
-                        AQUA,
-                        text("PulseBeat_02's Github", GOLD).asHoverEvent(),
-                        openUrl("https://github.com/PulseBeat02"))))
-            .append(text(", ", GOLD))
-            .append(
-                text(
-                    "itxfrosty",
-                    style(
-                        AQUA,
-                        text("itxfrosty's Github", GOLD).asHoverEvent(),
-                        openUrl("https://github.com/itxfrosty"))))
-            .append(newline())
-            .append(text("Version: ", GOLD, BOLD))
-            .append(text("BETA Release", AQUA))
-            .append(newline())
-            .append(newline())
-            .append(
-                text(
-                    "Click for Support Server",
-                    style(
-                        GOLD,
-                        BOLD,
-                        openUrl("https://discord.gg/AqK5dKdUZe"),
-                        text("Click for Discord Server", GOLD).asHoverEvent())))
-            .append(newline())
-            .append(text("-----------------------------------", GOLD))
-            .append()
-            .build();
-  }
-
   private final LiteralCommandNode node;
 
   public PluginCommand(
@@ -110,7 +58,7 @@ public PluginCommand(
   }
 
   private int sendInformation(@NotNull final CommandContext context) {
-    this.plugin().audience().sender(context.getSource()).sendMessage(PLUGIN_INFORMATION);
+    this.plugin().audience().sender(context.getSource()).sendMessage(Locale.PLUGIN_AUTHORS.build());
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/screen/ScreenCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/screen/ScreenCommand.java
index ee02a283b..1b7ceac38 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/screen/ScreenCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/screen/ScreenCommand.java
@@ -25,15 +25,13 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.screen;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.RED;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
 import io.github.pulsebeat02.deluxemediaplugin.command.gui.ScreenBuilderGui;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Map;
 import net.kyori.adventure.audience.Audience;
@@ -58,17 +56,13 @@ public ScreenCommand(
   }
 
   private int sendScreenBuilder(@NotNull final CommandContext context) {
-
     final CommandSender sender = context.getSource();
     final Audience audience = this.plugin().audience().sender(sender);
-
     if (!(sender instanceof Player)) {
-      audience.sendMessage(format(text("You must be a player to execute this command!", RED)));
-      return 1;
+      audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
+      return SINGLE_SUCCESS;
     }
-
     new ScreenBuilderGui(this.plugin(), (Player) sender);
-
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java
index 1bc2baa0e..4cf479621 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java
@@ -25,19 +25,7 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.video;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.external;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
 import static java.util.Map.entry;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.event.ClickEvent.openUrl;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
-import static net.kyori.adventure.text.format.NamedTextColor.RED;
-import static net.kyori.adventure.text.format.Style.style;
-import static net.kyori.adventure.text.format.TextDecoration.BOLD;
-import static net.kyori.adventure.text.format.TextDecoration.UNDERLINED;
 
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
@@ -47,6 +35,7 @@
 import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand;
 import io.github.pulsebeat02.deluxemediaplugin.config.ServerInfo;
 import io.github.pulsebeat02.deluxemediaplugin.executors.ExecutorProvider;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegAudioTrimmer;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegMediaStreamer;
@@ -63,7 +52,6 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Collection;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
@@ -105,36 +93,29 @@ public VideoCommand(
 
   private int dumpThreads(@NotNull final CommandContext context) {
     ThreadUtils.createThreadDump();
-    gold(this.plugin().audience().sender(context.getSource()), "Created thread dump! Look in console for more details.");
+    this.plugin().audience().sender(context.getSource()).sendMessage(Locale.DUMP_THREADS.build());
     return SINGLE_SUCCESS;
   }
 
   private int destroyVideo(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin().audience().sender(context.getSource());
     if (this.mediaNotSpecified(audience) || this.mediaProcessingIncomplete(audience)) {
       return SINGLE_SUCCESS;
     }
-
     this.releaseIfPlaying();
-    gold(audience, "Successfully destroyed the current video!");
-
+    audience.sendMessage(Locale.RELEASE_VIDEO.build());
     return SINGLE_SUCCESS;
   }
 
   private int playVideo(@NotNull final CommandContext context) {
-
     final CommandSender sender = context.getSource();
     final DeluxeMediaPlugin plugin = this.plugin();
     final Audience audience = plugin.audience().sender(sender);
     final Collection players = Bukkit.getOnlinePlayers();
-
     if (this.mediaNotSpecified(audience) || this.mediaProcessingIncomplete(audience)) {
       return SINGLE_SUCCESS;
     }
-
     this.releaseIfPlaying();
-
     final PlaybackType type = this.attributes.getVideoType();
     switch (type) {
       case ITEMFRAME -> this.attributes.setPlayer(this.builder.createMapPlayer(players));
@@ -142,7 +123,7 @@ private int playVideo(@NotNull final CommandContext context) {
         if (sender instanceof Player) {
           this.attributes.setPlayer(this.builder.createEntityPlayer((Player) sender, players));
         } else {
-          audience.sendMessage(format(text("You must be a player to execute this command!", RED)));
+          audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
           return SINGLE_SUCCESS;
         }
       }
@@ -153,7 +134,7 @@ private int playVideo(@NotNull final CommandContext context) {
           this.attributes.setPlayer(
               this.builder.createBlockHighlightPlayer((Player) sender));
         } else {
-          audience.sendMessage(format(text("You must be a player to execute this command!", RED)));
+          audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
           return SINGLE_SUCCESS;
         }
       }
@@ -187,25 +168,15 @@ private void handleStreamPlayers(@NotNull final Audience audience) {
             e.printStackTrace();
           }
           manager.addTrack(link);
-          gold(audience, "Started playing audio into Discord voice chat!");
+          audience.sendMessage(Locale.DISCORD_AUDIO_STREAM.build());
         });
       }
       case HTTP -> {
-        final TextComponent.Builder builder = text();
-        builder.append(text("Click ", GOLD));
-        builder.append(text(
-            "this message",
-            style(
-                AQUA,
-                BOLD,
-                UNDERLINED,
-                openUrl(this.openFFmpegStream(mrl)),
-                text("Click to get the link!", GOLD)
-                    .asHoverEvent())));
-        builder.append(text(" to retrieve the audio HTTP link!", GOLD));
-        plugin.audience().players().sendMessage(format(builder.build()));
+        plugin.audience().players()
+            .sendMessage(Locale.HTTP_SEND_LINK.build(this.openFFmpegStream(mrl)));
+      }
+      case RESOURCEPACK -> {
       }
-      case RESOURCEPACK -> {}
       default -> throw new IllegalArgumentException("Illegal Audio Output Option!");
     }
   }
@@ -220,7 +191,8 @@ private void setProperAudioHandler() {
           p.playSound(p.getLocation(), sound, SoundCategory.MASTER, 100.0F, 1.0F);
         }
       });
-      case DISCORD, HTTP -> player.setCustomAudioPlayback((mrl) -> {});
+      case DISCORD, HTTP -> player.setCustomAudioPlayback((mrl) -> {
+      });
       default -> throw new IllegalArgumentException("Illegal Audio Output!");
     }
   }
@@ -231,74 +203,65 @@ private String openFFmpegStream(@NotNull final String mrl) {
     final String ip = info.getIp();
     final int port = info.getPort();
     final FFmpegMediaStreamer streamer = new FFmpegMediaStreamer(
-        plugin.library(), plugin.getAudioConfiguration(), RequestUtils.getAudioURLs(mrl).get(0), ip, port);
+        plugin.library(), plugin.getAudioConfiguration(), RequestUtils.getAudioURLs(mrl).get(0), ip,
+        port);
     this.attributes.setStreamExtractor(streamer);
     streamer.executeAsync(ExecutorProvider.STREAM_THREAD_EXECUTOR);
     return "http://%s:%s/live.stream".formatted(ip, port);
   }
 
   private int stopVideo(@NotNull final CommandContext context) {
-
     final Audience audience = this.audience().sender(context.getSource());
     if (this.mediaNotSpecified(audience) || this.mediaProcessingIncomplete(audience)
         || this.mediaUninitialized(audience)) {
       return SINGLE_SUCCESS;
     }
-
     final MediaBot bot = this.plugin().getMediaBot();
     if (bot != null) {
       bot.getMusicManager().pauseTrack();
     }
-
     this.attributes.cancelCurrentStream();
-
     this.attributes.getPlayer().setPlayerState(PlayerControls.PAUSE);
-
-    gold(audience, "Stopped the video!");
-
+    audience.sendMessage(Locale.PAUSE_VIDEO.build());
     return SINGLE_SUCCESS;
   }
 
   private int resumeVideo(@NotNull final CommandContext context) {
-
     final CommandSender sender = context.getSource();
     final DeluxeMediaPlugin plugin = this.plugin();
     final Audience audience = plugin.audience().sender(sender);
-
     if (this.mediaNotSpecified(audience) || this.mediaProcessingIncomplete(audience)) {
       return SINGLE_SUCCESS;
     }
-
-    gold(
-        audience,
-        "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.");
-
+    audience.sendMessage(Locale.SETUP_RESOURCEPACK.build());
     CompletableFuture.runAsync(() -> this.buildResourcepack(audience))
         .thenRunAsync(
             () ->
                 ResourcepackUtils.forceResourcepackLoad(
                     plugin.library(), this.attributes.getResourcepackUrl(),
                     this.attributes.getResourcepackHash()))
-        .thenRun(() -> gold(audience, "Resumed the video!"));
+        .thenRun(() -> audience.sendMessage(Locale.RESUME_AUDIO.build()));
     return SINGLE_SUCCESS;
   }
 
   private void buildResourcepack(@NotNull final Audience audience) {
     final DeluxeMediaPlugin plugin = this.plugin();
+    final Audience console = plugin.getLogger();
     final JavaPlugin loader = plugin.getBootstrap();
     try {
       final HttpServer server = plugin.getHttpServer();
       final Path audio = Path.of(this.attributes.getOggMrl().getMrl());
       final Path ogg = audio.getParent().resolve("trimmed.ogg");
       final long ms = this.attributes.getPlayer().getElapsedMilliseconds();
-      plugin.log("Resuming Video at %s Milliseconds!".formatted(ms));
+      console.sendMessage(Locale.RESUMING_VIDEO_MS.build(ms));
       new FFmpegAudioTrimmer(
           plugin.library(), audio, ogg, ms)
-          .executeAsyncWithLogging((line) -> external(audience, line));
+          .executeAsyncWithLogging(
+              (line) -> audience.sendMessage(Locale.EXTERNAL_PROCESS.build(line)));
       final ResourcepackSoundWrapper wrapper =
           new ResourcepackSoundWrapper(
               server.getDaemon().getServerPath().resolve("resourcepack.zip"), "Video Pack", 6);
-      wrapper.addSound(loader.getName().toLowerCase(Locale.ROOT), ogg);
+      wrapper.addSound(loader.getName().toLowerCase(java.util.Locale.ROOT), ogg);
       wrapper.wrap();
       final Path path = wrapper.getResourcepackFilePath();
       this.attributes.setResourcepackUrl(server.createUrl(path));
@@ -307,14 +270,14 @@ private void buildResourcepack(@NotNull final Audience audience) {
       Files.delete(audio);
       Files.move(ogg, ogg.resolveSibling("audio.ogg"));
     } catch (final IOException e) {
-      loader.getLogger().severe("Failed to wrap resourcepack!");
+      console.sendMessage(Locale.ERR_RESOURCEPACK_WRAP.build());
       e.printStackTrace();
     }
   }
 
   private boolean mediaNotSpecified(@NotNull final Audience audience) {
     if (this.attributes.getVideoMrl() == null) {
-      red(audience, "Video not loaded!");
+      audience.sendMessage(Locale.ERR_VIDEO_NOT_LOADED.build());
       return true;
     }
     return false;
@@ -322,7 +285,7 @@ private boolean mediaNotSpecified(@NotNull final Audience audience) {
 
   private boolean mediaProcessingIncomplete(@NotNull final Audience audience) {
     if (!this.attributes.getCompletion().get()) {
-      red(audience, "Video is still processing!");
+      audience.sendMessage(Locale.ERR_VIDEO_PROCESSING.build());
       return true;
     }
     return false;
@@ -339,7 +302,7 @@ private void releaseIfPlaying() {
 
   private boolean mediaUninitialized(@NotNull final Audience audience) {
     if (this.attributes.getPlayer() == null) {
-      red(audience, "You haven't loaded up a video!");
+      audience.sendMessage(Locale.ERR_VIDEO_NOT_LOADED.build());
       return true;
     }
     return false;
@@ -348,7 +311,7 @@ private boolean mediaUninitialized(@NotNull final Audience audience) {
   private void sendPlayInformation(@NotNull final Audience audience) {
     final MrlConfiguration mrl = this.attributes.getVideoMrl();
     if (mrl != null) {
-      gold(audience, "Starting Video on MRL %s".formatted(mrl.getMrl()));
+      audience.sendMessage(Locale.STARTING_VIDEO.build(mrl.getMrl()));
     }
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java
index 62df10c12..30bc3362d 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java
@@ -40,25 +40,19 @@ public final class VideoCommandAttributes {
     TEMPORARY_PLACEHOLDER = true;
   }
 
+  private final AtomicBoolean completion;
   @Expose
   private DitherSetting ditherType;
-
   @Expose
   private AudioOutputType audioOutputType;
-
   @Expose
   private PlaybackType playbackType;
-
   @Expose
   private int map;
-
   @Expose
   private int frameWidth, frameHeight;
-
   @Expose
   private int pixelWidth, pixelHeight;
-
-  private final AtomicBoolean completion;
   private VideoPlayer player;
 
   private MrlConfiguration videoMrl;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java
index ddbd30530..37ce52795 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCreator.java
@@ -40,88 +40,90 @@
 import org.jetbrains.annotations.NotNull;
 
 public record VideoCreator(MediaLibraryCore library,
-						   VideoCommandAttributes attributes) {
+                           VideoCommandAttributes attributes) {
 
-	public VideoCreator(
-			@NotNull final MediaLibraryCore library, @NotNull final VideoCommandAttributes attributes) {
-		this.library = library;
-		this.attributes = attributes;
-	}
+  public VideoCreator(
+      @NotNull final MediaLibraryCore library, @NotNull final VideoCommandAttributes attributes) {
+    this.library = library;
+    this.attributes = attributes;
+  }
 
-	public @NotNull VideoPlayer createMapPlayer(@NotNull final Collection viewers) {
-		return VideoBuilder.unspecified()
-				.callback(
-						CallbackBuilder.map()
-								.algorithm(this.attributes.getDitherType().getAlgorithm())
-								.blockWidth(this.attributes.getPixelWidth())
-								.map(Identifier.ofIdentifier(0))
-								.dims(Dimension.ofDimension(this.attributes.getFrameWidth(), this.attributes.getFrameHeight()))
-								.viewers(Viewers.ofPlayers(viewers))
-								.delay(DelayConfiguration.DELAY_0_MS)
-								.build(this.library))
-				.dims(Dimension.ofDimension(this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
-				.soundKey(SoundKey.ofSound("emc"))
-				.build();
-	}
+  public @NotNull VideoPlayer createMapPlayer(@NotNull final Collection viewers) {
+    return VideoBuilder.unspecified()
+        .callback(
+            CallbackBuilder.map()
+                .algorithm(this.attributes.getDitherType().getAlgorithm())
+                .blockWidth(this.attributes.getPixelWidth())
+                .map(Identifier.ofIdentifier(0))
+                .dims(Dimension.ofDimension(this.attributes.getFrameWidth(),
+                    this.attributes.getFrameHeight()))
+                .viewers(Viewers.ofPlayers(viewers))
+                .delay(DelayConfiguration.DELAY_0_MS)
+                .build(this.library))
+        .dims(Dimension.ofDimension(this.attributes.getPixelWidth(),
+            this.attributes.getPixelHeight()))
+        .soundKey(SoundKey.ofSound("emc"))
+        .build();
+  }
 
-	public @NotNull VideoPlayer createEntityPlayer(
-			@NotNull final Player sender, @NotNull final Collection viewers) {
-		return VideoBuilder.unspecified()
-				.callback(
-						CallbackBuilder.entity()
-								.character(NamedEntityString.NORMAL_SQUARE)
-								.type(EntityType.ARMORSTAND)
-								.location(sender.getLocation())
-								.dims(Dimension.ofDimension(
-										this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
-								.viewers(Viewers.ofPlayers(viewers))
-								.delay(DelayConfiguration.DELAY_20_MS)
-								.build(this.library))
-				.soundKey(SoundKey.ofSound("emc"))
-				.build();
-	}
+  public @NotNull VideoPlayer createEntityPlayer(
+      @NotNull final Player sender, @NotNull final Collection viewers) {
+    return VideoBuilder.unspecified()
+        .callback(
+            CallbackBuilder.entity()
+                .character(NamedEntityString.NORMAL_SQUARE)
+                .type(EntityType.ARMORSTAND)
+                .location(sender.getLocation())
+                .dims(Dimension.ofDimension(
+                    this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
+                .viewers(Viewers.ofPlayers(viewers))
+                .delay(DelayConfiguration.DELAY_20_MS)
+                .build(this.library))
+        .soundKey(SoundKey.ofSound("emc"))
+        .build();
+  }
 
-	public @NotNull VideoPlayer createChatBoxPlayer(
-			@NotNull final Collection viewers) {
-		return VideoBuilder.unspecified()
-				.callback(
-						CallbackBuilder.chat()
-								.character(NamedEntityString.NORMAL_SQUARE)
-								.dims(Dimension.ofDimension(
-										this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
-								.viewers(Viewers.ofPlayers(viewers))
-								.delay(DelayConfiguration.ofDelay(20))
-								.build(this.library))
-				.soundKey(SoundKey.ofSound("emc"))
-				.build();
-	}
+  public @NotNull VideoPlayer createChatBoxPlayer(
+      @NotNull final Collection viewers) {
+    return VideoBuilder.unspecified()
+        .callback(
+            CallbackBuilder.chat()
+                .character(NamedEntityString.NORMAL_SQUARE)
+                .dims(Dimension.ofDimension(
+                    this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
+                .viewers(Viewers.ofPlayers(viewers))
+                .delay(DelayConfiguration.ofDelay(20))
+                .build(this.library))
+        .soundKey(SoundKey.ofSound("emc"))
+        .build();
+  }
 
-	public @NotNull VideoPlayer createScoreboardPlayer(
-			@NotNull final Collection viewers) {
-		return VideoBuilder.unspecified()
-				.callback(
-						CallbackBuilder.scoreboard()
-								.id(Identifier.ofIdentifier(1080))
-								.dims(Dimension.ofDimension(
-										this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
-								.viewers(Viewers.ofPlayers(viewers))
-								.delay(DelayConfiguration.DELAY_20_MS)
-								.build(this.library))
-				.soundKey(SoundKey.ofSound("emc"))
-				.build();
-	}
+  public @NotNull VideoPlayer createScoreboardPlayer(
+      @NotNull final Collection viewers) {
+    return VideoBuilder.unspecified()
+        .callback(
+            CallbackBuilder.scoreboard()
+                .id(Identifier.ofIdentifier(1080))
+                .dims(Dimension.ofDimension(
+                    this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
+                .viewers(Viewers.ofPlayers(viewers))
+                .delay(DelayConfiguration.DELAY_20_MS)
+                .build(this.library))
+        .soundKey(SoundKey.ofSound("emc"))
+        .build();
+  }
 
-	public @NotNull VideoPlayer createBlockHighlightPlayer(
-			@NotNull final Player sender) {
-		return VideoBuilder.unspecified()
-				.callback(
-						CallbackBuilder.blockHighlight()
-								.location(sender.getLocation())
-								.dims(Dimension.ofDimension(
-										this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
-								.delay(DelayConfiguration.ofDelay(40))
-								.build(this.library))
-				.soundKey(SoundKey.ofSound("emc"))
-				.build();
-	}
+  public @NotNull VideoPlayer createBlockHighlightPlayer(
+      @NotNull final Player sender) {
+    return VideoBuilder.unspecified()
+        .callback(
+            CallbackBuilder.blockHighlight()
+                .location(sender.getLocation())
+                .dims(Dimension.ofDimension(
+                    this.attributes.getPixelWidth(), this.attributes.getPixelHeight()))
+                .delay(DelayConfiguration.ofDelay(40))
+                .build(this.library))
+        .soundKey(SoundKey.ofSound("emc"))
+        .build();
+  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java
index 81b1e4379..ec135cf35 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java
@@ -25,23 +25,13 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.video;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.event.ClickEvent.runCommand;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
-import static net.kyori.adventure.text.format.NamedTextColor.RED;
-import static net.kyori.adventure.text.format.Style.style;
-import static net.kyori.adventure.text.format.TextDecoration.BOLD;
-import static net.kyori.adventure.text.format.TextDecoration.UNDERLINED;
 
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.context.CommandContext;
 import com.mojang.brigadier.tree.LiteralCommandNode;
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.EnhancedExecution;
 import io.github.pulsebeat02.ezmediacore.ffmpeg.FFmpegAudioExtractor;
 import io.github.pulsebeat02.ezmediacore.player.MrlConfiguration;
@@ -55,7 +45,6 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
-import java.util.Locale;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -104,27 +93,25 @@ private int cancelDownload(@NotNull final CommandContext context)
       this.task.cancel(true);
       this.attributes.setExtractor(null);
       this.task = null;
-      gold(audience, "Successfully cancelled the video loading process!");
+      audience.sendMessage(Locale.CANCELLED_VIDEO_PROCESSING.build());
     } else {
-      red(audience, "You aren't loading a video!");
+      audience.sendMessage(Locale.ERR_CANCELLATION_VIDEO_PROCESSING.build());
     }
     return SINGLE_SUCCESS;
   }
 
   private int loadVideo(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String mrl = context.getArgument("mrl", String.class);
     final Path folder = this.plugin.getBootstrap().getDataFolder().toPath().resolve("emc");
     final AtomicBoolean successful = new AtomicBoolean(true);
     final AtomicBoolean status = this.attributes.getCompletion();
-
+    final Audience console = this.plugin.getLogger();
     this.attributes.cancelCurrentStream();
-
     CompletableFuture.runAsync(
             () -> {
               try {
-                gold(audience, "Initializing and reading media...");
+                audience.sendMessage(Locale.LOADING_VIDEO.build());
                 if (this.checkStream(audience, mrl)) {
                   successful.set(false);
                   return;
@@ -132,12 +119,10 @@ private int loadVideo(@NotNull final CommandContext context) {
                 this.attributes.setVideoMrl(MrlConfiguration.ofMrl(mrl));
                 if (this.attributes.getAudioOutputType() == AudioOutputType.RESOURCEPACK) {
                   status.set(false);
-                  gold(
-                      audience,
-                      "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.");
+                  console.sendMessage(Locale.CREATE_RESOURCEPACK.build());
                   final Optional download = this.downloadMrl(audience, folder, mrl);
                   if (download.isEmpty()) {
-                    this.plugin.getBootstrap().getLogger().severe("Failed to download video!");
+                    this.plugin.getLogger().sendMessage(Locale.ERR_DOWNLOAD_VIDEO.build());
                     status.set(true);
                     successful.set(false);
                     return;
@@ -146,7 +131,7 @@ private int loadVideo(@NotNull final CommandContext context) {
                   status.set(true);
                 }
               } catch (final IOException | InterruptedException e) {
-                this.plugin.getBootstrap().getLogger().severe("Failed to load video!");
+                console.sendMessage(Locale.ERR_LOAD_VIDEO.build());
                 e.printStackTrace();
               }
             })
@@ -162,7 +147,6 @@ private int loadVideo(@NotNull final CommandContext context) {
 
   private void loadAndSendResourcepack(@NotNull final Path folder, @NotNull final Path download)
       throws IOException {
-
     final Path oggOutput = folder.resolve("output.ogg");
     final HttpServer daemon = this.plugin.getHttpServer();
     final FFmpegAudioExtractor extractor =
@@ -170,16 +154,15 @@ private void loadAndSendResourcepack(@NotNull final Path folder, @NotNull final
             this.plugin.library(), this.plugin.getAudioConfiguration(), download, oggOutput);
     this.attributes.setExtractor(extractor);
     extractor.execute();
-
     final ResourcepackSoundWrapper wrapper =
         new ResourcepackSoundWrapper(
             daemon.getDaemon().getServerPath().resolve("resourcepack.zip"),
             "Audio Resourcepack",
             PackFormat.getCurrentFormat().getId());
-    wrapper.addSound(this.plugin.getBootstrap().getName().toLowerCase(Locale.ROOT), oggOutput);
+    wrapper.addSound(this.plugin.getBootstrap().getName().toLowerCase(java.util.Locale.ROOT),
+        oggOutput);
     wrapper.wrap();
     this.attributes.setOggMrl(MrlConfiguration.ofMrl(oggOutput));
-
     final Path path = wrapper.getResourcepackFilePath();
     this.attributes.setResourcepackUrl(daemon.createUrl(path));
     this.attributes.setResourcepackHash(
@@ -195,7 +178,7 @@ private void loadAndSendResourcepack(@NotNull final Path folder, @NotNull final
     } else {
       final List videoMrls = RequestUtils.getAudioURLs(mrl);
       if (videoMrls.isEmpty()) {
-        red(audience, "Invalid MRL link! Not supported!");
+        audience.sendMessage(Locale.ERR_INVALID_MRL.build());
         return Optional.empty();
       }
       downloadPath = RequestUtils.downloadFile(folder.resolve("temp-audio"), videoMrls.get(0));
@@ -206,11 +189,9 @@ private void loadAndSendResourcepack(@NotNull final Path folder, @NotNull final
   private boolean checkStream(@NotNull final Audience audience, @NotNull final String mrl) {
     if (RequestUtils.isStream(mrl)) {
       if (this.attributes.getAudioOutputType() == AudioOutputType.RESOURCEPACK) {
-        red(
-            audience,
-            "You cannot play streams without using Discord or a dynamic audio player with audio. Proceeding to play without audio.");
+        audience.sendMessage(Locale.ERR_INVALID_AUDIO_OUTPUT.build());
       } else {
-        gold(audience, "Successfully loaded stream %s!".formatted(mrl));
+        audience.sendMessage(Locale.LOADED_MEDIA.build(mrl));
       }
       this.attributes.getCompletion().set(true);
       this.cancelled = false;
@@ -219,9 +200,7 @@ private boolean checkStream(@NotNull final Audience audience, @NotNull final Str
     } else {
       final List urls = RequestUtils.getVideoURLs(mrl);
       if (urls.size() == 1 && urls.get(0).equals(mrl)) {
-        red(
-            audience,
-            "Invalid media resource! Please check to make sure the media provided is supported!");
+        audience.sendMessage(Locale.ERR_INVALID_MRL.build());
       }
     }
     return false;
@@ -241,30 +220,9 @@ private void sendCompletionMessage(@NotNull final Audience audience, @NotNull fi
           Bukkit.getOnlinePlayers(),
           this.attributes.getResourcepackUrl(),
           this.attributes.getResourcepackHash());
-      Bukkit.getOnlinePlayers().parallelStream()
-          .forEach(
-              player ->
-                  this.plugin
-                      .audience()
-                      .player(player)
-                      .sendMessage(
-                          text()
-                              .append(text("Loaded resourcepack for all players! Click ", GOLD))
-                              .append(
-                                  text(
-                                      "this message",
-                                      style(
-                                          AQUA,
-                                          BOLD,
-                                          UNDERLINED,
-                                          runCommand(
-                                              "/video load resourcepack %s"
-                                                  .formatted(player.getName())),
-                                          text("Click to get the resourcepack!", GOLD)
-                                              .asHoverEvent())))
-                              .append(text(" to retrieve the resourcepack", GOLD))
-                              .build()));
-      gold(audience, "Successfully loaded video %s".formatted(mrl));
+      Bukkit.getOnlinePlayers().forEach((player) -> this.plugin.audience().player(player)
+          .sendMessage(Locale.SEND_RESOURCEPACK_URL.build(player)));
+      audience.sendMessage(Locale.LOADED_MEDIA.build(mrl));
     }
   }
 
@@ -290,14 +248,14 @@ private int sendResourcepack(@NotNull final CommandContext contex
         entities.stream().map(entity -> (Player) entity).collect(Collectors.toSet()),
         url,
         hash);
-    gold(audience, "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)));
+    audience.sendMessage(Locale.SENT_RESOURCEPACK.build(url, hash));
     return SINGLE_SUCCESS;
   }
 
   private boolean checkNonPlayer(
       @NotNull final Audience audience, @NotNull final List entities) {
     if (entities.parallelStream().anyMatch(entity -> !(entity instanceof Player))) {
-      red(audience, "The target selector you chose contains entities that aren't players!");
+      audience.sendMessage(Locale.ERR_INVALID_TARGET_SELECTOR.build());
       return true;
     }
     return false;
@@ -305,7 +263,7 @@ private boolean checkNonPlayer(
 
   private boolean isPlayer(@NotNull final Audience audience, @NotNull final CommandSender sender) {
     if (!(sender instanceof Player)) {
-      red(audience, "You must be a player to execute this command!");
+      audience.sendMessage(Locale.ERR_PLAYER_SENDER.build());
       return true;
     }
     return false;
@@ -314,8 +272,7 @@ private boolean isPlayer(@NotNull final Audience audience, @NotNull final Comman
   private boolean unloadedResourcepack(@NotNull final Audience audience) {
     if (this.attributes.getResourcepackUrl() == null
         && this.attributes.getResourcepackHash() == null) {
-      audience.sendMessage(
-          format(text("Please load a resourcepack before executing this command!", RED)));
+      audience.sendMessage(Locale.ERR_NO_RESOURCEPACK.build());
       return true;
     }
     return false;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java
index adf7999db..9bea85829 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoSettingCommand.java
@@ -25,14 +25,6 @@
 package io.github.pulsebeat02.deluxemediaplugin.command.video;
 
 import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.gold;
-import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.red;
-import static net.kyori.adventure.text.Component.join;
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.JoinConfiguration.noSeparators;
-import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
-import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 
 import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.arguments.StringArgumentType;
@@ -43,6 +35,7 @@
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.command.CommandSegment;
 import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils;
 import java.util.Arrays;
 import java.util.Optional;
@@ -120,46 +113,40 @@ public VideoSettingCommand(
   }
 
   private int setAudioOutput(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
-
     final String argument = context.getArgument("audio-type", String.class);
     final Optional optional = AudioOutputType.ofKey(argument);
     if (optional.isEmpty()) {
-      red(audience, "Could not find audio type %s".formatted(argument));
+      audience.sendMessage(Locale.ERR_INVALID_AUDIO_TYPE.build(argument));
       return SINGLE_SUCCESS;
     }
-
     switch (optional.get()) {
       case RESOURCEPACK -> this.attributes.setAudioOutputType(AudioOutputType.RESOURCEPACK);
       case DISCORD -> {
         if (VideoCommandAttributes.TEMPORARY_PLACEHOLDER) {
-          red(audience, "Unfortunately, Discord support is still being developed, as the Music API used is abandoned and we must find another solution!");
+          audience.sendMessage(Locale.ERR_DEVELOPMENT_FEATURE.build());
           return SINGLE_SUCCESS;
         }
         if (this.plugin.getMediaBot() == null) {
-          red(audience, "Discord bot information provided in bot.yml is invalid!");
+          audience.sendMessage(Locale.ERR_INVALID_DISCORD_BOT.build());
           return SINGLE_SUCCESS;
         }
         this.attributes.setAudioOutputType(AudioOutputType.DISCORD);
       }
       case HTTP -> {
         if (this.plugin.getHttpAudioServer() == null) {
-          red(audience, "HTTP audio information provided in httpaudio.yml is invalid!");
+          audience.sendMessage(Locale.ERR_HTTP_AUDIO.build());
           return SINGLE_SUCCESS;
         }
         this.attributes.setAudioOutputType(AudioOutputType.HTTP);
       }
       default -> throw new IllegalArgumentException("Audio type is invalid!");
     }
-
-    gold(audience, "Successfully set the audio type to %s".formatted(argument));
-
+    audience.sendMessage(Locale.SET_AUDIO_TYPE.build(argument));
     return SINGLE_SUCCESS;
   }
 
   private int setScreenDimensions(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final Optional optional =
         ChatUtils.checkDimensionBoundaries(
@@ -167,104 +154,60 @@ private int setScreenDimensions(@NotNull final CommandContext con
     if (optional.isEmpty()) {
       return SINGLE_SUCCESS;
     }
-
     final int[] dimensions = optional.get();
     this.attributes.setPixelWidth(dimensions[0]);
     this.attributes.setPixelHeight(dimensions[1]);
-
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Set screen dimensions to ", GOLD),
-                text(
-                    "%d:%d "
-                        .formatted(
-                            this.attributes.getPixelWidth(), this.attributes.getPixelHeight()),
-                    AQUA),
-                text("(width:height)", GOLD))));
-
+    audience.sendMessage(Locale.CHANGED_VIDEO_SCREEN_DIMS.build(this.attributes.getPixelWidth(),
+        this.attributes.getPixelHeight()));
     return SINGLE_SUCCESS;
   }
 
   private int setItemframeDimensions(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final Optional optional =
         ChatUtils.checkDimensionBoundaries(
             audience, context.getArgument("itemframe-dimensions", String.class));
-
     if (optional.isEmpty()) {
       return SINGLE_SUCCESS;
     }
-
     final int[] dims = optional.get();
     this.attributes.setFrameWidth(dims[0]);
     this.attributes.setFrameHeight(dims[1]);
-
-    audience.sendMessage(
-        format(
-            join(
-                noSeparators(),
-                text("Set itemframe map dimensions to ", GOLD),
-                text(
-                    "%s:%s "
-                        .formatted(
-                            this.attributes.getFrameWidth(), this.attributes.getFrameHeight()),
-                    AQUA),
-                text("(width:height)", GOLD))));
-
+    audience.sendMessage(Locale.CHANGED_ITEMFRAME_DIMS.build(this.attributes.getFrameWidth(),
+        this.attributes.getFrameHeight()));
     return SINGLE_SUCCESS;
   }
 
   private int setStartingMap(@NotNull final CommandContext context) {
-
     this.attributes.setMap(context.getArgument("map-id", int.class));
-
-    this.plugin
-        .audience()
-        .sender(context.getSource())
-        .sendMessage(
-            format(
-                join(
-                    noSeparators(),
-                    text("Set starting map id to ", GOLD),
-                    text(this.attributes.getMap(), AQUA))));
-
+    this.plugin.audience().sender(context.getSource())
+        .sendMessage(Locale.CHANGED_VIDEO_MAP_ID.build(this.attributes.getMap()));
     return SINGLE_SUCCESS;
   }
 
   private int setDitherMode(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String algorithm = context.getArgument("dithering-option", String.class);
     final Optional setting = DitherSetting.ofKey(algorithm);
-
     if (setting.isEmpty()) {
-      red(audience, "Could not find dither type %s".formatted(algorithm));
+      audience.sendMessage(Locale.ERR_INVALID_DITHER_TYPE.build(algorithm));
     } else {
       this.attributes.setDitherType(setting.get());
-      audience.sendMessage(
-          format(join(noSeparators(), text("Set dither type to ", GOLD), text(algorithm, AQUA))));
+      audience.sendMessage(Locale.SET_DITHER_TYPE.build(algorithm));
     }
-
     return SINGLE_SUCCESS;
   }
 
   private int setVideoMode(@NotNull final CommandContext context) {
-
     final Audience audience = this.plugin.audience().sender(context.getSource());
     final String mode = context.getArgument("video-mode", String.class);
     final Optional type = PlaybackType.ofKey(mode);
-
     if (type.isEmpty()) {
-      red(audience, "Could not find video mode %s".formatted(mode));
+      audience.sendMessage(Locale.ERR_INVALID_VIDEO_TYPE.build(mode));
     } else {
       this.attributes.setVideoType(type.get());
-      audience.sendMessage(
-          format(join(noSeparators(), text("Set video mode to ", GOLD), text(mode, AQUA))));
+      audience.sendMessage(Locale.SET_VIDEO_TYPE.build(mode));
     }
-
     return SINGLE_SUCCESS;
   }
 
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java
index 71dfee5ab..8caf0ef90 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java
@@ -24,15 +24,14 @@
 
 package io.github.pulsebeat02.deluxemediaplugin.config;
 
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.RED;
-
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
 import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import java.io.IOException;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.security.auth.login.LoginException;
+import net.kyori.adventure.audience.Audience;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -57,11 +56,12 @@ void serialize() throws IOException {
     final DeluxeMediaPlugin plugin = this.getPlugin();
     final FileConfiguration configuration = this.getFileConfiguration();
     final AtomicBoolean invalid = new AtomicBoolean(false);
+    final Audience console = plugin.getLogger();
     final String token =
         Objects.requireNonNullElseGet(
             configuration.getString("token"),
             () -> {
-              plugin.log("Bot token not specified in bot.yml!");
+              console.sendMessage(Locale.ERR_BOT_TOKEN.build());
               invalid.set(true);
               return "null";
             });
@@ -69,7 +69,7 @@ void serialize() throws IOException {
         Objects.requireNonNullElseGet(
             configuration.getString("guild-id"),
             () -> {
-              plugin.log("Guild token not specified in bot.yml!");
+              console.sendMessage(Locale.ERR_GUILD_TOKEN.build());
               invalid.set(true);
               return "null";
             });
@@ -77,7 +77,7 @@ void serialize() throws IOException {
         Objects.requireNonNullElseGet(
             configuration.getString("voice-chat-id"),
             () -> {
-              plugin.log("Voice Chat Identifier not specified in bot.yml!");
+              console.sendMessage(Locale.ERR_VC_ID.build());
               invalid.set(true);
               return "null";
             });
@@ -85,8 +85,7 @@ void serialize() throws IOException {
       try {
         this.bot = new MediaBot(token, guild, voicechannel);
       } catch (final LoginException | InterruptedException e) {
-        plugin.log(
-            text("A severe issue occurred while starting the bot. Please check the token!", RED));
+        console.sendMessage(Locale.ERR_INVALID_DISCORD_BOT.build());
         e.printStackTrace();
       }
     }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java
index b9cff9af2..c7b53531f 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java
@@ -1,3 +1,26 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
 package io.github.pulsebeat02.deluxemediaplugin.json;
 
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java
index ffb438d33..7a98a388c 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/GsonProvider.java
@@ -1,3 +1,26 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
 package io.github.pulsebeat02.deluxemediaplugin.json;
 
 import com.google.gson.Gson;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java
index 4fae33449..616c9fe38 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java
@@ -1,3 +1,26 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
 package io.github.pulsebeat02.deluxemediaplugin.json;
 
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
@@ -5,7 +28,7 @@
 import java.io.IOException;
 import org.jetbrains.annotations.NotNull;
 
-public class MediaAttributesData extends DataProvider  {
+public class MediaAttributesData extends DataProvider {
 
   public MediaAttributesData(
       @NotNull final DeluxeMediaPlugin plugin) throws IOException {
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java
index b23d94090..4055d4316 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java
@@ -1,16 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
 package io.github.pulsebeat02.deluxemediaplugin.message;
 
 import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format;
 import static net.kyori.adventure.text.Component.join;
+import static net.kyori.adventure.text.Component.newline;
+import static net.kyori.adventure.text.Component.space;
 import static net.kyori.adventure.text.Component.text;
 import static net.kyori.adventure.text.JoinConfiguration.separator;
+import static net.kyori.adventure.text.event.ClickEvent.openUrl;
+import static net.kyori.adventure.text.event.ClickEvent.runCommand;
 import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
 import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
 import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
 import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
 import static net.kyori.adventure.text.format.NamedTextColor.RED;
+import static net.kyori.adventure.text.format.Style.style;
+import static net.kyori.adventure.text.format.TextDecoration.BOLD;
+import static net.kyori.adventure.text.format.TextDecoration.UNDERLINED;
 
+import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting;
+import io.github.pulsebeat02.deluxemediaplugin.command.image.ImageMrlType;
+import java.util.List;
+import java.util.function.Function;
 import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TextComponent;
+import org.bukkit.entity.Player;
 import org.jetbrains.annotations.NotNull;
 
 public interface Locale {
@@ -39,37 +76,284 @@ public interface Locale {
   NullComponent
 
       ENABLE_PLUGIN = () -> join(separator(text(" ")),
-          text("Running DeluxeMediaPlugin", AQUA),
-          text("[BETA]", GOLD),
-          text("1.0.0", AQUA)),
+      text("Running DeluxeMediaPlugin", AQUA),
+      text("[BETA]", GOLD),
+      text("1.0.0", AQUA)),
       EMC_INIT = () -> text("Loading EzMediaCore instance... this may take some time!"),
       WELCOME = () -> text("""
-        Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this
-         is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for
-         support at my Discord! (https://discord.gg/MgqRKvycMC)
-        """),
+          Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this
+           is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for
+           support at my Discord! (https://discord.gg/MgqRKvycMC)
+          """),
 
-      DISABLE_PLUGIN = () -> text("DeluxeMediaPlugin is shutting down!"),
+  DISABLE_PLUGIN = () -> text("DeluxeMediaPlugin is shutting down!"),
       GOOD_EMC_SHUTDOWN = () -> text("Successfully shutdown MinecraftMediaLibrary instance!"),
       GOODBYE = () -> text("Good Bye! :("),
 
-      FIN_EMC_INIT = () -> text("Finished loading MinecraftMediaLibrary instance!"),
+  FIN_EMC_INIT = () -> text("Finished loading MinecraftMediaLibrary instance!"),
       FIN_PERSISTENT_INIT = () -> text("Finished loading persistent data!"),
       FIN_COMMANDS_INIT = () -> text("Finished registering plugin commands!"),
       FIN_METRICS_INIT = () -> text("Finished loading Metrics data!"),
       FIN_PLUGIN_INIT = () -> text("Finished loading DeluxeMediaPlugin!"),
 
-      ERR_EMC_INIT = () -> text("There was a severe issue while loading the EzMediaCore instance!", RED),
-      ERR_PERSISTENT_INIT = () -> text("A severe issue occurred while reading data from configuration files!", RED),
-      ERR_EMC_SHUTDOWN = () -> text("EzMediaCore instance is null... something fishy is going on.", RED)
+  RUNNING_LATEST_PLUGIN = () -> text(
+      "You are currently running the latest version of DeluxeMediaPlugin."),
+
+  ERR_EMC_INIT = () -> text("There was a severe issue while loading the EzMediaCore instance!",
+      RED),
+      ERR_PERSISTENT_INIT = () -> text(
+          "A severe issue occurred while reading data from configuration files!", RED),
+      ERR_EMC_SHUTDOWN = () -> text("EzMediaCore instance is null... something fishy is going on.",
+          RED),
+      ERR_NO_MRL = () -> text("File or URL not specified!", RED),
+      ERR_INVALID_MRL = () -> text("Invalid MRL link! Not supported!", RED),
+      ERR_RESOURCEPACK_WRAP = () -> text("Failed to wrap resourcepack!", RED),
+      ERR_NO_RESOURCEPACK = () -> text("Please load a resourcepack first!", RED),
+      ERR_INVALID_AUDIO_STATE = () -> text(
+          "Please wait for the previous audio to extract first before loading another one!", RED),
+      ERR_INVALID_DISCORD_BOT = () -> text(
+          "Discord bot not setup yet or invalid settings in bot.yml!", RED),
+      ERR_PLAYER_SENDER = () -> text("You must be a player to execute this command!", RED),
+      ERR_INVALID_EXTENSION = () -> text(
+          "Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS)),
+      ERR_IMG_SET = () -> text("Failed to set image file!", RED),
+      ERR_IMAGE_NOT_LOADED = () -> text("The image you request purge from the map is not loaded!",
+          RED),
+      ERR_MAP_RANGE = () -> text("Invalid format! Must follow [starting-id]-[ending-id]", RED),
+      ERR_VIDEO_NOT_LOADED = () -> text("Video not loaded!", RED),
+      ERR_VIDEO_PROCESSING = () -> text("Video is still processing!", RED),
+      ERR_CANCELLATION_VIDEO_PROCESSING = () -> text("You aren't loading a video!", RED),
+      ERR_DOWNLOAD_VIDEO = () -> text("Failed to download video!", RED),
+      ERR_LOAD_VIDEO = () -> text("Failed to load video!", RED),
+      ERR_INVALID_AUDIO_OUTPUT = () -> text(
+          "You cannot play streams without using Discord or a dynamic audio player with audio. Proceeding to play without audio.",
+          RED),
+      ERR_INVALID_TARGET_SELECTOR = () -> text(
+          "The target selector you chose contains entities that aren't players!", RED),
+      ERR_DEVELOPMENT_FEATURE = () -> text(
+          "This feature is current being developed! Stay tuned and join the Discord for updates!",
+          RED),
+      ERR_HTTP_AUDIO = () -> text("HTTP audio information provided in httpaudio.yml is invalid!",
+          RED),
+      ERR_BOT_TOKEN = () -> text("Bot token not specified in bot.yml!", RED),
+      ERR_GUILD_TOKEN = () -> text("Guild token not specified in bot.yml!", RED),
+      ERR_VC_ID = () -> text("Voice Chat Identifier not specified in bot.yml!", RED),
+
+  START_AUDIO = () -> text("Started playing audio!"),
+      PAUSE_AUDIO = () -> text("Stopped playing audio!"),
+      RESUME_AUDIO = () -> text("Resumed the video!"),
+      CREATE_RESOURCEPACK = () -> text(
+          "Creating a resourcepack for audio. Depending on the length of the video, it make take some time."),
+
+  DC_DISCORD = () -> text("Successfully disconnected from voice channel!"),
+      C_DISCORD = () -> text("Successfully connected to voice channel!"),
+      PAUSED_TRACK_DISCORD = () -> text("Successfully paused track!"),
+      RESUMED_TRACK_DISCORD = () -> text("Successfully resumed track!"),
+
+  DITHERING_OPTIONS = () -> text("Dithering Options ->")
+      .append(getComponent(DitherSetting.class,
+          (value) -> text(value.getName(), AQUA).append(newline()))),
+
+  FFMPEG_EXEC = () -> text("Executed FFmpeg command!"),
+      RESET_FFMPEG_ARGS = () -> text("Reset all FFmpeg arguments!"),
+
+  LOAD_IMG = () -> text("Loading image..."),
+      PURGE_ALL_MAPS_VERIFY = () -> text(
+          "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue..."),
+      PURGED_ALL_MAPS = () -> text("Successfully purged all images!"),
+      CANCELLED_PURGE_ALL_MAPS = () -> text("Cancelled purge of all images!"),
+
+  PAUSE_VIDEO = () -> text("Stopped the video!"),
+      RELEASE_VIDEO = () -> text("Successfully destroyed the current video!"),
+      SETUP_RESOURCEPACK = () -> text(
+          "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is."),
+      DISCORD_AUDIO_STREAM = () -> text("Started playing audio into Discord voice chat!"),
+
+  DUMP_THREADS = () -> text("Created thread dump! Look in console for more details."),
+
+  CANCELLED_VIDEO_PROCESSING = () -> text("Successfully cancelled the video loading process!"),
+      LOADING_VIDEO = () -> text("Initializing and reading media..."),
+
+  PLUGIN_AUTHORS = () -> text()
+      .append(text("-----------------------------------", GOLD))
+      .append(newline())
+      .append(text("Plugin: ", GOLD, BOLD))
+      .append(text("DeluxeMediaPlugin", AQUA))
+      .append(newline())
+      .append(text("Authors: ", GOLD, BOLD))
+      .append(
+          text(
+              "PulseBeat_02",
+              style(
+                  AQUA,
+                  text("PulseBeat_02's Github", GOLD).asHoverEvent(),
+                  openUrl("https://github.com/PulseBeat02"))))
+      .append(text(", ", GOLD))
+      .append(
+          text(
+              "itxfrosty",
+              style(
+                  AQUA,
+                  text("itxfrosty's Github", GOLD).asHoverEvent(),
+                  openUrl("https://github.com/itxfrosty"))))
+      .append(newline())
+      .append(text("Version: ", GOLD, BOLD))
+      .append(text("BETA Release", AQUA))
+      .append(newline())
+      .append(newline())
+      .append(
+          text(
+              "Click for Support Server",
+              style(
+                  GOLD,
+                  BOLD,
+                  openUrl("https://discord.gg/AqK5dKdUZe"),
+                  text("Click for Discord Server", GOLD).asHoverEvent())))
+      .append(newline())
+      .append(text("-----------------------------------", GOLD))
+      .append()
+      .build();
+
+  UniComponent
+      DREW_IMG = (mrl) -> text("Successfully drew image with mrl %s".formatted(mrl)),
+      START_TRACK_DISCORD = (mrl) -> text("Successfully started audio on MRL %s!".formatted(mrl)),
+      ADD_FFMPEG_ARG = (str) -> join(
+          separator(space()),
+          text("Added arguments", GOLD),
+          text(str, AQUA),
+          text("to the FFmpeg command.", GOLD)),
+      REMOVE_FFMPEG_ARG = (str) -> join(
+          separator(space()),
+          text("Removed arguments", GOLD),
+          text(str, AQUA),
+          text("from the FFmpeg command.", GOLD)),
+      HTTP_SEND_LINK = (mrl) ->
+          text()
+              .append(text("Click ", GOLD)).append(text(
+                  "this message",
+                  style(
+                      AQUA,
+                      BOLD,
+                      UNDERLINED,
+                      openUrl(mrl),
+                      text("Click to get the link!", GOLD)
+                          .asHoverEvent()))).append(text(" to retrieve the audio HTTP link!", GOLD))
+              .build(),
+      STARTING_VIDEO = (mrl) -> text("Starting Video on MRL %s".formatted(mrl)),
+      LOADED_MEDIA = (mrl) -> text("Successfully loaded media %s!".formatted(mrl)),
+      SET_AUDIO_TYPE = (argument) -> text(
+          "Successfully set the audio type to %s".formatted(argument)),
+      SET_DITHER_TYPE = (algorithm) -> join(separator(space()), text("Set dither type to", GOLD),
+          text(algorithm, AQUA)),
+      SET_VIDEO_TYPE = (mode) -> join(separator(space()), text("Set video mode to", GOLD),
+          text(mode, AQUA)),
+      EXTERNAL_PROCESS = (line) -> join(separator(space()), text()
+              .color(AQUA)
+              .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)),
+          text(line, GOLD)),
+      NEW_UPDATE_PLUGIN = (update) -> text(
+          "There is a new update available! (%s)".formatted(update)),
+
+  ERR_INVALID_AUDIO_TYPE = (argument) -> text(
+      "Could not find audio type %s".formatted(argument), RED),
+      ERR_INVALID_DITHER_TYPE = (algorithm) -> text(
+          "Could not find dither type %s".formatted(algorithm), RED),
+      ERR_INVALID_VIDEO_TYPE = (mode) -> text("Could not find video mode %s".formatted(mode), RED),
+      ERR_CANNOT_CHECK_UPDATES = (msg) -> text("Cannot look for updates: %s".formatted(msg), RED);
 
+  UniComponent> LIST_FFMPEG_ARGS = (list) -> join(
+      separator(space()),
+      text("Current FFmpeg arguments:", GOLD),
+      text(list.toString(), AQUA));
 
+  UniComponent
+      PURGE_MAP = (id) ->
+      join(
+          separator(space()),
+          text("Successfully purged all maps with id", GOLD),
+          text(id, AQUA)),
+      GIVE_MAP_ID = (id) -> join(
+          separator(space()), text("Gave map with id", GOLD), text(id, AQUA)),
+      CHANGED_VIDEO_MAP_ID = (id) -> join(
+          separator(space()),
+          text("Set starting map id to", GOLD),
+          text(id, AQUA));
 
+  UniComponent RESUMING_VIDEO_MS = (ms) -> text("Resuming Video at %s Milliseconds!");
+
+  UniComponent SEND_RESOURCEPACK_URL = (player) -> text()
+      .append(text("Loaded resourcepack for all players! Click ", GOLD))
+      .append(
+          text(
+              "this message",
+              style(
+                  AQUA,
+                  BOLD,
+                  UNDERLINED,
+                  runCommand(
+                      "/video load resourcepack %s"
+                          .formatted(player.getName())),
+                  text("Click to get the resourcepack!", GOLD)
+                      .asHoverEvent())))
+      .append(text(" to retrieve the resourcepack", GOLD))
+      .build();
+
+  BiComponent
+      FIN_RESOURCEPACK_INIT = (url, hash) -> text(
+      "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash))),
+      SENT_RESOURCEPACK = (url, hash) -> text(
+          "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)));
+
+  BiComponent
+      ADD_FFMPEG_ARG_INDX = (str, index) ->
+      join(
+          separator(space()),
+          text("Added arguments", GOLD),
+          text(str, AQUA),
+          text("  the FFmpeg command at index", GOLD),
+          text(index, AQUA)),
+      REMOVE_FFMPEG_ARG_INDX = (str, index) ->
+          join(
+              separator(space()),
+              text("Removed arguments", GOLD),
+              text(str, AQUA),
+              text("from the FFmpeg command at index", GOLD),
+              text(index, AQUA));
+
+  BiComponent
+      CHANGED_IMG_DIMS = (width, height) -> text(
+      "Changed itemframe dimensions to %d:%d (width:height)".formatted(width, height)),
+      GAVE_MAP_RANGE = (start, end) -> join(
+          separator(space()),
+          text("Gave maps between IDs", GOLD),
+          text(start, AQUA),
+          text("and", GOLD),
+          text(end, AQUA)),
+      CHANGED_VIDEO_SCREEN_DIMS = (width, height) -> join(
+          separator(space()),
+          text("Set screen dimensions to", GOLD),
+          text("%d:%d".formatted(width, height), AQUA),
+          text("(width:height)", GOLD)),
+      CHANGED_ITEMFRAME_DIMS = (width, height) -> join(
+          separator(space()),
+          text("Set itemframe map dimensions to", GOLD),
+          text("%d:%d".formatted(width, height), AQUA),
+          text("(width:height)", GOLD));
+
+  static > @NotNull Component getComponent(@NotNull final Class clazz,
+      @NotNull final Function function) {
+    final T[] arr = clazz.getEnumConstants();
+    final TextComponent.Builder component = text();
+    for (final T value : arr) {
+      component.append(function.apply(value));
+    }
+    return component.build();
+  }
 
-  ;
 
   @FunctionalInterface
   interface NullComponent {
+
     Component build();
 
     default void send(@NotNull final S sender) {
@@ -79,6 +363,7 @@ default void send(@NotNull final S sender) {
 
   @FunctionalInterface
   interface UniComponent {
+
     Component build(A0 arg0);
 
     default void send(@NotNull final S sender, final A0 arg0) {
@@ -88,6 +373,7 @@ default void send(@NotNull final S sender, final A0 arg0) {
 
   @FunctionalInterface
   interface BiComponent {
+
     Component build(A0 arg0, A1 arg1);
 
     default void send(@NotNull final S sender, @NotNull final A0 arg0, @NotNull final A1 arg1) {
@@ -97,6 +383,7 @@ default void send(@NotNull final S sender, @NotNull final A0 arg0, @NotNull fina
 
   @FunctionalInterface
   interface TriComponent {
+
     Component build(A0 arg0, A1 arg1, A2 arg2);
 
     default void send(
@@ -110,6 +397,7 @@ default void send(
 
   @FunctionalInterface
   interface QuadComponent {
+
     Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3);
 
     default void send(
@@ -124,6 +412,7 @@ default void send(
 
   @FunctionalInterface
   interface PentaComponent {
+
     Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4);
 
     default void send(
@@ -139,6 +428,7 @@ default void send(
 
   @FunctionalInterface
   interface HexaComponent {
+
     Component build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5);
 
     default void send(
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java
index d45fb3df3..6efd39d10 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Sender.java
@@ -1,3 +1,26 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
 package io.github.pulsebeat02.deluxemediaplugin.message;
 
 import net.kyori.adventure.text.Component;
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java
index edc95a711..dc0d72669 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java
@@ -25,10 +25,12 @@
 package io.github.pulsebeat02.deluxemediaplugin.update;
 
 import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin;
+import io.github.pulsebeat02.deluxemediaplugin.message.Locale;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Scanner;
 import java.util.concurrent.CompletableFuture;
+import net.kyori.adventure.audience.Audience;
 import org.jetbrains.annotations.NotNull;
 
 public final class UpdateChecker {
@@ -46,23 +48,25 @@ public UpdateChecker(@NotNull final DeluxeMediaPlugin plugin) {
   }
 
   public void check() {
-    CompletableFuture.runAsync(
-        () -> {
-          try (final Scanner scanner =
-              new Scanner(
-                  new URL(
-                          "https://api.spigotmc.org/legacy/update.php?resource=%d"
-                              .formatted(this.resource))
-                      .openStream())) {
-            final String update = scanner.next();
-            if (this.plugin.getBootstrap().getDescription().getVersion().equalsIgnoreCase(update)) {
-              this.plugin.log("There is a new update available! (%s)".formatted(update));
-            } else {
-              this.plugin.log("You are currently running the latest version of DeluxeMediaPlugin.");
-            }
-          } catch (final IOException exception) {
-            this.plugin.log("Cannot look for updates: %s".formatted(exception.getMessage()));
-          }
-        });
+    CompletableFuture.runAsync(this::request);
+  }
+
+  private void request() {
+    final Audience console = this.plugin.getLogger();
+    try (final Scanner scanner =
+        new Scanner(
+            new URL(
+                "https://api.spigotmc.org/legacy/update.php?resource=%d"
+                    .formatted(this.resource))
+                .openStream())) {
+      final String update = scanner.next();
+      if (this.plugin.getBootstrap().getDescription().getVersion().equalsIgnoreCase(update)) {
+        console.sendMessage(Locale.NEW_UPDATE_PLUGIN.build(update));
+      } else {
+        console.sendMessage(Locale.RUNNING_LATEST_PLUGIN.build());
+      }
+    } catch (final IOException exception) {
+      console.sendMessage(Locale.ERR_CANNOT_CHECK_UPDATES.build(exception.getMessage()));
+    }
   }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java
index 8a141ca28..d9705d857 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java
@@ -61,7 +61,8 @@ public final class ChatUtils {
             .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY));
   }
 
-  private ChatUtils() {}
+  private ChatUtils() {
+  }
 
   public static @NotNull Component format(@NotNull final Component message) {
     return join(separator(space()), PREFIX, message);
@@ -82,7 +83,7 @@ private ChatUtils() {}
     } else if (height.isEmpty()) {
       message = dims[1];
     } else {
-      return Optional.of(new int[] {width.getAsInt(), height.getAsInt()});
+      return Optional.of(new int[]{width.getAsInt(), height.getAsInt()});
     }
     sender.sendMessage(
         text()
@@ -119,20 +120,4 @@ private ChatUtils() {}
     builder.append(text("------------------", AQUA));
     return builder.build();
   }
-
-  public static void gold(@NotNull final Audience audience, final String message) {
-    audience.sendMessage(format(text(message, GOLD)));
-  }
-
-  public static void red(@NotNull final Audience audience, final String message) {
-    audience.sendMessage(format(text(message, RED)));
-  }
-
-  public static void aqua(@NotNull final Audience audience, final String message) {
-    audience.sendMessage(format(text(message, AQUA)));
-  }
-
-  public static void external(@NotNull final Audience audience, @NotNull final String message) {
-    audience.sendMessage(join(separator(space()), EXTERNAL_PROCESS, text(message, GOLD)));
-  }
 }
diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java
index 3631c8cf8..d08c69a53 100644
--- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java
+++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java
@@ -41,13 +41,14 @@ public final class CommandUtils {
     knownCommands =
         (HashMap)
             (getPrivateField(
-                    (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap")
-                        .orElseThrow(AssertionError::new)),
-                    "knownCommands")
+                (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap")
+                    .orElseThrow(AssertionError::new)),
+                "knownCommands")
                 .orElseThrow(AssertionError::new));
   }
 
-  private CommandUtils() {}
+  private CommandUtils() {
+  }
 
   public static void unRegisterBukkitCommand(
       @NotNull final DeluxeMediaPlugin plugin, @NotNull final BaseCommand cmd) {
diff --git a/lib/src/main/java/io/github/pulsebeat02/ezmediacore/LibraryProvider.java b/lib/src/main/java/io/github/pulsebeat02/ezmediacore/LibraryProvider.java
index f1b3df145..0e5d0ea1b 100644
--- a/lib/src/main/java/io/github/pulsebeat02/ezmediacore/LibraryProvider.java
+++ b/lib/src/main/java/io/github/pulsebeat02/ezmediacore/LibraryProvider.java
@@ -53,7 +53,8 @@ public final class LibraryProvider {
   private Path videoPath;
   private SpotifyClient client;
 
-  LibraryProvider() {}
+  LibraryProvider() {
+  }
 
   @Contract(value = " -> new", pure = true)
   public static @NotNull LibraryProvider builder() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java
index e27209b52..4aea95c89 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java
@@ -129,7 +129,8 @@ private void getPacketInstance() {
   }
 
   private void initializeStream() {
-    IntStream.range(0, 5).parallel().forEach(key -> {}); // jump start int stream
+    IntStream.range(0, 5).parallel().forEach(key -> {
+    }); // jump start int stream
   }
 
   private void initializeProviders() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/NativePluginLoader.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/NativePluginLoader.java
index d296892ca..1bc0f13ef 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/NativePluginLoader.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/NativePluginLoader.java
@@ -31,7 +31,8 @@
 
 public class NativePluginLoader {
 
-  public NativePluginLoader() {}
+  public NativePluginLoader() {
+  }
 
   public void executePhantomPlayers() {
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallback.java
index ae9938a1c..8d35d0513 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/BlockHighlightCallback.java
@@ -77,7 +77,8 @@ public static final class Builder extends CallbackBuilder {
 
     private Location location;
 
-    Builder() {}
+    Builder() {
+    }
 
     @Contract("_ -> this")
     @Override
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ChatCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ChatCallback.java
index 8167d1ae4..298230d70 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ChatCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ChatCallback.java
@@ -80,7 +80,8 @@ public static final class Builder extends CallbackBuilder {
 
     private NamedEntityString character = NamedEntityString.NORMAL_SQUARE;
 
-    Builder() {}
+    Builder() {
+    }
 
     @Contract("_ -> this")
     @Override
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/EntityCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/EntityCallback.java
index 8c8ecc6a9..c6d93d244 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/EntityCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/EntityCallback.java
@@ -156,7 +156,8 @@ public void process(final int[] data) {
     if (time - this.getLastUpdated() >= this.getDelayConfiguration().getDelay()) {
       this.setLastUpdated(time);
       this.getPacketHandler()
-          .displayEntities(this.getWatchers().getViewers(), this.entities, data, this.getDimensions().getWidth());
+          .displayEntities(this.getWatchers().getViewers(), this.entities, data,
+              this.getDimensions().getWidth());
     }
   }
 
@@ -180,6 +181,7 @@ public static final class Builder extends CallbackBuilder {
     private NamedEntityString character = NamedEntityString.NORMAL_SQUARE;
     private Location location;
     private EntityType type = EntityType.ARMORSTAND;
+
     Builder() {
     }
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/FrameCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/FrameCallback.java
index 7e279bea3..783aac3e4 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/FrameCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/FrameCallback.java
@@ -57,7 +57,8 @@ public abstract class FrameCallback implements Callback {
   }
 
   @Override
-  public void preparePlayerStateChange(@NotNull final PlayerControls status) {}
+  public void preparePlayerStateChange(@NotNull final PlayerControls status) {
+  }
 
   @Override
   public @NotNull DelayConfiguration getDelayConfiguration() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/MapCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/MapCallback.java
index 0553889c9..883c866b0 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/MapCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/MapCallback.java
@@ -84,7 +84,8 @@ public static final class Builder extends CallbackBuilder {
     private Identifier map = Identifier.ofIdentifier(0);
     private int blockWidth;
 
-    Builder() {}
+    Builder() {
+    }
 
     @Contract("_ -> this")
     @Override
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ScoreboardCallback.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ScoreboardCallback.java
index 2f3502df1..da6f0b834 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ScoreboardCallback.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/callback/ScoreboardCallback.java
@@ -136,7 +136,8 @@ public static final class Builder extends CallbackBuilder {
 
     private Identifier id;
 
-    Builder() {}
+    Builder() {
+    }
 
     @Contract("_ -> this")
     @Override
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/MapPalette.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/MapPalette.java
index 8a1cc2842..fca39eb34 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/MapPalette.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/MapPalette.java
@@ -29,151 +29,151 @@
 public final class MapPalette {
 
   public static final Color[] colors =
-      new Color[] {
-        c(0, 0, 0),
-        c(0, 0, 0),
-        c(0, 0, 0),
-        c(0, 0, 0),
-        c(89, 125, 39),
-        c(109, 153, 48),
-        c(127, 178, 56),
-        c(67, 94, 29),
-        c(174, 164, 115),
-        c(213, 201, 140),
-        c(247, 233, 163),
-        c(130, 123, 86),
-        c(140, 140, 140),
-        c(171, 171, 171),
-        c(199, 199, 199),
-        c(105, 105, 105),
-        c(180, 0, 0),
-        c(220, 0, 0),
-        c(255, 0, 0),
-        c(135, 0, 0),
-        c(112, 112, 180),
-        c(138, 138, 220),
-        c(160, 160, 255),
-        c(84, 84, 135),
-        c(117, 117, 117),
-        c(144, 144, 144),
-        c(167, 167, 167),
-        c(88, 88, 88),
-        c(0, 87, 0),
-        c(0, 106, 0),
-        c(0, 124, 0),
-        c(0, 65, 0),
-        c(180, 180, 180),
-        c(220, 220, 220),
-        c(255, 255, 255),
-        c(135, 135, 135),
-        c(115, 118, 129),
-        c(141, 144, 158),
-        c(164, 168, 184),
-        c(86, 88, 97),
-        c(106, 76, 54),
-        c(130, 94, 66),
-        c(151, 109, 77),
-        c(79, 57, 40),
-        c(79, 79, 79),
-        c(96, 96, 96),
-        c(112, 112, 112),
-        c(59, 59, 59),
-        c(45, 45, 180),
-        c(55, 55, 220),
-        c(64, 64, 255),
-        c(33, 33, 135),
-        c(100, 84, 50),
-        c(123, 102, 62),
-        c(143, 119, 72),
-        c(75, 63, 38),
-        c(180, 177, 172),
-        c(220, 217, 211),
-        c(255, 252, 245),
-        c(135, 133, 129),
-        c(152, 89, 36),
-        c(186, 109, 44),
-        c(216, 127, 51),
-        c(114, 67, 27),
-        c(125, 53, 152),
-        c(153, 65, 186),
-        c(178, 76, 216),
-        c(94, 40, 114),
-        c(72, 108, 152),
-        c(88, 132, 186),
-        c(102, 153, 216),
-        c(54, 81, 114),
-        c(161, 161, 36),
-        c(197, 197, 44),
-        c(229, 229, 51),
-        c(121, 121, 27),
-        c(89, 144, 17),
-        c(109, 176, 21),
-        c(127, 204, 25),
-        c(67, 108, 13),
-        c(170, 89, 116),
-        c(208, 109, 142),
-        c(242, 127, 165),
-        c(128, 67, 87),
-        c(53, 53, 53),
-        c(65, 65, 65),
-        c(76, 76, 76),
-        c(40, 40, 40),
-        c(108, 108, 108),
-        c(132, 132, 132),
-        c(153, 153, 153),
-        c(81, 81, 81),
-        c(53, 89, 108),
-        c(65, 109, 132),
-        c(76, 127, 153),
-        c(40, 67, 81),
-        c(89, 44, 125),
-        c(109, 54, 153),
-        c(127, 63, 178),
-        c(67, 33, 94),
-        c(36, 53, 125),
-        c(44, 65, 153),
-        c(51, 76, 178),
-        c(27, 40, 94),
-        c(72, 53, 36),
-        c(88, 65, 44),
-        c(102, 76, 51),
-        c(54, 40, 27),
-        c(72, 89, 36),
-        c(88, 109, 44),
-        c(102, 127, 51),
-        c(54, 67, 27),
-        c(108, 36, 36),
-        c(132, 44, 44),
-        c(153, 51, 51),
-        c(81, 27, 27),
-        c(17, 17, 17),
-        c(21, 21, 21),
-        c(25, 25, 25),
-        c(13, 13, 13),
-        c(176, 168, 54),
-        c(215, 205, 66),
-        c(250, 238, 77),
-        c(132, 126, 40),
-        c(64, 154, 150),
-        c(79, 188, 183),
-        c(92, 219, 213),
-        c(48, 115, 112),
-        c(52, 90, 180),
-        c(63, 110, 220),
-        c(74, 128, 255),
-        c(39, 67, 135),
-        c(0, 153, 40),
-        c(0, 187, 50),
-        c(0, 217, 58),
-        c(0, 114, 30),
-        c(91, 60, 34),
-        c(111, 74, 42),
-        c(129, 86, 49),
-        c(68, 45, 25),
-        c(79, 1, 0),
-        c(96, 1, 0),
-        c(112, 2, 0),
-        c(59, 1, 0)
+      new Color[]{
+          c(0, 0, 0),
+          c(0, 0, 0),
+          c(0, 0, 0),
+          c(0, 0, 0),
+          c(89, 125, 39),
+          c(109, 153, 48),
+          c(127, 178, 56),
+          c(67, 94, 29),
+          c(174, 164, 115),
+          c(213, 201, 140),
+          c(247, 233, 163),
+          c(130, 123, 86),
+          c(140, 140, 140),
+          c(171, 171, 171),
+          c(199, 199, 199),
+          c(105, 105, 105),
+          c(180, 0, 0),
+          c(220, 0, 0),
+          c(255, 0, 0),
+          c(135, 0, 0),
+          c(112, 112, 180),
+          c(138, 138, 220),
+          c(160, 160, 255),
+          c(84, 84, 135),
+          c(117, 117, 117),
+          c(144, 144, 144),
+          c(167, 167, 167),
+          c(88, 88, 88),
+          c(0, 87, 0),
+          c(0, 106, 0),
+          c(0, 124, 0),
+          c(0, 65, 0),
+          c(180, 180, 180),
+          c(220, 220, 220),
+          c(255, 255, 255),
+          c(135, 135, 135),
+          c(115, 118, 129),
+          c(141, 144, 158),
+          c(164, 168, 184),
+          c(86, 88, 97),
+          c(106, 76, 54),
+          c(130, 94, 66),
+          c(151, 109, 77),
+          c(79, 57, 40),
+          c(79, 79, 79),
+          c(96, 96, 96),
+          c(112, 112, 112),
+          c(59, 59, 59),
+          c(45, 45, 180),
+          c(55, 55, 220),
+          c(64, 64, 255),
+          c(33, 33, 135),
+          c(100, 84, 50),
+          c(123, 102, 62),
+          c(143, 119, 72),
+          c(75, 63, 38),
+          c(180, 177, 172),
+          c(220, 217, 211),
+          c(255, 252, 245),
+          c(135, 133, 129),
+          c(152, 89, 36),
+          c(186, 109, 44),
+          c(216, 127, 51),
+          c(114, 67, 27),
+          c(125, 53, 152),
+          c(153, 65, 186),
+          c(178, 76, 216),
+          c(94, 40, 114),
+          c(72, 108, 152),
+          c(88, 132, 186),
+          c(102, 153, 216),
+          c(54, 81, 114),
+          c(161, 161, 36),
+          c(197, 197, 44),
+          c(229, 229, 51),
+          c(121, 121, 27),
+          c(89, 144, 17),
+          c(109, 176, 21),
+          c(127, 204, 25),
+          c(67, 108, 13),
+          c(170, 89, 116),
+          c(208, 109, 142),
+          c(242, 127, 165),
+          c(128, 67, 87),
+          c(53, 53, 53),
+          c(65, 65, 65),
+          c(76, 76, 76),
+          c(40, 40, 40),
+          c(108, 108, 108),
+          c(132, 132, 132),
+          c(153, 153, 153),
+          c(81, 81, 81),
+          c(53, 89, 108),
+          c(65, 109, 132),
+          c(76, 127, 153),
+          c(40, 67, 81),
+          c(89, 44, 125),
+          c(109, 54, 153),
+          c(127, 63, 178),
+          c(67, 33, 94),
+          c(36, 53, 125),
+          c(44, 65, 153),
+          c(51, 76, 178),
+          c(27, 40, 94),
+          c(72, 53, 36),
+          c(88, 65, 44),
+          c(102, 76, 51),
+          c(54, 40, 27),
+          c(72, 89, 36),
+          c(88, 109, 44),
+          c(102, 127, 51),
+          c(54, 67, 27),
+          c(108, 36, 36),
+          c(132, 44, 44),
+          c(153, 51, 51),
+          c(81, 27, 27),
+          c(17, 17, 17),
+          c(21, 21, 21),
+          c(25, 25, 25),
+          c(13, 13, 13),
+          c(176, 168, 54),
+          c(215, 205, 66),
+          c(250, 238, 77),
+          c(132, 126, 40),
+          c(64, 154, 150),
+          c(79, 188, 183),
+          c(92, 219, 213),
+          c(48, 115, 112),
+          c(52, 90, 180),
+          c(63, 110, 220),
+          c(74, 128, 255),
+          c(39, 67, 135),
+          c(0, 153, 40),
+          c(0, 187, 50),
+          c(0, 217, 58),
+          c(0, 114, 30),
+          c(91, 60, 34),
+          c(111, 74, 42),
+          c(129, 86, 49),
+          c(68, 45, 25),
+          c(79, 1, 0),
+          c(96, 1, 0),
+          c(112, 2, 0),
+          c(59, 1, 0)
       };
 
   @NotNull
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FilterLiteDither.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FilterLiteDither.java
index b2ca64676..194b3969d 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FilterLiteDither.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FilterLiteDither.java
@@ -32,7 +32,8 @@
 
 public class FilterLiteDither implements DitherAlgorithm {
 
-  FilterLiteDither() {}
+  FilterLiteDither() {
+  }
 
   /**
    * Performs Filter Lite Dithering at a more optimized pace while giving similar results to Floyd
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FloydDither.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FloydDither.java
index 3a75491de..fd7c7a437 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FloydDither.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/FloydDither.java
@@ -40,7 +40,8 @@
  */
 public class FloydDither implements DitherAlgorithm {
 
-  FloydDither() {}
+  FloydDither() {
+  }
 
   private int getColorFromMinecraftPalette(final byte val) {
     return PALETTE[(val + 256) % 256];
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/SimpleDither.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/SimpleDither.java
index a55431753..688784040 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/SimpleDither.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/algorithm/SimpleDither.java
@@ -32,7 +32,8 @@
 
 public class SimpleDither implements DitherAlgorithm {
 
-  SimpleDither() {}
+  SimpleDither() {
+  }
 
   @Override
   public void dither(final int @NotNull [] buffer, final int width) {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/DitherLookupUtil.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/DitherLookupUtil.java
index fb5477bea..17704ef64 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/DitherLookupUtil.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/DitherLookupUtil.java
@@ -94,6 +94,9 @@ public static int[] getFullColorMap() {
     return FULL_COLOR_MAP;
   }
 
-  /** Init. */
-  public static void init() {}
+  /**
+   * Init.
+   */
+  public static void init() {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadBlue.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadBlue.java
index 48e04b171..f6fca9bba 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadBlue.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadBlue.java
@@ -29,7 +29,8 @@
 
 final class LoadBlue extends RecursiveTask {
 
-  @Serial private static final long serialVersionUID = 5331764784578439634L;
+  @Serial
+  private static final long serialVersionUID = 5331764784578439634L;
   private final int r, g, b;
   private final int[] palette;
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadGreen.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadGreen.java
index eb63b9544..2a0587309 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadGreen.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadGreen.java
@@ -32,7 +32,8 @@
 
 final class LoadGreen extends RecursiveTask {
 
-  @Serial private static final long serialVersionUID = -1221290051151782146L;
+  @Serial
+  private static final long serialVersionUID = -1221290051151782146L;
   private final int r;
   private final int g;
   private final int[] palette;
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadRed.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadRed.java
index a3ba3e03f..306fcfed7 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadRed.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dither/load/LoadRed.java
@@ -32,7 +32,8 @@
 
 final class LoadRed extends RecursiveTask {
 
-  @Serial private static final long serialVersionUID = -6408377810782246185L;
+  @Serial
+  private static final long serialVersionUID = -6408377810782246185L;
   private final int r;
   private final int[] palette;
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/FFmpegCommandExecutor.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/FFmpegCommandExecutor.java
index 5acd043d5..e4b3a54db 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/FFmpegCommandExecutor.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/FFmpegCommandExecutor.java
@@ -199,10 +199,12 @@ public boolean isCancelled() {
   }
 
   @Override
-  public void onBeforeExecution() {}
+  public void onBeforeExecution() {
+  }
 
   @Override
-  public void onAfterExecution() {}
+  public void onAfterExecution() {
+  }
 
   @Override
   public boolean isCompleted() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/SpotifyTrackExtractor.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/SpotifyTrackExtractor.java
index 986b8d0de..24b7bba1b 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/SpotifyTrackExtractor.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/SpotifyTrackExtractor.java
@@ -118,13 +118,16 @@ public boolean isCancelled() {
   }
 
   @Override
-  public void onDownloadCancellation() {}
+  public void onDownloadCancellation() {
+  }
 
   @Override
-  public void onStartAudioExtraction() {}
+  public void onStartAudioExtraction() {
+  }
 
   @Override
-  public void onFinishAudioExtraction() {}
+  public void onFinishAudioExtraction() {
+  }
 
   @Override
   public @NotNull TrackDownloader getTrackDownloader() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/YoutubeVideoAudioExtractor.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/YoutubeVideoAudioExtractor.java
index c3d731cc6..773ca2399 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/YoutubeVideoAudioExtractor.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/ffmpeg/YoutubeVideoAudioExtractor.java
@@ -116,10 +116,12 @@ public void close() {
   }
 
   @Override
-  public void onStartAudioExtraction() {}
+  public void onStartAudioExtraction() {
+  }
 
   @Override
-  public void onFinishAudioExtraction() {}
+  public void onFinishAudioExtraction() {
+  }
 
   @Override
   public @NotNull VideoDownloader getDownloader() {
@@ -137,5 +139,6 @@ public boolean isCancelled() {
   }
 
   @Override
-  public void onDownloadCancellation() {}
+  public void onDownloadCancellation() {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/FileRequestHandler.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/FileRequestHandler.java
index 350b181b0..7e01f3c61 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/FileRequestHandler.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/FileRequestHandler.java
@@ -110,7 +110,7 @@ public void handleIncomingRequest() {
     this.daemon.onClientConnection(this.client);
     boolean flag = false;
     try (final BufferedReader in =
-            new BufferedReader(new InputStreamReader(this.client.getInputStream(), "8859_1"));
+        new BufferedReader(new InputStreamReader(this.client.getInputStream(), "8859_1"));
         final OutputStream out = this.client.getOutputStream();
         final PrintWriter pout = new PrintWriter(new OutputStreamWriter(out, "8859_1"), true)) {
       final InetAddress address = this.client.getInetAddress();
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java
index 1033b771f..c1f3eaa60 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java
@@ -98,7 +98,8 @@ public void start() {
   }
 
   @Override
-  public void onServerStart() {}
+  public void onServerStart() {
+  }
 
   @Override
   public void stop() {
@@ -114,13 +115,16 @@ public void stop() {
   }
 
   @Override
-  public void onServerTermination() {}
+  public void onServerTermination() {
+  }
 
   @Override
-  public void onClientConnection(@NotNull final Socket client) {}
+  public void onClientConnection(@NotNull final Socket client) {
+  }
 
   @Override
-  public void onRequestFailure(@NotNull final Socket client) {}
+  public void onRequestFailure(@NotNull final Socket client) {
+  }
 
   @Override
   public boolean isVerbose() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/DynamicImage.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/DynamicImage.java
index 3d81b6e0b..a47feb72d 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/DynamicImage.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/DynamicImage.java
@@ -82,7 +82,8 @@ public void stopDrawing() {
   }
 
   @Override
-  public void onStopDrawing() {}
+  public void onStopDrawing() {
+  }
 
   @Override
   public int getCurrentFrame() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java
index 66096e668..0d6f786f9 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java
@@ -62,7 +62,8 @@ public Image(
   }
 
   @Override
-  public void onStartDrawImage() {}
+  public void onStartDrawImage() {
+  }
 
   @Override
   public @NotNull BufferedImage[][] process(@NotNull BufferedImage image, final boolean resize) {
@@ -84,7 +85,8 @@ public void onStartDrawImage() {}
   }
 
   @Override
-  public void onFinishDrawImage() {}
+  public void onFinishDrawImage() {
+  }
 
   @Override
   public void resetMaps() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java
index 7335b768e..345d0b8a1 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java
@@ -51,6 +51,7 @@ public List deserialize() throws IOException {
     return GsonProvider.getSimple()
         .fromJson(
             Files.newBufferedReader(this.getStorageFile()),
-            new TypeToken>() {}.getType());
+            new TypeToken>() {
+            }.getType());
   }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/FFmpegMediaPlayer.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/FFmpegMediaPlayer.java
index feafff80b..b1b2c4441 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/FFmpegMediaPlayer.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/FFmpegMediaPlayer.java
@@ -120,16 +120,17 @@ public void setDimensions(@NotNull final Dimension dimensions) {
   }
 
   @Override
-  public void setPlayerState(@NotNull final PlayerControls controls, @NotNull final Object... arguments) {
+  public void setPlayerState(@NotNull final PlayerControls controls,
+      @NotNull final Object... arguments) {
     super.setPlayerState(controls);
     CompletableFuture.runAsync(() -> {
-    this.firstFrame = false;
-    switch (controls) {
-      case START, RESUME -> this.play(controls, arguments);
-      case PAUSE -> this.pause();
-      case RELEASE -> this.release();
-      default -> throw new IllegalArgumentException("Player state is invalid!");
-    }
+      this.firstFrame = false;
+      switch (controls) {
+        case START, RESUME -> this.play(controls, arguments);
+        case PAUSE -> this.pause();
+        case RELEASE -> this.release();
+        default -> throw new IllegalArgumentException("Player state is invalid!");
+      }
     });
   }
 
@@ -157,7 +158,8 @@ public void initializePlayer(final long seconds, @NotNull final Object... argume
             .addArguments("-vf",
                 "scale=%s:%s".formatted(dimension.getWidth(), dimension.getHeight()))
             .setLogLevel(LogLevel.FATAL)
-            .setProgressListener((line) -> {})
+            .setProgressListener((line) -> {
+            })
             .setOutputListener(Logger::directPrintFFmpegPlayer);
     for (int i = 1; i < arguments.length; i++) {
       this.ffmpeg.addArgument(arguments[i].toString());
@@ -237,16 +239,17 @@ private void play(@NotNull final PlayerControls controls, @NotNull final Object[
     });
   }
 
-  private void setupPlayer(@NotNull final PlayerControls controls, @NotNull final Object[] arguments) {
-      if (controls == PlayerControls.START) {
-        this.stopAudio();
-        if (this.ffmpeg == null) {
-          this.initializePlayer(0L, arguments);
-        }
-        this.start = 0L;
-      } else if (controls == PlayerControls.RESUME) {
-        this.initializePlayer(System.currentTimeMillis() - this.start, arguments);
+  private void setupPlayer(@NotNull final PlayerControls controls,
+      @NotNull final Object[] arguments) {
+    if (controls == PlayerControls.START) {
+      this.stopAudio();
+      if (this.ffmpeg == null) {
+        this.initializePlayer(0L, arguments);
       }
+      this.start = 0L;
+    } else if (controls == PlayerControls.RESUME) {
+      this.initializePlayer(System.currentTimeMillis() - this.start, arguments);
+    }
   }
 
   private FFmpegResultFuture updateFFmpegPlayer() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/JCodecMediaPlayer.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/JCodecMediaPlayer.java
index 315c494dd..f0491a73a 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/JCodecMediaPlayer.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/JCodecMediaPlayer.java
@@ -87,38 +87,39 @@ private void modifyPlayerAttributes() {
   }
 
   @Override
-  public void setPlayerState(@NotNull final PlayerControls controls, @NotNull final Object... arguments) {
+  public void setPlayerState(@NotNull final PlayerControls controls,
+      @NotNull final Object... arguments) {
     super.setPlayerState(controls);
     CompletableFuture.runAsync(() -> {
-    switch (controls) {
-      case START -> CompletableFuture.runAsync(() -> {
-        this.setDirectVideoMrl(ArgumentUtils.retrieveDirectVideo(arguments));
-        this.setDirectAudioMrl(ArgumentUtils.retrieveDirectAudio(arguments));
-        if (this.grabber == null) {
-          this.initializePlayer(0L);
+      switch (controls) {
+        case START -> CompletableFuture.runAsync(() -> {
+          this.setDirectVideoMrl(ArgumentUtils.retrieveDirectVideo(arguments));
+          this.setDirectAudioMrl(ArgumentUtils.retrieveDirectAudio(arguments));
+          if (this.grabber == null) {
+            this.initializePlayer(0L);
+          }
+          this.paused = false;
+          this.play();
+          this.start = System.currentTimeMillis();
+        });
+        case PAUSE -> {
+          this.stopAudio();
+          this.paused = true;
+          this.start = System.currentTimeMillis();
         }
-        this.paused = false;
-        this.play();
-        this.start = System.currentTimeMillis();
-      });
-      case PAUSE -> {
-        this.stopAudio();
-        this.paused = true;
-        this.start = System.currentTimeMillis();
-      }
-      case RESUME -> {
-        this.initializePlayer(System.currentTimeMillis() - this.start);
-        this.paused = false;
-        this.play();
-      }
-      case RELEASE -> {
-        this.paused = false;
-        if (this.grabber != null) {
-          this.grabber = null;
+        case RESUME -> {
+          this.initializePlayer(System.currentTimeMillis() - this.start);
+          this.paused = false;
+          this.play();
         }
+        case RELEASE -> {
+          this.paused = false;
+          if (this.grabber != null) {
+            this.grabber = null;
+          }
+        }
+        default -> throw new IllegalArgumentException("Player state is invalid!");
       }
-      default -> throw new IllegalArgumentException("Player state is invalid!");
-    }
     });
   }
 
@@ -202,7 +203,8 @@ public void initializePlayer(final long ms, @NotNull final Object... arguments)
     final Dimension dimension = this.getDimensions();
     this.start = ms;
     try {
-      this.grabber = FrameGrab.createFrameGrab(NIOUtils.readableFileChannel(this.getDirectVideoMrl().getMrl()));
+      this.grabber = FrameGrab.createFrameGrab(
+          NIOUtils.readableFileChannel(this.getDirectVideoMrl().getMrl()));
       this.grabber.seekToSecondPrecise(ms / 1000.0F);
       this.grabber.getMediaInfo().setDim(new Size(dimension.getWidth(), dimension.getHeight()));
     } catch (final IOException | JCodecException e) {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/MediaPlayer.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/MediaPlayer.java
index 9ad3ba5d9..737ebbccc 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/MediaPlayer.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/MediaPlayer.java
@@ -130,7 +130,8 @@ public void setPlayerState(
 
   @Override
   public void onPlayerStateChange(
-      @NotNull final PlayerControls status, @NotNull final Object... arguments) {}
+      @NotNull final PlayerControls status, @NotNull final Object... arguments) {
+  }
 
   @Override
   public void playAudio() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/VideoBuilder.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/VideoBuilder.java
index aedf26a57..ab0f67c1c 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/VideoBuilder.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/player/VideoBuilder.java
@@ -97,7 +97,8 @@ public MediaPlayer build() {
       }
       case UNIX -> {
         return core.isVLCSupported() ? this.vlcOption()
-            : new FFmpegMediaPlayer(this.callback, this.callback.getWatchers(), this.dims, BufferConfiguration.BUFFER_10, this.key, this.rate);
+            : new FFmpegMediaPlayer(this.callback, this.callback.getWatchers(), this.dims,
+                BufferConfiguration.BUFFER_10, this.key, this.rate);
       }
       default -> throw new UnsupportedPlatformException("Unknown");
     }
@@ -105,7 +106,8 @@ public MediaPlayer build() {
 
   @Contract(" -> new")
   private @NotNull MediaPlayer vlcOption() {
-    return vlc().callback(this.callback).dims(this.dims).soundKey(this.key).frameRate(this.rate).build();
+    return vlc().callback(this.callback).dims(this.dims).soundKey(this.key).frameRate(this.rate)
+        .build();
   }
 
   public void calculateFrameRate() {
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsiteControls.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsiteControls.java
index 5a9936787..90250c4a9 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsiteControls.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsiteControls.java
@@ -50,23 +50,30 @@ public WebsiteControls(final String url, @NotNull final PlaylistType type) {
   }
 
   @Override
-  public void skipSong() {}
+  public void skipSong() {
+  }
 
   @Override
-  public void previousSong() {}
+  public void previousSong() {
+  }
 
   @Override
-  public void pauseSong() {}
+  public void pauseSong() {
+  }
 
   @Override
-  public void resumeSong() {}
+  public void resumeSong() {
+  }
 
   @Override
-  public void seekToTime(final int seconds) {}
+  public void seekToTime(final int seconds) {
+  }
 
   @Override
-  public void randomize() {}
+  public void randomize() {
+  }
 
   @Override
-  public void loopMode(final boolean mode) {}
+  public void loopMode(final boolean mode) {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsitePlayer.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsitePlayer.java
index 40db73b65..7941ff3f3 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsitePlayer.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/WebsitePlayer.java
@@ -48,26 +48,34 @@ public int getIndex() {
   }
 
   @Override
-  public void setIndex(final int index) {}
+  public void setIndex(final int index) {
+  }
 
   @Override
-  public void skipSong() {}
+  public void skipSong() {
+  }
 
   @Override
-  public void previousSong() {}
+  public void previousSong() {
+  }
 
   @Override
-  public void pauseSong() {}
+  public void pauseSong() {
+  }
 
   @Override
-  public void resumeSong() {}
+  public void resumeSong() {
+  }
 
   @Override
-  public void seekToTime(final int seconds) {}
+  public void seekToTime(final int seconds) {
+  }
 
   @Override
-  public void randomize() {}
+  public void randomize() {
+  }
 
   @Override
-  public void loopMode(final boolean mode) {}
+  public void loopMode(final boolean mode) {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/SpotifyProvider.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/SpotifyProvider.java
index 168a11984..4d121f14a 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/SpotifyProvider.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/spotify/SpotifyProvider.java
@@ -31,7 +31,8 @@ public final class SpotifyProvider {
 
   private static SpotifyApi SPOTIFY_API;
 
-  private SpotifyProvider() {}
+  private SpotifyProvider() {
+  }
 
   public static void initialize(@NotNull final MediaLibraryCore core) {
     final SpotifyClient client = core.getSpotifyClient();
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/SpotifyTrackDownloader.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/SpotifyTrackDownloader.java
index f7bc53003..a495b452c 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/SpotifyTrackDownloader.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/SpotifyTrackDownloader.java
@@ -82,8 +82,8 @@ public void downloadVideo(@NotNull final VideoQuality format, final boolean over
 
   private void internalDownload(@NotNull final RequestVideoFileDownload download) {
     if (ResponseUtils.getResponseResult(
-                YoutubeProvider.getYoutubeDownloader().downloadVideoFile(download))
-            .isEmpty()
+            YoutubeProvider.getYoutubeDownloader().downloadVideoFile(download))
+        .isEmpty()
         && !this.cancelled) {
       this.internalDownload(download);
     }
@@ -101,10 +101,12 @@ private com.github.kiulian.downloader.model.videos.formats.VideoFormat getFormat
   }
 
   @Override
-  public void onStartVideoDownload() {}
+  public void onStartVideoDownload() {
+  }
 
   @Override
-  public void onFinishVideoDownload() {}
+  public void onFinishVideoDownload() {
+  }
 
   @Override
   public @NotNull Path getDownloadPath() {
@@ -133,8 +135,10 @@ public boolean isCancelled() {
   }
 
   @Override
-  public void onDownloadCancellation() {}
+  public void onDownloadCancellation() {
+  }
 
   @Override
-  public void onDownloadFailure() {}
+  public void onDownloadFailure() {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeAudioFormat.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeAudioFormat.java
index 5b10e41e1..e4cd5bfd3 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeAudioFormat.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeAudioFormat.java
@@ -42,7 +42,7 @@
 public class YoutubeAudioFormat implements AudioFormat {
 
   private static final BiMap<
-          com.github.kiulian.downloader.model.videos.quality.AudioQuality, AudioQuality>
+      com.github.kiulian.downloader.model.videos.quality.AudioQuality, AudioQuality>
       AUDIO_FORMATS;
 
   static {
@@ -64,8 +64,8 @@ public YoutubeAudioFormat(
   }
 
   static @NotNull BiMap<
-          com.github.kiulian.downloader.model.videos.quality.AudioQuality, AudioQuality>
-      getAudioMappings() {
+      com.github.kiulian.downloader.model.videos.quality.AudioQuality, AudioQuality>
+  getAudioMappings() {
     return AUDIO_FORMATS;
   }
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeProvider.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeProvider.java
index b3fd2cb81..dc91efce6 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeProvider.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeProvider.java
@@ -35,9 +35,11 @@ public final class YoutubeProvider {
     YOUTUBE_DOWNLOADER = new YoutubeDownloader();
   }
 
-  private YoutubeProvider() {}
+  private YoutubeProvider() {
+  }
 
-  public static void initialize(@NotNull final MediaLibraryCore core) {}
+  public static void initialize(@NotNull final MediaLibraryCore core) {
+  }
 
   static YoutubeDownloader getYoutubeDownloader() {
     return YOUTUBE_DOWNLOADER;
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoDownloader.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoDownloader.java
index 789088bc0..74f522b9e 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoDownloader.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoDownloader.java
@@ -90,8 +90,8 @@ public void downloadVideo(@NotNull final VideoQuality format, final boolean over
 
   private void internalDownload(@NotNull final RequestVideoFileDownload download) {
     if (ResponseUtils.getResponseResult(
-                YoutubeProvider.getYoutubeDownloader().downloadVideoFile(download))
-            .isEmpty()
+            YoutubeProvider.getYoutubeDownloader().downloadVideoFile(download))
+        .isEmpty()
         && !this.cancelled) {
       this.internalDownload(download);
     }
@@ -109,13 +109,16 @@ private com.github.kiulian.downloader.model.videos.formats.VideoFormat getFormat
   }
 
   @Override
-  public void onStartVideoDownload() {}
+  public void onStartVideoDownload() {
+  }
 
   @Override
-  public void onFinishVideoDownload() {}
+  public void onFinishVideoDownload() {
+  }
 
   @Override
-  public void onDownloadFailure() {}
+  public void onDownloadFailure() {
+  }
 
   @Override
   public void cancelDownload() {
@@ -139,5 +142,6 @@ public boolean isCancelled() {
   }
 
   @Override
-  public void onDownloadCancellation() {}
+  public void onDownloadCancellation() {
+  }
 }
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoFormat.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoFormat.java
index 1f2d51cd1..4b19327d1 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoFormat.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/playlist/youtube/YoutubeVideoFormat.java
@@ -58,7 +58,7 @@
 public final class YoutubeVideoFormat implements VideoFormat {
 
   private static final BiMap<
-          com.github.kiulian.downloader.model.videos.quality.VideoQuality, VideoQuality>
+      com.github.kiulian.downloader.model.videos.quality.VideoQuality, VideoQuality>
       VIDEO_FORMATS;
 
   static {
@@ -89,8 +89,8 @@ public final class YoutubeVideoFormat implements VideoFormat {
   }
 
   static @NotNull BiMap<
-          com.github.kiulian.downloader.model.videos.quality.VideoQuality, VideoQuality>
-      getVideoFormatMappings() {
+      com.github.kiulian.downloader.model.videos.quality.VideoQuality, VideoQuality>
+  getVideoFormatMappings() {
     return VIDEO_FORMATS;
   }
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/Reflection.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/Reflection.java
index a9baaa73b..f71d71de6 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/Reflection.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/Reflection.java
@@ -76,10 +76,10 @@ private Reflection() {
   /**
    * Retrieve a field accessor for a specific field type and name.
    *
-   * @param target - the target type.
-   * @param name - the name of the field, or NULL to ignore.
+   * @param target    - the target type.
+   * @param name      - the name of the field, or NULL to ignore.
    * @param fieldType - a compatible field type.
-   * @param  - T field
+   * @param        - T field
    * @return The field accessor.
    */
   public static  FieldAccessor getField(
@@ -91,9 +91,9 @@ public static  FieldAccessor getField(
    * Retrieve a field accessor for a specific field type and name.
    *
    * @param className - lookup name of the class, see {@link #getClass(String)}.
-   * @param name - the name of the field, or NULL to ignore.
+   * @param name      - the name of the field, or NULL to ignore.
    * @param fieldType - a compatible field type.
-   * @param  - T field
+   * @param        - T field
    * @return The field accessor.
    */
   public static  FieldAccessor getField(
@@ -104,10 +104,10 @@ public static  FieldAccessor getField(
   /**
    * Retrieve a field accessor for a specific field type and name.
    *
-   * @param target - the target type.
+   * @param target    - the target type.
    * @param fieldType - a compatible field type.
-   * @param index - the number of compatible fields to skip.
-   * @param  - T field
+   * @param index     - the number of compatible fields to skip.
+   * @param        - T field
    * @return The field accessor.
    */
   public static  FieldAccessor getField(
@@ -120,8 +120,8 @@ public static  FieldAccessor getField(
    *
    * @param className - lookup name of the class, see {@link #getClass(String)}.
    * @param fieldType - a compatible field type.
-   * @param index - the number of compatible fields to skip.
-   * @param  - T field
+   * @param index     - the number of compatible fields to skip.
+   * @param        - T field
    * @return The field accessor.
    */
   public static  FieldAccessor getField(
@@ -180,9 +180,9 @@ public boolean hasField(final Object target) {
    * Search for the first publicly and privately defined method of the given name and parameter
    * count.
    *
-   * @param className - lookup name of the class, see {@link #getClass(String)}.
+   * @param className  - lookup name of the class, see {@link #getClass(String)}.
    * @param methodName - the method name, or NULL to skip.
-   * @param params - the expected parameters.
+   * @param params     - the expected parameters.
    * @return An object that invokes this specific method.
    * @throws IllegalStateException If we cannot find this method.
    */
@@ -195,9 +195,9 @@ public static MethodInvoker getMethod(
    * Search for the first publicly and privately defined method of the given name and parameter
    * count.
    *
-   * @param clazz - a class to start with.
+   * @param clazz      - a class to start with.
    * @param methodName - the method name, or NULL to skip.
-   * @param params - the expected parameters.
+   * @param params     - the expected parameters.
    * @return An object that invokes this specific method.
    * @throws IllegalStateException If we cannot find this method.
    */
@@ -210,10 +210,10 @@ public static MethodInvoker getMethod(
    * Search for the first publicly and privately defined method of the given name and parameter
    * count.
    *
-   * @param clazz - a class to start with.
+   * @param clazz      - a class to start with.
    * @param methodName - the method name, or NULL to skip.
    * @param returnType - the expected return type, or NULL to ignore.
-   * @param params - the expected parameters.
+   * @param params     - the expected parameters.
    * @return An object that invokes this specific method.
    * @throws IllegalStateException If we cannot find this method.
    */
@@ -251,7 +251,7 @@ public static MethodInvoker getTypedMethod(
    * parameter count.
    *
    * @param className - lookup name of the class, see {@link #getClass(String)}.
-   * @param params - the expected parameters.
+   * @param params    - the expected parameters.
    * @return An object that invokes this constructor.
    * @throws IllegalStateException If we cannot find this method.
    */
@@ -264,7 +264,7 @@ public static ConstructorInvoker getConstructor(
    * Search for the first publically and privately defined constructor of the given name and
    * parameter count.
    *
-   * @param clazz - a class to start with.
+   * @param clazz  - a class to start with.
    * @param params - the expected parameters.
    * @return An object that invokes this constructor.
    * @throws IllegalStateException If we cannot find this method.
@@ -410,7 +410,9 @@ private static String expandVariables(final String name) {
     return output.toString();
   }
 
-  /** An interface for invoking a specific constructor. */
+  /**
+   * An interface for invoking a specific constructor.
+   */
   @FunctionalInterface
   public interface ConstructorInvoker {
 
@@ -423,14 +425,16 @@ public interface ConstructorInvoker {
     Object invoke(Object... arguments);
   }
 
-  /** An interface for invoking a specific method. */
+  /**
+   * An interface for invoking a specific method.
+   */
   @FunctionalInterface
   public interface MethodInvoker {
 
     /**
      * Invoke a method on a specific target object.
      *
-     * @param target - the target object, or NULL for a static method.
+     * @param target    - the target object, or NULL for a static method.
      * @param arguments - the arguments to pass to the method.
      * @return The return value, or NULL if is void.
      */
@@ -456,7 +460,7 @@ public interface FieldAccessor {
      * Set the content of a field.
      *
      * @param target - the target object, or NULL for a static field.
-     * @param value - the new value of the field.
+     * @param value  - the new value of the field.
      */
     void set(Object target, Object value);
 
diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/TinyProtocol.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/TinyProtocol.java
index a8bae7a70..d893de8e3 100644
--- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/TinyProtocol.java
+++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/reflect/TinyProtocol.java
@@ -235,7 +235,9 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
         };
   }
 
-  /** Register bukkit events. */
+  /**
+   * Register bukkit events.
+   */
   private void registerBukkitEvents() {
     this.listener =
         new Listener() {
@@ -332,8 +334,8 @@ private void registerPlayers(final Plugin plugin) {
    * 

Note that this is not executed on the main thread. * * @param receiver - the receiving player, NULL for early login/status packets. - * @param channel - the channel that received the packet. Never NULL. - * @param packet - the packet being sent. + * @param channel - the channel that received the packet. Never NULL. + * @param packet - the packet being sent. * @return The packet to send instead, or NULL to cancel the transmission. */ public Object onPacketOutAsync( @@ -346,9 +348,9 @@ public Object onPacketOutAsync( * *

Use {@link Channel#remoteAddress()} to get the remote address of the client. * - * @param sender - the player that sent the packet, NULL for early login/status packets. + * @param sender - the player that sent the packet, NULL for early login/status packets. * @param channel - channel that received the packet. Never NULL. - * @param packet - the packet being received. + * @param packet - the packet being received. * @return The packet to recieve instead, or NULL to cancel. */ public Object onPacketInAsync(final Player sender, final Channel channel, final Object packet) { @@ -375,7 +377,7 @@ public void sendPacket(final Player player, final Object packet) { * packet. * * @param channel - client identified by a channel. - * @param packet - the packet to send. + * @param packet - the packet to send. */ public void sendPacket(final Channel channel, final Object packet) { channel.pipeline().writeAndFlush(packet); @@ -401,7 +403,7 @@ public void receivePacket(final Player player, final Object packet) { * packet. * * @param channel - client identified by a channel. - * @param packet - the packet that will be received by the server. + * @param packet - the packet that will be received by the server. */ public void receivePacket(final Channel channel, final Object packet) { channel.pipeline().context("encoder").fireChannelRead(packet); @@ -491,7 +493,7 @@ public Channel getChannel(final Player player) { /** * Retrieve the netty channel for async purposes * - * @param uuid The uuid of the player + * @param uuid The uuid of the player * @param playerConnection PlayerConnection object * @return The Netty channel */ @@ -556,7 +558,9 @@ public boolean hasInjected(final Channel channel) { return channel.pipeline().get(this.handlerName) != null; } - /** Cease listening for packets. This is called automatically when your plugin is disabled. */ + /** + * Cease listening for packets. This is called automatically when your plugin is disabled. + */ public final void close() { if (!this.closed) { this.closed = true; diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java index 49f4650c1..e51d38319 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java @@ -134,10 +134,12 @@ public void internalWrap() throws IOException { } @Override - public void onPackStartWrap() {} + public void onPackStartWrap() { + } @Override - public void onPackFinishWrap() {} + public void onPackFinishWrap() { + } @Override public void addFile(@NotNull final String path, @NotNull final Path file) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTask.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTask.java index c171a65b2..4c6d4e78b 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTask.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTask.java @@ -70,7 +70,7 @@ public class CommandTask { /** * Instantiates a CommandTask. * - * @param command command + * @param command command * @param runOnCreation whether it should be ran instantly * @throws IOException if the command isn't valid (when ran instantly) */ diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java index d78ad6f33..52ba58971 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java @@ -53,12 +53,16 @@ import java.util.concurrent.CompletableFuture; import org.jetbrains.annotations.NotNull; -/** Constructs a chain of commands to be executed accordingly. */ +/** + * Constructs a chain of commands to be executed accordingly. + */ public class CommandTaskChain { private final Map chain; - /** Instantiates a new CommandTaskChain */ + /** + * Instantiates a new CommandTaskChain + */ public CommandTaskChain() { this.chain = new LinkedHashMap<>(); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArgumentUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArgumentUtils.java index ba7a0c598..fb9ead631 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArgumentUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ArgumentUtils.java @@ -32,7 +32,8 @@ public final class ArgumentUtils { - private ArgumentUtils() {} + private ArgumentUtils() { + } public static @NotNull MrlConfiguration retrieveDirectVideo( @NotNull final Object @Nullable [] arguments) { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/DependencyUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/DependencyUtils.java index 964efd2b9..dcba94cdf 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/DependencyUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/DependencyUtils.java @@ -77,13 +77,14 @@ public final class DependencyUtils { ARTIFACT_HASHES = new HashMap<>(); } - private DependencyUtils() {} + private DependencyUtils() { + } /** * Downloads dependency. * * @param dependency the dependency - * @param parent the parent + * @param parent the parent * @return the file * @throws IOException the io exception */ @@ -123,10 +124,10 @@ public static String getDependencyUrl(@NotNull final DependencyInfo dependency) /** * Constructs dependency URL directly based on parameters. * - * @param groupId the group id + * @param groupId the group id * @param artifactId the artifact id - * @param version the version - * @param base the base + * @param version the version + * @param base the base * @return the dependency url */ @NotNull @@ -147,8 +148,8 @@ public static String getDependencyUrl( * Download dependency file. * * @param dependency the dependency - * @param link the link - * @param parent the parent + * @param link the link + * @param parent the parent * @return the file * @throws IOException the io exception */ @@ -167,9 +168,9 @@ public static Path downloadFile( * Download dependency file with consumer. * * @param dependency the dependency - * @param link the link - * @param parent the parent - * @param consumer the consumer + * @param link the link + * @param parent the parent + * @param consumer the consumer * @return the file * @throws IOException the io exception */ @@ -188,10 +189,10 @@ public static Path downloadFile( /** * Download dependency file. * - * @param groupId the group id + * @param groupId the group id * @param artifactId the artifact id - * @param version the version - * @param parent the parent + * @param version the version + * @param parent the parent * @param resolution the resolution * @return the file * @throws IOException the io exception @@ -212,11 +213,11 @@ public static Path downloadFile( /** * Download dependency file with consumer. * - * @param groupId the group id + * @param groupId the group id * @param artifactId the artifact id - * @param version the version - * @param parent the parent - * @param consumer the consumer + * @param version the version + * @param parent the parent + * @param consumer the consumer * @param resolution the resolution * @return the file * @throws IOException the io exception @@ -240,7 +241,7 @@ public static Path downloadFile(@NotNull final Path p, @NotNull final String url throws IOException { Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "URL cannot be empty or null!"); try (final ReadableByteChannel readableByteChannel = - Channels.newChannel(new URL(url).openStream()); + Channels.newChannel(new URL(url).openStream()); final FileChannel channel = new FileOutputStream(p.toFile()).getChannel()) { channel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE); } @@ -267,7 +268,7 @@ public static Path downloadFile( /** * Checks if the hash of the file matches the dependency. * - * @param file the file + * @param file the file * @param dependency the dependency * @return checks that the hash of the file matches the dependency */ @@ -290,10 +291,10 @@ public static String getDependencyHash(@NotNull final DependencyInfo dependency) /** * Gets the dependency hash from an artifact. * - * @param groupId the group id + * @param groupId the group id * @param artifactId the artifact id - * @param version the version - * @param base the base + * @param version the version + * @param base the base * @return the hash */ @NotNull @@ -330,10 +331,10 @@ public static String getHashFromUrl(@NotNull final String url) { /** * Gets the dependency hash url for an artifact. * - * @param groupId the group id + * @param groupId the group id * @param artifactId the artifact id - * @param version the version - * @param base the base + * @param version the version + * @param base the base * @return the url */ @NotNull diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MediaExtractionUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MediaExtractionUtils.java index c00740d5e..65010fb1c 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MediaExtractionUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/MediaExtractionUtils.java @@ -59,7 +59,8 @@ public final class MediaExtractionUtils { SEARCH_KEYWORD = "videoId"; } - private MediaExtractionUtils() {} + private MediaExtractionUtils() { + } /** * Extracts id from Youtube URL. diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/RequestUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/RequestUtils.java index 6278dd2e9..c149be8b7 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/RequestUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/RequestUtils.java @@ -75,7 +75,8 @@ public final class RequestUtils { .build(); } - private RequestUtils() {} + private RequestUtils() { + } public static @NotNull String getSearchedVideos( @NotNull final String apiKey, @NotNull final String keyword) { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourceUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourceUtils.java index 209b38d4a..cef397ad2 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourceUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourceUtils.java @@ -32,7 +32,8 @@ public final class ResourceUtils { - private ResourceUtils() {} + private ResourceUtils() { + } @NotNull public static String getFileContents(@NotNull final String name) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourcepackUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourcepackUtils.java index 6f8b02521..962182bba 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourcepackUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/ResourcepackUtils.java @@ -36,7 +36,8 @@ public final class ResourcepackUtils { - private ResourcepackUtils() {} + private ResourcepackUtils() { + } public static boolean validatePackFormat(final int format) { return Arrays.stream(PackFormat.values()).anyMatch(value -> value.getId() == format); @@ -52,7 +53,7 @@ public static void forceResourcepackLoad( @NotNull final String url, final byte @NotNull [] hash) { new ForcefulResourcepackListener( - core, players.stream().map(Player::getUniqueId).collect(Collectors.toSet()), url, hash) + core, players.stream().map(Player::getUniqueId).collect(Collectors.toSet()), url, hash) .start(); } @@ -61,10 +62,10 @@ public static void forceResourcepackLoad( @NotNull final String url, final byte @NotNull [] hash) { new ForcefulResourcepackListener( - core, - Bukkit.getOnlinePlayers().stream().map(Player::getUniqueId).collect(Collectors.toSet()), - url, - hash) + core, + Bukkit.getOnlinePlayers().stream().map(Player::getUniqueId).collect(Collectors.toSet()), + url, + hash) .start(); } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/TaskUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/TaskUtils.java index d5d54f4bb..b7794392b 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/TaskUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/TaskUtils.java @@ -31,7 +31,8 @@ public final class TaskUtils { - private TaskUtils() {} + private TaskUtils() { + } public static @NotNull Future sync( @NotNull final MediaLibraryCore core, @NotNull final Callable task) { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/VideoFrameUtils.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/VideoFrameUtils.java index 903dcad9d..53cf5ea85 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/VideoFrameUtils.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/VideoFrameUtils.java @@ -54,7 +54,8 @@ public final class VideoFrameUtils { - private VideoFrameUtils() {} + private VideoFrameUtils() { + } public static int @NotNull [] toResizedColorArray( @NotNull final Picture frame, diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java index 63d45c929..6d466b144 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java @@ -160,7 +160,7 @@ private void setVLCPluginPath(@NotNull final Path path) { private boolean loadLibVLCLibrary() { try { final libvlc_instance_t instance = - libvlc_new(0, new StringArray(new String[] {"--reset-plugins-cache"})); + libvlc_new(0, new StringArray(new String[]{"--reset-plugins-cache"})); if (instance != null) { libvlc_release(instance); final LibVlcVersion version = new LibVlcVersion(); diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java index 6f856075a..2238bc1dc 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java @@ -88,7 +88,7 @@ public void loadNativeBinaries() throws IOException { private int mountDiskImage(@NotNull final Path dmg) throws IOException, InterruptedException { final CommandTask t = - new CommandTask(new String[] {"/usr/bin/hdiutil", "attach", dmg.toString()}, true); + new CommandTask(new String[]{"/usr/bin/hdiutil", "attach", dmg.toString()}, true); Logger.info("============= DMG INFORMATION ============="); Logger.info(t.getResult()); @@ -100,7 +100,7 @@ private int mountDiskImage(@NotNull final Path dmg) throws IOException, Interrup private int unmountDiskImage(@NotNull final Path path) throws IOException, InterruptedException { final CommandTask t = - new CommandTask(new String[] {"diskutil", "unmount", path.toString()}, true); + new CommandTask(new String[]{"diskutil", "unmount", path.toString()}, true); Logger.info("=========== UNMOUNT INFORMATION ==========="); Logger.info(t.getResult()); @@ -110,7 +110,7 @@ private int unmountDiskImage(@NotNull final Path path) throws IOException, Inter } private int changePermissions(@NotNull final Path path) throws IOException, InterruptedException { - return new CommandTask(new String[] {"chmod", "-R", "755", path.toString()}, true) + return new CommandTask(new String[]{"chmod", "-R", "755", path.toString()}, true) .getProcess() .waitFor(); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/unix/UnixNativeDiscovery.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/unix/UnixNativeDiscovery.java index 13351d1d9..34b688782 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/unix/UnixNativeDiscovery.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/unix/UnixNativeDiscovery.java @@ -47,5 +47,6 @@ public class UnixNativeDiscovery implements NativeDiscoveryAlgorithm { } @Override - public void onLibVlcFound(@NotNull final Path discoveredPath) {} + public void onLibVlcFound(@NotNull final Path discoveredPath) { + } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/WindowsNativeDiscovery.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/WindowsNativeDiscovery.java index e540d9fb9..8d95e082b 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/WindowsNativeDiscovery.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/WindowsNativeDiscovery.java @@ -47,5 +47,6 @@ public class WindowsNativeDiscovery implements NativeDiscoveryAlgorithm { } @Override - public void onLibVlcFound(@NotNull final Path discoveredPath) {} + public void onLibVlcFound(@NotNull final Path discoveredPath) { + } } diff --git a/main/src/test/java/io/github/pulsebeat02/ezmediacore/FFmpegVideoTest.java b/main/src/test/java/io/github/pulsebeat02/ezmediacore/FFmpegVideoTest.java index fdf44226b..9b6df25c4 100644 --- a/main/src/test/java/io/github/pulsebeat02/ezmediacore/FFmpegVideoTest.java +++ b/main/src/test/java/io/github/pulsebeat02/ezmediacore/FFmpegVideoTest.java @@ -67,7 +67,8 @@ private void init(@NotNull final Path path, @NotNull final Path input, final lon private FrameConsumer getFrameConsumer(final Consumer callback) { return new FrameConsumer() { @Override - public void consumeStreams(final List streams) {} + public void consumeStreams(final List streams) { + } @Override public void consume(final Frame frame) { diff --git a/main/src/test/java/io/github/pulsebeat02/ezmediacore/VLCDownloadTest.java b/main/src/test/java/io/github/pulsebeat02/ezmediacore/VLCDownloadTest.java index 93b12b720..42f15247b 100644 --- a/main/src/test/java/io/github/pulsebeat02/ezmediacore/VLCDownloadTest.java +++ b/main/src/test/java/io/github/pulsebeat02/ezmediacore/VLCDownloadTest.java @@ -4,5 +4,6 @@ public class VLCDownloadTest { - public static void main(final String[] args) throws IOException {} + public static void main(final String[] args) throws IOException { + } } diff --git a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/BadFileException.java b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/BadFileException.java index 7b31a8730..c41eb68d7 100644 --- a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/BadFileException.java +++ b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/BadFileException.java @@ -9,9 +9,11 @@ */ public class BadFileException extends Exception { - @Serial private static final long serialVersionUID = -8935110974026120897L; + @Serial + private static final long serialVersionUID = -8935110974026120897L; - public BadFileException() {} + public BadFileException() { + } public BadFileException(final String message) { super(message); diff --git a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/PushStreamException.java b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/PushStreamException.java index 65617d34b..ea8386752 100644 --- a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/PushStreamException.java +++ b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/PushStreamException.java @@ -9,9 +9,11 @@ */ public class PushStreamException extends RuntimeException { - @Serial private static final long serialVersionUID = 3516759721627203423L; + @Serial + private static final long serialVersionUID = 3516759721627203423L; - public PushStreamException() {} + public PushStreamException() { + } public PushStreamException(final String message) { super(message); diff --git a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/ReadStreamException.java b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/ReadStreamException.java index 6b31fcdee..063f32ff4 100644 --- a/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/ReadStreamException.java +++ b/main/src/test/java/io/github/pulsebeat02/ezmediacore/libshout/exception/ReadStreamException.java @@ -9,9 +9,11 @@ */ public class ReadStreamException extends RuntimeException { - @Serial private static final long serialVersionUID = 3531880196344252231L; + @Serial + private static final long serialVersionUID = 3531880196344252231L; - public ReadStreamException() {} + public ReadStreamException() { + } public ReadStreamException(final int code) { super("source stream code is " + code); From 42683b73d3c7ea76c2887af61a40cfeb318a102b Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sat, 2 Oct 2021 10:48:43 -0400 Subject: [PATCH 04/10] =?UTF-8?q?=E2=9C=A8=20Finished=20Locale=20(Code=20S?= =?UTF-8?q?tyle=20is=20Messy)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/DeluxeMediaPlugin.java | 26 +- .../DeluxeMediaPluginBootstrap.java | 25 +- .../deluxemediaplugin/bot/DiscordLocale.java | 136 +++++++ .../bot/audio/BufferedAudioSendHandler.java | 82 ----- .../bot/audio/MusicManager.java | 57 +-- .../bot/command/ConnectAudioCommand.java | 11 +- .../bot/command/DisconnectAudioCommand.java | 11 +- .../bot/command/DiscordBaseCommand.java | 10 +- .../bot/command/DiscordCommand.java | 45 +++ .../bot/command/PlayAudioCommand.java | 20 +- .../bot/command/StopAudioCommand.java | 8 +- .../command/ffmpeg/FFmpegCommand.java | 4 +- .../command/gui/ScreenBuilderGui.java | 23 +- .../config/BotConfiguration.java | 55 ++- .../config/ConfigHolder.java | 62 ++++ .../config/ConfigurationProvider.java | 41 +-- .../config/EncoderConfiguration.java | 16 +- .../config/HttpAudioConfiguration.java | 4 +- .../config/HttpConfiguration.java | 2 +- .../config/PersistentPictureManager.java | 30 +- .../executors/ExecutorProvider.java | 3 + .../deluxemediaplugin/json/DataHolder.java | 48 +++ .../deluxemediaplugin/json/DataProvider.java | 21 +- .../json/MediaAttributesData.java | 4 +- .../deluxemediaplugin/message/Locale.java | 339 ++++++++++-------- .../update/UpdateChecker.java | 4 +- .../deluxemediaplugin/utility/ChatUtils.java | 31 +- .../utility/CommandUtils.java | 9 +- .../{WrappedInteger.java => MutableInt.java} | 20 +- .../ezmediacore/utility/PluginUsageTips.java | 16 - 30 files changed, 636 insertions(+), 527 deletions(-) create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/DiscordLocale.java delete mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/BufferedAudioSendHandler.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordCommand.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigHolder.java create mode 100644 deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java rename deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/{WrappedInteger.java => MutableInt.java} (79%) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 97a93f93b..1053d8257 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -24,9 +24,6 @@ package io.github.pulsebeat02.deluxemediaplugin; -import static net.kyori.adventure.text.Component.text; -import static net.kyori.adventure.text.format.NamedTextColor.BLUE; - import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.command.BaseCommand; import io.github.pulsebeat02.deluxemediaplugin.command.CommandHandler; @@ -48,8 +45,6 @@ import io.github.pulsebeat02.ezmediacore.sneaky.ThrowingConsumer; import io.github.pulsebeat02.ezmediacore.utility.FileUtils; import java.io.IOException; -import java.util.Arrays; -import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import net.kyori.adventure.audience.Audience; @@ -83,7 +78,7 @@ public DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { public void enable() { this.audiences = BukkitAudiences.create(this.plugin); this.console = this.audiences.console(); - this.printLogo(); + this.console.sendMessage(Locale.PLUGIN_LOGO.build()); this.console.sendMessage(Locale.ENABLE_PLUGIN.build()); this.console.sendMessage(Locale.EMC_INIT.build()); this.startLibrary(); @@ -108,8 +103,7 @@ public void disable() throws Exception { this.console.sendMessage(Locale.GOODBYE.build()); } - public void load() { - } + public void load() {} private void startLibrary() { try { @@ -130,22 +124,6 @@ private void checkUpdates() { new UpdateChecker(this).check(); } - private void printLogo() { - final List logo = - Arrays.asList( - " _____ _ __ __ _ _ _____ _ _ ", - " | __ \\ | | | \\/ | | (_) | __ \\| | (_) ", - " | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ ", - " | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\ ", - " | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | |", - " |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_|", - " __/ | ", - " |___/ "); - for (final String line : logo) { - this.audiences.console().sendMessage(text(line, BLUE)); - } - } - private void disableBot() { if (this.mediaBot != null) { this.mediaBot.getJDA().shutdown(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java index dc7d45345..902431bbf 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java @@ -23,6 +23,7 @@ */ package io.github.pulsebeat02.deluxemediaplugin; +import io.github.pulsebeat02.deluxemediaplugin.message.Sender; import io.github.slimjar.app.builder.ApplicationBuilder; import java.io.IOException; import java.net.URISyntaxException; @@ -37,7 +38,14 @@ public final class DeluxeMediaPluginBootstrap extends JavaPlugin { @Override public void onLoad() { final Logger logger = this.getLogger(); - logger.info("Loading DeluxeMediaPlugin dependencies... this may take a minute!"); + logger.info(InternalLocale.SLIMJAR_LOAD.build()); + this.buildApplication(); + logger.info(InternalLocale.SLIMJAR_FINISH.build()); + this.plugin = new DeluxeMediaPlugin(this); + this.plugin.load(); + } + + private void buildApplication() { try { ApplicationBuilder.appending("DeluxeMediaPlugin").build(); } catch (final IOException @@ -46,9 +54,6 @@ public void onLoad() { | ReflectiveOperationException e) { e.printStackTrace(); } - logger.info("Finished loading DeluxeMediaPlugin dependencies!"); - this.plugin = new DeluxeMediaPlugin(this); - this.plugin.load(); } @Override @@ -64,4 +69,16 @@ public void onDisable() { e.printStackTrace(); } } + + interface InternalLocale { + + NullComponent SLIMJAR_LOAD = + () -> "Loading DeluxeMediaPlugin dependencies... this may take a minute!"; + NullComponent SLIMJAR_FINISH = () -> "Finished loading DeluxeMediaPlugin dependencies!"; + + @FunctionalInterface + interface NullComponent { + String build(); + } + } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/DiscordLocale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/DiscordLocale.java new file mode 100644 index 000000000..343fa9f64 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/DiscordLocale.java @@ -0,0 +1,136 @@ +/* + * MIT License + * + * Copyright (c) 2021 Brandon Li + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.pulsebeat02.deluxemediaplugin.bot; + +import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; +import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; +import io.github.pulsebeat02.deluxemediaplugin.message.Sender; +import java.text.SimpleDateFormat; +import java.util.Date; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; + +public interface DiscordLocale { + + SimpleDateFormat HOURS_MINUTES_SECONDS = new SimpleDateFormat("mm:ss:SSS"); + + NullComponent CONNECT_VC_EMBED = + () -> + new EmbedBuilder() + .setTitle("Audio Voice Channel Connection") + .setDescription("Connected to voice channel!") + .build(); + + NullComponent DC_VC_EMBED = + () -> + new EmbedBuilder() + .setTitle("Audio Voice Channel Connection") + .setDescription("Left voice channel!") + .build(); + + NullComponent ERR_INVALID_MRL = + () -> + new EmbedBuilder() + .setTitle("User Error") + .setDescription("Invalid arguments! Specify a media source argument to play.") + .build(); + + NullComponent ERR_LAVAPLAYER = + () -> + new EmbedBuilder() + .setTitle("Severe Player Error Occurred!") + .setDescription( + "An error occurred! Check console for possible exceptions or warnings.") + .build(); + + NullComponent PAUSE_AUDIO = + () -> new EmbedBuilder().setTitle("Audio Stop").setDescription("Stopped Audio!").build(); + + UniComponent LOADED_TRACK = + (info) -> + new EmbedBuilder() + .setTitle(info.title, info.uri) + .addField("Author", info.author, false) + .addField( + "Playtime Length", HOURS_MINUTES_SECONDS.format(new Date(info.length)), false) + .addField("Stream", info.isStream ? "Yes" : "No", false) + .build(); + + UniComponent ERR_INVALID_TRACK = + (url) -> + new EmbedBuilder() + .setTitle("Media Error") + .setDescription("Could not find song %s!".formatted(url)) + .build(); + + TriComponent LOADED_PLAYLIST = + (ms, audioPlaylist, url) -> + new EmbedBuilder() + .setTitle(audioPlaylist.getName(), url) + .addField("Playtime Length", HOURS_MINUTES_SECONDS.format(new Date(ms)), false) + .build(); + + @FunctionalInterface + interface NullComponent { + + MessageEmbed build(); + } + + @FunctionalInterface + interface UniComponent { + + MessageEmbed build(A0 arg0); + } + + @FunctionalInterface + interface BiComponent { + + MessageEmbed build(A0 arg0, A1 arg1); + } + + @FunctionalInterface + interface TriComponent { + + MessageEmbed build(A0 arg0, A1 arg1, A2 arg2); + } + + @FunctionalInterface + interface QuadComponent { + + MessageEmbed build(A0 arg0, A1 arg1, A2 arg2, A3 arg3); + } + + @FunctionalInterface + interface PentaComponent { + + MessageEmbed build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4); + } + + @FunctionalInterface + interface HexaComponent { + + MessageEmbed build(A0 arg0, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5); + } +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/BufferedAudioSendHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/BufferedAudioSendHandler.java deleted file mode 100644 index 2a11144ec..000000000 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/BufferedAudioSendHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2021 Brandon Li - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package io.github.pulsebeat02.deluxemediaplugin.bot.audio; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.ByteBuffer; -import java.util.Queue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; -import net.dv8tion.jda.api.audio.AudioSendHandler; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class BufferedAudioSendHandler implements AudioSendHandler { - - private final Queue packets; - private final ByteArrayOutputStream output; - private final InputStream input; - - public BufferedAudioSendHandler(@NotNull final String url) throws IOException { - this.packets = new ConcurrentLinkedQueue<>(); - this.output = new ByteArrayOutputStream(); - this.input = new URL(url).openStream(); - } - - public void startListening() { - CompletableFuture.runAsync( - () -> { - try { - final byte[] chunk = new byte[4096]; - int bytesRead; - while ((bytesRead = this.input.read(chunk)) > 0) { - this.output.write(chunk, 0, bytesRead); - } - this.packets.add(ByteBuffer.wrap(chunk)); - } catch (final IOException e) { - e.printStackTrace(); - } - }); - } - - @Override - public boolean canProvide() { - return this.packets.size() < 15; - } - - @Nullable - @Override - public ByteBuffer provide20MsAudio() { - return this.packets.poll(); - } - - @Override - public boolean isOpus() { - return false; - } -} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java index aa57c33b7..7c04c53db 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java @@ -32,12 +32,10 @@ import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist; import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo; +import io.github.pulsebeat02.deluxemediaplugin.bot.DiscordLocale; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.HashMap; import java.util.Map; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.VoiceChannel; @@ -47,12 +45,6 @@ public class MusicManager { - private static final SimpleDateFormat HOURS_MINUTES_SECONDS; - - static { - HOURS_MINUTES_SECONDS = new SimpleDateFormat("mm:ss:SSS"); - } - private final Map musicGuildManager; private final MediaBot bot; private final AudioPlayerManager playerManager; @@ -66,9 +58,7 @@ public MusicManager(@NotNull final MediaBot bot) { AudioSourceManagers.registerLocalSource(this.playerManager); } - /** - * Join's Voice Chanel and set's log channel. - */ + /** Join's Voice Chanel and set's log channel. */ public void joinVoiceChannel() { final Guild guild = this.bot.getGuild(); final long id = guild.getIdLong(); @@ -82,9 +72,7 @@ public void joinVoiceChannel() { audio.openAudioConnection(voiceChannel); } - /** - * Leave's Voice Channel. - */ + /** Leave's Voice Channel. */ public void leaveVoiceChannel() { final Guild guild = this.bot.getGuild(); guild.getAudioManager().closeAudioConnection(); @@ -98,7 +86,7 @@ public void addTrack(@NotNull final String url) { /** * Adds track. * - * @param url Load's Song. + * @param url Load's Song. * @param channel Channel to send message. */ public void addTrack(@Nullable final MessageChannel channel, @NotNull final String url) { @@ -115,18 +103,7 @@ public void trackLoaded(final AudioTrack audioTrack) { .getTrackScheduler() .queueSong(audioTrack); if (channel != null) { - channel - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle(info.title, info.uri) - .addField("Author", info.author, false) - .addField( - "Playtime Length", - HOURS_MINUTES_SECONDS.format(new Date(info.length)), - false) - .addField("Stream", info.isStream ? "Yes" : "No", false) - .build()) - .queue(); + channel.sendMessageEmbeds(DiscordLocale.LOADED_TRACK.build(info)).queue(); } } @@ -143,12 +120,7 @@ public void playlistLoaded(final AudioPlaylist audioPlaylist) { } if (channel != null) { channel - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle(audioPlaylist.getName(), url) - .addField( - "Playtime Length", HOURS_MINUTES_SECONDS.format(new Date(ms)), false) - .build()) + .sendMessageEmbeds(DiscordLocale.LOADED_PLAYLIST.build(ms, audioPlaylist, url)) .queue(); } } @@ -156,27 +128,14 @@ public void playlistLoaded(final AudioPlaylist audioPlaylist) { @Override public void noMatches() { if (channel != null) { - channel - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("Media Error") - .setDescription("Could not find song %s!".formatted(url)) - .build()) - .queue(); + channel.sendMessageEmbeds(DiscordLocale.ERR_INVALID_TRACK.build(url)).queue(); } } @Override public void loadFailed(final FriendlyException e) { if (channel != null) { - channel - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("Severe Player Error Occurred!") - .setDescription( - "An error occurred! Check console for possible exceptions or warnings.") - .build()) - .queue(); + channel.sendMessageEmbeds(DiscordLocale.ERR_LAVAPLAYER.build()).queue(); } } }); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/ConnectAudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/ConnectAudioCommand.java index bc610b4af..9aa4a2266 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/ConnectAudioCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/ConnectAudioCommand.java @@ -23,10 +23,10 @@ */ package io.github.pulsebeat02.deluxemediaplugin.bot.command; +import io.github.pulsebeat02.deluxemediaplugin.bot.DiscordLocale; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.bot.audio.MusicManager; import java.util.Set; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,14 +41,7 @@ public ConnectAudioCommand(@NotNull final MediaBot bot) { public boolean execute(@NotNull final Message executor, final String @Nullable [] arguments) { final MusicManager manager = this.getBot().getMusicManager(); manager.joinVoiceChannel(); - executor - .getChannel() - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("Audio Voice Channel Connection") - .setDescription("Connected to voice channel!") - .build()) - .queue(); + executor.getChannel().sendMessageEmbeds(DiscordLocale.CONNECT_VC_EMBED.build()).queue(); return true; } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DisconnectAudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DisconnectAudioCommand.java index 5410b064c..29ea000c6 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DisconnectAudioCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DisconnectAudioCommand.java @@ -23,10 +23,10 @@ */ package io.github.pulsebeat02.deluxemediaplugin.bot.command; +import io.github.pulsebeat02.deluxemediaplugin.bot.DiscordLocale; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.bot.audio.MusicManager; import java.util.Set; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,14 +41,7 @@ public DisconnectAudioCommand(@NotNull final MediaBot bot) { public boolean execute(@NotNull final Message executor, final String @Nullable [] arguments) { final MusicManager manager = this.getBot().getMusicManager(); manager.leaveVoiceChannel(); - executor - .getChannel() - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("Audio Voice Channel Connection") - .setDescription("Left voice channel!") - .build()) - .queue(); + executor.getChannel().sendMessageEmbeds(DiscordLocale.DC_VC_EMBED.build()).queue(); return true; } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordBaseCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordBaseCommand.java index 45551522b..62e52fdb5 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordBaseCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordBaseCommand.java @@ -25,11 +25,9 @@ import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import java.util.Collection; -import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -public abstract class DiscordBaseCommand { +public abstract class DiscordBaseCommand implements DiscordCommand { private final MediaBot bot; private final String command; @@ -44,17 +42,17 @@ public DiscordBaseCommand( this.subcommands = subcommands; } - public abstract boolean execute( - @NotNull final Message executor, final String @Nullable [] arguments); - + @Override public @NotNull String getCommand() { return this.command; } + @Override public @NotNull Collection getArguments() { return this.subcommands; } + @Override public @NotNull MediaBot getBot() { return this.bot; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordCommand.java new file mode 100644 index 000000000..643960a16 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/DiscordCommand.java @@ -0,0 +1,45 @@ +/* + * MIT License + * + * Copyright (c) 2021 Brandon Li + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.pulsebeat02.deluxemediaplugin.bot.command; + +import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; +import java.util.Collection; +import net.dv8tion.jda.api.entities.Message; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface DiscordCommand { + + boolean execute(@NotNull final Message executor, final String @Nullable [] arguments); + + @NotNull + String getCommand(); + + @NotNull + Collection getArguments(); + + @NotNull + MediaBot getBot(); +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/PlayAudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/PlayAudioCommand.java index fdbc7add7..55911715d 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/PlayAudioCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/PlayAudioCommand.java @@ -23,10 +23,10 @@ */ package io.github.pulsebeat02.deluxemediaplugin.bot.command; +import io.github.pulsebeat02.deluxemediaplugin.bot.DiscordLocale; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.bot.audio.MusicManager; import java.util.Set; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,27 +40,13 @@ public PlayAudioCommand(@NotNull final MediaBot bot) { @Override public boolean execute(@NotNull final Message executor, final String @Nullable [] arguments) { if (arguments == null || arguments.length < 1) { - executor - .getChannel() - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("User Error") - .setDescription("Invalid arguments! Specify a media source argument to play.") - .build()) - .queue(); + executor.getChannel().sendMessageEmbeds(DiscordLocale.ERR_INVALID_MRL.build()).queue(); return false; } final MusicManager manager = this.getBot().getMusicManager(); manager.joinVoiceChannel(); manager.addTrack(executor.getChannel(), arguments[0]); - executor - .getChannel() - .sendMessageEmbeds( - new EmbedBuilder() - .setTitle("Audio Voice Channel Connection") - .setDescription("Connected to voice channel!") - .build()) - .queue(); + executor.getChannel().sendMessageEmbeds(DiscordLocale.CONNECT_VC_EMBED.build()).queue(); return true; } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/StopAudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/StopAudioCommand.java index 903e898b0..a6d13bb90 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/StopAudioCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/command/StopAudioCommand.java @@ -23,10 +23,10 @@ */ package io.github.pulsebeat02.deluxemediaplugin.bot.command; +import io.github.pulsebeat02.deluxemediaplugin.bot.DiscordLocale; import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.bot.audio.MusicManager; import java.util.Set; -import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,11 +41,7 @@ public StopAudioCommand(@NotNull final MediaBot bot) { public boolean execute(@NotNull final Message executor, final String @Nullable [] arguments) { final MusicManager manager = this.getBot().getMusicManager(); manager.getPlayerManager().shutdown(); - executor - .getChannel() - .sendMessageEmbeds( - new EmbedBuilder().setTitle("Audio Stop").setDescription("Stopped Audio!").build()) - .queue(); + executor.getChannel().sendMessageEmbeds(DiscordLocale.PAUSE_AUDIO.build()).queue(); return true; } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java index 0749e836a..eac9b8bc5 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegCommand.java @@ -25,8 +25,6 @@ package io.github.pulsebeat02.deluxemediaplugin.command.ffmpeg; import static com.mojang.brigadier.Command.SINGLE_SUCCESS; -import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.ffmpeg; -import static net.kyori.adventure.text.Component.text; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.tree.LiteralCommandNode; @@ -78,7 +76,7 @@ private int listFFmpegArguments(@NotNull final CommandContext con private int runFFmpegProcess(@NotNull final CommandContext context) { final Audience audience = this.plugin().audience().sender(context.getSource()); - this.ffmpeg.executeWithLogging(s -> audience.sendMessage(ffmpeg(text(s)))); + this.ffmpeg.executeWithLogging(s -> audience.sendMessage(Locale.FFMPEG_PROCESS.build(s))); audience.sendMessage(Locale.FFMPEG_EXEC.build()); return SINGLE_SUCCESS; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ScreenBuilderGui.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ScreenBuilderGui.java index ebd3b56f3..642bb7423 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ScreenBuilderGui.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ScreenBuilderGui.java @@ -24,7 +24,6 @@ package io.github.pulsebeat02.deluxemediaplugin.command.gui; -import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format; import static net.kyori.adventure.text.Component.join; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.JoinConfiguration.noSeparators; @@ -38,7 +37,8 @@ import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; import com.github.stefvanschie.inventoryframework.pane.StaticPane; import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; -import io.github.pulsebeat02.deluxemediaplugin.utility.WrappedInteger; +import io.github.pulsebeat02.deluxemediaplugin.message.Locale; +import io.github.pulsebeat02.deluxemediaplugin.utility.MutableInt; import io.github.pulsebeat02.ezmediacore.utility.MapUtils; import org.bukkit.Material; import org.bukkit.Sound; @@ -53,9 +53,9 @@ public final class ScreenBuilderGui { private final StaticPane pane; private final Player viewer; private final DeluxeMediaPlugin plugin; - private final WrappedInteger width; - private final WrappedInteger height; - private final WrappedInteger id; + private final MutableInt width; + private final MutableInt height; + private final MutableInt id; private Material material; public ScreenBuilderGui(@NotNull final DeluxeMediaPlugin plugin, @NotNull final Player player) { @@ -64,9 +64,9 @@ public ScreenBuilderGui(@NotNull final DeluxeMediaPlugin plugin, @NotNull final this.plugin = plugin; this.material = Material.OAK_PLANKS; this.viewer = player; - this.width = WrappedInteger.ofInteger(5); - this.height = WrappedInteger.ofInteger(5); - this.id = WrappedInteger.ofInteger(0); + this.width = MutableInt.ofInteger(5); + this.height = MutableInt.ofInteger(5); + this.id = MutableInt.ofInteger(0); this.initialize(); this.gui.show(player); } @@ -96,10 +96,7 @@ private void initialize() { this.width.getNumber(), this.height.getNumber(), this.id.getNumber()); - this.plugin - .audience() - .sender(this.viewer) - .sendMessage(format(text("Successfully built your new screen!", GREEN))); + this.plugin.audience().sender(this.viewer).sendMessage(Locale.BUILT_SCREEN.build()); this.viewer.playSound(this.viewer.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 10, 1); }) .build(); @@ -107,7 +104,7 @@ private void initialize() { @Contract("_, _, _ -> new") private @NotNull GuiItem getGuiItem( - @NotNull final ItemStack stack, @NotNull final WrappedInteger update, final boolean add) { + @NotNull final ItemStack stack, @NotNull final MutableInt update, final boolean add) { return new GuiItem( stack, (event) -> { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java index 8caf0ef90..b5c1870e0 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java @@ -28,8 +28,6 @@ import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import io.github.pulsebeat02.deluxemediaplugin.message.Locale; import java.io.IOException; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; import javax.security.auth.login.LoginException; import net.kyori.adventure.audience.Audience; import org.bukkit.configuration.file.FileConfiguration; @@ -45,45 +43,40 @@ public BotConfiguration(@NotNull final DeluxeMediaPlugin plugin) throws IOExcept } @Override - void deserialize() { + public void deserialize() throws IOException { final FileConfiguration configuration = this.getFileConfiguration(); configuration.set("token", this.bot.getJDA().getToken()); this.saveConfig(); } @Override - void serialize() throws IOException { + public void serialize() { final DeluxeMediaPlugin plugin = this.getPlugin(); final FileConfiguration configuration = this.getFileConfiguration(); - final AtomicBoolean invalid = new AtomicBoolean(false); final Audience console = plugin.getLogger(); - final String token = - Objects.requireNonNullElseGet( - configuration.getString("token"), - () -> { - console.sendMessage(Locale.ERR_BOT_TOKEN.build()); - invalid.set(true); - return "null"; - }); - final String guild = - Objects.requireNonNullElseGet( - configuration.getString("guild-id"), - () -> { - console.sendMessage(Locale.ERR_GUILD_TOKEN.build()); - invalid.set(true); - return "null"; - }); - final String voicechannel = - Objects.requireNonNullElseGet( - configuration.getString("voice-chat-id"), - () -> { - console.sendMessage(Locale.ERR_VC_ID.build()); - invalid.set(true); - return "null"; - }); - if (!invalid.get()) { + + boolean invalid = false; + final String token = configuration.getString("token"); + if (token == null) { + console.sendMessage(Locale.ERR_BOT_TOKEN.build()); + invalid = true; + } + + final String guild = configuration.getString("guild-id"); + if (guild == null) { + console.sendMessage(Locale.ERR_GUILD_TOKEN.build()); + invalid = true; + } + + final String vc = configuration.getString("voice-chat-id"); + if (vc == null) { + console.sendMessage(Locale.ERR_VC_ID.build()); + invalid = true; + } + + if (invalid) { try { - this.bot = new MediaBot(token, guild, voicechannel); + this.bot = new MediaBot(token, guild, vc); } catch (final LoginException | InterruptedException e) { console.sendMessage(Locale.ERR_INVALID_DISCORD_BOT.build()); e.printStackTrace(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigHolder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigHolder.java new file mode 100644 index 000000000..fbbaff633 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigHolder.java @@ -0,0 +1,62 @@ +/* + * MIT License + * + * Copyright (c) 2021 Brandon Li + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.pulsebeat02.deluxemediaplugin.config; + +import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import java.io.IOException; +import java.nio.file.Path; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; + +public interface ConfigHolder { + + void reloadConfig(); + + FileConfiguration getConfig(); + + void saveConfig() throws IOException; + + void saveDefaultConfig(); + + void read() throws IOException; + + void deserialize() throws IOException; + + void serialize() throws IOException; + + T getSerializedValue(); + + @NotNull + DeluxeMediaPlugin getPlugin(); + + @NotNull + String getFileName(); + + @NotNull + Path getConfigFile(); + + @NotNull + FileConfiguration getFileConfiguration(); +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java index 379cab431..71f663122 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/ConfigurationProvider.java @@ -30,14 +30,12 @@ import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; -import java.util.logging.Level; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -public abstract class ConfigurationProvider { +public abstract class ConfigurationProvider implements ConfigHolder { private final DeluxeMediaPlugin plugin; private final JavaPlugin loader; @@ -46,14 +44,15 @@ public abstract class ConfigurationProvider { private FileConfiguration fileConfiguration; - public ConfigurationProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) - throws IOException { + public ConfigurationProvider( + @NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) { this.plugin = plugin; this.name = name; this.loader = plugin.getBootstrap(); this.config = this.loader.getDataFolder().toPath().resolve(this.name); } + @Override public void reloadConfig() { this.fileConfiguration = YamlConfiguration.loadConfiguration(this.config.toFile()); final InputStream defConfigStream = this.loader.getResource(this.name); @@ -64,6 +63,7 @@ public void reloadConfig() { } } + @Override public FileConfiguration getConfig() { if (this.fileConfiguration == null) { this.reloadConfig(); @@ -71,52 +71,43 @@ public FileConfiguration getConfig() { return this.fileConfiguration; } - public void saveConfig() { + @Override + public void saveConfig() throws IOException { if (this.fileConfiguration != null && this.config != null) { - try { - this.getConfig().save(this.config.toFile()); - } catch (final IOException e) { - this.loader - .getLogger() - .log(Level.SEVERE, "Could not save config to %s".formatted(this.config), e); - } + this.getConfig().save(this.config.toFile()); } } + @Override public void saveDefaultConfig() { if (!Files.exists(this.config)) { this.loader.saveResource(this.name, false); } } - public void read() { + @Override + public void read() throws IOException { this.saveDefaultConfig(); this.getConfig(); - try { - this.serialize(); - } catch (final IOException e) { - e.printStackTrace(); - } + this.serialize(); } - abstract void deserialize(); - - abstract void serialize() throws IOException; - - abstract @Nullable T getSerializedValue(); - + @Override public @NotNull DeluxeMediaPlugin getPlugin() { return this.plugin; } + @Override public @NotNull String getFileName() { return this.name; } + @Override public @NotNull Path getConfigFile() { return this.config; } + @Override public @NotNull FileConfiguration getFileConfiguration() { return this.fileConfiguration; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/EncoderConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/EncoderConfiguration.java index 80d58c908..620f497c8 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/EncoderConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/EncoderConfiguration.java @@ -40,7 +40,7 @@ public EncoderConfiguration(@NotNull final DeluxeMediaPlugin plugin) throws IOEx } @Override - void deserialize() { + public void deserialize() throws IOException { final FileConfiguration configuration = this.getFileConfiguration(); configuration.set("bitrate", this.settings.getBitrate()); configuration.set("channels", this.settings.getChannels()); @@ -50,13 +50,15 @@ void deserialize() { } @Override - void serialize() { + public void serialize() throws IOException { final FileConfiguration configuration = this.getFileConfiguration(); - final int bitrate = configuration.getInt("bitrate"); - final int channels = configuration.getInt("channels"); - final int samplingRate = configuration.getInt("sampling-rate"); - final int volume = configuration.getInt("volume"); - this.settings = new AudioAttributes("libvorbis", bitrate, channels, samplingRate, volume); + this.settings = + new AudioAttributes( + "libvorbis", + configuration.getInt("bitrate"), + configuration.getInt("channels"), + configuration.getInt("sampling-rate"), + configuration.getInt("volume")); } @Override diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpAudioConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpAudioConfiguration.java index 023bd677e..9022e3d92 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpAudioConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpAudioConfiguration.java @@ -39,12 +39,12 @@ public HttpAudioConfiguration(@NotNull final DeluxeMediaPlugin plugin) throws IO } @Override - void deserialize() { + public void deserialize() throws IOException { this.saveConfig(); } @Override - void serialize() throws IOException { + public void serialize() throws IOException { final FileConfiguration configuration = this.getFileConfiguration(); final boolean enabled = configuration.getBoolean("enabled"); final String ip = configuration.getString("ip"); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpConfiguration.java index bacb7b530..6ce29bf98 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/HttpConfiguration.java @@ -42,7 +42,7 @@ public HttpConfiguration(@NotNull final DeluxeMediaPlugin plugin) throws IOExcep } @Override - public void deserialize() { + public void deserialize() throws IOException { final FileConfiguration configuration = this.getFileConfiguration(); configuration.set("enabled", this.enabled); configuration.set("port", this.daemon.getDaemon().getPort()); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/PersistentPictureManager.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/PersistentPictureManager.java index 7dfdb022c..f0bf14f43 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/PersistentPictureManager.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/PersistentPictureManager.java @@ -25,6 +25,7 @@ package io.github.pulsebeat02.deluxemediaplugin.config; import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import io.github.pulsebeat02.deluxemediaplugin.executors.ExecutorProvider; import io.github.pulsebeat02.ezmediacore.dimension.ImmutableDimension; import io.github.pulsebeat02.ezmediacore.image.DynamicImage; import io.github.pulsebeat02.ezmediacore.image.Image; @@ -34,21 +35,12 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; public final class PersistentPictureManager { - private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE; - - static { - SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(1); - } - private final DeluxeMediaPlugin plugin; private final JavaPlugin loader; private final PersistentImageStorage storage; @@ -64,7 +56,16 @@ public PersistentPictureManager(@NotNull final DeluxeMediaPlugin plugin) throws } public void startTask() { - SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(this::save, 0, 5, TimeUnit.MINUTES); + ExecutorProvider.SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate( + this::scheduledSave, 0, 5, TimeUnit.MINUTES); + } + + private void scheduledSave() { + try { + this.save(); + } catch (final IOException e) { + e.printStackTrace(); + } } public void addPhoto( @@ -83,13 +84,8 @@ public void addGif( this.images.add(new DynamicImage(this.plugin.library(), file, maps, dimension)); } - public void save() { - try { - this.storage.serialize(this.images); - } catch (final IOException e) { - this.loader.getLogger().log(Level.SEVERE, "There was an issue saving images!"); - e.printStackTrace(); - } + public void save() throws IOException { + this.storage.serialize(this.images); } public @NotNull DeluxeMediaPlugin getPlugin() { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java index 7d7a8a464..a638010a9 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java @@ -26,12 +26,15 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; public class ExecutorProvider { public static final Executor STREAM_THREAD_EXECUTOR; + public static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE; static { STREAM_THREAD_EXECUTOR = Executors.newFixedThreadPool(4); + SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(1); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java new file mode 100644 index 000000000..35bc10035 --- /dev/null +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java @@ -0,0 +1,48 @@ +/* + * MIT License + * + * Copyright (c) 2021 Brandon Li + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.pulsebeat02.deluxemediaplugin.json; + +import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import java.io.IOException; +import java.nio.file.Path; +import org.jetbrains.annotations.NotNull; + +public interface DataHolder { + + void deserialize() throws IOException; + + void serialize() throws IOException; + + T getSerializedValue(); + + @NotNull + DeluxeMediaPlugin getPlugin(); + + @NotNull + String getFileName(); + + @NotNull + Path getConfigFile(); +} diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java index c7b53531f..94daeb914 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java @@ -30,46 +30,55 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public abstract class DataProvider { +public abstract class DataProvider implements DataHolder { private final DeluxeMediaPlugin plugin; private final String name; private final Path path; private T object; - public DataProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) - throws IOException { + public DataProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) { this.plugin = plugin; this.name = name; this.path = plugin.getBootstrap().getDataFolder().toPath().resolve(this.name); } + @Override public void deserialize() throws IOException { GsonProvider.getGson().toJson(this.object, Files.newBufferedWriter(this.path)); } + @Override public void serialize() throws IOException { - if (!Files.exists(this.path)) { - this.plugin.getBootstrap().saveResource(this.name, false); - } + this.saveConfig(); this.object = (T) GsonProvider.getGson() .fromJson(Files.newBufferedReader(this.path), this.object.getClass()); } + private void saveConfig() { + if (!Files.exists(this.path)) { + this.plugin.getBootstrap().saveResource(this.name, false); + } + } + + @Override public @Nullable T getSerializedValue() { return this.object; } + @Override public @NotNull DeluxeMediaPlugin getPlugin() { return this.plugin; } + @Override public @NotNull String getFileName() { return this.name; } + @Override public @NotNull Path getConfigFile() { return this.path; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java index 616c9fe38..3219dd0a0 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java @@ -25,13 +25,11 @@ import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; import io.github.pulsebeat02.deluxemediaplugin.command.video.VideoCommandAttributes; -import java.io.IOException; import org.jetbrains.annotations.NotNull; public class MediaAttributesData extends DataProvider { - public MediaAttributesData( - @NotNull final DeluxeMediaPlugin plugin) throws IOException { + public MediaAttributesData(@NotNull final DeluxeMediaPlugin plugin) { super(plugin, "video-attributes.json"); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java index 4055d4316..7f71341ed 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java @@ -24,7 +24,6 @@ package io.github.pulsebeat02.deluxemediaplugin.message; -import static io.github.pulsebeat02.deluxemediaplugin.utility.ChatUtils.format; import static net.kyori.adventure.text.Component.join; import static net.kyori.adventure.text.Component.newline; import static net.kyori.adventure.text.Component.space; @@ -33,6 +32,7 @@ import static net.kyori.adventure.text.event.ClickEvent.openUrl; import static net.kyori.adventure.text.event.ClickEvent.runCommand; import static net.kyori.adventure.text.format.NamedTextColor.AQUA; +import static net.kyori.adventure.text.format.NamedTextColor.BLUE; import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; import static net.kyori.adventure.text.format.NamedTextColor.GRAY; @@ -43,6 +43,8 @@ import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting; import io.github.pulsebeat02.deluxemediaplugin.command.image.ImageMrlType; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.function.Function; import net.kyori.adventure.text.Component; @@ -52,11 +54,8 @@ public interface Locale { - Component NEW_LINE = Component.newline(); - Component SPACE = Component.space(); - UniComponent REQUIRED_ARGUMENT = - argument -> + (argument) -> text() .color(DARK_GRAY) .append(text("<")) @@ -65,7 +64,7 @@ public interface Locale { .build(); UniComponent OPTIONAL_ARGUMENT = - argument -> + (argument) -> text() .color(DARK_GRAY) .append(text("[")) @@ -73,108 +72,107 @@ public interface Locale { .append(text("]")) .build(); - NullComponent - - ENABLE_PLUGIN = () -> join(separator(text(" ")), + NullComponent ENABLE_PLUGIN = () -> format(join(separator(text(" ")), text("Running DeluxeMediaPlugin", AQUA), text("[BETA]", GOLD), - text("1.0.0", AQUA)), - EMC_INIT = () -> text("Loading EzMediaCore instance... this may take some time!"), - WELCOME = () -> text(""" + text("1.0.0", AQUA))); + NullComponent EMC_INIT = () -> format(text("Loading EzMediaCore instance... this may take some time!")); + NullComponent WELCOME = () -> format(text(""" Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for support at my Discord! (https://discord.gg/MgqRKvycMC) - """), - - DISABLE_PLUGIN = () -> text("DeluxeMediaPlugin is shutting down!"), - GOOD_EMC_SHUTDOWN = () -> text("Successfully shutdown MinecraftMediaLibrary instance!"), - GOODBYE = () -> text("Good Bye! :("), - - FIN_EMC_INIT = () -> text("Finished loading MinecraftMediaLibrary instance!"), - FIN_PERSISTENT_INIT = () -> text("Finished loading persistent data!"), - FIN_COMMANDS_INIT = () -> text("Finished registering plugin commands!"), - FIN_METRICS_INIT = () -> text("Finished loading Metrics data!"), - FIN_PLUGIN_INIT = () -> text("Finished loading DeluxeMediaPlugin!"), - - RUNNING_LATEST_PLUGIN = () -> text( - "You are currently running the latest version of DeluxeMediaPlugin."), - - ERR_EMC_INIT = () -> text("There was a severe issue while loading the EzMediaCore instance!", - RED), - ERR_PERSISTENT_INIT = () -> text( - "A severe issue occurred while reading data from configuration files!", RED), - ERR_EMC_SHUTDOWN = () -> text("EzMediaCore instance is null... something fishy is going on.", - RED), - ERR_NO_MRL = () -> text("File or URL not specified!", RED), - ERR_INVALID_MRL = () -> text("Invalid MRL link! Not supported!", RED), - ERR_RESOURCEPACK_WRAP = () -> text("Failed to wrap resourcepack!", RED), - ERR_NO_RESOURCEPACK = () -> text("Please load a resourcepack first!", RED), - ERR_INVALID_AUDIO_STATE = () -> text( - "Please wait for the previous audio to extract first before loading another one!", RED), - ERR_INVALID_DISCORD_BOT = () -> text( - "Discord bot not setup yet or invalid settings in bot.yml!", RED), - ERR_PLAYER_SENDER = () -> text("You must be a player to execute this command!", RED), - ERR_INVALID_EXTENSION = () -> text( - "Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS)), - ERR_IMG_SET = () -> text("Failed to set image file!", RED), - ERR_IMAGE_NOT_LOADED = () -> text("The image you request purge from the map is not loaded!", - RED), - ERR_MAP_RANGE = () -> text("Invalid format! Must follow [starting-id]-[ending-id]", RED), - ERR_VIDEO_NOT_LOADED = () -> text("Video not loaded!", RED), - ERR_VIDEO_PROCESSING = () -> text("Video is still processing!", RED), - ERR_CANCELLATION_VIDEO_PROCESSING = () -> text("You aren't loading a video!", RED), - ERR_DOWNLOAD_VIDEO = () -> text("Failed to download video!", RED), - ERR_LOAD_VIDEO = () -> text("Failed to load video!", RED), - ERR_INVALID_AUDIO_OUTPUT = () -> text( + """)); + NullComponent DISABLE_PLUGIN = () -> format(text("DeluxeMediaPlugin is shutting down!")); + NullComponent GOOD_EMC_SHUTDOWN = () -> format(text("Successfully shutdown MinecraftMediaLibrary instance!")); + NullComponent GOODBYE = () -> format(text("Good Bye! :(")); + + NullComponent FIN_EMC_INIT = () -> format(text("Finished loading MinecraftMediaLibrary instance!")); + NullComponent FIN_PERSISTENT_INIT = () -> format(text("Finished loading persistent data!")); + NullComponent FIN_COMMANDS_INIT = () -> format(text("Finished registering plugin commands!")); + NullComponent FIN_METRICS_INIT = () -> format(text("Finished loading Metrics data!")); + NullComponent FIN_PLUGIN_INIT = () -> format(text("Finished loading DeluxeMediaPlugin!")); + + NullComponent RUNNING_LATEST_PLUGIN = () -> format(text( + "You are currently running the latest version of DeluxeMediaPlugin.")); + + NullComponent ERR_EMC_INIT = () -> format(text("There was a severe issue while loading the EzMediaCore instance!", + RED)); + NullComponent ERR_PERSISTENT_INIT = () -> format(text( + "A severe issue occurred while reading data from configuration files!", RED)); + NullComponent ERR_EMC_SHUTDOWN = () -> format(text("EzMediaCore instance is null... something fishy is going on.", + RED)); + NullComponent ERR_NO_MRL = () -> format(text("File or URL not specified!", RED)); + NullComponent ERR_INVALID_MRL = () -> format(text("Invalid MRL link! Not supported!", RED)); + NullComponent ERR_RESOURCEPACK_WRAP = () -> format(text("Failed to wrap resourcepack!", RED)); + NullComponent ERR_NO_RESOURCEPACK = () -> format(text("Please load a resourcepack first!", RED)); + NullComponent ERR_INVALID_AUDIO_STATE = () -> format(text( + "Please wait for the previous audio to extract first before loading another one!", RED)); + NullComponent ERR_INVALID_DISCORD_BOT = () -> format(text( + "Discord bot not setup yet or invalid settings in bot.yml!", RED)); + NullComponent ERR_PLAYER_SENDER = () -> format(text("You must be a player to execute this command!", RED)); + NullComponent ERR_INVALID_EXTENSION = () -> format(text( + "Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS))); + NullComponent ERR_IMG_SET = () -> format(text("Failed to set image file!", RED)); + NullComponent ERR_IMAGE_NOT_LOADED = () -> format(text("The image you request purge from the map is not loaded!", + RED)); + NullComponent ERR_MAP_RANGE = () -> format(text("Invalid format! Must follow [starting-id]-[ending-id]", RED)); + NullComponent ERR_VIDEO_NOT_LOADED = () -> format(text("Video not loaded!", RED)); + NullComponent ERR_VIDEO_PROCESSING = () -> format(text("Video is still processing!", RED)); + NullComponent ERR_CANCELLATION_VIDEO_PROCESSING = () -> format(text("You aren't loading a video!", RED)); + NullComponent ERR_DOWNLOAD_VIDEO = () -> format(text("Failed to download video!", RED)); + NullComponent ERR_LOAD_VIDEO = () -> format(text("Failed to load video!", RED)); + NullComponent ERR_INVALID_AUDIO_OUTPUT = () -> format(text( "You cannot play streams without using Discord or a dynamic audio player with audio. Proceeding to play without audio.", - RED), - ERR_INVALID_TARGET_SELECTOR = () -> text( - "The target selector you chose contains entities that aren't players!", RED), - ERR_DEVELOPMENT_FEATURE = () -> text( + RED)); + NullComponent ERR_INVALID_TARGET_SELECTOR = () -> format(text( + "The target selector you chose contains entities that aren't players!", RED)); + NullComponent ERR_DEVELOPMENT_FEATURE = () -> format(text( "This feature is current being developed! Stay tuned and join the Discord for updates!", - RED), - ERR_HTTP_AUDIO = () -> text("HTTP audio information provided in httpaudio.yml is invalid!", - RED), - ERR_BOT_TOKEN = () -> text("Bot token not specified in bot.yml!", RED), - ERR_GUILD_TOKEN = () -> text("Guild token not specified in bot.yml!", RED), - ERR_VC_ID = () -> text("Voice Chat Identifier not specified in bot.yml!", RED), - - START_AUDIO = () -> text("Started playing audio!"), - PAUSE_AUDIO = () -> text("Stopped playing audio!"), - RESUME_AUDIO = () -> text("Resumed the video!"), - CREATE_RESOURCEPACK = () -> text( - "Creating a resourcepack for audio. Depending on the length of the video, it make take some time."), - - DC_DISCORD = () -> text("Successfully disconnected from voice channel!"), - C_DISCORD = () -> text("Successfully connected to voice channel!"), - PAUSED_TRACK_DISCORD = () -> text("Successfully paused track!"), - RESUMED_TRACK_DISCORD = () -> text("Successfully resumed track!"), - - DITHERING_OPTIONS = () -> text("Dithering Options ->") + RED)); + NullComponent ERR_HTTP_AUDIO = () -> format(text("HTTP audio information provided in httpaudio.yml is invalid!", + RED)); + NullComponent ERR_BOT_TOKEN = () -> format(text("Bot token not specified in bot.yml!", RED)); + NullComponent ERR_GUILD_TOKEN = () -> format(text("Guild token not specified in bot.yml!", RED)); + NullComponent ERR_VC_ID = () -> format(text("Voice Chat Identifier not specified in bot.yml!", RED)); + + NullComponent START_AUDIO = () -> format(text("Started playing audio!")); + NullComponent PAUSE_AUDIO = () -> format(text("Stopped playing audio!")); + NullComponent RESUME_AUDIO = () -> format(text("Resumed the video!")); + NullComponent CREATE_RESOURCEPACK = () -> format(text( + "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.")); + + NullComponent DC_DISCORD = () -> format(text("Successfully disconnected from voice channel!")); + NullComponent C_DISCORD = () -> format(text("Successfully connected to voice channel!")); + NullComponent PAUSED_TRACK_DISCORD = () -> format(text("Successfully paused track!")); + NullComponent RESUMED_TRACK_DISCORD = () -> format(text("Successfully resumed track!")); + + NullComponentDITHERING_OPTIONS = () -> format(text("Dithering Options ->") .append(getComponent(DitherSetting.class, - (value) -> text(value.getName(), AQUA).append(newline()))), + (value) -> text(value.getName(), AQUA).append(newline())))); + + NullComponent FFMPEG_EXEC = () -> format(text("Executed FFmpeg command!")); + NullComponent RESET_FFMPEG_ARGS = () -> format(text("Reset all FFmpeg arguments!")); - FFMPEG_EXEC = () -> text("Executed FFmpeg command!"), - RESET_FFMPEG_ARGS = () -> text("Reset all FFmpeg arguments!"), + NullComponent LOAD_IMG = () -> format(text("Loading image...")); + NullComponentPURGE_ALL_MAPS_VERIFY = () -> format(text( + "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...")); + NullComponentPURGED_ALL_MAPS = () -> format(text("Successfully purged all images!")); + NullComponentCANCELLED_PURGE_ALL_MAPS = () -> format(text("Cancelled purge of all images!")); - LOAD_IMG = () -> text("Loading image..."), - PURGE_ALL_MAPS_VERIFY = () -> text( - "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue..."), - PURGED_ALL_MAPS = () -> text("Successfully purged all images!"), - CANCELLED_PURGE_ALL_MAPS = () -> text("Cancelled purge of all images!"), + NullComponentPAUSE_VIDEO = () -> format(text("Stopped the video!")); + NullComponent RELEASE_VIDEO = () -> format(text("Successfully destroyed the current video!")); + NullComponentSETUP_RESOURCEPACK = () -> format(text( + "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.")); + NullComponentDISCORD_AUDIO_STREAM = () -> format(text("Started playing audio into Discord voice chat!")); - PAUSE_VIDEO = () -> text("Stopped the video!"), - RELEASE_VIDEO = () -> text("Successfully destroyed the current video!"), - SETUP_RESOURCEPACK = () -> text( - "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is."), - DISCORD_AUDIO_STREAM = () -> text("Started playing audio into Discord voice chat!"), + NullComponentDUMP_THREADS = () -> format(text("Created thread dump! Look in console for more details.")); - DUMP_THREADS = () -> text("Created thread dump! Look in console for more details."), + NullComponent CANCELLED_VIDEO_PROCESSING = () -> format(text("Successfully cancelled the video loading process!")); + NullComponent LOADING_VIDEO = () -> format(text("Initializing and reading media...")); - CANCELLED_VIDEO_PROCESSING = () -> text("Successfully cancelled the video loading process!"), - LOADING_VIDEO = () -> text("Initializing and reading media..."), + NullComponent BUILT_SCREEN = () -> format(text("Successfully built your new screen!")); - PLUGIN_AUTHORS = () -> text() + NullComponentPLUGIN_AUTHORS = () -> text() .append(text("-----------------------------------", GOLD)) .append(newline()) .append(text("Plugin: ", GOLD, BOLD)) @@ -213,22 +211,33 @@ public interface Locale { .append(text("-----------------------------------", GOLD)) .append() .build(); + NullComponent PLUGIN_LOGO = () -> getComponent( + Arrays.asList( + " _____ _ __ __ _ _ _____ _ _ ", + " | __ \\ | | | \\/ | | (_) | __ \\| | (_) ", + " | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ ", + " | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\ ", + " | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | |", + " |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_|", + " __/ | ", + " |___/ "), + (line) -> text(line, BLUE).append(newline())); UniComponent - DREW_IMG = (mrl) -> text("Successfully drew image with mrl %s".formatted(mrl)), - START_TRACK_DISCORD = (mrl) -> text("Successfully started audio on MRL %s!".formatted(mrl)), - ADD_FFMPEG_ARG = (str) -> join( + DREW_IMG = (mrl) -> format(text("Successfully drew image with mrl %s".formatted(mrl))); + UniComponent START_TRACK_DISCORD = (mrl) -> format(text("Successfully started audio on MRL %s!".formatted(mrl))); + UniComponent ADD_FFMPEG_ARG = (str) -> format(join( separator(space()), text("Added arguments", GOLD), text(str, AQUA), - text("to the FFmpeg command.", GOLD)), - REMOVE_FFMPEG_ARG = (str) -> join( + text("to the FFmpeg command.", GOLD))); + UniComponent REMOVE_FFMPEG_ARG = (str) -> format(join( separator(space()), text("Removed arguments", GOLD), text(str, AQUA), - text("from the FFmpeg command.", GOLD)), - HTTP_SEND_LINK = (mrl) -> - text() + text("from the FFmpeg command.", GOLD))); + UniComponent HTTP_SEND_LINK = (mrl) -> + format(text() .append(text("Click ", GOLD)).append(text( "this message", style( @@ -238,50 +247,49 @@ public interface Locale { openUrl(mrl), text("Click to get the link!", GOLD) .asHoverEvent()))).append(text(" to retrieve the audio HTTP link!", GOLD)) - .build(), - STARTING_VIDEO = (mrl) -> text("Starting Video on MRL %s".formatted(mrl)), - LOADED_MEDIA = (mrl) -> text("Successfully loaded media %s!".formatted(mrl)), - SET_AUDIO_TYPE = (argument) -> text( - "Successfully set the audio type to %s".formatted(argument)), - SET_DITHER_TYPE = (algorithm) -> join(separator(space()), text("Set dither type to", GOLD), - text(algorithm, AQUA)), - SET_VIDEO_TYPE = (mode) -> join(separator(space()), text("Set video mode to", GOLD), - text(mode, AQUA)), - EXTERNAL_PROCESS = (line) -> join(separator(space()), text() + .build()); + UniComponent STARTING_VIDEO = (mrl) -> format(text("Starting Video on MRL %s".formatted(mrl))); + UniComponent LOADED_MEDIA = (mrl) -> format(text("Successfully loaded media %s!".formatted(mrl))); + UniComponent SET_AUDIO_TYPE = (argument) -> format(text( + "Successfully set the audio type to %s".formatted(argument))); + UniComponent SET_DITHER_TYPE = (algorithm) -> format(join(separator(space()), text("Set dither type to", GOLD), + text(algorithm, AQUA))); + UniComponent SET_VIDEO_TYPE = (mode) -> format(join(separator(space()), text("Set video mode to", GOLD), + text(mode, AQUA))); + UniComponent EXTERNAL_PROCESS = (line) -> format(join(separator(space()), text() .color(AQUA) .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)), - text(line, GOLD)), - NEW_UPDATE_PLUGIN = (update) -> text( - "There is a new update available! (%s)".formatted(update)), - - ERR_INVALID_AUDIO_TYPE = (argument) -> text( - "Could not find audio type %s".formatted(argument), RED), - ERR_INVALID_DITHER_TYPE = (algorithm) -> text( - "Could not find dither type %s".formatted(algorithm), RED), - ERR_INVALID_VIDEO_TYPE = (mode) -> text("Could not find video mode %s".formatted(mode), RED), - ERR_CANNOT_CHECK_UPDATES = (msg) -> text("Cannot look for updates: %s".formatted(msg), RED); - - UniComponent> LIST_FFMPEG_ARGS = (list) -> join( + text(line, GOLD))); + UniComponent NEW_UPDATE_PLUGIN = (update) -> format(text( + "There is a new update available! (%s)".formatted(update))); + UniComponent ERR_INVALID_AUDIO_TYPE = (argument) -> format(text( + "Could not find audio type %s".formatted(argument), RED)); + UniComponent ERR_INVALID_DITHER_TYPE = (algorithm) -> format(text( + "Could not find dither type %s".formatted(algorithm), RED)); + UniComponent ERR_INVALID_VIDEO_TYPE = (mode) -> format(text("Could not find video mode %s".formatted(mode), RED)); + UniComponent ERR_CANNOT_CHECK_UPDATES = (msg) -> format(text("Cannot look for updates: %s".formatted(msg), RED)); + + UniComponent> LIST_FFMPEG_ARGS = (list) -> format(join( separator(space()), text("Current FFmpeg arguments:", GOLD), - text(list.toString(), AQUA)); + text(list.toString(), AQUA))); UniComponent PURGE_MAP = (id) -> - join( + format(join( separator(space()), text("Successfully purged all maps with id", GOLD), - text(id, AQUA)), - GIVE_MAP_ID = (id) -> join( - separator(space()), text("Gave map with id", GOLD), text(id, AQUA)), - CHANGED_VIDEO_MAP_ID = (id) -> join( + text(id, AQUA))); + UniComponent GIVE_MAP_ID = (id) -> format(join( + separator(space()), text("Gave map with id", GOLD), text(id, AQUA))); + UniComponent CHANGED_VIDEO_MAP_ID = (id) -> format(join( separator(space()), text("Set starting map id to", GOLD), - text(id, AQUA)); + text(id, AQUA))); - UniComponent RESUMING_VIDEO_MS = (ms) -> text("Resuming Video at %s Milliseconds!"); + UniComponent RESUMING_VIDEO_MS = (ms) -> format(text("Resuming Video at %s Milliseconds!")); - UniComponent SEND_RESOURCEPACK_URL = (player) -> text() + UniComponent SEND_RESOURCEPACK_URL = (player) -> format(text() .append(text("Loaded resourcepack for all players! Click ", GOLD)) .append( text( @@ -296,49 +304,69 @@ public interface Locale { text("Click to get the resourcepack!", GOLD) .asHoverEvent()))) .append(text(" to retrieve the resourcepack", GOLD)) - .build(); + .build()); BiComponent - FIN_RESOURCEPACK_INIT = (url, hash) -> text( - "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash))), - SENT_RESOURCEPACK = (url, hash) -> text( - "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash))); + FIN_RESOURCEPACK_INIT = (url, hash) -> format(text( + "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); + BiComponent SENT_RESOURCEPACK = (url, hash) -> format(text( + "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); BiComponent ADD_FFMPEG_ARG_INDX = (str, index) -> - join( + format(join( separator(space()), text("Added arguments", GOLD), text(str, AQUA), text(" the FFmpeg command at index", GOLD), - text(index, AQUA)), - REMOVE_FFMPEG_ARG_INDX = (str, index) -> - join( + text(index, AQUA))); + BiComponent REMOVE_FFMPEG_ARG_INDX = (str, index) -> + format(join( separator(space()), text("Removed arguments", GOLD), text(str, AQUA), text("from the FFmpeg command at index", GOLD), - text(index, AQUA)); + text(index, AQUA))); BiComponent - CHANGED_IMG_DIMS = (width, height) -> text( - "Changed itemframe dimensions to %d:%d (width:height)".formatted(width, height)), - GAVE_MAP_RANGE = (start, end) -> join( + CHANGED_IMG_DIMS = (width, height) -> format(text( + "Changed itemframe dimensions to %d:%d (width:height)".formatted(width, height))); + BiComponent GAVE_MAP_RANGE = (start, end) -> + format(join( separator(space()), text("Gave maps between IDs", GOLD), text(start, AQUA), text("and", GOLD), - text(end, AQUA)), - CHANGED_VIDEO_SCREEN_DIMS = (width, height) -> join( + text(end, AQUA))); + BiComponent CHANGED_VIDEO_SCREEN_DIMS = (width, height) -> + format(join( separator(space()), text("Set screen dimensions to", GOLD), text("%d:%d".formatted(width, height), AQUA), - text("(width:height)", GOLD)), - CHANGED_ITEMFRAME_DIMS = (width, height) -> join( + text("(width:height)", GOLD))); + BiComponent CHANGED_ITEMFRAME_DIMS = (width, height) -> + format(join( separator(space()), text("Set itemframe map dimensions to", GOLD), text("%d:%d".formatted(width, height), AQUA), - text("(width:height)", GOLD)); + text("(width:height)", GOLD))); + + NullComponent PLUGIN_PREFIX = () -> + text() + .color(AQUA) + .append( + text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)).build(); + + UniComponent FFMPEG_PROCESS = (str) -> + text() + .color(AQUA) + .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)) + .append(text(" %s".formatted(str))) + .build(); + + static @NotNull Component format(@NotNull final Component message) { + return join(separator(space()), PLUGIN_PREFIX.build(), message); + } static > @NotNull Component getComponent(@NotNull final Class clazz, @NotNull final Function function) { @@ -350,6 +378,15 @@ public interface Locale { return component.build(); } + static @NotNull Component getComponent( + @NotNull final Collection collection, + @NotNull final Function function) { + final TextComponent.Builder component = text(); + for (final E value : collection) { + component.append(function.apply(value)); + } + return component.build(); + } @FunctionalInterface interface NullComponent { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java index dc0d72669..4a8b5420d 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java @@ -56,8 +56,8 @@ private void request() { try (final Scanner scanner = new Scanner( new URL( - "https://api.spigotmc.org/legacy/update.php?resource=%d" - .formatted(this.resource)) + "https://api.spigotmc.org/legacy/update.php?resource=%d" + .formatted(this.resource)) .openStream())) { final String update = scanner.next(); if (this.plugin.getBootstrap().getDescription().getVersion().equalsIgnoreCase(update)) { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java index d9705d857..f0671364a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java @@ -31,7 +31,6 @@ import static net.kyori.adventure.text.JoinConfiguration.separator; import static net.kyori.adventure.text.format.NamedTextColor.AQUA; import static net.kyori.adventure.text.format.NamedTextColor.GOLD; -import static net.kyori.adventure.text.format.NamedTextColor.GRAY; import static net.kyori.adventure.text.format.NamedTextColor.LIGHT_PURPLE; import static net.kyori.adventure.text.format.NamedTextColor.RED; @@ -39,38 +38,12 @@ import java.util.Optional; import java.util.OptionalInt; import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.TextComponent; import org.jetbrains.annotations.NotNull; public final class ChatUtils { - private static final ComponentLike PREFIX; - private static final ComponentLike EXTERNAL_PROCESS; - - static { - PREFIX = - text() - .color(AQUA) - .append( - text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)); - EXTERNAL_PROCESS = - text() - .color(AQUA) - .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)); - } - - private ChatUtils() { - } - - public static @NotNull Component format(@NotNull final Component message) { - return join(separator(space()), PREFIX, message); - } - - public static @NotNull Component ffmpeg(@NotNull final Component message) { - return join(separator(space()), EXTERNAL_PROCESS, message); - } + private ChatUtils() {} public static @NotNull Optional checkDimensionBoundaries( @NotNull final Audience sender, @NotNull final String str) { @@ -83,7 +56,7 @@ private ChatUtils() { } else if (height.isEmpty()) { message = dims[1]; } else { - return Optional.of(new int[]{width.getAsInt(), height.getAsInt()}); + return Optional.of(new int[] {width.getAsInt(), height.getAsInt()}); } sender.sendMessage( text() diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java index d08c69a53..3631c8cf8 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java @@ -41,14 +41,13 @@ public final class CommandUtils { knownCommands = (HashMap) (getPrivateField( - (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap") - .orElseThrow(AssertionError::new)), - "knownCommands") + (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap") + .orElseThrow(AssertionError::new)), + "knownCommands") .orElseThrow(AssertionError::new)); } - private CommandUtils() { - } + private CommandUtils() {} public static void unRegisterBukkitCommand( @NotNull final DeluxeMediaPlugin plugin, @NotNull final BaseCommand cmd) { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/WrappedInteger.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java similarity index 79% rename from deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/WrappedInteger.java rename to deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java index 1a31ac64e..36859b0f4 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/WrappedInteger.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java @@ -26,35 +26,35 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; -public class WrappedInteger { +public class MutableInt { private int number; - WrappedInteger(@NotNull final Number number) { + MutableInt(@NotNull final Number number) { this.number = (int) number; } - WrappedInteger(final int number) { + MutableInt(final int number) { this.number = number; } - WrappedInteger(@NotNull final String number) { + MutableInt(@NotNull final String number) { this.number = Integer.parseInt(number); } @Contract(value = "_ -> new", pure = true) - public static @NotNull WrappedInteger ofNumber(@NotNull final Number number) { - return new WrappedInteger(number); + public static @NotNull MutableInt ofNumber(@NotNull final Number number) { + return new MutableInt(number); } @Contract(value = "_ -> new", pure = true) - public static @NotNull WrappedInteger ofInteger(final int number) { - return new WrappedInteger(number); + public static @NotNull MutableInt ofInteger(final int number) { + return new MutableInt(number); } @Contract(value = "_ -> new", pure = true) - public static @NotNull WrappedInteger ofString(@NotNull final String string) { - return new WrappedInteger(string); + public static @NotNull MutableInt ofString(@NotNull final String string) { + return new MutableInt(string); } public void increment() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PluginUsageTips.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PluginUsageTips.java index b76f8a580..52866e5b3 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PluginUsageTips.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/utility/PluginUsageTips.java @@ -30,25 +30,9 @@ public final class PluginUsageTips { - private static final String JAVA_VERSION; - private static final int MAJOR_VERSION; - - static { - JAVA_VERSION = System.getProperty("java.version"); - MAJOR_VERSION = Integer.parseInt(JAVA_VERSION.split("\\.")[1]); - } - private PluginUsageTips() { } - public static String getJavaVersion() { - return JAVA_VERSION; - } - - public static int getMajorVersion() { - return MAJOR_VERSION; - } - public static void sendWarningMessage() { Logger.warn(""" As a reminder, the only server softwares supported by this library are Spigot and Paper. From 9bf322a43c7aa067b4eae9498babcd570e67d09c Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sat, 2 Oct 2021 11:14:03 -0400 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20Bug=20(Silly=20Me)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pulsebeat02/deluxemediaplugin/config/BotConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java index b5c1870e0..dba4818ea 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java @@ -74,7 +74,7 @@ public void serialize() { invalid = true; } - if (invalid) { + if (!invalid) { try { this.bot = new MediaBot(token, guild, vc); } catch (final LoginException | InterruptedException e) { From 20919b69800d2cf8934619c90f58a7dab1517428 Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sat, 2 Oct 2021 12:36:52 -0400 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=90=9B=20Added=20More=20Changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/DeluxeMediaPlugin.java | 173 +++++++++++++----- .../DeluxeMediaPluginBootstrap.java | 6 +- .../command/CommandHandler.java | 41 +++-- .../command/audio/AudioCommand.java | 32 ++-- .../command/video/VideoCommand.java | 3 +- .../executors/ExecutorProvider.java | 2 +- .../deluxemediaplugin/json/DataHolder.java | 2 +- .../deluxemediaplugin/json/DataProvider.java | 4 +- .../json/MediaAttributesData.java | 2 +- .../deluxemediaplugin/message/Locale.java | 22 ++- .../main/resources/data/video-attributes.json | 11 ++ .../JSONVideoAttributesTest.java | 23 +++ 12 files changed, 224 insertions(+), 97 deletions(-) create mode 100644 deluxemediaplugin/src/main/resources/data/video-attributes.json create mode 100644 deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 1053d8257..94357fabf 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -34,6 +34,8 @@ import io.github.pulsebeat02.deluxemediaplugin.config.HttpConfiguration; import io.github.pulsebeat02.deluxemediaplugin.config.PersistentPictureManager; import io.github.pulsebeat02.deluxemediaplugin.config.ServerInfo; +import io.github.pulsebeat02.deluxemediaplugin.executors.ExecutorProvider; +import io.github.pulsebeat02.deluxemediaplugin.json.MediaAttributesData; import io.github.pulsebeat02.deluxemediaplugin.message.Locale; import io.github.pulsebeat02.deluxemediaplugin.update.UpdateChecker; import io.github.pulsebeat02.deluxemediaplugin.utility.CommandUtils; @@ -47,6 +49,7 @@ import java.io.IOException; import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import org.bstats.bukkit.Metrics; @@ -58,54 +61,76 @@ public final class DeluxeMediaPlugin { private final JavaPlugin plugin; + private AudioConfiguration audioConfiguration; private MediaLibraryCore library; private BukkitAudiences audiences; private Audience console; private CommandHandler handler; - - private AudioConfiguration audioConfiguration; private PersistentPictureManager manager; private HttpServer server; private MediaBot mediaBot; private ServerInfo httpAudioServer; - private VideoCommandAttributes attributes; + private MediaAttributesData mediaAttributesData; public DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { this.plugin = plugin; } public void enable() { - this.audiences = BukkitAudiences.create(this.plugin); - this.console = this.audiences.console(); - this.console.sendMessage(Locale.PLUGIN_LOGO.build()); - this.console.sendMessage(Locale.ENABLE_PLUGIN.build()); - this.console.sendMessage(Locale.EMC_INIT.build()); this.startLibrary(); - this.console.sendMessage(Locale.FIN_EMC_INIT.build()); this.loadPersistentData(); - this.console.sendMessage(Locale.FIN_PERSISTENT_INIT.build()); this.registerCommands(); - this.console.sendMessage(Locale.FIN_COMMANDS_INIT.build()); this.startMetrics(); - this.console.sendMessage(Locale.FIN_METRICS_INIT.build()); this.checkUpdates(); - this.console.sendMessage(Locale.FIN_PLUGIN_INIT.build()); - this.console.sendMessage(Locale.WELCOME.build()); + this.finishEnabling(); } public void disable() throws Exception { - this.console.sendMessage(Locale.DISABLE_PLUGIN.build()); this.shutdownLibrary(); + this.deserializeData(); this.unregisterCommands(); this.disableBot(); this.cancelNativeTasks(); - this.console.sendMessage(Locale.GOODBYE.build()); + this.finishDisabling(); } - public void load() {} + public void load() { + this.audiences = BukkitAudiences.create(this.plugin); + this.console = this.audiences.console(); + this.finishLoading(); + } + + private void deserializeData() { + try { + this.mediaAttributesData.deserialize(this.attributes); + } catch (final IOException e) { + e.printStackTrace(); + } + this.console.sendMessage(Locale.DESERIALIZE_DATA.build()); + } + + private void startMetrics() { + new Metrics(this.plugin, 10229); + this.console.sendMessage(Locale.FIN_METRICS_INIT.build()); + } + + private void finishLoading() {} + + private void finishEnabling() { + this.checkUpdates(); + this.console.sendMessage(Locale.FIN_PLUGIN_INIT.build()); + this.console.sendMessage(Locale.WELCOME.build()); + } + + private void finishDisabling() { + this.console.sendMessage(Locale.GOODBYE.build()); + } private void startLibrary() { + this.console.sendMessage(Locale.PLUGIN_LOGO.build()); + this.console.sendMessage(Locale.ENABLE_PLUGIN.build()); + this.console.sendMessage(Locale.EMC_INIT.build()); try { this.library = LibraryProvider.builder().plugin(this.plugin).build(); this.library.initialize(); @@ -114,10 +139,7 @@ private void startLibrary() { e.printStackTrace(); this.plugin.getServer().getPluginManager().disablePlugin(this.plugin); } - } - - private void startMetrics() { - new Metrics(this.plugin, 10229); + this.console.sendMessage(Locale.FIN_EMC_INIT.build()); } private void checkUpdates() { @@ -128,6 +150,7 @@ private void disableBot() { if (this.mediaBot != null) { this.mediaBot.getJDA().shutdown(); } + this.console.sendMessage(Locale.DISABLE_BOT.build()); } private void unregisterCommands() { @@ -136,62 +159,124 @@ private void unregisterCommands() { CommandUtils.unRegisterBukkitCommand(this, cmd); } } + this.console.sendMessage(Locale.DISABLE_COMMANDS.build()); } private void shutdownLibrary() { + this.console.sendMessage(Locale.DISABLE_PLUGIN.build()); if (this.library != null) { this.library.shutdown(); - this.console.sendMessage(Locale.GOOD_EMC_SHUTDOWN.build()); + this.console.sendMessage(Locale.DISABLE_EMC.build()); } else { this.console.sendMessage(Locale.ERR_EMC_SHUTDOWN.build()); } } private void cancelNativeTasks() throws Exception { + this.cancelNativeExtractor(); + this.cancelNativeStreamExtractor(); + this.console.sendMessage(Locale.CANCELLED_TASKS.build()); + } + + private void cancelNativeExtractor() throws Exception { final EnhancedExecution extractor = this.attributes.getExtractor(); if (extractor != null) { extractor.close(); } + } + + private void cancelNativeStreamExtractor() throws Exception { final EnhancedExecution streamExtractor = this.attributes.getStreamExtractor(); if (streamExtractor != null) { streamExtractor.close(); } } + private void createFolders() { + Set.of(this.plugin.getDataFolder().toPath().resolve("configuration")) + .forEach(ThrowingConsumer.unchecked(FileUtils::createFolderIfNotExists)); + } + + private void readConfigurationFiles() throws IOException { + this.readHttpConfiguration(); + this.readEncoderConfiguration(); + this.readBotConfiguration(); + this.readStreamAudioConfiguration(); + this.readPictureData(); + } + + private void readHttpConfiguration() throws IOException { + final HttpConfiguration httpConfiguration = new HttpConfiguration(this); + httpConfiguration.read(); + this.server = httpConfiguration.getSerializedValue(); + } + + private void readEncoderConfiguration() throws IOException { + final EncoderConfiguration encoderConfiguration = new EncoderConfiguration(this); + encoderConfiguration.read(); + this.audioConfiguration = encoderConfiguration.getSerializedValue(); + } + + private void readBotConfiguration() throws IOException { + final BotConfiguration botConfiguration = new BotConfiguration(this); + botConfiguration.read(); + this.mediaBot = botConfiguration.getSerializedValue(); + } + + private void readStreamAudioConfiguration() throws IOException { + final HttpAudioConfiguration audioConfiguration = new HttpAudioConfiguration(this); + audioConfiguration.read(); + this.httpAudioServer = audioConfiguration.getSerializedValue(); + } + + private void readJsonFiles() throws IOException { + this.mediaAttributesData = new MediaAttributesData(this); + this.mediaAttributesData.serialize(); + this.attributes = this.mediaAttributesData.getSerializedValue(); + } + + private void readPictureData() throws IOException { + this.manager = new PersistentPictureManager(this); + this.manager.startTask(); + } + private void loadPersistentData() { try { - Set.of(this.plugin.getDataFolder().toPath().resolve("configuration")) - .forEach(ThrowingConsumer.unchecked(FileUtils::createFolderIfNotExists)); - final HttpConfiguration httpConfiguration = new HttpConfiguration(this); - final EncoderConfiguration encoderConfiguration = new EncoderConfiguration(this); - final BotConfiguration botConfiguration = new BotConfiguration(this); - final HttpAudioConfiguration audioConfiguration = new HttpAudioConfiguration(this); - httpConfiguration.read(); - encoderConfiguration.read(); - botConfiguration.read(); - audioConfiguration.read(); - this.server = httpConfiguration.getSerializedValue(); - this.audioConfiguration = encoderConfiguration.getSerializedValue(); - this.mediaBot = botConfiguration.getSerializedValue(); - this.httpAudioServer = audioConfiguration.getSerializedValue(); - this.manager = new PersistentPictureManager(this); - this.manager.startTask(); + this.createFolders(); + this.readConfigurationFiles(); + this.readJsonFiles(); + this.writeToFile(); } catch (final IOException e) { this.console.sendMessage(Locale.ERR_PERSISTENT_INIT.build()); e.printStackTrace(); } + this.console.sendMessage(Locale.FIN_PERSISTENT_INIT.build()); } - public Audience getLogger() { - return this.console; + private void writeToFile() { + ExecutorProvider.SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate( + this::deserializeAttributes, 0L, 5L, TimeUnit.MINUTES); } - public @NotNull JavaPlugin getBootstrap() { - return this.plugin; + private void deserializeAttributes() { + try { + this.mediaAttributesData.deserialize(this.attributes); + } catch (final IOException e) { + e.printStackTrace(); + } } private void registerCommands() { this.handler = new CommandHandler(this); + this.console.sendMessage(Locale.FIN_COMMANDS_INIT.build()); + } + + public Audience getLogger() { + return this.console; + } + + public @NotNull JavaPlugin getBootstrap() { + return this.plugin; } public @NotNull PersistentPictureManager getPictureManager() { @@ -222,10 +307,6 @@ private void registerCommands() { return this.attributes; } - public void setAttributes(final VideoCommandAttributes attributes) { - this.attributes = attributes; - } - public @Nullable ServerInfo getHttpAudioServer() { return this.httpAudioServer; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java index 902431bbf..5e51a3c5a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java @@ -37,15 +37,14 @@ public final class DeluxeMediaPluginBootstrap extends JavaPlugin { @Override public void onLoad() { - final Logger logger = this.getLogger(); - logger.info(InternalLocale.SLIMJAR_LOAD.build()); this.buildApplication(); - logger.info(InternalLocale.SLIMJAR_FINISH.build()); this.plugin = new DeluxeMediaPlugin(this); this.plugin.load(); } private void buildApplication() { + final Logger logger = this.getLogger(); + logger.info(InternalLocale.SLIMJAR_LOAD.build()); try { ApplicationBuilder.appending("DeluxeMediaPlugin").build(); } catch (final IOException @@ -54,6 +53,7 @@ private void buildApplication() { | ReflectiveOperationException e) { e.printStackTrace(); } + logger.info(InternalLocale.SLIMJAR_FINISH.build()); } @Override diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java index 07b50b529..09c112a2a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java @@ -52,6 +52,7 @@ import org.bukkit.command.TabExecutor; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public final class CommandHandler implements TabExecutor { @@ -75,32 +76,42 @@ public CommandHandler(@NotNull final DeluxeMediaPlugin plugin) { new FFmpegCommand(plugin, this), new PluginCommand(plugin, this), new DiscordCommand(plugin, this)); - final JavaPlugin loader = plugin.getBootstrap(); + this.registerCommands(); + } + + private void registerCommands() { + final JavaPlugin loader = this.plugin.getBootstrap(); final CommandMap commandMap = CommandMapHelper.getCommandMap(); final Commodore commodore = CommodoreProvider.isSupported() ? CommodoreProvider.getCommodore(loader) : null; for (final BaseCommand command : this.commands) { this.rootNode.addChild(command.node()); commandMap.register(loader.getName(), command); - try { - if (commodore != null) { - commodore.register( - CommodoreFileFormat.parse( - loader.getResource("commodore/%s.commodore".formatted(command.getName())))); - } - } catch (final IOException e) { - e.printStackTrace(); + this.registerCommodoreCommand(commodore, command); + } + } + + private void registerCommodoreCommand( + @Nullable final Commodore commodore, @NotNull final BaseCommand command) { + final JavaPlugin loader = this.plugin.getBootstrap(); + try { + if (commodore != null) { + commodore.register( + CommodoreFileFormat.parse( + loader.getResource("commodore/%s.commodore".formatted(command.getName())))); } + } catch (final IOException e) { + e.printStackTrace(); } } /** * CommandHandler to read input and execute other commands. * - * @param sender command sender + * @param sender command sender * @param command command sent - * @param label label of command - * @param args arguments for command + * @param label label of command + * @param args arguments for command * @return whether the command usage should be showed up. */ @Override @@ -123,10 +134,10 @@ public boolean onCommand( /** * Tab handler to handle tab completer. * - * @param sender command sender + * @param sender command sender * @param command current command - * @param alias aliases of command - * @param args arguments of the command + * @param alias aliases of command + * @param args arguments of the command * @return list of options. */ @Override diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java index c2d1ec382..fbd27b504 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioCommand.java @@ -62,13 +62,26 @@ public AudioCommand( } private int playAudio(@NotNull final CommandContext context) { - final Audience audience = this.plugin().audience().sender(context.getSource()); + if (this.checkUnloaded(audience) || this.checkIncompleteLoad(audience)) { + return SINGLE_SUCCESS; + } + this.playAudio(); + audience.sendMessage(Locale.START_AUDIO.build()); + return SINGLE_SUCCESS; + } + private int stopAudio(@NotNull final CommandContext context) { + final Audience audience = this.plugin().audience().sender(context.getSource()); if (this.checkUnloaded(audience) || this.checkIncompleteLoad(audience)) { return SINGLE_SUCCESS; } + this.stopAudio(); + audience.sendMessage(Locale.PAUSE_AUDIO.build()); + return SINGLE_SUCCESS; + } + private void playAudio() { this.audioAction( player -> player.playSound( @@ -77,25 +90,10 @@ private int playAudio(@NotNull final CommandContext context) { SoundCategory.MASTER, 100.0F, 1.0F)); - - audience.sendMessage(Locale.START_AUDIO.build()); - - return SINGLE_SUCCESS; } - private int stopAudio(@NotNull final CommandContext context) { - - final Audience audience = this.plugin().audience().sender(context.getSource()); - - if (this.checkUnloaded(audience) || this.checkIncompleteLoad(audience)) { - return SINGLE_SUCCESS; - } - + private void stopAudio() { this.audioAction(player -> player.stopSound(this.attributes.getKey())); - - audience.sendMessage(Locale.PAUSE_AUDIO.build()); - - return SINGLE_SUCCESS; } private void audioAction(@NotNull final Consumer consumer) { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java index 4cf479621..8d9a6e250 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java @@ -75,8 +75,7 @@ public final class VideoCommand extends BaseCommand { public VideoCommand( @NotNull final DeluxeMediaPlugin plugin, @NotNull final TabExecutor executor) { super(plugin, "video", executor, "deluxemediaplugin.command.video", ""); - this.attributes = new VideoCommandAttributes(); - plugin.setAttributes(this.attributes); + this.attributes = plugin.getAttributes(); this.builder = new VideoCreator(plugin.library(), this.attributes); this.node = this.literal(this.getName()) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java index a638010a9..a5cc981da 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java @@ -35,6 +35,6 @@ public class ExecutorProvider { static { STREAM_THREAD_EXECUTOR = Executors.newFixedThreadPool(4); - SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(1); + SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(4); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java index 35bc10035..607fd477c 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataHolder.java @@ -31,7 +31,7 @@ public interface DataHolder { - void deserialize() throws IOException; + void deserialize(@NotNull final T obj) throws IOException; void serialize() throws IOException; diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java index 94daeb914..aebfe998f 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java @@ -44,8 +44,8 @@ public DataProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final Stri } @Override - public void deserialize() throws IOException { - GsonProvider.getGson().toJson(this.object, Files.newBufferedWriter(this.path)); + public void deserialize(@NotNull final T obj) throws IOException { + GsonProvider.getGson().toJson(obj, Files.newBufferedWriter(this.path)); } @Override diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java index 3219dd0a0..2ea2437d4 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java @@ -30,6 +30,6 @@ public class MediaAttributesData extends DataProvider { public MediaAttributesData(@NotNull final DeluxeMediaPlugin plugin) { - super(plugin, "video-attributes.json"); + super(plugin, "data/video-attributes.json"); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java index 7f71341ed..39e330676 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java @@ -83,7 +83,11 @@ public interface Locale { support at my Discord! (https://discord.gg/MgqRKvycMC) """)); NullComponent DISABLE_PLUGIN = () -> format(text("DeluxeMediaPlugin is shutting down!")); - NullComponent GOOD_EMC_SHUTDOWN = () -> format(text("Successfully shutdown MinecraftMediaLibrary instance!")); + NullComponent DISABLE_EMC = () -> format(text("Successfully shutdown MinecraftMediaLibrary instance!")); + NullComponent DESERIALIZE_DATA = () -> format(text("Successfully deserialized data!")); + NullComponent DISABLE_COMMANDS = () -> format(text("Successfully disabled commands!")); + NullComponent DISABLE_BOT = () -> format(text("Successfully disabled Discord bot! (If running)")); + NullComponent CANCELLED_TASKS = () -> format(text("Successfully disabled all native tasks!")); NullComponent GOODBYE = () -> format(text("Good Bye! :(")); NullComponent FIN_EMC_INIT = () -> format(text("Finished loading MinecraftMediaLibrary instance!")); @@ -146,7 +150,7 @@ public interface Locale { NullComponent PAUSED_TRACK_DISCORD = () -> format(text("Successfully paused track!")); NullComponent RESUMED_TRACK_DISCORD = () -> format(text("Successfully resumed track!")); - NullComponentDITHERING_OPTIONS = () -> format(text("Dithering Options ->") + NullComponent DITHERING_OPTIONS = () -> format(text("Dithering Options ->") .append(getComponent(DitherSetting.class, (value) -> text(value.getName(), AQUA).append(newline())))); @@ -154,25 +158,25 @@ public interface Locale { NullComponent RESET_FFMPEG_ARGS = () -> format(text("Reset all FFmpeg arguments!")); NullComponent LOAD_IMG = () -> format(text("Loading image...")); - NullComponentPURGE_ALL_MAPS_VERIFY = () -> format(text( + NullComponent PURGE_ALL_MAPS_VERIFY = () -> format(text( "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...")); - NullComponentPURGED_ALL_MAPS = () -> format(text("Successfully purged all images!")); - NullComponentCANCELLED_PURGE_ALL_MAPS = () -> format(text("Cancelled purge of all images!")); + NullComponent PURGED_ALL_MAPS = () -> format(text("Successfully purged all images!")); + NullComponent CANCELLED_PURGE_ALL_MAPS = () -> format(text("Cancelled purge of all images!")); - NullComponentPAUSE_VIDEO = () -> format(text("Stopped the video!")); + NullComponent PAUSE_VIDEO = () -> format(text("Stopped the video!")); NullComponent RELEASE_VIDEO = () -> format(text("Successfully destroyed the current video!")); - NullComponentSETUP_RESOURCEPACK = () -> format(text( + NullComponent SETUP_RESOURCEPACK = () -> format(text( "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.")); NullComponentDISCORD_AUDIO_STREAM = () -> format(text("Started playing audio into Discord voice chat!")); - NullComponentDUMP_THREADS = () -> format(text("Created thread dump! Look in console for more details.")); + NullComponent DUMP_THREADS = () -> format(text("Created thread dump! Look in console for more details.")); NullComponent CANCELLED_VIDEO_PROCESSING = () -> format(text("Successfully cancelled the video loading process!")); NullComponent LOADING_VIDEO = () -> format(text("Initializing and reading media...")); NullComponent BUILT_SCREEN = () -> format(text("Successfully built your new screen!")); - NullComponentPLUGIN_AUTHORS = () -> text() + NullComponent PLUGIN_AUTHORS = () -> text() .append(text("-----------------------------------", GOLD)) .append(newline()) .append(text("Plugin: ", GOLD, BOLD)) diff --git a/deluxemediaplugin/src/main/resources/data/video-attributes.json b/deluxemediaplugin/src/main/resources/data/video-attributes.json new file mode 100644 index 000000000..1f1811988 --- /dev/null +++ b/deluxemediaplugin/src/main/resources/data/video-attributes.json @@ -0,0 +1,11 @@ +{ + "completion": false, + "ditherType": "FILTER_LITE", + "audioOutputType": "RESOURCEPACK", + "playbackType": "ITEMFRAME", + "map": 0, + "frameWidth": 5, + "frameHeight": 5, + "pixelWidth": 640, + "pixelHeight": 360 +} \ No newline at end of file diff --git a/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java b/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java new file mode 100644 index 000000000..8ce147bb7 --- /dev/null +++ b/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java @@ -0,0 +1,23 @@ +package io.github.deluxemediaplugin; + +import com.google.gson.Gson; +import io.github.pulsebeat02.deluxemediaplugin.command.video.VideoCommandAttributes; +import io.github.pulsebeat02.deluxemediaplugin.json.GsonProvider; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class JSONVideoAttributesTest { + + public static void main(final String[] args) throws IOException { + final Gson gson = GsonProvider.getGson(); + System.out.println(gson.toJson(new VideoCommandAttributes())); + System.out.println( + gson.fromJson( + Files.newBufferedReader( + Path.of( + System.getProperty("user.dir"), + "deluxemediaplugin/src/main/resources/data/video-attributes.json")), + VideoCommandAttributes.class)); + } +} From 15ced94ba6af6a598dd28c1cd5892b9fc3ab96af Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sat, 2 Oct 2021 18:48:23 -0400 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=90=9B=20Large=20Plugin=20Update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/DeluxeMediaPlugin.java | 19 ++- .../audio/M3uStreamSegmentUrlProvider.java | 8 +- .../bot/audio/MusicSendHandler.java | 2 +- .../bot/audio/TrackScheduler.java | 12 +- .../command/CommandSegment.java | 12 +- .../command/audio/AudioLoadCommand.java | 6 +- .../ffmpeg/FFmpegRemoveArgumentCommand.java | 3 +- .../command/gui/ItemBuilder.java | 2 +- .../command/gui/SkullException.java | 3 +- .../command/image/SetImageCommand.java | 2 +- .../command/video/VideoCommand.java | 2 +- .../command/video/VideoCommandAttributes.java | 26 +++- .../command/video/VideoLoadCommand.java | 17 ++- .../config/BotConfiguration.java | 2 +- .../executors/ExecutorProvider.java | 2 + .../deluxemediaplugin/json/DataProvider.java | 30 ++-- .../json/MediaAttributesData.java | 2 +- .../deluxemediaplugin/message/Locale.java | 134 +++++++----------- .../update/UpdateChecker.java | 20 +-- .../main/resources/data/video-attributes.json | 16 +-- .../JSONVideoAttributesTest.java | 15 +- .../pulsebeat02/ezmediacore/EzMediaCore.java | 5 +- .../pulsebeat02/ezmediacore/Logger.java | 8 ++ .../dependency/ArtifactInstaller.java | 15 -- .../dependency/FFmpegInstaller.java | 16 ++- .../ezmediacore/dependency/RTPInstaller.java | 23 ++- .../ezmediacore/http/HttpServerDaemon.java | 61 ++++---- .../pulsebeat02/ezmediacore/image/Image.java | 6 +- .../persistent/PersistentImageStorage.java | 14 +- .../ResourcepackSoundWrapper.java | 4 - .../resourcepack/ResourcepackWrapper.java | 39 +---- .../ezmediacore/task/CommandTaskChain.java | 53 +++---- .../ezmediacore/vlc/EMCNativeDiscovery.java | 22 ++- .../ezmediacore/vlc/NativeBinarySearch.java | 5 - .../vlc/os/mac/SilentMacInstallation.java | 46 +++--- .../os/window/SilentWindowsInstallation.java | 16 ++- 36 files changed, 329 insertions(+), 339 deletions(-) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 94357fabf..340366a9d 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -47,6 +47,7 @@ import io.github.pulsebeat02.ezmediacore.sneaky.ThrowingConsumer; import io.github.pulsebeat02.ezmediacore.utility.FileUtils; import java.io.IOException; +import java.nio.file.Path; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -78,11 +79,11 @@ public DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { } public void enable() { + this.assignAudiences(); this.startLibrary(); this.loadPersistentData(); this.registerCommands(); this.startMetrics(); - this.checkUpdates(); this.finishEnabling(); } @@ -96,9 +97,12 @@ public void disable() throws Exception { } public void load() { + this.finishLoading(); + } + + private void assignAudiences() { this.audiences = BukkitAudiences.create(this.plugin); this.console = this.audiences.console(); - this.finishLoading(); } private void deserializeData() { @@ -173,8 +177,10 @@ private void shutdownLibrary() { } private void cancelNativeTasks() throws Exception { - this.cancelNativeExtractor(); - this.cancelNativeStreamExtractor(); + if (this.attributes != null) { + this.cancelNativeExtractor(); + this.cancelNativeStreamExtractor(); + } this.console.sendMessage(Locale.CANCELLED_TASKS.build()); } @@ -193,7 +199,8 @@ private void cancelNativeStreamExtractor() throws Exception { } private void createFolders() { - Set.of(this.plugin.getDataFolder().toPath().resolve("configuration")) + final Path folder = this.plugin.getDataFolder().toPath(); + Set.of(folder.resolve("configuration"), folder.resolve("data")) .forEach(ThrowingConsumer.unchecked(FileUtils::createFolderIfNotExists)); } @@ -271,7 +278,7 @@ private void registerCommands() { this.console.sendMessage(Locale.FIN_COMMANDS_INIT.build()); } - public Audience getLogger() { + public Audience getConsoleAudience() { return this.console; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java index dbe510dd6..26970acf2 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java @@ -180,11 +180,7 @@ private boolean shouldWaitForSegment( return false; } - record ChannelStreamInfo(String quality, String url) { + record ChannelStreamInfo(String quality, String url) {} - } - - record SegmentInfo(String url, Long duration, String name) { - - } + record SegmentInfo(String url, Long duration, String name) {} } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java index 564fd3858..386026a13 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java @@ -42,7 +42,7 @@ public class MusicSendHandler implements AudioSendHandler { * MusicSendHandler Public Constructor. * * @param musicManager MusicManager Class. - * @param audioPlayer AudioPlayer. + * @param audioPlayer AudioPlayer. */ public MusicSendHandler( @NotNull final MediaBot bot, diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java index ad6c7d1c5..8d376ee04 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java @@ -30,9 +30,7 @@ import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import org.jetbrains.annotations.NotNull; -/** - * Stolen from itxfrosty Music bot. - */ +/** Stolen from itxfrosty Music bot. */ public class TrackScheduler extends AudioEventAdapter { private final MediaBot bot; @@ -59,16 +57,12 @@ public void queueSong(@NotNull final AudioTrack track) { } } - /** - * Clear's Audio Queue. - */ + /** Clear's Audio Queue. */ public void clearQueue() { this.audioPlayer.stopTrack(); } - /** - * Skips Song. - */ + /** Skips Song. */ public void skip() { this.audioPlayer .getPlayingTrack() diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java index 2ec1b89d8..83dd27853 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java @@ -51,17 +51,11 @@ default RequiredArgumentBuilder argument( } @FunctionalInterface - interface Root extends CommandSegment> { - - } + interface Root extends CommandSegment> {} @FunctionalInterface - interface Literal extends CommandSegment> { - - } + interface Literal extends CommandSegment> {} @FunctionalInterface - interface Argument extends CommandSegment> { - - } + interface Argument extends CommandSegment> {} } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java index 74341d479..4c05c8d7f 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/audio/AudioLoadCommand.java @@ -96,14 +96,14 @@ private void wrapResourcepack() { final ResourcepackSoundWrapper wrapper = new ResourcepackSoundWrapper( daemon.getDaemon().getServerPath().resolve("resourcepack.zip"), "Audio Pack", 6); - wrapper.addSound(loader.getName().toLowerCase(java.util.Locale.ROOT), - this.attributes.getAudio()); + wrapper.addSound( + loader.getName().toLowerCase(java.util.Locale.ROOT), this.attributes.getAudio()); wrapper.wrap(); final Path path = wrapper.getResourcepackFilePath(); this.attributes.setLink(daemon.createUrl(path)); this.attributes.setHash(HashingUtils.createHashSHA(path).orElseThrow(AssertionError::new)); } catch (final IOException e) { - this.plugin.getLogger().sendMessage(Locale.ERR_RESOURCEPACK_WRAP.build()); + this.plugin.getConsoleAudience().sendMessage(Locale.ERR_RESOURCEPACK_WRAP.build()); e.printStackTrace(); } this.attributes.setCompletion(true); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java index 9238d5adf..7cd85f9a6 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/ffmpeg/FFmpegRemoveArgumentCommand.java @@ -71,8 +71,7 @@ private int removeArgument(@NotNull final CommandContext context) final Audience audience = this.plugin.audience().sender(context.getSource()); final String argument = context.getArgument("argument", String.class); this.ffmpeg.removeArgument(argument); - audience.sendMessage( - Locale.REMOVE_FFMPEG_ARG.build(argument)); + audience.sendMessage(Locale.REMOVE_FFMPEG_ARG.build(argument)); return SINGLE_SUCCESS; } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java index ae87ed03c..b4a907c05 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java @@ -190,7 +190,7 @@ public ItemBuilder clone() { * Add a lore line. * * @param line The lore line to add. - * @param pos The index of where to put it. + * @param pos The index of where to put it. */ public @NotNull ItemBuilder lore(@NotNull final Component line, final int pos) { final ItemMeta im = this.is.getItemMeta(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java index c56c4a48a..ec52638a9 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java @@ -29,8 +29,7 @@ public class SkullException extends AssertionError { - @Serial - private static final long serialVersionUID = 2394089956129784304L; + @Serial private static final long serialVersionUID = 2394089956129784304L; public SkullException(@NotNull final String message) { super("Invalid Skull Base64 %s!".formatted(message)); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java index 999d4bd11..77e53b243 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/image/SetImageCommand.java @@ -99,7 +99,7 @@ private int setImage(@NotNull final CommandContext context) { } audience.sendMessage(Locale.DREW_IMG.build(mrl)); } catch (final IOException e) { - this.plugin.getLogger().sendMessage(Locale.ERR_IMG_SET.build()); + this.plugin.getConsoleAudience().sendMessage(Locale.ERR_IMG_SET.build()); e.printStackTrace(); } }); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java index 8d9a6e250..467737231 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommand.java @@ -245,7 +245,7 @@ private int resumeVideo(@NotNull final CommandContext context) { private void buildResourcepack(@NotNull final Audience audience) { final DeluxeMediaPlugin plugin = this.plugin(); - final Audience console = plugin.getLogger(); + final Audience console = plugin.getConsoleAudience(); final JavaPlugin loader = plugin.getBootstrap(); try { final HttpServer server = plugin.getHttpServer(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java index 30bc3362d..ee21a0e70 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoCommandAttributes.java @@ -25,6 +25,7 @@ package io.github.pulsebeat02.deluxemediaplugin.command.video; import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting; import io.github.pulsebeat02.ezmediacore.ffmpeg.EnhancedExecution; import io.github.pulsebeat02.ezmediacore.player.MrlConfiguration; @@ -41,18 +42,39 @@ public final class VideoCommandAttributes { } private final AtomicBoolean completion; + @Expose + @SerializedName(value = "dither-type") private DitherSetting ditherType; + @Expose + @SerializedName(value = "audio-output") private AudioOutputType audioOutputType; + @Expose + @SerializedName(value = "playback-output") private PlaybackType playbackType; + @Expose + @SerializedName(value = "map-id") private int map; + @Expose - private int frameWidth, frameHeight; + @SerializedName(value = "frame-width") + private int frameWidth; + @Expose - private int pixelWidth, pixelHeight; + @SerializedName(value = "frame-height") + private int frameHeight; + + @Expose + @SerializedName(value = "pixel-width") + private int pixelWidth; + + @Expose + @SerializedName(value = "pixel-height") + private int pixelHeight; + private VideoPlayer player; private MrlConfiguration videoMrl; diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java index ec135cf35..3ffac3a05 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/video/VideoLoadCommand.java @@ -106,7 +106,7 @@ private int loadVideo(@NotNull final CommandContext context) { final Path folder = this.plugin.getBootstrap().getDataFolder().toPath().resolve("emc"); final AtomicBoolean successful = new AtomicBoolean(true); final AtomicBoolean status = this.attributes.getCompletion(); - final Audience console = this.plugin.getLogger(); + final Audience console = this.plugin.getConsoleAudience(); this.attributes.cancelCurrentStream(); CompletableFuture.runAsync( () -> { @@ -122,7 +122,7 @@ private int loadVideo(@NotNull final CommandContext context) { console.sendMessage(Locale.CREATE_RESOURCEPACK.build()); final Optional download = this.downloadMrl(audience, folder, mrl); if (download.isEmpty()) { - this.plugin.getLogger().sendMessage(Locale.ERR_DOWNLOAD_VIDEO.build()); + this.plugin.getConsoleAudience().sendMessage(Locale.ERR_DOWNLOAD_VIDEO.build()); status.set(true); successful.set(false); return; @@ -159,8 +159,8 @@ private void loadAndSendResourcepack(@NotNull final Path folder, @NotNull final daemon.getDaemon().getServerPath().resolve("resourcepack.zip"), "Audio Resourcepack", PackFormat.getCurrentFormat().getId()); - wrapper.addSound(this.plugin.getBootstrap().getName().toLowerCase(java.util.Locale.ROOT), - oggOutput); + wrapper.addSound( + this.plugin.getBootstrap().getName().toLowerCase(java.util.Locale.ROOT), oggOutput); wrapper.wrap(); this.attributes.setOggMrl(MrlConfiguration.ofMrl(oggOutput)); final Path path = wrapper.getResourcepackFilePath(); @@ -220,8 +220,13 @@ private void sendCompletionMessage(@NotNull final Audience audience, @NotNull fi Bukkit.getOnlinePlayers(), this.attributes.getResourcepackUrl(), this.attributes.getResourcepackHash()); - Bukkit.getOnlinePlayers().forEach((player) -> this.plugin.audience().player(player) - .sendMessage(Locale.SEND_RESOURCEPACK_URL.build(player))); + Bukkit.getOnlinePlayers() + .forEach( + (player) -> + this.plugin + .audience() + .player(player) + .sendMessage(Locale.SEND_RESOURCEPACK_URL.build(player))); audience.sendMessage(Locale.LOADED_MEDIA.build(mrl)); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java index dba4818ea..3369197e8 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/config/BotConfiguration.java @@ -53,7 +53,7 @@ public void deserialize() throws IOException { public void serialize() { final DeluxeMediaPlugin plugin = this.getPlugin(); final FileConfiguration configuration = this.getFileConfiguration(); - final Audience console = plugin.getLogger(); + final Audience console = plugin.getConsoleAudience(); boolean invalid = false; final String token = configuration.getString("token"); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java index a5cc981da..5b1552e91 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/executors/ExecutorProvider.java @@ -31,10 +31,12 @@ public class ExecutorProvider { public static final Executor STREAM_THREAD_EXECUTOR; + public static final Executor PERIODIC_CHECK_EXECUTOR; public static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE; static { STREAM_THREAD_EXECUTOR = Executors.newFixedThreadPool(4); + PERIODIC_CHECK_EXECUTOR = Executors.newSingleThreadExecutor(); SCHEDULED_EXECUTOR_SERVICE = Executors.newScheduledThreadPool(4); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java index aebfe998f..3bf4b0d12 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/DataProvider.java @@ -24,9 +24,12 @@ package io.github.pulsebeat02.deluxemediaplugin.json; import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,31 +38,40 @@ public abstract class DataProvider implements DataHolder { private final DeluxeMediaPlugin plugin; private final String name; private final Path path; + private final Class clazz; private T object; - public DataProvider(@NotNull final DeluxeMediaPlugin plugin, @NotNull final String name) { + public DataProvider( + @NotNull final DeluxeMediaPlugin plugin, + @NotNull final Class clazz, + @NotNull final String name) { this.plugin = plugin; this.name = name; - this.path = plugin.getBootstrap().getDataFolder().toPath().resolve(this.name); + this.path = plugin.getBootstrap().getDataFolder().toPath().resolve(this.name).toAbsolutePath(); + this.clazz = clazz; } @Override public void deserialize(@NotNull final T obj) throws IOException { - GsonProvider.getGson().toJson(obj, Files.newBufferedWriter(this.path)); + try (final BufferedWriter writer = Files.newBufferedWriter(this.path)) { + GsonProvider.getGson().toJson(obj, writer); + } } @Override public void serialize() throws IOException { this.saveConfig(); - this.object = - (T) - GsonProvider.getGson() - .fromJson(Files.newBufferedReader(this.path), this.object.getClass()); + try (final BufferedReader reader = Files.newBufferedReader(this.path.toAbsolutePath())) { + this.object = GsonProvider.getGson().fromJson(reader, this.clazz); + } } - private void saveConfig() { + private void saveConfig() throws IOException { if (!Files.exists(this.path)) { - this.plugin.getBootstrap().saveResource(this.name, false); + Files.copy( + this.plugin.getBootstrap().getResource(this.name), + this.path, + StandardCopyOption.REPLACE_EXISTING); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java index 2ea2437d4..3d6b35924 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/json/MediaAttributesData.java @@ -30,6 +30,6 @@ public class MediaAttributesData extends DataProvider { public MediaAttributesData(@NotNull final DeluxeMediaPlugin plugin) { - super(plugin, "data/video-attributes.json"); + super(plugin, VideoCommandAttributes.class, "data/video-attributes.json"); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java index 39e330676..3abf65d65 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java @@ -71,7 +71,61 @@ public interface Locale { .append(text(argument, GRAY)) .append(text("]")) .build(); - + NullComponent PLUGIN_AUTHORS = () -> text() + .append(text("-----------------------------------", GOLD)) + .append(newline()) + .append(text("Plugin: ", GOLD, BOLD)) + .append(text("DeluxeMediaPlugin", AQUA)) + .append(newline()) + .append(text("Authors: ", GOLD, BOLD)) + .append( + text( + "PulseBeat_02", + style( + AQUA, + text("PulseBeat_02's Github", GOLD).asHoverEvent(), + openUrl("https://github.com/PulseBeat02")))) + .append(text(", ", GOLD)) + .append( + text( + "itxfrosty", + style( + AQUA, + text("itxfrosty's Github", GOLD).asHoverEvent(), + openUrl("https://github.com/itxfrosty")))) + .append(newline()) + .append(text("Version: ", GOLD, BOLD)) + .append(text("BETA Release", AQUA)) + .append(newline()) + .append(newline()) + .append( + text( + "Click for Support Server", + style( + GOLD, + BOLD, + openUrl("https://discord.gg/AqK5dKdUZe"), + text("Click for Discord Server", GOLD).asHoverEvent()))) + .append(newline()) + .append(text("-----------------------------------", GOLD)) + .append() + .build(); + NullComponent PLUGIN_LOGO = () -> getComponent( + Arrays.asList( + " _____ _ __ __ _ _ _____ _ _ ", + " | __ \\ | | | \\/ | | (_) | __ \\| | (_) ", + " | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ ", + " | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\ ", + " | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | |", + " |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_|", + " __/ | ", + " |___/ "), + (line) -> newline().append(text(line, BLUE))); + NullComponent PLUGIN_PREFIX = () -> + text() + .color(AQUA) + .append( + text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)).build(); NullComponent ENABLE_PLUGIN = () -> format(join(separator(text(" ")), text("Running DeluxeMediaPlugin", AQUA), text("[BETA]", GOLD), @@ -89,16 +143,13 @@ public interface Locale { NullComponent DISABLE_BOT = () -> format(text("Successfully disabled Discord bot! (If running)")); NullComponent CANCELLED_TASKS = () -> format(text("Successfully disabled all native tasks!")); NullComponent GOODBYE = () -> format(text("Good Bye! :(")); - NullComponent FIN_EMC_INIT = () -> format(text("Finished loading MinecraftMediaLibrary instance!")); NullComponent FIN_PERSISTENT_INIT = () -> format(text("Finished loading persistent data!")); NullComponent FIN_COMMANDS_INIT = () -> format(text("Finished registering plugin commands!")); NullComponent FIN_METRICS_INIT = () -> format(text("Finished loading Metrics data!")); NullComponent FIN_PLUGIN_INIT = () -> format(text("Finished loading DeluxeMediaPlugin!")); - NullComponent RUNNING_LATEST_PLUGIN = () -> format(text( "You are currently running the latest version of DeluxeMediaPlugin.")); - NullComponent ERR_EMC_INIT = () -> format(text("There was a severe issue while loading the EzMediaCore instance!", RED)); NullComponent ERR_PERSISTENT_INIT = () -> format(text( @@ -138,95 +189,34 @@ public interface Locale { NullComponent ERR_BOT_TOKEN = () -> format(text("Bot token not specified in bot.yml!", RED)); NullComponent ERR_GUILD_TOKEN = () -> format(text("Guild token not specified in bot.yml!", RED)); NullComponent ERR_VC_ID = () -> format(text("Voice Chat Identifier not specified in bot.yml!", RED)); - NullComponent START_AUDIO = () -> format(text("Started playing audio!")); NullComponent PAUSE_AUDIO = () -> format(text("Stopped playing audio!")); NullComponent RESUME_AUDIO = () -> format(text("Resumed the video!")); NullComponent CREATE_RESOURCEPACK = () -> format(text( "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.")); - NullComponent DC_DISCORD = () -> format(text("Successfully disconnected from voice channel!")); NullComponent C_DISCORD = () -> format(text("Successfully connected to voice channel!")); NullComponent PAUSED_TRACK_DISCORD = () -> format(text("Successfully paused track!")); NullComponent RESUMED_TRACK_DISCORD = () -> format(text("Successfully resumed track!")); - NullComponent DITHERING_OPTIONS = () -> format(text("Dithering Options ->") .append(getComponent(DitherSetting.class, (value) -> text(value.getName(), AQUA).append(newline())))); - NullComponent FFMPEG_EXEC = () -> format(text("Executed FFmpeg command!")); NullComponent RESET_FFMPEG_ARGS = () -> format(text("Reset all FFmpeg arguments!")); - NullComponent LOAD_IMG = () -> format(text("Loading image...")); NullComponent PURGE_ALL_MAPS_VERIFY = () -> format(text( "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...")); NullComponent PURGED_ALL_MAPS = () -> format(text("Successfully purged all images!")); NullComponent CANCELLED_PURGE_ALL_MAPS = () -> format(text("Cancelled purge of all images!")); - NullComponent PAUSE_VIDEO = () -> format(text("Stopped the video!")); NullComponent RELEASE_VIDEO = () -> format(text("Successfully destroyed the current video!")); NullComponent SETUP_RESOURCEPACK = () -> format(text( "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.")); NullComponentDISCORD_AUDIO_STREAM = () -> format(text("Started playing audio into Discord voice chat!")); - NullComponent DUMP_THREADS = () -> format(text("Created thread dump! Look in console for more details.")); - NullComponent CANCELLED_VIDEO_PROCESSING = () -> format(text("Successfully cancelled the video loading process!")); NullComponent LOADING_VIDEO = () -> format(text("Initializing and reading media...")); - NullComponent BUILT_SCREEN = () -> format(text("Successfully built your new screen!")); - - NullComponent PLUGIN_AUTHORS = () -> text() - .append(text("-----------------------------------", GOLD)) - .append(newline()) - .append(text("Plugin: ", GOLD, BOLD)) - .append(text("DeluxeMediaPlugin", AQUA)) - .append(newline()) - .append(text("Authors: ", GOLD, BOLD)) - .append( - text( - "PulseBeat_02", - style( - AQUA, - text("PulseBeat_02's Github", GOLD).asHoverEvent(), - openUrl("https://github.com/PulseBeat02")))) - .append(text(", ", GOLD)) - .append( - text( - "itxfrosty", - style( - AQUA, - text("itxfrosty's Github", GOLD).asHoverEvent(), - openUrl("https://github.com/itxfrosty")))) - .append(newline()) - .append(text("Version: ", GOLD, BOLD)) - .append(text("BETA Release", AQUA)) - .append(newline()) - .append(newline()) - .append( - text( - "Click for Support Server", - style( - GOLD, - BOLD, - openUrl("https://discord.gg/AqK5dKdUZe"), - text("Click for Discord Server", GOLD).asHoverEvent()))) - .append(newline()) - .append(text("-----------------------------------", GOLD)) - .append() - .build(); - NullComponent PLUGIN_LOGO = () -> getComponent( - Arrays.asList( - " _____ _ __ __ _ _ _____ _ _ ", - " | __ \\ | | | \\/ | | (_) | __ \\| | (_) ", - " | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ ", - " | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\ ", - " | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | |", - " |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_|", - " __/ | ", - " |___/ "), - (line) -> text(line, BLUE).append(newline())); - UniComponent DREW_IMG = (mrl) -> format(text("Successfully drew image with mrl %s".formatted(mrl))); UniComponent START_TRACK_DISCORD = (mrl) -> format(text("Successfully started audio on MRL %s!".formatted(mrl))); @@ -272,12 +262,10 @@ public interface Locale { "Could not find dither type %s".formatted(algorithm), RED)); UniComponent ERR_INVALID_VIDEO_TYPE = (mode) -> format(text("Could not find video mode %s".formatted(mode), RED)); UniComponent ERR_CANNOT_CHECK_UPDATES = (msg) -> format(text("Cannot look for updates: %s".formatted(msg), RED)); - UniComponent> LIST_FFMPEG_ARGS = (list) -> format(join( separator(space()), text("Current FFmpeg arguments:", GOLD), text(list.toString(), AQUA))); - UniComponent PURGE_MAP = (id) -> format(join( @@ -290,9 +278,7 @@ public interface Locale { separator(space()), text("Set starting map id to", GOLD), text(id, AQUA))); - UniComponent RESUMING_VIDEO_MS = (ms) -> format(text("Resuming Video at %s Milliseconds!")); - UniComponent SEND_RESOURCEPACK_URL = (player) -> format(text() .append(text("Loaded resourcepack for all players! Click ", GOLD)) .append( @@ -309,13 +295,11 @@ public interface Locale { .asHoverEvent()))) .append(text(" to retrieve the resourcepack", GOLD)) .build()); - BiComponent FIN_RESOURCEPACK_INIT = (url, hash) -> format(text( "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); BiComponent SENT_RESOURCEPACK = (url, hash) -> format(text( "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); - BiComponent ADD_FFMPEG_ARG_INDX = (str, index) -> format(join( @@ -331,7 +315,6 @@ public interface Locale { text(str, AQUA), text("from the FFmpeg command at index", GOLD), text(index, AQUA))); - BiComponent CHANGED_IMG_DIMS = (width, height) -> format(text( "Changed itemframe dimensions to %d:%d (width:height)".formatted(width, height))); @@ -354,13 +337,6 @@ public interface Locale { text("Set itemframe map dimensions to", GOLD), text("%d:%d".formatted(width, height), AQUA), text("(width:height)", GOLD))); - - NullComponent PLUGIN_PREFIX = () -> - text() - .color(AQUA) - .append( - text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)).build(); - UniComponent FFMPEG_PROCESS = (str) -> text() .color(AQUA) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java index 4a8b5420d..86de9811a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/update/UpdateChecker.java @@ -25,8 +25,10 @@ package io.github.pulsebeat02.deluxemediaplugin.update; import io.github.pulsebeat02.deluxemediaplugin.DeluxeMediaPlugin; +import io.github.pulsebeat02.deluxemediaplugin.executors.ExecutorProvider; import io.github.pulsebeat02.deluxemediaplugin.message.Locale; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.util.Scanner; import java.util.concurrent.CompletableFuture; @@ -48,25 +50,23 @@ public UpdateChecker(@NotNull final DeluxeMediaPlugin plugin) { } public void check() { - CompletableFuture.runAsync(this::request); + CompletableFuture.runAsync(this::request, ExecutorProvider.PERIODIC_CHECK_EXECUTOR); } private void request() { - final Audience console = this.plugin.getLogger(); - try (final Scanner scanner = - new Scanner( - new URL( - "https://api.spigotmc.org/legacy/update.php?resource=%d" - .formatted(this.resource)) - .openStream())) { + final Audience console = this.plugin.getConsoleAudience(); + final String url = + "https://api.spigotmc.org/legacy/update.php?resource=%d".formatted(this.resource); + try (final InputStream is = new URL(url).openStream(); + final Scanner scanner = new Scanner(is)) { final String update = scanner.next(); if (this.plugin.getBootstrap().getDescription().getVersion().equalsIgnoreCase(update)) { console.sendMessage(Locale.NEW_UPDATE_PLUGIN.build(update)); } else { console.sendMessage(Locale.RUNNING_LATEST_PLUGIN.build()); } - } catch (final IOException exception) { - console.sendMessage(Locale.ERR_CANNOT_CHECK_UPDATES.build(exception.getMessage())); + } catch (final IOException e) { + console.sendMessage(Locale.ERR_CANNOT_CHECK_UPDATES.build(e.getMessage())); } } } diff --git a/deluxemediaplugin/src/main/resources/data/video-attributes.json b/deluxemediaplugin/src/main/resources/data/video-attributes.json index 1f1811988..a5a6f3873 100644 --- a/deluxemediaplugin/src/main/resources/data/video-attributes.json +++ b/deluxemediaplugin/src/main/resources/data/video-attributes.json @@ -1,11 +1,11 @@ { "completion": false, - "ditherType": "FILTER_LITE", - "audioOutputType": "RESOURCEPACK", - "playbackType": "ITEMFRAME", - "map": 0, - "frameWidth": 5, - "frameHeight": 5, - "pixelWidth": 640, - "pixelHeight": 360 + "dither-type": "FILTER_LITE", + "audio-output": "RESOURCEPACK", + "playback-output": "ITEMFRAME", + "map-id": 0, + "frame-width": 5, + "frame-height": 5, + "pixel-width": 640, + "pixel-height": 360 } \ No newline at end of file diff --git a/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java b/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java index 8ce147bb7..3832a95ae 100644 --- a/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java +++ b/deluxemediaplugin/src/test/java/io/github/deluxemediaplugin/JSONVideoAttributesTest.java @@ -3,6 +3,7 @@ import com.google.gson.Gson; import io.github.pulsebeat02.deluxemediaplugin.command.video.VideoCommandAttributes; import io.github.pulsebeat02.deluxemediaplugin.json.GsonProvider; +import java.io.BufferedReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -12,12 +13,12 @@ public class JSONVideoAttributesTest { public static void main(final String[] args) throws IOException { final Gson gson = GsonProvider.getGson(); System.out.println(gson.toJson(new VideoCommandAttributes())); - System.out.println( - gson.fromJson( - Files.newBufferedReader( - Path.of( - System.getProperty("user.dir"), - "deluxemediaplugin/src/main/resources/data/video-attributes.json")), - VideoCommandAttributes.class)); + try (final BufferedReader writer = + Files.newBufferedReader( + Path.of( + System.getProperty("user.dir"), + "deluxemediaplugin/src/main/resources/data/video-attributes.json"))) { + System.out.println(gson.fromJson(writer, VideoCommandAttributes.class)); + } } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java index 4aea95c89..671b67112 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java @@ -129,8 +129,7 @@ private void getPacketInstance() { } private void initializeStream() { - IntStream.range(0, 5).parallel().forEach(key -> { - }); // jump start int stream + IntStream.range(0, 5).parallel().forEach(key -> {}); // jump start int stream } private void initializeProviders() { @@ -150,9 +149,9 @@ private void sendUsageTips() { public void shutdown() { Logger.info("Shutting Down"); this.disabled = true; - // this.streams.release(); HandlerList.unregisterAll(this.registrationListener); Logger.info("Good Bye! :("); + Logger.closeAllLoggers(); } @Override diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java index e8a13c4ed..79058a748 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java @@ -69,6 +69,14 @@ public static void init(@NotNull final MediaLibraryCore core) { } } + public static void closeAllLoggers() { + LOGGER.close(); + VLC_LOGGER.close(); + RTP_LOGGER.close(); + FFMPEG_PLAYER_LOGGER.close(); + FFMPEG_STREAMER_LOGGER.close(); + } + /** * Prints the text as an [INFO] * diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/ArtifactInstaller.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/ArtifactInstaller.java index 213773ef1..94f340c23 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/ArtifactInstaller.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/ArtifactInstaller.java @@ -125,10 +125,8 @@ private void download() throws InterruptedException { } private void relocate() throws InterruptedException { - Logger.info( "Preparing to relocate %d dependencies (%s)".formatted(this.jars.size(), this.jars)); - this.service.invokeAll( this.jars.stream() .map(path -> Executors.callable(() -> this.relocateFile(path, this.factory))) @@ -136,25 +134,20 @@ private void relocate() throws InterruptedException { } private void writeHashes() throws IOException { - Logger.info("Recording relocated JAR hashes"); - try (final PrintWriter writer = new PrintWriter(Files.newBufferedWriter(this.hashFile))) { this.hashes.forEach(writer::println); } } private void load() throws IOException { - Logger.info("Preparing to load %d dependencies (%s)".formatted(this.jars.size(), this.jars)); - final Set invalid = Files.walk(this.relocatedFolder, 1) .filter(Files::isRegularFile) .filter(path -> PathUtils.getName(path).endsWith(".jar")) .filter(path -> !this.hashes.contains(HashingUtils.getHash(path))) .collect(Collectors.toSet()); - if (!invalid.isEmpty()) { for (final Path p : invalid) { Logger.warn( @@ -162,7 +155,6 @@ private void load() throws IOException { this.redownload(p, this.getDependency(p).orElseThrow(AssertionError::new)); } } - new JarLoader( Files.walk(this.relocatedFolder, 1) .filter(Files::isRegularFile) @@ -172,12 +164,9 @@ private void load() throws IOException { } private void delete() { - Logger.info( "Preparing to delete %d stale dependencies (%s)".formatted(this.jars.size(), this.jars)); - this.jars.forEach(ThrowingConsumer.unchecked(Files::delete)); - this.jars.clear(); } @@ -203,11 +192,9 @@ private boolean requiresDownload(@NotNull final DependencyInfo dependency) { @NotNull private Path downloadDependency(@NotNull final DependencyInfo dependency) { - final Repositories resolution = dependency.getResolution(); final String artifact = dependency.getArtifact(); final String path = this.dependencyFolder.toString(); - Optional file; try { switch (resolution) { @@ -226,7 +213,6 @@ private Path downloadDependency(@NotNull final DependencyInfo dependency) { resolution.getUrl())); e.printStackTrace(); } - if (file.isPresent()) { final Path p = file.get(); if (DependencyUtils.validateDependency(p, dependency)) { @@ -249,7 +235,6 @@ private Path downloadDependency(@NotNull final DependencyInfo dependency) { */ return this.downloadDependency(dependency); } - return file.get(); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/FFmpegInstaller.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/FFmpegInstaller.java index 5cab630ab..8ac5da3c5 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/FFmpegInstaller.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/FFmpegInstaller.java @@ -77,26 +77,30 @@ private void writeHashes() throws IOException { } private void download() throws IOException { - final Optional optional = this.detectExecutable(this.folder); if (optional.isPresent()) { this.executable = optional.get(); return; } + this.executable = this.internalDownload(); + this.setPermissions(this.executable); + this.hash = HashingUtils.getHash(this.executable); + } + private Path internalDownload() throws IOException { final Diagnostic diagnostic = this.core.getDiagnostics(); - final OSType type = diagnostic.getSystem().getOSType(); final String url = diagnostic.getFFmpegUrl(); final Path download = this.folder.resolve(FilenameUtils.getName(new URL(url).getPath())); FileUtils.createIfNotExists(download); - DependencyUtils.downloadFile(download, url); + return download; + } + + private void setPermissions(@NotNull final Path download) throws IOException { + final OSType type = this.core.getDiagnostics().getSystem().getOSType(); if (type == OSType.MAC || type == OSType.UNIX) { new CommandTask("chmod", "-R", "777", download.toAbsolutePath().toString()).run(); } - - this.executable = download; - this.hash = HashingUtils.getHash(this.executable); } private @NotNull Optional detectExecutable(@NotNull final Path folder) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/RTPInstaller.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/RTPInstaller.java index aa7143124..66d7e181d 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/RTPInstaller.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/dependency/RTPInstaller.java @@ -83,23 +83,32 @@ private void download() throws IOException { this.executable = optional.get(); return; } + final Path parent = this.internalDownload(); + final String baseName = "rtsp-simple-server"; + this.executable = + this.core.getDiagnostics().getSystem().getOSType() == OSType.WINDOWS + ? parent.resolve("%s.exe".formatted(baseName)) + : parent.resolve(baseName); + this.changePermissions(); + this.hash = HashingUtils.getHash(this.executable); + } + + private Path internalDownload() throws IOException { final Diagnostic diagnostic = this.core.getDiagnostics(); - final OSType type = diagnostic.getSystem().getOSType(); final String url = diagnostic.getRtpUrl(); final Path download = this.folder.resolve(FilenameUtils.getName(new URL(url).getPath())); final Path parent = download.getParent(); FileUtils.createIfNotExists(download); DependencyUtils.downloadFile(download, url); ArchiveUtils.decompressArchive(download, parent); - final String baseName = "rtsp-simple-server"; - this.executable = - this.core.getDiagnostics().getSystem().getOSType() == OSType.WINDOWS - ? parent.resolve("%s.exe".formatted(baseName)) - : parent.resolve(baseName); + return parent; + } + + private void changePermissions() throws IOException { + final OSType type = this.core.getDiagnostics().getSystem().getOSType(); if (type == OSType.MAC || type == OSType.UNIX) { new CommandTask("chmod", "-R", "777", this.executable.toAbsolutePath().toString()).run(); } - this.hash = HashingUtils.getHash(this.executable); } private @NotNull Optional detectExecutable(@NotNull final Path folder) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java index c1f3eaa60..d77964cb6 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java @@ -29,7 +29,6 @@ import io.github.pulsebeat02.ezmediacore.http.request.ZipHeader; import io.github.pulsebeat02.ezmediacore.http.request.ZipRequest; import java.io.IOException; -import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.nio.file.Path; @@ -47,32 +46,14 @@ public class HttpServerDaemon implements HttpDaemon, ZipRequest { private boolean running; public HttpServerDaemon( - @NotNull final Path path, @NotNull final String ip, final int port, final boolean verbose) - throws IOException { + @NotNull final Path path, @NotNull final String ip, final int port, final boolean verbose) { this.running = true; this.directory = path; this.ip = ip; this.port = port; this.verbose = verbose; this.header = ZipHeader.ZIP; - - try { - this.socket = new ServerSocket(port); - this.socket.setReuseAddress(true); - } catch (final BindException e) { - Logger.error( - "The port specified is being used by another process. Please make sure to port-forward the port first and make sure it is open."); - Logger.error(e.getMessage()); - return; - } - - Logger.info("========================================"); - Logger.info(" Started HTTP Server: "); - Logger.info("========================================"); - Logger.info("IP Address: %s".formatted(ip)); - Logger.info("Port: %d".formatted(port)); - Logger.info("Directory: %s".formatted(path)); - Logger.info("========================================"); + this.logServerInformation(); } public HttpServerDaemon( @@ -84,9 +65,35 @@ public HttpServerDaemon( this(core.getHttpServerPath(), ip, port, verbose); } + private void logServerInformation() { + Logger.info("========================================"); + Logger.info(" Started HTTP Server: "); + Logger.info("========================================"); + Logger.info("IP Address: %s".formatted(this.ip)); + Logger.info("Port: %d".formatted(this.port)); + Logger.info("Directory: %s".formatted(this.directory)); + Logger.info("========================================"); + } + @Override public void start() { this.onServerStart(); + this.openServerSocket(); + this.handleServerRequests(); + } + + private void openServerSocket() { + try { + this.socket = new ServerSocket(this.port); + this.socket.setReuseAddress(true); + } catch (final IOException e) { + Logger.error( + "The port specified is being used by another process. Please make sure to port-forward the port first and make sure it is open."); + Logger.error(e.getMessage()); + } + } + + private void handleServerRequests() { while (this.running) { try { ExecutorProvider.HTTP_REQUEST_POOL.submit( @@ -98,8 +105,7 @@ public void start() { } @Override - public void onServerStart() { - } + public void onServerStart() {} @Override public void stop() { @@ -115,16 +121,13 @@ public void stop() { } @Override - public void onServerTermination() { - } + public void onServerTermination() {} @Override - public void onClientConnection(@NotNull final Socket client) { - } + public void onClientConnection(@NotNull final Socket client) {} @Override - public void onRequestFailure(@NotNull final Socket client) { - } + public void onRequestFailure(@NotNull final Socket client) {} @Override public boolean isVerbose() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java index 0d6f786f9..66096e668 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java @@ -62,8 +62,7 @@ public Image( } @Override - public void onStartDrawImage() { - } + public void onStartDrawImage() {} @Override public @NotNull BufferedImage[][] process(@NotNull BufferedImage image, final boolean resize) { @@ -85,8 +84,7 @@ public void onStartDrawImage() { } @Override - public void onFinishDrawImage() { - } + public void onFinishDrawImage() {} @Override public void resetMaps() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java index 345d0b8a1..d69e81b2c 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java @@ -26,6 +26,8 @@ import com.google.common.reflect.TypeToken; import io.github.pulsebeat02.ezmediacore.image.Image; import io.github.pulsebeat02.ezmediacore.json.GsonProvider; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -42,16 +44,16 @@ public PersistentImageStorage(@NotNull final Path path) { @Override public void serialize(@NotNull final Collection list) throws IOException { super.serialize(list); - GsonProvider.getPretty().toJson(list, Files.newBufferedWriter(this.getStorageFile())); + try (final BufferedWriter writer = Files.newBufferedWriter(this.getStorageFile())) { + GsonProvider.getPretty().toJson(list, writer); + } } @Override public List deserialize() throws IOException { super.deserialize(); - return GsonProvider.getSimple() - .fromJson( - Files.newBufferedReader(this.getStorageFile()), - new TypeToken>() { - }.getType()); + try (final BufferedReader reader = Files.newBufferedReader(this.getStorageFile())) { + return GsonProvider.getSimple().fromJson(reader, new TypeToken>() {}.getType()); + } } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackSoundWrapper.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackSoundWrapper.java index e7b7772a6..af9413bb3 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackSoundWrapper.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackSoundWrapper.java @@ -58,16 +58,12 @@ public ResourcepackSoundWrapper( @Override public void wrap() throws IOException { - this.onPackStartWrap(); - this.sounds.forEach( ThrowingBiConsumer.sneaky( (key, value) -> this.addFile("assets/minecraft/sounds/%s.ogg".formatted(key), value))); this.addFile("assets/minecraft/sounds.json", this.createSoundJson()); - this.internalWrap(); - this.onPackFinishWrap(); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java index e51d38319..2d0f590ff 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java @@ -78,52 +78,19 @@ public ResourcepackWrapper( public void wrap() throws IOException { this.onPackStartWrap(); this.internalWrap(); - - // try (final ZipOutputStream out = - // new ZipOutputStream(new FileOutputStream(this.path.toFile()))) { - // - // FileUtils.createFileIfNotExists(this.path); - // - // final ZipEntry config = new ZipEntry("pack.mcmeta"); - // out.putNextEntry(config); - // out.write(getPackMcmeta().getBytes()); - // out.closeEntry(); - // - // final ZipEntry sound = new ZipEntry("assets/minecraft/sounds.json"); - // out.putNextEntry(sound); - // out.write(getSoundJson().getBytes()); - // out.closeEntry(); - // - // final ZipEntry soundFile = new ZipEntry("assets/minecraft/sounds/audio.ogg"); - // out.putNextEntry(soundFile); - // out.write(Files.readAllBytes(Path.of(this.audio.toString()))); - // out.closeEntry(); - // - // if (this.icon != null && Files.exists(this.icon)) { - // final ZipEntry iconFile = new ZipEntry("pack.png"); - // out.putNextEntry(iconFile); - // out.write(Files.readAllBytes(icon)); - // out.closeEntry(); - // } - // } - this.onPackFinishWrap(); } @Override public void internalWrap() throws IOException { - Logger.info("Wrapping the Resourcepack"); try (final ZipOutputStream out = new ZipOutputStream(new FileOutputStream(this.path.toFile()))) { - FileUtils.createIfNotExists(this.path); this.addFile("pack.mcmeta", this.getPackMcmeta().getBytes()); - if (this.icon != null) { this.addFile("pack.png", this.icon); } - for (final Map.Entry entry : this.files.entrySet()) { out.putNextEntry(new ZipEntry(entry.getKey())); out.write(entry.getValue()); @@ -134,12 +101,10 @@ public void internalWrap() throws IOException { } @Override - public void onPackStartWrap() { - } + public void onPackStartWrap() {} @Override - public void onPackFinishWrap() { - } + public void onPackFinishWrap() {} @Override public void addFile(@NotNull final String path, @NotNull final Path file) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java index 52ba58971..f2f9a6c4e 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java @@ -53,16 +53,12 @@ import java.util.concurrent.CompletableFuture; import org.jetbrains.annotations.NotNull; -/** - * Constructs a chain of commands to be executed accordingly. - */ +/** Constructs a chain of commands to be executed accordingly. */ public class CommandTaskChain { private final Map chain; - /** - * Instantiates a new CommandTaskChain - */ + /** Instantiates a new CommandTaskChain */ public CommandTaskChain() { this.chain = new LinkedHashMap<>(); } @@ -112,28 +108,33 @@ public void run() throws IOException, InterruptedException { for (final Map.Entry entry : this.chain.entrySet()) { final CommandTask task = entry.getKey(); if (entry.getValue()) { - CompletableFuture.runAsync( - () -> { - try { - task.run(); - Logger.info( - "Task Command: %s Result: %s" - .formatted(String.join(" ", task.getCommand()), task.getResult())); - } catch (final IOException e) { - e.printStackTrace(); - } - }, - ExecutorProvider.EXTERNAL_PROCESS_POOL); + CompletableFuture.runAsync(() -> this.runTask(task), ExecutorProvider.EXTERNAL_PROCESS_POOL); } else { - task.run(); - if (task.getProcess().waitFor() == 0) { - Logger.info( - "Task Command: %s Result: %s" - .formatted(String.join(" ", task.getCommand()), task.getResult())); - } else { - Logger.info("An exception has occurred!"); - } + this.runTaskChain(task); } } } + + private void runTask(@NotNull final CommandTask task) { + try { + task.run(); + Logger.info( + "Task Command: %s Result: %s" + .formatted(String.join(" ", task.getCommand()), task.getResult())); + } catch (final IOException e) { + e.printStackTrace(); + } + } + + private void runTaskChain(@NotNull final CommandTask task) + throws IOException, InterruptedException { + task.run(); + if (task.getProcess().waitFor() == 0) { + Logger.info( + "Task Command: %s Result: %s" + .formatted(String.join(" ", task.getCommand()), task.getResult())); + } else { + Logger.info("An exception has occurred!"); + } + } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java index 6d466b144..c62e1a160 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java @@ -68,20 +68,29 @@ public EMCNativeDiscovery( this.keyword = "libvlc.%s".formatted(algorithm.getFileExtension()); } - @Override - public @NotNull Optional discover(@NotNull final Path directory) { - - Logger.info("Searching in Directory %s".formatted(directory)); - + private @NotNull Optional vlcjDiscovery() { final NativeDiscovery discovery = new NativeDiscovery(); if (discovery.discover()) { return Optional.of(Path.of(discovery.discoveredPath())); } + return Optional.empty(); + } + @Override + public @NotNull Optional discover(@NotNull final Path directory) { + Logger.info("Searching in Directory %s".formatted(directory)); + final Optional discovery = this.vlcjDiscovery(); + if (discovery.isPresent()) { + return discovery; + } if (Files.notExists(directory)) { + Logger.info("Discover directory path does not exist!"); return Optional.empty(); } + return this.discoverDirectory(directory); + } + private @NotNull Optional discoverDirectory(@NotNull final Path directory) { try { final CompletableFuture plugins = CompletableFuture.supplyAsync(() -> this.locatePluginsFolder(directory)); @@ -94,7 +103,6 @@ public EMCNativeDiscovery( } catch (final InterruptedException | ExecutionException e) { e.printStackTrace(); } - return Optional.empty(); } @@ -160,7 +168,7 @@ private void setVLCPluginPath(@NotNull final Path path) { private boolean loadLibVLCLibrary() { try { final libvlc_instance_t instance = - libvlc_new(0, new StringArray(new String[]{"--reset-plugins-cache"})); + libvlc_new(0, new StringArray(new String[] {"--reset-plugins-cache"})); if (instance != null) { libvlc_release(instance); final LibVlcVersion version = new LibVlcVersion(); diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/NativeBinarySearch.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/NativeBinarySearch.java index 816413f7b..08ecaf059 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/NativeBinarySearch.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/NativeBinarySearch.java @@ -118,16 +118,13 @@ private EMCNativeDiscovery getDiscovery() { @Override public Optional search() { - if (this.path != null) { return Optional.of(this.path); } - final List paths = this.getSearchDirectories(); if (this.search != null) { paths.add(this.search.toString()); } - for (final String path : paths) { final Optional optional = this.provider.discover(Path.of(path)); if (optional.isPresent()) { @@ -135,9 +132,7 @@ public Optional search() { break; } } - Logger.info(this.path == null ? "VLC path is invalid!" : "VLC path is valid!"); - return Optional.ofNullable(this.path); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java index 2238bc1dc..6a0ea8b4e 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java @@ -45,36 +45,49 @@ public SilentMacInstallation( return OSType.MAC; } - @Override - public void downloadBinaries() throws IOException, InterruptedException { - - final Path directory = this.getDirectory(); - final Path dmg = directory.resolve("VLC.dmg"); - final Path disk = Path.of("/Volumes/VLC media player"); - final Path app = directory.resolve("VLC.app"); - + private void downloadChecksum(@NotNull final Path dmg) throws IOException { new VLCBinaryChecksum(this.getCore().getDiagnostics().getVlcUrl(), dmg).downloadFile(); Logger.info("Successfully downloaded DMG file!"); + } + private void mountDisk(@NotNull final Path dmg) throws IOException, InterruptedException { if (this.mountDiskImage(dmg) != 0) { throw new RuntimeException("A severe I/O error has occurred. Could not mount disk file!"); } Logger.info("Successfully mounted disk!"); + } + private void copyDiskFiles(@NotNull final Path disk, @NotNull final Path app) throws IOException { org.apache.commons.io.FileUtils.copyDirectory(disk.resolve("VLC.app").toFile(), app.toFile()); Logger.info("Successfully moved VLC app folder!"); + } - if (this.changePermissions(app) != 0) { + private void changePermissions(@NotNull final Path app) throws IOException, InterruptedException { + if (this.changePermissionsTask(app) != 0) { throw new RuntimeException( "A severe permission error has occurred. Could not change permissions of VLC application!"); } Logger.info("Successfully changed permissions for application!"); + } + private void unmountDisk(@NotNull final Path disk) throws IOException, InterruptedException { if (this.unmountDiskImage(disk) != 0) { throw new RuntimeException("A severe I/O error has occurred. Could not unmount disk file!"); } Logger.info("Successfully unmounted disk!"); + } + @Override + public void downloadBinaries() throws IOException, InterruptedException { + final Path directory = this.getDirectory(); + final Path dmg = directory.resolve("VLC.dmg"); + final Path disk = Path.of("/Volumes/VLC media player"); + final Path app = directory.resolve("VLC.app"); + this.downloadChecksum(app); + this.mountDisk(dmg); + this.copyDiskFiles(disk, app); + this.changePermissions(app); + this.unmountDisk(disk); this.setInstallationPath(app); this.deleteArchive(dmg); this.loadNativeBinaries(); @@ -86,31 +99,26 @@ public void loadNativeBinaries() throws IOException { } private int mountDiskImage(@NotNull final Path dmg) throws IOException, InterruptedException { - final CommandTask t = - new CommandTask(new String[]{"/usr/bin/hdiutil", "attach", dmg.toString()}, true); - + new CommandTask(new String[] {"/usr/bin/hdiutil", "attach", dmg.toString()}, true); Logger.info("============= DMG INFORMATION ============="); Logger.info(t.getResult()); Logger.info("==========================================="); - return t.getProcess().waitFor(); } private int unmountDiskImage(@NotNull final Path path) throws IOException, InterruptedException { - final CommandTask t = - new CommandTask(new String[]{"diskutil", "unmount", path.toString()}, true); - + new CommandTask(new String[] {"diskutil", "unmount", path.toString()}, true); Logger.info("=========== UNMOUNT INFORMATION ==========="); Logger.info(t.getResult()); Logger.info("==========================================="); - return t.getProcess().waitFor(); } - private int changePermissions(@NotNull final Path path) throws IOException, InterruptedException { - return new CommandTask(new String[]{"chmod", "-R", "755", path.toString()}, true) + private int changePermissionsTask(@NotNull final Path path) + throws IOException, InterruptedException { + return new CommandTask(new String[] {"chmod", "-R", "755", path.toString()}, true) .getProcess() .waitFor(); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/SilentWindowsInstallation.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/SilentWindowsInstallation.java index 80be96c8c..4d4d8b0db 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/SilentWindowsInstallation.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/window/SilentWindowsInstallation.java @@ -50,21 +50,23 @@ public SilentWindowsInstallation( @Override public void downloadBinaries() throws IOException { - - Logger.info("No VLC binary found on machine, installing Windows binaries."); - final Path folder = this.getDirectory(); final Path archive = folder.resolve("VLC.zip"); + this.downloadChecksum(archive); + this.extractArchive(archive, folder); + this.setInstallationPath(folder.resolve("vlc-%s".formatted(VLCDownloadPortal.VLC_VERSION))); + this.deleteArchive(archive); + this.loadNativeBinaries(); + } + private void downloadChecksum(@NotNull final Path archive) throws IOException { new VLCBinaryChecksum(this.getCore().getDiagnostics().getVlcUrl(), archive).downloadFile(); Logger.info("Successfully downloaded archived binaries!"); + } + private void extractArchive(@NotNull final Path archive, @NotNull final Path folder) { ArchiveUtils.decompressArchive(archive, folder); Logger.info("Successfully extracted archived binaries!"); - - this.setInstallationPath(folder.resolve("vlc-%s".formatted(VLCDownloadPortal.VLC_VERSION))); - this.deleteArchive(archive); - this.loadNativeBinaries(); } @Override From e1e8878f9ba19fbc88d4949dfc27616968a17eb8 Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sat, 2 Oct 2021 18:58:29 -0400 Subject: [PATCH 08/10] =?UTF-8?q?=F0=9F=90=9B=20Quick=20Fix=20with=20Mutab?= =?UTF-8?q?leInt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deluxemediaplugin/utility/MutableInt.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java index 36859b0f4..b76ac8512 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/MutableInt.java @@ -30,21 +30,13 @@ public class MutableInt { private int number; - MutableInt(@NotNull final Number number) { - this.number = (int) number; - } - MutableInt(final int number) { this.number = number; } - MutableInt(@NotNull final String number) { - this.number = Integer.parseInt(number); - } - @Contract(value = "_ -> new", pure = true) public static @NotNull MutableInt ofNumber(@NotNull final Number number) { - return new MutableInt(number); + return new MutableInt(number.intValue()); } @Contract(value = "_ -> new", pure = true) @@ -54,7 +46,7 @@ public class MutableInt { @Contract(value = "_ -> new", pure = true) public static @NotNull MutableInt ofString(@NotNull final String string) { - return new MutableInt(string); + return new MutableInt(Integer.parseInt(string)); } public void increment() { From 2a07903f8b5ec681592bea7312da4eba06af0d61 Mon Sep 17 00:00:00 2001 From: Brandon Li <40838203+PulseBeat02@users.noreply.github.com> Date: Sat, 2 Oct 2021 19:38:59 -0400 Subject: [PATCH 09/10] =?UTF-8?q?=E2=9C=A8=20Refactored=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pulsebeat02/ezmediacore/search/BNDM.java | 3 +- .../deluxemediaplugin/DeluxeMediaPlugin.java | 21 +- .../DeluxeMediaPluginBootstrap.java | 7 +- .../audio/M3uStreamSegmentUrlProvider.java | 8 +- .../bot/audio/MusicManager.java | 10 +- .../bot/audio/MusicSendHandler.java | 2 +- .../bot/audio/TrackScheduler.java | 12 +- .../command/CommandHandler.java | 12 +- .../command/CommandSegment.java | 12 +- .../command/gui/ItemBuilder.java | 2 +- .../command/gui/SkullException.java | 3 +- .../deluxemediaplugin/message/Locale.java | 287 +++++++++++------- .../deluxemediaplugin/utility/ChatUtils.java | 5 +- .../utility/CommandUtils.java | 9 +- .../pulsebeat02/ezmediacore/EzMediaCore.java | 3 +- .../pulsebeat02/ezmediacore/Logger.java | 7 +- .../ezmediacore/http/HttpServerDaemon.java | 12 +- .../pulsebeat02/ezmediacore/image/Image.java | 6 +- .../persistent/PersistentImageStorage.java | 3 +- .../resourcepack/ResourcepackWrapper.java | 6 +- .../ezmediacore/task/CommandTaskChain.java | 11 +- .../ezmediacore/vlc/EMCNativeDiscovery.java | 2 +- .../vlc/os/mac/SilentMacInstallation.java | 6 +- 23 files changed, 276 insertions(+), 173 deletions(-) diff --git a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java index e68670700..2e7850e57 100644 --- a/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java +++ b/api/src/main/java/io/github/pulsebeat02/ezmediacore/search/BNDM.java @@ -96,8 +96,7 @@ public Object processBytes(final byte @NotNull [] pattern) { /** * Pre-processing of the pattern. The pattern may not exceed 32 bytes in length. If it does, * only it's first 32 bytes are processed which might lead to unexpected results. Returns - * a - * {@link CharIntMap} which is serializable. + * a {@link CharIntMap} which is serializable. */ @Override public Object processChars(final char @NotNull [] pattern) { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java index 340366a9d..19b726d74 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPlugin.java @@ -74,11 +74,11 @@ public final class DeluxeMediaPlugin { private VideoCommandAttributes attributes; private MediaAttributesData mediaAttributesData; - public DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { + DeluxeMediaPlugin(@NotNull final JavaPlugin plugin) { this.plugin = plugin; } - public void enable() { + void enable() { this.assignAudiences(); this.startLibrary(); this.loadPersistentData(); @@ -87,7 +87,7 @@ public void enable() { this.finishEnabling(); } - public void disable() throws Exception { + void disable() { this.shutdownLibrary(); this.deserializeData(); this.unregisterCommands(); @@ -96,7 +96,7 @@ public void disable() throws Exception { this.finishDisabling(); } - public void load() { + void load() { this.finishLoading(); } @@ -119,7 +119,8 @@ private void startMetrics() { this.console.sendMessage(Locale.FIN_METRICS_INIT.build()); } - private void finishLoading() {} + private void finishLoading() { + } private void finishEnabling() { this.checkUpdates(); @@ -176,10 +177,14 @@ private void shutdownLibrary() { } } - private void cancelNativeTasks() throws Exception { + private void cancelNativeTasks() { if (this.attributes != null) { - this.cancelNativeExtractor(); - this.cancelNativeStreamExtractor(); + try { + this.cancelNativeExtractor(); + this.cancelNativeStreamExtractor(); + } catch (final Exception e) { + e.printStackTrace(); + } } this.console.sendMessage(Locale.CANCELLED_TASKS.build()); } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java index 5e51a3c5a..0e568bff9 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/DeluxeMediaPluginBootstrap.java @@ -63,11 +63,7 @@ public void onEnable() { @Override public void onDisable() { - try { - this.plugin.disable(); - } catch (final Exception e) { - e.printStackTrace(); - } + this.plugin.disable(); } interface InternalLocale { @@ -78,6 +74,7 @@ interface InternalLocale { @FunctionalInterface interface NullComponent { + String build(); } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java index 26970acf2..dbe510dd6 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/M3uStreamSegmentUrlProvider.java @@ -180,7 +180,11 @@ private boolean shouldWaitForSegment( return false; } - record ChannelStreamInfo(String quality, String url) {} + record ChannelStreamInfo(String quality, String url) { - record SegmentInfo(String url, Long duration, String name) {} + } + + record SegmentInfo(String url, Long duration, String name) { + + } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java index 7c04c53db..1a264e12a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicManager.java @@ -58,7 +58,9 @@ public MusicManager(@NotNull final MediaBot bot) { AudioSourceManagers.registerLocalSource(this.playerManager); } - /** Join's Voice Chanel and set's log channel. */ + /** + * Join's Voice Chanel and set's log channel. + */ public void joinVoiceChannel() { final Guild guild = this.bot.getGuild(); final long id = guild.getIdLong(); @@ -72,7 +74,9 @@ public void joinVoiceChannel() { audio.openAudioConnection(voiceChannel); } - /** Leave's Voice Channel. */ + /** + * Leave's Voice Channel. + */ public void leaveVoiceChannel() { final Guild guild = this.bot.getGuild(); guild.getAudioManager().closeAudioConnection(); @@ -86,7 +90,7 @@ public void addTrack(@NotNull final String url) { /** * Adds track. * - * @param url Load's Song. + * @param url Load's Song. * @param channel Channel to send message. */ public void addTrack(@Nullable final MessageChannel channel, @NotNull final String url) { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java index 386026a13..564fd3858 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/MusicSendHandler.java @@ -42,7 +42,7 @@ public class MusicSendHandler implements AudioSendHandler { * MusicSendHandler Public Constructor. * * @param musicManager MusicManager Class. - * @param audioPlayer AudioPlayer. + * @param audioPlayer AudioPlayer. */ public MusicSendHandler( @NotNull final MediaBot bot, diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java index 8d376ee04..ad6c7d1c5 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/bot/audio/TrackScheduler.java @@ -30,7 +30,9 @@ import io.github.pulsebeat02.deluxemediaplugin.bot.MediaBot; import org.jetbrains.annotations.NotNull; -/** Stolen from itxfrosty Music bot. */ +/** + * Stolen from itxfrosty Music bot. + */ public class TrackScheduler extends AudioEventAdapter { private final MediaBot bot; @@ -57,12 +59,16 @@ public void queueSong(@NotNull final AudioTrack track) { } } - /** Clear's Audio Queue. */ + /** + * Clear's Audio Queue. + */ public void clearQueue() { this.audioPlayer.stopTrack(); } - /** Skips Song. */ + /** + * Skips Song. + */ public void skip() { this.audioPlayer .getPlayingTrack() diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java index 09c112a2a..e5b2bc22f 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandHandler.java @@ -108,10 +108,10 @@ private void registerCommodoreCommand( /** * CommandHandler to read input and execute other commands. * - * @param sender command sender + * @param sender command sender * @param command command sent - * @param label label of command - * @param args arguments for command + * @param label label of command + * @param args arguments for command * @return whether the command usage should be showed up. */ @Override @@ -134,10 +134,10 @@ public boolean onCommand( /** * Tab handler to handle tab completer. * - * @param sender command sender + * @param sender command sender * @param command current command - * @param alias aliases of command - * @param args arguments of the command + * @param alias aliases of command + * @param args arguments of the command * @return list of options. */ @Override diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java index 83dd27853..2ec1b89d8 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/CommandSegment.java @@ -51,11 +51,17 @@ default RequiredArgumentBuilder argument( } @FunctionalInterface - interface Root extends CommandSegment> {} + interface Root extends CommandSegment> { + + } @FunctionalInterface - interface Literal extends CommandSegment> {} + interface Literal extends CommandSegment> { + + } @FunctionalInterface - interface Argument extends CommandSegment> {} + interface Argument extends CommandSegment> { + + } } diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java index b4a907c05..ae87ed03c 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/ItemBuilder.java @@ -190,7 +190,7 @@ public ItemBuilder clone() { * Add a lore line. * * @param line The lore line to add. - * @param pos The index of where to put it. + * @param pos The index of where to put it. */ public @NotNull ItemBuilder lore(@NotNull final Component line, final int pos) { final ItemMeta im = this.is.getItemMeta(); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java index ec52638a9..c56c4a48a 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/command/gui/SkullException.java @@ -29,7 +29,8 @@ public class SkullException extends AssertionError { - @Serial private static final long serialVersionUID = 2394089956129784304L; + @Serial + private static final long serialVersionUID = 2394089956129784304L; public SkullException(@NotNull final String message) { super("Invalid Skull Base64 %s!".formatted(message)); diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java index 3abf65d65..5e34aab48 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/message/Locale.java @@ -43,7 +43,6 @@ import io.github.pulsebeat02.deluxemediaplugin.command.dither.DitherSetting; import io.github.pulsebeat02.deluxemediaplugin.command.image.ImageMrlType; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.function.Function; @@ -111,93 +110,117 @@ public interface Locale { .append() .build(); NullComponent PLUGIN_LOGO = () -> getComponent( - Arrays.asList( - " _____ _ __ __ _ _ _____ _ _ ", - " | __ \\ | | | \\/ | | (_) | __ \\| | (_) ", - " | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ ", - " | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\ ", - " | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | |", - " |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_|", - " __/ | ", - " |___/ "), + """ + _____ _ __ __ _ _ _____ _ _ \s + | __ \\ | | | \\/ | | (_) | __ \\| | (_) \s + | | | | ___| |_ ___ _____| \\ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ \s + | | | |/ _ \\ | | | \\ \\/ / _ \\ |\\/| |/ _ \\/ _` | |/ _` | ___/| | | | |/ _` | | '_ \\\s + | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | | + |_____/ \\___|_|\\__,_/_/\\_\\___|_| |_|\\___|\\__,_|_|\\__,_|_| |_|\\__,_|\\__, |_|_| |_| + __/ | \s + |___/ \s + """, (line) -> newline().append(text(line, BLUE))); NullComponent PLUGIN_PREFIX = () -> text() .color(AQUA) .append( - text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)).build(); + text('['), text("DeluxeMediaPlugin", GOLD), text(']'), space(), text("»", GRAY)) + .build(); NullComponent ENABLE_PLUGIN = () -> format(join(separator(text(" ")), text("Running DeluxeMediaPlugin", AQUA), text("[BETA]", GOLD), text("1.0.0", AQUA))); - NullComponent EMC_INIT = () -> format(text("Loading EzMediaCore instance... this may take some time!")); + NullComponent EMC_INIT = () -> format( + text("Loading EzMediaCore instance... this may take some time!")); NullComponent WELCOME = () -> format(text(""" - Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this - is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for - support at my Discord! (https://discord.gg/MgqRKvycMC) - """)); + Hello %%__USER__%%! Thank you for purchasing DeluxeMediaPlugin. For identifier purposes, this + is your purchase identification code: %%__NONCE__%% - Enjoy using the plugin, and ask for + support at my Discord! (https://discord.gg/MgqRKvycMC) + """)); NullComponent DISABLE_PLUGIN = () -> format(text("DeluxeMediaPlugin is shutting down!")); - NullComponent DISABLE_EMC = () -> format(text("Successfully shutdown MinecraftMediaLibrary instance!")); + NullComponent DISABLE_EMC = () -> format( + text("Successfully shutdown MinecraftMediaLibrary instance!")); NullComponent DESERIALIZE_DATA = () -> format(text("Successfully deserialized data!")); NullComponent DISABLE_COMMANDS = () -> format(text("Successfully disabled commands!")); - NullComponent DISABLE_BOT = () -> format(text("Successfully disabled Discord bot! (If running)")); - NullComponent CANCELLED_TASKS = () -> format(text("Successfully disabled all native tasks!")); + NullComponent DISABLE_BOT = () -> format( + text("Successfully disabled Discord bot! (If running)")); + NullComponent CANCELLED_TASKS = () -> format( + text("Successfully disabled all native tasks!")); NullComponent GOODBYE = () -> format(text("Good Bye! :(")); - NullComponent FIN_EMC_INIT = () -> format(text("Finished loading MinecraftMediaLibrary instance!")); - NullComponent FIN_PERSISTENT_INIT = () -> format(text("Finished loading persistent data!")); - NullComponent FIN_COMMANDS_INIT = () -> format(text("Finished registering plugin commands!")); + NullComponent FIN_EMC_INIT = () -> format( + text("Finished loading MinecraftMediaLibrary instance!")); + NullComponent FIN_PERSISTENT_INIT = () -> format( + text("Finished loading persistent data!")); + NullComponent FIN_COMMANDS_INIT = () -> format( + text("Finished registering plugin commands!")); NullComponent FIN_METRICS_INIT = () -> format(text("Finished loading Metrics data!")); NullComponent FIN_PLUGIN_INIT = () -> format(text("Finished loading DeluxeMediaPlugin!")); NullComponent RUNNING_LATEST_PLUGIN = () -> format(text( "You are currently running the latest version of DeluxeMediaPlugin.")); - NullComponent ERR_EMC_INIT = () -> format(text("There was a severe issue while loading the EzMediaCore instance!", - RED)); + NullComponent ERR_EMC_INIT = () -> format( + text("There was a severe issue while loading the EzMediaCore instance!", + RED)); NullComponent ERR_PERSISTENT_INIT = () -> format(text( - "A severe issue occurred while reading data from configuration files!", RED)); - NullComponent ERR_EMC_SHUTDOWN = () -> format(text("EzMediaCore instance is null... something fishy is going on.", + "A severe issue occurred while reading data from configuration files!", RED)); + NullComponent ERR_EMC_SHUTDOWN = () -> format( + text("EzMediaCore instance is null... something fishy is going on.", RED)); - NullComponent ERR_NO_MRL = () -> format(text("File or URL not specified!", RED)); - NullComponent ERR_INVALID_MRL = () -> format(text("Invalid MRL link! Not supported!", RED)); - NullComponent ERR_RESOURCEPACK_WRAP = () -> format(text("Failed to wrap resourcepack!", RED)); - NullComponent ERR_NO_RESOURCEPACK = () -> format(text("Please load a resourcepack first!", RED)); - NullComponent ERR_INVALID_AUDIO_STATE = () -> format(text( - "Please wait for the previous audio to extract first before loading another one!", RED)); + NullComponent ERR_NO_MRL = () -> format(text("File or URL not specified!", RED)); + NullComponent ERR_INVALID_MRL = () -> format( + text("Invalid MRL link! Not supported!", RED)); + NullComponent ERR_RESOURCEPACK_WRAP = () -> format( + text("Failed to wrap resourcepack!", RED)); + NullComponent ERR_NO_RESOURCEPACK = () -> format( + text("Please load a resourcepack first!", RED)); + NullComponent ERR_INVALID_AUDIO_STATE = () -> format(text( + "Please wait for the previous audio to extract first before loading another one!", RED)); NullComponent ERR_INVALID_DISCORD_BOT = () -> format(text( - "Discord bot not setup yet or invalid settings in bot.yml!", RED)); - NullComponent ERR_PLAYER_SENDER = () -> format(text("You must be a player to execute this command!", RED)); + "Discord bot not setup yet or invalid settings in bot.yml!", RED)); + NullComponent ERR_PLAYER_SENDER = () -> format( + text("You must be a player to execute this command!", RED)); NullComponent ERR_INVALID_EXTENSION = () -> format(text( - "Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS))); - NullComponent ERR_IMG_SET = () -> format(text("Failed to set image file!", RED)); - NullComponent ERR_IMAGE_NOT_LOADED = () -> format(text("The image you request purge from the map is not loaded!", - RED)); - NullComponent ERR_MAP_RANGE = () -> format(text("Invalid format! Must follow [starting-id]-[ending-id]", RED)); - NullComponent ERR_VIDEO_NOT_LOADED = () -> format(text("Video not loaded!", RED)); - NullComponent ERR_VIDEO_PROCESSING = () -> format(text("Video is still processing!", RED)); - NullComponent ERR_CANCELLATION_VIDEO_PROCESSING = () -> format(text("You aren't loading a video!", RED)); - NullComponent ERR_DOWNLOAD_VIDEO = () -> format(text("Failed to download video!", RED)); - NullComponent ERR_LOAD_VIDEO = () -> format(text("Failed to load video!", RED)); - NullComponent ERR_INVALID_AUDIO_OUTPUT = () -> format(text( - "You cannot play streams without using Discord or a dynamic audio player with audio. Proceeding to play without audio.", - RED)); - NullComponent ERR_INVALID_TARGET_SELECTOR = () -> format(text( - "The target selector you chose contains entities that aren't players!", RED)); - NullComponent ERR_DEVELOPMENT_FEATURE = () -> format(text( - "This feature is current being developed! Stay tuned and join the Discord for updates!", + "Image doesn't match any supported extensions! (%s)".formatted(ImageMrlType.EXTENSIONS))); + NullComponent ERR_IMG_SET = () -> format(text("Failed to set image file!", RED)); + NullComponent ERR_IMAGE_NOT_LOADED = () -> format( + text("The image you request purge from the map is not loaded!", RED)); - NullComponent ERR_HTTP_AUDIO = () -> format(text("HTTP audio information provided in httpaudio.yml is invalid!", + NullComponent ERR_MAP_RANGE = () -> format( + text("Invalid format! Must follow [starting-id]-[ending-id]", RED)); + NullComponent ERR_VIDEO_NOT_LOADED = () -> format(text("Video not loaded!", RED)); + NullComponent ERR_VIDEO_PROCESSING = () -> format( + text("Video is still processing!", RED)); + NullComponent ERR_CANCELLATION_VIDEO_PROCESSING = () -> format( + text("You aren't loading a video!", RED)); + NullComponent ERR_DOWNLOAD_VIDEO = () -> format(text("Failed to download video!", RED)); + NullComponent ERR_LOAD_VIDEO = () -> format(text("Failed to load video!", RED)); + NullComponent ERR_INVALID_AUDIO_OUTPUT = () -> format(text( + "You cannot play streams without using Discord or a dynamic audio player with audio. Proceeding to play without audio.", + RED)); + NullComponent ERR_INVALID_TARGET_SELECTOR = () -> format(text( + "The target selector you chose contains entities that aren't players!", RED)); + NullComponent ERR_DEVELOPMENT_FEATURE = () -> format(text( + "This feature is current being developed! Stay tuned and join the Discord for updates!", + RED)); + NullComponent ERR_HTTP_AUDIO = () -> format( + text("HTTP audio information provided in httpaudio.yml is invalid!", RED)); - NullComponent ERR_BOT_TOKEN = () -> format(text("Bot token not specified in bot.yml!", RED)); - NullComponent ERR_GUILD_TOKEN = () -> format(text("Guild token not specified in bot.yml!", RED)); - NullComponent ERR_VC_ID = () -> format(text("Voice Chat Identifier not specified in bot.yml!", RED)); + NullComponent ERR_BOT_TOKEN = () -> format( + text("Bot token not specified in bot.yml!", RED)); + NullComponent ERR_GUILD_TOKEN = () -> format( + text("Guild token not specified in bot.yml!", RED)); + NullComponent ERR_VC_ID = () -> format( + text("Voice Chat Identifier not specified in bot.yml!", RED)); NullComponent START_AUDIO = () -> format(text("Started playing audio!")); - NullComponent PAUSE_AUDIO = () -> format(text("Stopped playing audio!")); - NullComponent RESUME_AUDIO = () -> format(text("Resumed the video!")); - NullComponent CREATE_RESOURCEPACK = () -> format(text( - "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.")); - NullComponent DC_DISCORD = () -> format(text("Successfully disconnected from voice channel!")); - NullComponent C_DISCORD = () -> format(text("Successfully connected to voice channel!")); - NullComponent PAUSED_TRACK_DISCORD = () -> format(text("Successfully paused track!")); - NullComponent RESUMED_TRACK_DISCORD = () -> format(text("Successfully resumed track!")); + NullComponent PAUSE_AUDIO = () -> format(text("Stopped playing audio!")); + NullComponent RESUME_AUDIO = () -> format(text("Resumed the video!")); + NullComponent CREATE_RESOURCEPACK = () -> format(text( + "Creating a resourcepack for audio. Depending on the length of the video, it make take some time.")); + NullComponent DC_DISCORD = () -> format( + text("Successfully disconnected from voice channel!")); + NullComponent C_DISCORD = () -> format(text("Successfully connected to voice channel!")); + NullComponent PAUSED_TRACK_DISCORD = () -> format(text("Successfully paused track!")); + NullComponent RESUMED_TRACK_DISCORD = () -> format(text("Successfully resumed track!")); NullComponent DITHERING_OPTIONS = () -> format(text("Dithering Options ->") .append(getComponent(DitherSetting.class, (value) -> text(value.getName(), AQUA).append(newline())))); @@ -205,63 +228,75 @@ public interface Locale { NullComponent RESET_FFMPEG_ARGS = () -> format(text("Reset all FFmpeg arguments!")); NullComponent LOAD_IMG = () -> format(text("Loading image...")); NullComponent PURGE_ALL_MAPS_VERIFY = () -> format(text( - "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...")); + "Are you sure you want to purge all maps? Type YES (all caps) if you would like to continue...")); NullComponent PURGED_ALL_MAPS = () -> format(text("Successfully purged all images!")); - NullComponent CANCELLED_PURGE_ALL_MAPS = () -> format(text("Cancelled purge of all images!")); + NullComponent CANCELLED_PURGE_ALL_MAPS = () -> format( + text("Cancelled purge of all images!")); NullComponent PAUSE_VIDEO = () -> format(text("Stopped the video!")); - NullComponent RELEASE_VIDEO = () -> format(text("Successfully destroyed the current video!")); + NullComponent RELEASE_VIDEO = () -> format( + text("Successfully destroyed the current video!")); NullComponent SETUP_RESOURCEPACK = () -> format(text( - "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.")); - NullComponentDISCORD_AUDIO_STREAM = () -> format(text("Started playing audio into Discord voice chat!")); - NullComponent DUMP_THREADS = () -> format(text("Created thread dump! Look in console for more details.")); - NullComponent CANCELLED_VIDEO_PROCESSING = () -> format(text("Successfully cancelled the video loading process!")); + "Setting up resourcepack for resuming... this may take a while depending on how large the audio file is.")); + NullComponent DISCORD_AUDIO_STREAM = () -> format( + text("Started playing audio into Discord voice chat!")); + NullComponent DUMP_THREADS = () -> format( + text("Created thread dump! Look in console for more details.")); + NullComponent CANCELLED_VIDEO_PROCESSING = () -> format( + text("Successfully cancelled the video loading process!")); NullComponent LOADING_VIDEO = () -> format(text("Initializing and reading media...")); NullComponent BUILT_SCREEN = () -> format(text("Successfully built your new screen!")); UniComponent DREW_IMG = (mrl) -> format(text("Successfully drew image with mrl %s".formatted(mrl))); - UniComponent START_TRACK_DISCORD = (mrl) -> format(text("Successfully started audio on MRL %s!".formatted(mrl))); + UniComponent START_TRACK_DISCORD = (mrl) -> format( + text("Successfully started audio on MRL %s!".formatted(mrl))); UniComponent ADD_FFMPEG_ARG = (str) -> format(join( - separator(space()), - text("Added arguments", GOLD), - text(str, AQUA), - text("to the FFmpeg command.", GOLD))); + separator(space()), + text("Added arguments", GOLD), + text(str, AQUA), + text("to the FFmpeg command.", GOLD))); UniComponent REMOVE_FFMPEG_ARG = (str) -> format(join( - separator(space()), - text("Removed arguments", GOLD), - text(str, AQUA), - text("from the FFmpeg command.", GOLD))); + separator(space()), + text("Removed arguments", GOLD), + text(str, AQUA), + text("from the FFmpeg command.", GOLD))); UniComponent HTTP_SEND_LINK = (mrl) -> format(text() - .append(text("Click ", GOLD)).append(text( - "this message", - style( - AQUA, - BOLD, - UNDERLINED, - openUrl(mrl), - text("Click to get the link!", GOLD) - .asHoverEvent()))).append(text(" to retrieve the audio HTTP link!", GOLD)) - .build()); - UniComponent STARTING_VIDEO = (mrl) -> format(text("Starting Video on MRL %s".formatted(mrl))); - UniComponent LOADED_MEDIA = (mrl) -> format(text("Successfully loaded media %s!".formatted(mrl))); + .append(text("Click ", GOLD)).append(text( + "this message", + style( + AQUA, + BOLD, + UNDERLINED, + openUrl(mrl), + text("Click to get the link!", GOLD) + .asHoverEvent()))).append(text(" to retrieve the audio HTTP link!", GOLD)) + .build()); + UniComponent STARTING_VIDEO = (mrl) -> format( + text("Starting Video on MRL %s".formatted(mrl))); + UniComponent LOADED_MEDIA = (mrl) -> format( + text("Successfully loaded media %s!".formatted(mrl))); UniComponent SET_AUDIO_TYPE = (argument) -> format(text( - "Successfully set the audio type to %s".formatted(argument))); - UniComponent SET_DITHER_TYPE = (algorithm) -> format(join(separator(space()), text("Set dither type to", GOLD), + "Successfully set the audio type to %s".formatted(argument))); + UniComponent SET_DITHER_TYPE = (algorithm) -> format( + join(separator(space()), text("Set dither type to", GOLD), text(algorithm, AQUA))); - UniComponent SET_VIDEO_TYPE = (mode) -> format(join(separator(space()), text("Set video mode to", GOLD), + UniComponent SET_VIDEO_TYPE = (mode) -> format( + join(separator(space()), text("Set video mode to", GOLD), text(mode, AQUA))); UniComponent EXTERNAL_PROCESS = (line) -> format(join(separator(space()), text() - .color(AQUA) - .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)), - text(line, GOLD))); - UniComponent NEW_UPDATE_PLUGIN = (update) -> format(text( - "There is a new update available! (%s)".formatted(update))); + .color(AQUA) + .append(text('['), text("External Process", GOLD), text(']'), space(), text("»", GRAY)), + text(line, GOLD))); + UniComponent NEW_UPDATE_PLUGIN = (update) -> format(text( + "There is a new update available! (%s)".formatted(update))); UniComponent ERR_INVALID_AUDIO_TYPE = (argument) -> format(text( "Could not find audio type %s".formatted(argument), RED)); UniComponent ERR_INVALID_DITHER_TYPE = (algorithm) -> format(text( - "Could not find dither type %s".formatted(algorithm), RED)); - UniComponent ERR_INVALID_VIDEO_TYPE = (mode) -> format(text("Could not find video mode %s".formatted(mode), RED)); - UniComponent ERR_CANNOT_CHECK_UPDATES = (msg) -> format(text("Cannot look for updates: %s".formatted(msg), RED)); + "Could not find dither type %s".formatted(algorithm), RED)); + UniComponent ERR_INVALID_VIDEO_TYPE = (mode) -> format( + text("Could not find video mode %s".formatted(mode), RED)); + UniComponent ERR_CANNOT_CHECK_UPDATES = (msg) -> format( + text("Cannot look for updates: %s".formatted(msg), RED)); UniComponent> LIST_FFMPEG_ARGS = (list) -> format(join( separator(space()), text("Current FFmpeg arguments:", GOLD), @@ -273,12 +308,13 @@ public interface Locale { text("Successfully purged all maps with id", GOLD), text(id, AQUA))); UniComponent GIVE_MAP_ID = (id) -> format(join( - separator(space()), text("Gave map with id", GOLD), text(id, AQUA))); + separator(space()), text("Gave map with id", GOLD), text(id, AQUA))); UniComponent CHANGED_VIDEO_MAP_ID = (id) -> format(join( - separator(space()), - text("Set starting map id to", GOLD), - text(id, AQUA))); - UniComponent RESUMING_VIDEO_MS = (ms) -> format(text("Resuming Video at %s Milliseconds!")); + separator(space()), + text("Set starting map id to", GOLD), + text(id, AQUA))); + UniComponent RESUMING_VIDEO_MS = (ms) -> format( + text("Resuming Video at %s Milliseconds!")); UniComponent SEND_RESOURCEPACK_URL = (player) -> format(text() .append(text("Loaded resourcepack for all players! Click ", GOLD)) .append( @@ -299,7 +335,7 @@ public interface Locale { FIN_RESOURCEPACK_INIT = (url, hash) -> format(text( "Loaded Resourcepack Successfully! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); BiComponent SENT_RESOURCEPACK = (url, hash) -> format(text( - "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); + "Sent Resourcepack! (URL: %s, Hash: %s)".formatted(url, new String(hash)))); BiComponent ADD_FFMPEG_ARG_INDX = (str, index) -> format(join( @@ -310,11 +346,11 @@ public interface Locale { text(index, AQUA))); BiComponent REMOVE_FFMPEG_ARG_INDX = (str, index) -> format(join( - separator(space()), - text("Removed arguments", GOLD), - text(str, AQUA), - text("from the FFmpeg command at index", GOLD), - text(index, AQUA))); + separator(space()), + text("Removed arguments", GOLD), + text(str, AQUA), + text("from the FFmpeg command at index", GOLD), + text(index, AQUA))); BiComponent CHANGED_IMG_DIMS = (width, height) -> format(text( "Changed itemframe dimensions to %d:%d (width:height)".formatted(width, height))); @@ -331,7 +367,7 @@ public interface Locale { text("Set screen dimensions to", GOLD), text("%d:%d".formatted(width, height), AQUA), text("(width:height)", GOLD))); - BiComponent CHANGED_ITEMFRAME_DIMS = (width, height) -> + BiComponent CHANGED_ITEMFRAME_DIMS = (width, height) -> format(join( separator(space()), text("Set itemframe map dimensions to", GOLD), @@ -368,6 +404,29 @@ public interface Locale { return component.build(); } + /* + + + _____ _ __ __ _ _ _____ _ _ + | __ \ | | | \/ | | (_) | __ \| | (_) + | | | | ___| |_ ___ _____| \ / | ___ __| |_ __ _| |__) | |_ _ __ _ _ _ __ + | | | |/ _ \ | | | \ \/ / _ \ |\/| |/ _ \/ _` | |/ _` | ___/| | | | |/ _` | | '_ \ + | |__| | __/ | |_| |> < __/ | | | __/ (_| | | (_| | | | | |_| | (_| | | | | | + |_____/ \___|_|\__,_/_/\_\___|_| |_|\___|\__,_|_|\__,_|_| |_|\__,_|\__, |_|_| |_| + __/ | + |___/ + + */ + + static @NotNull Component getComponent(@NotNull final String largeString, + @NotNull final Function function) { + final TextComponent.Builder component = text(); + for (final String line : largeString.split("\n")) { + component.append(function.apply(line)); + } + return component.build(); + } + @FunctionalInterface interface NullComponent { diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java index f0671364a..a0429d21c 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/ChatUtils.java @@ -43,7 +43,8 @@ public final class ChatUtils { - private ChatUtils() {} + private ChatUtils() { + } public static @NotNull Optional checkDimensionBoundaries( @NotNull final Audience sender, @NotNull final String str) { @@ -56,7 +57,7 @@ private ChatUtils() {} } else if (height.isEmpty()) { message = dims[1]; } else { - return Optional.of(new int[] {width.getAsInt(), height.getAsInt()}); + return Optional.of(new int[]{width.getAsInt(), height.getAsInt()}); } sender.sendMessage( text() diff --git a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java index 3631c8cf8..d08c69a53 100644 --- a/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java +++ b/deluxemediaplugin/src/main/java/io/github/pulsebeat02/deluxemediaplugin/utility/CommandUtils.java @@ -41,13 +41,14 @@ public final class CommandUtils { knownCommands = (HashMap) (getPrivateField( - (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap") - .orElseThrow(AssertionError::new)), - "knownCommands") + (getPrivateField(Bukkit.getServer().getPluginManager(), "commandMap") + .orElseThrow(AssertionError::new)), + "knownCommands") .orElseThrow(AssertionError::new)); } - private CommandUtils() {} + private CommandUtils() { + } public static void unRegisterBukkitCommand( @NotNull final DeluxeMediaPlugin plugin, @NotNull final BaseCommand cmd) { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java index 671b67112..8fa9a00f8 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/EzMediaCore.java @@ -129,7 +129,8 @@ private void getPacketInstance() { } private void initializeStream() { - IntStream.range(0, 5).parallel().forEach(key -> {}); // jump start int stream + IntStream.range(0, 5).parallel().forEach(key -> { + }); // jump start int stream } private void initializeProviders() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java index 79058a748..fbd6159c0 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java @@ -25,6 +25,7 @@ import io.github.pulsebeat02.ezmediacore.executor.ExecutorProvider; import io.github.pulsebeat02.ezmediacore.sneaky.ThrowingConsumer; +import io.github.pulsebeat02.ezmediacore.task.CommandTask; import io.github.pulsebeat02.ezmediacore.utility.FileUtils; import java.io.IOException; import java.io.PrintWriter; @@ -32,6 +33,7 @@ import java.nio.file.Path; import java.util.Set; import org.jetbrains.annotations.NotNull; +import uk.co.caprica.vlcj.binding.RuntimeUtil; public final class Logger { @@ -55,9 +57,12 @@ public static void init(@NotNull final MediaLibraryCore core) { FFMPEG_PLAYER_LOG_FILE = path.resolve("ffmpeg.log"); FFMPEG_STREAM_LOG_FILE = path.resolve("ffmpeg-stream.log"); try { - Files.createDirectories(LOG_FILE.getParent()); + Files.createDirectories(path); Set.of(LOG_FILE, VLC_LOG_FILE, RTP_LOG_FILE, FFMPEG_PLAYER_LOG_FILE, FFMPEG_STREAM_LOG_FILE) .forEach(ThrowingConsumer.unchecked(FileUtils::createIfNotExists)); + if (RuntimeUtil.isMac() || RuntimeUtil.isNix()) { + new CommandTask("chmod", "-R", "777", path.toAbsolutePath().toString()); + } LOGGER = new PrintWriter(Files.newBufferedWriter(LOG_FILE), true); VLC_LOGGER = new PrintWriter(Files.newBufferedWriter(VLC_LOG_FILE), true); RTP_LOGGER = new PrintWriter(Files.newBufferedWriter(RTP_LOG_FILE), true); diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java index d77964cb6..9f2cefbd1 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/http/HttpServerDaemon.java @@ -105,7 +105,8 @@ private void handleServerRequests() { } @Override - public void onServerStart() {} + public void onServerStart() { + } @Override public void stop() { @@ -121,13 +122,16 @@ public void stop() { } @Override - public void onServerTermination() {} + public void onServerTermination() { + } @Override - public void onClientConnection(@NotNull final Socket client) {} + public void onClientConnection(@NotNull final Socket client) { + } @Override - public void onRequestFailure(@NotNull final Socket client) {} + public void onRequestFailure(@NotNull final Socket client) { + } @Override public boolean isVerbose() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java index 66096e668..0d6f786f9 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/image/Image.java @@ -62,7 +62,8 @@ public Image( } @Override - public void onStartDrawImage() {} + public void onStartDrawImage() { + } @Override public @NotNull BufferedImage[][] process(@NotNull BufferedImage image, final boolean resize) { @@ -84,7 +85,8 @@ public void onStartDrawImage() {} } @Override - public void onFinishDrawImage() {} + public void onFinishDrawImage() { + } @Override public void resetMaps() { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java index d69e81b2c..62e70b9fb 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/persistent/PersistentImageStorage.java @@ -53,7 +53,8 @@ public void serialize(@NotNull final Collection list) throws IOException public List deserialize() throws IOException { super.deserialize(); try (final BufferedReader reader = Files.newBufferedReader(this.getStorageFile())) { - return GsonProvider.getSimple().fromJson(reader, new TypeToken>() {}.getType()); + return GsonProvider.getSimple().fromJson(reader, new TypeToken>() { + }.getType()); } } } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java index 2d0f590ff..c9d8deff0 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/resourcepack/ResourcepackWrapper.java @@ -101,10 +101,12 @@ public void internalWrap() throws IOException { } @Override - public void onPackStartWrap() {} + public void onPackStartWrap() { + } @Override - public void onPackFinishWrap() {} + public void onPackFinishWrap() { + } @Override public void addFile(@NotNull final String path, @NotNull final Path file) throws IOException { diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java index f2f9a6c4e..e937cc692 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/task/CommandTaskChain.java @@ -53,12 +53,16 @@ import java.util.concurrent.CompletableFuture; import org.jetbrains.annotations.NotNull; -/** Constructs a chain of commands to be executed accordingly. */ +/** + * Constructs a chain of commands to be executed accordingly. + */ public class CommandTaskChain { private final Map chain; - /** Instantiates a new CommandTaskChain */ + /** + * Instantiates a new CommandTaskChain + */ public CommandTaskChain() { this.chain = new LinkedHashMap<>(); } @@ -108,7 +112,8 @@ public void run() throws IOException, InterruptedException { for (final Map.Entry entry : this.chain.entrySet()) { final CommandTask task = entry.getKey(); if (entry.getValue()) { - CompletableFuture.runAsync(() -> this.runTask(task), ExecutorProvider.EXTERNAL_PROCESS_POOL); + CompletableFuture.runAsync(() -> this.runTask(task), + ExecutorProvider.EXTERNAL_PROCESS_POOL); } else { this.runTaskChain(task); } diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java index c62e1a160..b3c5a4d9f 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/EMCNativeDiscovery.java @@ -168,7 +168,7 @@ private void setVLCPluginPath(@NotNull final Path path) { private boolean loadLibVLCLibrary() { try { final libvlc_instance_t instance = - libvlc_new(0, new StringArray(new String[] {"--reset-plugins-cache"})); + libvlc_new(0, new StringArray(new String[]{"--reset-plugins-cache"})); if (instance != null) { libvlc_release(instance); final LibVlcVersion version = new LibVlcVersion(); diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java index 6a0ea8b4e..856fb2443 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/vlc/os/mac/SilentMacInstallation.java @@ -100,7 +100,7 @@ public void loadNativeBinaries() throws IOException { private int mountDiskImage(@NotNull final Path dmg) throws IOException, InterruptedException { final CommandTask t = - new CommandTask(new String[] {"/usr/bin/hdiutil", "attach", dmg.toString()}, true); + new CommandTask(new String[]{"/usr/bin/hdiutil", "attach", dmg.toString()}, true); Logger.info("============= DMG INFORMATION ============="); Logger.info(t.getResult()); Logger.info("==========================================="); @@ -109,7 +109,7 @@ private int mountDiskImage(@NotNull final Path dmg) throws IOException, Interrup private int unmountDiskImage(@NotNull final Path path) throws IOException, InterruptedException { final CommandTask t = - new CommandTask(new String[] {"diskutil", "unmount", path.toString()}, true); + new CommandTask(new String[]{"diskutil", "unmount", path.toString()}, true); Logger.info("=========== UNMOUNT INFORMATION ==========="); Logger.info(t.getResult()); Logger.info("==========================================="); @@ -118,7 +118,7 @@ private int unmountDiskImage(@NotNull final Path path) throws IOException, Inter private int changePermissionsTask(@NotNull final Path path) throws IOException, InterruptedException { - return new CommandTask(new String[] {"chmod", "-R", "755", path.toString()}, true) + return new CommandTask(new String[]{"chmod", "-R", "755", path.toString()}, true) .getProcess() .waitFor(); } From 10f6902153c5f03989ab39bd7afc799704404800 Mon Sep 17 00:00:00 2001 From: PulseBeat02 Date: Sun, 3 Oct 2021 13:42:29 -0400 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=90=9B=20Quick=20Fix=20with=20Permi?= =?UTF-8?q?ssions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pulsebeat02/ezmediacore/Logger.java | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java index fbd6159c0..2ef579376 100644 --- a/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java +++ b/main/src/main/java/io/github/pulsebeat02/ezmediacore/Logger.java @@ -33,7 +33,6 @@ import java.nio.file.Path; import java.util.Set; import org.jetbrains.annotations.NotNull; -import uk.co.caprica.vlcj.binding.RuntimeUtil; public final class Logger { @@ -51,29 +50,50 @@ public final class Logger { public static void init(@NotNull final MediaLibraryCore core) { final Path path = core.getLibraryPath(); + assignLoggerPaths(path); + try { + createDirectories(path); + assignPermissions(path); + assignFileWriters(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + + private static void assignLoggerPaths(@NotNull final Path path) { LOG_FILE = path.resolve("emc.log"); VLC_LOG_FILE = path.resolve("vlc.log"); RTP_LOG_FILE = path.resolve("rtp.log"); FFMPEG_PLAYER_LOG_FILE = path.resolve("ffmpeg.log"); FFMPEG_STREAM_LOG_FILE = path.resolve("ffmpeg-stream.log"); - try { - Files.createDirectories(path); - Set.of(LOG_FILE, VLC_LOG_FILE, RTP_LOG_FILE, FFMPEG_PLAYER_LOG_FILE, FFMPEG_STREAM_LOG_FILE) - .forEach(ThrowingConsumer.unchecked(FileUtils::createIfNotExists)); - if (RuntimeUtil.isMac() || RuntimeUtil.isNix()) { - new CommandTask("chmod", "-R", "777", path.toAbsolutePath().toString()); - } - LOGGER = new PrintWriter(Files.newBufferedWriter(LOG_FILE), true); - VLC_LOGGER = new PrintWriter(Files.newBufferedWriter(VLC_LOG_FILE), true); - RTP_LOGGER = new PrintWriter(Files.newBufferedWriter(RTP_LOG_FILE), true); - FFMPEG_PLAYER_LOGGER = new PrintWriter(Files.newBufferedWriter(FFMPEG_PLAYER_LOG_FILE), true); - FFMPEG_STREAMER_LOGGER = - new PrintWriter(Files.newBufferedWriter(FFMPEG_STREAM_LOG_FILE), true); - } catch (final IOException e) { - e.printStackTrace(); + } + + private static void createDirectories(@NotNull final Path path) throws IOException { + Files.createDirectories(path); + Set.of(LOG_FILE, VLC_LOG_FILE, RTP_LOG_FILE, FFMPEG_PLAYER_LOG_FILE, FFMPEG_STREAM_LOG_FILE) + .forEach(ThrowingConsumer.unchecked(FileUtils::createIfNotExists)); + } + + private static void assignPermissions(@NotNull final Path path) { + if (isUnix()) { + new CommandTask("chmod", "-R", "777", path.toAbsolutePath().toString()); } } + private static boolean isUnix() { + // cannot use Diagnostics because it's not created yet. Premature logger setup. + final String os = System.getProperty("os.name").toLowerCase(); + return os.contains("mac") || os.contains("nix") || os.contains("nux") || os.contains("aix"); + } + + private static void assignFileWriters() throws IOException { + LOGGER = new PrintWriter(Files.newBufferedWriter(LOG_FILE), true); + VLC_LOGGER = new PrintWriter(Files.newBufferedWriter(VLC_LOG_FILE), true); + RTP_LOGGER = new PrintWriter(Files.newBufferedWriter(RTP_LOG_FILE), true); + FFMPEG_PLAYER_LOGGER = new PrintWriter(Files.newBufferedWriter(FFMPEG_PLAYER_LOG_FILE), true); + FFMPEG_STREAMER_LOGGER = new PrintWriter(Files.newBufferedWriter(FFMPEG_STREAM_LOG_FILE), true); + } + public static void closeAllLoggers() { LOGGER.close(); VLC_LOGGER.close();