commit 372de930432a36cff96c594ddae5e9ea8400d697
Author: 5gi <5gi@s5gi.com>
Date:   Wed May 15 19:20:36 2024 -0400

    Fixed Double Prefix call.

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6b7dbb3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/run/
+/build/
+/.gradle/
+/.idea/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2bf618b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# UnEssentials
+It's basically **EssentialsX** but with only the essential features.
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..a8fdb22
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,64 @@
+plugins {
+    id 'java'
+    id("com.github.johnrengelman.shadow") version "8.1.1"
+    id("xyz.jpenilla.run-paper") version "2.1.0"
+}
+
+group = 'com.the5gi'
+version = '1.0.0'
+
+repositories {
+    mavenCentral()
+    maven {
+        name = "spigotmc-repo"
+        url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
+    }
+    maven {
+        name = "sonatype"
+        url = "https://oss.sonatype.org/content/groups/public/"
+    }
+    maven { url 'https://jitpack.io' }
+    maven {
+        url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
+    }
+}
+
+dependencies {
+    compileOnly "org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT"
+    implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
+    compileOnly 'me.clip:placeholderapi:2.11.4'
+}
+
+def targetJavaVersion = 17
+java {
+    def javaVersion = JavaVersion.toVersion(targetJavaVersion)
+    sourceCompatibility = javaVersion
+    targetCompatibility = javaVersion
+    if (JavaVersion.current() < javaVersion) {
+        toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
+    }
+}
+
+tasks.withType(JavaCompile).configureEach {
+    if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
+        options.release = targetJavaVersion
+    }
+}
+
+processResources {
+    def props = [version: version]
+    inputs.properties props
+    filteringCharset 'UTF-8'
+    filesMatching('plugin.yml') {
+        expand props
+    }
+}
+
+tasks {
+    runServer {
+        // Configure the Minecraft version for our task.
+        // This is the only required configuration besides applying the plugin.
+        // Your plugin's jar (or shadowJar if present) will be used automatically.
+        minecraftVersion("1.20.2")
+    }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..e69de29
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..02f683e
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..24b7fcf
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'UnEssentials'
diff --git a/src/main/java/com/the5gi/unessentials/Chat/Listeners/ChatReformatting.java b/src/main/java/com/the5gi/unessentials/Chat/Listeners/ChatReformatting.java
new file mode 100644
index 0000000..1511931
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/Chat/Listeners/ChatReformatting.java
@@ -0,0 +1,30 @@
+package com.the5gi.unessentials.Chat.Listeners;
+
+import com.the5gi.unessentials.UnEssentials;
+import com.the5gi.unessentials.Util.Config;
+import me.clip.placeholderapi.PlaceholderAPI;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.AsyncPlayerChatEvent;
+
+public class ChatReformatting implements Listener {
+    @EventHandler(priority = EventPriority.HIGHEST)
+    public static void onMessage(AsyncPlayerChatEvent event) {
+        if (Config.getFieldBool(Config.Chat.CHAT_FORMAT_ENABLED)) {
+            event.setCancelled(true);
+            String messagePre = UnEssentials.color(
+                    Config.getFieldString(Config.Chat.CHAT_FORMAT).replace(
+                            "%MESSAGE%", event.getMessage()).replace("%NAME%", event.getPlayer().getName()));
+            if (UnEssentials.PAPI) {
+                messagePre = UnEssentials.color(
+                        PlaceholderAPI.setPlaceholders(event
+                                        .getPlayer(),
+                                Config.getFieldString(Config.Chat.CHAT_FORMAT).replace("%MESSAGE%", event.getMessage()).replace("%NAME%", event.getPlayer().getName())));
+
+            }
+
+            UnEssentials.plugin.getServer().broadcastMessage(messagePre);
+        }
+    }
+}
diff --git a/src/main/java/com/the5gi/unessentials/Commands/BaseCommands.java b/src/main/java/com/the5gi/unessentials/Commands/BaseCommands.java
new file mode 100644
index 0000000..04be42e
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/Commands/BaseCommands.java
@@ -0,0 +1,44 @@
+package com.the5gi.unessentials.Commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.the5gi.unessentials.UnEssentials;
+import com.the5gi.unessentials.Util.Config;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.TabCompleter;
+
+public class BaseCommands {
+    public static final CommandExecutor unessentials;
+
+    public static final TabCompleter unessentialsTabCompleter;
+
+    static {
+        unessentials = ((sender, command, label, args) -> {
+            if (args.length == 0) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cRunning &oUnEssentials &r&c&lv" + UnEssentials.plugin.getDescription().getVersion()));
+            } else if (args.length == 1) {
+                if (args[0].equalsIgnoreCase("reload") && sender.hasPermission("unessentials.reload")) {
+                    long before = System.currentTimeMillis();
+                    Config.reload();
+                    long after = System.currentTimeMillis();
+                    long time = after - before;
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cReloaded in " + time + "ms"));
+                    UnEssentials.plugin.getLogger().info("&cReloaded in " + time + "ms");
+                } else {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cUnknown Argument"));
+                }
+            }
+            return false;
+        });
+        unessentialsTabCompleter = ((sender, command, label, args) -> {
+            List<String> l = new ArrayList<>();
+            if (args.length == 1) {
+                l.add("reload");
+            } else if (args.length >= 2) {
+                l.add("any_arguments_after_and_including_this_will_not_do_anything");
+            }
+            return l;
+        });
+    }
+}
diff --git a/src/main/java/com/the5gi/unessentials/Commands/CoolCommands.java b/src/main/java/com/the5gi/unessentials/Commands/CoolCommands.java
new file mode 100644
index 0000000..a0c76a1
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/Commands/CoolCommands.java
@@ -0,0 +1,261 @@
+package com.the5gi.unessentials.Commands;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import com.the5gi.unessentials.UnEssentials;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class CoolCommands {
+    public static HashMap<Player, Location> deathLocation = new HashMap<>();
+
+    public static final CommandExecutor top;
+
+    public static final CommandExecutor essenchant;
+
+    public static TabCompleter essenchantTabCompleter;
+
+    public static final CommandExecutor hat;
+
+    public static final CommandExecutor fly;
+
+    public static final CommandExecutor chicken;
+
+    public static final CommandExecutor butcher;
+
+    static {
+        top = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.top")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+            } else if (sender instanceof Player player) {
+                World world = player.getWorld();
+                Block block = world.getHighestBlockAt(player.getLocation());
+                if (player.getLocation().getY() == block.getY() + 1) {
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou are already on the top!"));
+                    return false;
+                } else {
+                    player.teleport(new Location(world, block.getX() + 0.5D, block.getY() + 1.5D, block.getZ() + 0.5D, player.getLocation().getYaw(), player.getLocation().getPitch()));
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&aTeleported you to the top!"));
+                }
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole cannot execute this command."));
+            }
+            return false;
+        });
+        essenchant = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.enchant")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            List<Enchantment> enchantments = List.of(Enchantment.values());
+            HashMap<String, Enchantment> enchantmentNames = new HashMap<>();
+            for (Enchantment enchantment : enchantments)
+                enchantmentNames.put(enchantment.getKey().getKey(), enchantment);
+            if (sender instanceof Player player) {
+                if (player.getInventory().getItemInMainHand() == null || player.getInventory().getItemInMainHand().getType().equals(Material.AIR)) {
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou are not holding an item."));
+                    return true;
+                }
+                if (args.length >= 2) {
+                    int enchantLevel;
+                    String enchantName = args[0];
+                    String enchantLevelS = args[1];
+                    if (!enchantmentNames.containsKey(enchantName)) {
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cThe enchantment \"" + UnEssentials.PREFIX + "\" does not exist."));
+                        return false;
+                    }
+                    Enchantment enchantment = enchantmentNames.get(enchantName);
+                    try {
+                        enchantLevel = Integer.parseInt(enchantLevelS);
+                    } catch (NumberFormatException ignore) {
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cPlease enter a real number."));
+                        return false;
+                    }
+                    ItemMeta meta = player.getInventory().getItemInMainHand().getItemMeta();
+                    assert meta != null;
+                    meta.addEnchant(enchantment, enchantLevel, true);
+                    player.getInventory().getItemInMainHand().setItemMeta(meta);
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&aEnchantment Applied!"));
+                    return false;
+                }
+                if (args.length == 1)
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cNot enough Arguments!. Expected 2"));
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole cannot execute this command."));
+                return false;
+            }
+            return false;
+        });
+        essenchantTabCompleter = ((sender, command, label, args) -> {
+            List<String> l = new ArrayList<>();
+            if (args.length == 1) {
+                List<Enchantment> enchantments = List.of(Enchantment.values());
+                for (Enchantment enchantment : enchantments)
+                    l.add(enchantment.getKey().getKey());
+            } else if (args.length >= 3) {
+                l.add("any_arguments_after_and_including_this_will_not_do_anything");
+            }
+            return l;
+        });
+        hat = ((sender, command, label, args) -> {
+            if (sender instanceof Player player) {
+                if (player.hasPermission("unessentials.hat")) {
+                    if (!player.getInventory().getItemInMainHand().getType().equals(Material.AIR)) {
+                        ItemStack prevHat = player.getInventory().getHelmet();
+                        player.getInventory().setHelmet(player.getInventory().getItemInMainHand());
+                        player.getInventory().getItemInMainHand().setAmount(0);
+                        player.getInventory().setItemInMainHand(prevHat);
+                        player.playSound(player, Sound.ITEM_ARMOR_EQUIP_LEATHER, 1.0F, 1.0F);
+                        return false;
+                    }
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou have nothing in your hand!"));
+                    return true;
+                }
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole cannot execute this command."));
+            return false;
+        });
+        fly = ((sender, command, label, args) -> {
+            if (sender.hasPermission("unessentials.fly")) {
+                if (sender instanceof Player player) {
+                    player.setAllowFlight(!player.getAllowFlight());
+                    if (player.getAllowFlight()) {
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou can now fly!"));
+                    } else {
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou can no longer fly."));
+                    }
+                } else {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole cannot execute this command."));
+                }
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+            }
+            return false;
+        });
+        chicken = ((sender, command, label, args) -> {
+            if (sender instanceof Player player) {
+                if (player.hasPermission("unessentials.chicken"))
+                    player.getWorld().spawnEntity(player.getLocation(), EntityType.CHICKEN, true);
+            }
+            return false;
+        });
+        butcher = ((sender, command, label, args) -> {
+            if (sender.hasPermission("unessentials.butcher")) {
+                if (sender instanceof Player player) {
+                    if (args.length == 1) {
+                        int radius;
+                        try {
+                            radius = Integer.parseInt(args[0]);
+                        } catch (NumberFormatException ignore) {
+                            player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&aPlease enter a valid number!"));
+                            return false;
+                        }
+                        List<Entity> nearbyEntities = player.getNearbyEntities(radius, radius, radius);
+                        int entityCount = 0;
+                        for (Entity entity : nearbyEntities) {
+                            if (entity instanceof LivingEntity livingEntity) {
+                                if (!(entity instanceof Player)) livingEntity.remove();
+                                entityCount++;
+                            }
+                        }
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&c&lKilled&r&c&o " + entityCount + "&r&c entities."));
+                    } else {
+                        sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cNot enough Arguments!. Expected 1"));
+                        return false;
+                    }
+                } else {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole cannot execute this command."));
+                    return false;
+                }
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return false;
+            }
+            return false;
+        });
+    }
+
+    public static Listener deathListener = new Listener() {
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        @EventHandler
+        public void onDeath(PlayerDeathEvent event) {
+            CoolCommands.deathLocation.put(event.getEntity(), event.getEntity().getLocation());
+        }
+    };
+
+    public static final CommandExecutor back;
+
+    public static final CommandExecutor name;
+
+    static {
+        back = ((sender, command, label, args) -> {
+            if (sender.hasPermission("unessentials.back")) {
+                if (sender instanceof Player player) {
+                    if (deathLocation.containsKey(player)) {
+                        player.teleport(deathLocation.get(player));
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou have been teleported to your last death location."));
+                        deathLocation.remove(player);
+                    } else {
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou have not died yet."));
+                    }
+                } else {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                }
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+            }
+            return false;
+        });
+        name = ((sender, command, label, args) -> {
+            if (sender.hasPermission("unessentials.name")) {
+                if (args.length < 1) {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cNot enough Arguments!. Expected at least 1"));
+                    return false;
+                }
+                if (sender instanceof Player player) {
+                    if (!player.getInventory().getItemInMainHand().getType().equals(Material.AIR)) {
+                        ItemStack itemStack = player.getInventory().getItemInMainHand();
+                        ItemMeta meta = itemStack.getItemMeta();
+                        StringBuilder builder = new StringBuilder();
+                        for (int i = 0; i < args.length; i++) {
+                            builder.append(args[i]);
+                            if (i != args.length - 1)
+                                builder.append(" ");
+                        }
+                        assert meta != null;
+                        meta.setDisplayName(UnEssentials.color(builder.toString()));
+                        itemStack.setItemMeta(meta);
+                        player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cSet."));
+                    }
+                } else {
+                    sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                }
+            } else {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+            }
+            return false;
+        });
+    }
+}
diff --git a/src/main/java/com/the5gi/unessentials/Commands/GameModesCommands.java b/src/main/java/com/the5gi/unessentials/Commands/GameModesCommands.java
new file mode 100644
index 0000000..98fdeac
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/Commands/GameModesCommands.java
@@ -0,0 +1,153 @@
+package com.the5gi.unessentials.Commands;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.the5gi.unessentials.UnEssentials;
+import org.bukkit.GameMode;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabCompleter;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public class GameModesCommands implements TabCompleter {
+    public static final CommandExecutor GMS;
+
+    public static final CommandExecutor GMC;
+
+    public static final CommandExecutor GMSP;
+
+    public static final CommandExecutor GMA;
+
+    static {
+        GMS = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.gms")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            if (args.length == 0) {
+                if (sender instanceof Player player) {
+                    player.setGameMode(GameMode.SURVIVAL);
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to SURVIVAL."));
+                    return false;
+                }
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole Cannot execute this command!"));
+                return false;
+            }
+            if (args.length >= 1 && isPlayerOnline(args[0])) {
+                Player player = UnEssentials.plugin.getServer().getPlayer(args[0]);
+                assert player != null;
+                player.setGameMode(GameMode.SURVIVAL);
+                String apostropheCheck = player.getName().endsWith("s") ? "'" : "'s";
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + player.getName() + apostropheCheck + " gamemode was set to SURVIVAL."));
+                player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to SURVIVAL."));
+                return false;
+            }
+            return false;
+        });
+        GMC = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.gmc")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            if (args.length == 0) {
+                if (sender instanceof Player player) {
+                    player.setGameMode(GameMode.CREATIVE);
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to CREATIVE."));
+                    return false;
+                }
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole Cannot execute this command!"));
+                return false;
+            }
+            if (args.length >= 1 && isPlayerOnline(args[0])) {
+                Player player = UnEssentials.plugin.getServer().getPlayer(args[0]);
+                assert player != null;
+                player.setGameMode(GameMode.CREATIVE);
+                String apostropheCheck = player.getName().endsWith("s") ? "'" : "'s";
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + player.getName() + apostropheCheck + " gamemode was set to CREATIVE."));
+                player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to CREATIVE."));
+                return false;
+            }
+            return false;
+        });
+        GMSP = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.gmsp")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            if (args.length == 0) {
+                if (sender instanceof Player player) {
+                    player.setGameMode(GameMode.SPECTATOR);
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to SPECTATOR."));
+                    return false;
+                }
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole Cannot execute this command!"));
+                return false;
+            }
+            if (args.length >= 1 && isPlayerOnline(args[0])) {
+                Player player = UnEssentials.plugin.getServer().getPlayer(args[0]);
+                assert player != null;
+                player.setGameMode(GameMode.SPECTATOR);
+                String apostropheCheck = player.getName().endsWith("s") ? "'" : "'s";
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + player.getName() + apostropheCheck + " gamemode was set to SPECTATOR."));
+                player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to SPECTATOR."));
+                return false;
+            }
+            return false;
+        });
+        GMA = ((sender, command, label, args) -> {
+            if (!sender.hasPermission("unessentials.gms")) {
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYou do not have permission to execute this command!"));
+                return true;
+            }
+            if (args.length == 0) {
+                if (sender instanceof Player player) {
+                    player.setGameMode(GameMode.ADVENTURE);
+                    player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to ADVENTURE."));
+                    return false;
+                }
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cConsole Cannot execute this command!"));
+                return false;
+            }
+            if (args.length >= 1 && isPlayerOnline(args[0])) {
+                Player player = UnEssentials.plugin.getServer().getPlayer(args[0]);
+                assert player != null;
+                player.setGameMode(GameMode.ADVENTURE);
+                String apostropheCheck = player.getName().endsWith("s") ? "'" : "'s";
+                sender.sendMessage(UnEssentials.color(UnEssentials.PREFIX + player.getName() + apostropheCheck + " gamemode was set to ADVENTURE."));
+                player.sendMessage(UnEssentials.color(UnEssentials.PREFIX + "&cYour gamemode was updated to ADVENTURE."));
+                return false;
+            }
+            return false;
+        });
+    }
+
+    private static boolean isPlayerOnline(String name) {
+        for (Player player : UnEssentials.plugin.getServer().getOnlinePlayers()) {
+            if (player.getName().equals(name))
+                return true;
+        }
+        return false;
+    }
+
+    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
+        List<String> l = new ArrayList<>();
+        if (args.length == 2) {
+            l.add("any_arguments_after_and_including_this_will_not_do_anything");
+        } else if (args.length == 1) {
+            l.addAll(getNames());
+        }
+        return l;
+    }
+
+    private Collection<String> getNames() {
+        Collection<String> s = new ArrayList<>();
+        for (Player player : UnEssentials.plugin.getServer().getOnlinePlayers())
+            s.add(player.getName());
+        return s;
+    }
+}
diff --git a/src/main/java/com/the5gi/unessentials/UnEssentials.java b/src/main/java/com/the5gi/unessentials/UnEssentials.java
new file mode 100644
index 0000000..604583a
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/UnEssentials.java
@@ -0,0 +1,75 @@
+package com.the5gi.unessentials;
+
+import com.the5gi.unessentials.Chat.Listeners.ChatReformatting;
+import com.the5gi.unessentials.Commands.BaseCommands;
+import com.the5gi.unessentials.Commands.CoolCommands;
+import com.the5gi.unessentials.Commands.GameModesCommands;
+import com.the5gi.unessentials.Util.Config;
+import me.clip.placeholderapi.PlaceholderAPI;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.List;
+import java.util.Objects;
+
+public class UnEssentials extends JavaPlugin {
+    public static boolean PAPI = false;
+
+    public static boolean LUCKPERMS = false;
+
+    public static String PREFIX = ChatColor.translateAlternateColorCodes('&', "&c&l[UnEssentials]&r ");
+
+    public static Plugin plugin;
+
+    public void onEnable() {
+        if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null)
+            PAPI = true;
+        if (Bukkit.getPluginManager().getPlugin("LuckPerms") != null)
+            LUCKPERMS = true;
+        plugin = this;
+        Config.onStart();
+        PREFIX = color(Config.getFieldString(Config.BaseLevel.PLUGIN_PREFIX));
+        getServer().getScheduler().scheduleSyncRepeatingTask(this, UnEssentials::tickCycle, 20L, 0L);
+        getServer().getPluginManager().registerEvents(new ChatReformatting(), this);
+        getServer().getPluginManager().registerEvents(CoolCommands.deathListener, this);
+        Objects.requireNonNull(getCommand("gms")).setExecutor(GameModesCommands.GMS);
+        Objects.requireNonNull(getCommand("gmc")).setExecutor(GameModesCommands.GMC);
+        Objects.requireNonNull(getCommand("gma")).setExecutor(GameModesCommands.GMA);
+        Objects.requireNonNull(getCommand("gmsp")).setExecutor(GameModesCommands.GMSP);
+        Objects.requireNonNull(getCommand("gms")).setTabCompleter(new GameModesCommands());
+        Objects.requireNonNull(getCommand("gmc")).setTabCompleter(new GameModesCommands());
+        Objects.requireNonNull(getCommand("gma")).setTabCompleter(new GameModesCommands());
+        Objects.requireNonNull(getCommand("gmsp")).setTabCompleter(new GameModesCommands());
+        Objects.requireNonNull(getCommand("essenchant")).setExecutor(CoolCommands.essenchant);
+        Objects.requireNonNull(getCommand("essenchant")).setTabCompleter(CoolCommands.essenchantTabCompleter);
+        Objects.requireNonNull(getCommand("chicken")).setExecutor(CoolCommands.chicken);
+        Objects.requireNonNull(getCommand("hat")).setExecutor(CoolCommands.hat);
+        Objects.requireNonNull(getCommand("fly")).setExecutor(CoolCommands.fly);
+        Objects.requireNonNull(getCommand("unessentials")).setExecutor(BaseCommands.unessentials);
+        Objects.requireNonNull(getCommand("unessentials")).setTabCompleter(BaseCommands.unessentialsTabCompleter);
+        Objects.requireNonNull(getCommand("unessentials")).setAliases(List.of("uness"));
+        Objects.requireNonNull(getCommand("top")).setExecutor(CoolCommands.top);
+        Objects.requireNonNull(getCommand("butcher")).setExecutor(CoolCommands.butcher);
+        Objects.requireNonNull(getCommand("back")).setExecutor(CoolCommands.back);
+        Objects.requireNonNull(getCommand("name")).setExecutor(CoolCommands.name);
+    }
+
+    public static String color(String s) {
+        return ChatColor.translateAlternateColorCodes('&', s);
+    }
+
+    public static void tickCycle() {
+        for (Player player : plugin.getServer().getOnlinePlayers()) {
+            String preName = player.getName();;
+            if (Config.getFieldBool(Config.Tab.TAB_FORMAT_ENABLED)) {
+                preName = color(Config.getFieldString(Config.Tab.TAB_FORMAT).replace("%NAME%", player.getName()));
+                if (UnEssentials.PAPI) preName = color(PlaceholderAPI.setPlaceholders(player, Config.getFieldString(Config.Tab.TAB_FORMAT).replace("%NAME%", player.getName())));
+            }
+            //old system: ignored if PAPI wasn't installed : if (UnEssentials.PAPI && Config.getFieldBool(Config.Tab.TAB_FORMAT_ENABLED)) preName = color(PlaceholderAPI.setPlaceholders(player, Config.getFieldString(Config.Tab.TAB_FORMAT).replace("%NAME%", player.getName())));
+            player.setPlayerListName(preName);
+        }
+    }
+}
diff --git a/src/main/java/com/the5gi/unessentials/Util/Config.java b/src/main/java/com/the5gi/unessentials/Util/Config.java
new file mode 100644
index 0000000..6906992
--- /dev/null
+++ b/src/main/java/com/the5gi/unessentials/Util/Config.java
@@ -0,0 +1,155 @@
+package com.the5gi.unessentials.Util;
+
+import java.io.IOException;
+
+import com.the5gi.unessentials.UnEssentials;
+import org.simpleyaml.configuration.file.YamlFile;
+
+public class Config {
+    private static final YamlFile config = new YamlFile(UnEssentials.plugin.getDataFolder().getPath() + "/config.yml");
+
+    public static void onStart() {
+        try {
+            if (!config.exists()) {
+                UnEssentials.plugin.getLogger().info("Creating Config...");
+                UnEssentials.plugin.getDataFolder().mkdir();
+                config.createNewFile();
+                UnEssentials.plugin.getLogger().info("Config Created!");
+            }
+            load();
+            UnEssentials.plugin.getLogger().info("Loaded Config");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        config.setComment(BaseLevel.PLUGIN_PREFIX.getField(), """
+                Prefix of Plugin Commands ex: "[UnEssentials] Your gamemode has been changed!"
+                You can use the & sign to use colors. https://htmlcolorcodes.com/minecraft-color-codes/""");
+        config.addDefault(BaseLevel.PLUGIN_PREFIX.getField(), "&c&l[UnEssentials]&r ");
+
+        config.setBlankLine("chat");
+        config.setComment(Chat.CHAT_FORMAT_ENABLED.getField(), "If enabled, Reformats chat messages using the format field below.");
+        config.addDefault(Chat.CHAT_FORMAT_ENABLED.getField(), Boolean.TRUE);
+
+        config.setComment(Chat.CHAT_FORMAT.getField(), """
+                The format of chat messages.
+                There are built in placeholders, but otherwise external placeholders require PlaceHolderAPI.
+                %NAME% gives the player's username. %MESSAGE% gives the player's message.
+                You can use colors with the & sign. https://htmlcolorcodes.com/minecraft-color-codes/""");
+        if (UnEssentials.PAPI && UnEssentials.LUCKPERMS) {
+            config.addDefault(Chat.CHAT_FORMAT.getField(), "%luckperms_prefix% %NAME% %luckperms_suffix%:&r %MESSAGE%");
+        } else {
+            config.addDefault(Chat.CHAT_FORMAT.getField(), "<%NAME%> %MESSAGE%");
+        }
+        config.setBlankLine(Chat.CHAT_FORMAT.getField());
+
+        config.setComment(Tab.TAB_FORMAT_ENABLED.getField(), "If enabled, Reformats tab usernames using the format field below.");
+        config.addDefault(Tab.TAB_FORMAT_ENABLED.getField(), Boolean.TRUE);
+
+        config.setComment(Tab.TAB_FORMAT.getField(), """
+                The format of usernames in tab.
+                There are built in placeholders, but otherwise external placeholders require PlaceHolderAPI.
+                %NAME% gives the player's username.
+                You can use colors with the & sign. https://htmlcolorcodes.com/minecraft-color-codes/""");
+        if (UnEssentials.PAPI && UnEssentials.LUCKPERMS) {
+            config.addDefault(Tab.TAB_FORMAT.getField(), "%luckperms_prefix% %NAME% %luckperms_suffix%");
+        } else {
+            config.addDefault(Tab.TAB_FORMAT.getField(), "%NAME%");
+        }
+        config.setBlankLine(Tab.TAB_FORMAT.getField());
+        save();
+        reload();
+    }
+
+    public static void load() {
+        try {
+            config.load();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void reload() {
+        try {
+            config.load();
+            UnEssentials.PREFIX = UnEssentials.color(getFieldString(BaseLevel.PLUGIN_PREFIX));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void save() {
+        try {
+            config.save();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static String getFieldString(Chat chat) {
+        return config.getString(chat.getField());
+    }
+
+    public static String getFieldString(Tab tab) {
+        return config.getString(tab.getField());
+    }
+
+    public static boolean getFieldBool(Chat chat) {
+        return config.getBoolean(chat.getField());
+    }
+
+    public static boolean getFieldBool(Tab tab) {
+        return config.getBoolean(tab.getField());
+    }
+
+    public static String getFieldString(BaseLevel bl) {
+        return config.getString(bl.getField());
+    }
+
+    public static boolean getFieldBool(BaseLevel bl) {
+        return config.getBoolean(bl.getField());
+    }
+
+    public enum Chat {
+        CHAT_FORMAT_ENABLED("chat.formatting_enabled"),
+        CHAT_FORMAT("chat.format");
+
+        private final String field;
+
+        Chat(String field) {
+            this.field = field;
+        }
+
+        public String getField() {
+            return this.field;
+        }
+    }
+
+    public enum Tab {
+        TAB_FORMAT_ENABLED("tab.formatting_enabled"),
+        TAB_FORMAT("tab.format");
+
+        private final String field;
+
+        Tab(String field) {
+            this.field = field;
+        }
+
+        public String getField() {
+            return this.field;
+        }
+    }
+
+    public enum BaseLevel {
+        PLUGIN_PREFIX("prefix");
+
+        private final String field;
+
+        BaseLevel(String field) {
+            this.field = field;
+        }
+
+        public String getField() {
+            return this.field;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..5397ac2
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,50 @@
+name: UnEssentials
+version: '1.0.0'
+main: com.the5gi.unessentials.UnEssentials
+api-version: 1.20
+authors: [s5gi]
+description: essentials but not gay asf
+website: 5gi.dev
+commands:
+  unessentials:
+    aliases:
+      - "uness"
+    permission: "unessentials.unessentials"
+    permission-message: "&cYou do not have permission to execute this command!"
+  gms:
+    permission: "unessentials.gms"
+    permission-message: "&cYou do not have permission to execute this command!"
+  gmc:
+    permission: "unessentials.gmc"
+    permission-message: "&cYou do not have permission to execute this command!"
+  gmsp:
+    permission: "unessentials.gmsp"
+    permission-message: "&cYou do not have permission to execute this command!"
+  gma:
+    permission: "unessentials.gma"
+    permission-message: "&cYou do not have permission to execute this command!"
+  essenchant:
+    permission: "unessentials.essenchant"
+    permission-message: "&cYou do not have permission to execute this command!"
+  chicken:
+    permission: "unessentials.chicken"
+    permission-message: "&cYou do not have permission to execute this command!"
+    description: "ignore me i just spawn a chicken because buh-cock"
+  hat:
+    permission: "unessentials.hat"
+    permission-message: "&cYou do not have permission to execute this command!"
+  fly:
+    permission: "unessentials.fly"
+    permission-message: "&cYou do not have permission to execute this command!"
+  top:
+    permission: "unessentials.top"
+    permission-message: "&cYou do not have permission to execute this command!"
+  butcher:
+    permission: "unessentials.butcher"
+    permission-message: "&cYou do not have permission to execute this command!"
+  back:
+    permission: "unessentials.back"
+    permission-message: "&cYou do not have permission to execute this command!"
+  name:
+    permission: "unessentials.name"
+    permission-message: "&cYou do not have permission to execute this command!"