diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 89022a7..436a660 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -8,6 +8,11 @@
         <option name="modules">
           <set>
             <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/api" />
+            <option value="$PROJECT_DIR$/common" />
+            <option value="$PROJECT_DIR$/mappings" />
+            <option value="$PROJECT_DIR$/mappings/v1_20" />
+            <option value="$PROJECT_DIR$/v1_20" />
           </set>
         </option>
       </GradleProjectSettings>
diff --git a/api/build.gradle.kts b/api/build.gradle.kts
new file mode 100644
index 0000000..32f99de
--- /dev/null
+++ b/api/build.gradle.kts
@@ -0,0 +1,11 @@
+plugins {
+    id("java")
+}
+
+java {
+    sourceCompatibility = JavaVersion.VERSION_21
+    targetCompatibility = JavaVersion.VERSION_21
+    toolchain {
+        languageVersion = JavaLanguageVersion.of(21)
+    }
+}
\ No newline at end of file
diff --git a/api/src/main/java/xyz/ineanto/nicko/api/NickoAPI.java b/api/src/main/java/xyz/ineanto/nicko/api/NickoAPI.java
new file mode 100644
index 0000000..c7dc0ac
--- /dev/null
+++ b/api/src/main/java/xyz/ineanto/nicko/api/NickoAPI.java
@@ -0,0 +1,4 @@
+package xyz.ineanto.nicko.api;
+
+public class NickoAPI {
+}
diff --git a/build.gradle.kts b/build.gradle.kts
index 18ed652..e2e0cde 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,12 +1,8 @@
 plugins {
     id("java")
     id("io.github.goooler.shadow") version "8.1.7"
-    id("xyz.jpenilla.run-paper") version "2.3.0"
 }
 
-group = "xyz.ineanto"
-version = "1.1.8"
-
 java {
     sourceCompatibility = JavaVersion.VERSION_21
     targetCompatibility = JavaVersion.VERSION_21
@@ -15,127 +11,7 @@ java {
     }
 }
 
-repositories {
-    mavenCentral()
-    mavenLocal()
-    maven { url = uri("https://jitpack.io") }
-    maven {
-        name = "xenondevs"
-        url = uri("https://repo.xenondevs.xyz/releases")
-    }
-    maven {
-        name = "papermc"
-        url = uri("https://repo.papermc.io/repository/maven-public/")
-    }
-    maven {
-        name = "codemc"
-        url = uri("https://repo.codemc.io/repository/maven-snapshots/")
-    }
-    maven {
-        name = "placeholderapi"
-        url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
-    }
-}
-
-dependencies {
-    // Nicko
-    compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
-    compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT")
-    compileOnly("me.clip:placeholderapi:2.11.5")
-    compileOnly("net.kyori:adventure-api:4.17.0")
-
-    implementation("xyz.xenondevs.invui:invui:1.35")
-    implementation("net.wesjd:anvilgui:1.10.1-SNAPSHOT")
-    implementation("com.github.jsixface:yamlconfig:1.2")
-    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2")
-    implementation("com.fasterxml.jackson.core:jackson-core:2.15.2")
-    implementation("com.mysql:mysql-connector-j:8.2.0")
-    implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1")
-    implementation("redis.clients:jedis:5.1.2")
-    implementation("com.google.code.gson:gson:2.10.1")
-    implementation("org.bstats:bstats-bukkit:3.0.2")
-
-    testImplementation("com.github.MockBukkit:MockBukkit:v3.99.1")
-    testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2")
-    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.2")
-    testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
-}
-
-tasks {
-    processResources {
-        from("src/main/resources")
-        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
-        filesMatching("*.yml") {
-            expand("version" to version)
-        }
-    }
-
-    shadowJar {
-        // NAMING
-        archiveBaseName.set("nicko")
-        archiveVersion.set(version.toString())
-        archiveAppendix.set("")
-        archiveClassifier.set("")
-
-        // RELOCATIONS
-        relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui")
-        relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi")
-        relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui")
-        relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml")
-        relocate("com.fasterxml.jackson.dataformat", "xyz.ineanto.nicko.libs.jackson.yaml")
-        relocate("com.fasterxml.jackson.core", "xyz.ineanto.nicko.libs.jackson.core")
-        relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql")
-        relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb")
-        relocate("redis.clients", "xyz.ineanto.nicko.libs.redis")
-        relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson")
-        relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2")
-        relocate("org.bstats", "xyz.ineanto.nicko.libs.bstats")
-
-        // EXCLUSIONS
-        exclude("colors.bin")
-        exclude("waffle/**")
-        exclude("com/sun/**")
-        exclude("com/google/protobuf/**")
-        exclude("com/google/errorprone/**")
-        exclude("org/apache/commons/logging/**")
-        exclude("org/jetbrains/**")
-        exclude("org/intellij/**")
-        exclude("org/checkerframework/**")
-        exclude("org/json/**")
-        exclude("org/slf4j/**")
-        exclude("org/yaml/**")
-        exclude("google/protobuf/**")
-        exclude("net/kyori/**")
-
-        // MINIFY
-        minimize {
-            exclude(dependency("xyz.xenondevs.invui:.*"))
-            exclude(dependency("net.wesjd:.*"))
-            exclude(dependency("org.bstats:.*"))
-        }
-    }
-
-    jar {
-        enabled = false
-    }
-
-    test {
-        useJUnitPlatform()
-    }
-
-    runServer {
-        dependsOn(shadowJar)
-
-        downloadPlugins {
-            url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar")
-
-            // 1.20 - 1.20.4 testing
-            //url("https://github.com/dmulloy2/ProtocolLib/releases/download/5.2.0/ProtocolLib.jar")
-
-            // 1.20.5 - latest testing
-            url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
-        }
-
-        minecraftVersion("1.21.1")
-    }
+allprojects {
+    group = "xyz.ineanto.nicko"
+    version = "1.2.0"
 }
\ No newline at end of file
diff --git a/common/build.gradle.kts b/common/build.gradle.kts
new file mode 100644
index 0000000..7872b82
--- /dev/null
+++ b/common/build.gradle.kts
@@ -0,0 +1,108 @@
+plugins {
+    id("java")
+    id("xyz.jpenilla.run-paper") version "2.3.0"
+    id("io.github.goooler.shadow") version "8.1.7"
+}
+
+java {
+    sourceCompatibility = JavaVersion.VERSION_21
+    targetCompatibility = JavaVersion.VERSION_21
+    toolchain {
+        languageVersion = JavaLanguageVersion.of(21)
+    }
+}
+
+dependencies {
+    compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT")
+    compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT")
+    compileOnly("me.clip:placeholderapi:2.11.5")
+    compileOnly("net.kyori:adventure-api:4.17.0")
+
+    rootProject.subprojects.forEach {
+        if (!it.name.startsWith("v")) return@forEach
+
+        compileOnly(project(":mappings:${it.name}"))
+    }
+
+    implementation("xyz.xenondevs.invui:invui:1.35")
+    implementation("net.wesjd:anvilgui:1.10.1-SNAPSHOT")
+    implementation("com.github.jsixface:yamlconfig:1.2")
+    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2")
+    implementation("com.fasterxml.jackson.core:jackson-core:2.15.2")
+    implementation("com.mysql:mysql-connector-j:8.2.0")
+    implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1")
+    implementation("redis.clients:jedis:5.1.2")
+    implementation("com.google.code.gson:gson:2.10.1")
+    implementation("org.bstats:bstats-bukkit:3.0.2")
+}
+
+tasks {
+    processResources {
+        from("src/main/resources")
+        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+        filesMatching("*.yml") {
+            expand("version" to version)
+        }
+    }
+
+    shadowJar {
+        // NAMING
+        archiveBaseName.set("nicko")
+        archiveVersion.set(version.toString())
+        archiveAppendix.set("")
+        archiveClassifier.set("")
+
+        // RELOCATIONS
+        relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui")
+        relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi")
+        relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui")
+        relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml")
+        relocate("com.fasterxml.jackson.dataformat", "xyz.ineanto.nicko.libs.jackson.yaml")
+        relocate("com.fasterxml.jackson.core", "xyz.ineanto.nicko.libs.jackson.core")
+        relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql")
+        relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb")
+        relocate("redis.clients", "xyz.ineanto.nicko.libs.redis")
+        relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson")
+        relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2")
+        relocate("org.bstats", "xyz.ineanto.nicko.libs.bstats")
+
+        // EXCLUSIONS
+        exclude("colors.bin")
+        exclude("waffle/**")
+        exclude("com/sun/**")
+        exclude("com/google/protobuf/**")
+        exclude("com/google/errorprone/**")
+        exclude("org/apache/commons/logging/**")
+        exclude("org/jetbrains/**")
+        exclude("org/intellij/**")
+        exclude("org/checkerframework/**")
+        exclude("org/json/**")
+        exclude("org/slf4j/**")
+        exclude("org/yaml/**")
+        exclude("google/protobuf/**")
+        exclude("net/kyori/**")
+
+        // MINIFY
+        minimize {
+            exclude(dependency("xyz.xenondevs.invui:.*"))
+            exclude(dependency("net.wesjd:.*"))
+            exclude(dependency("org.bstats:.*"))
+        }
+    }
+
+    runServer {
+        dependsOn(shadowJar)
+
+        downloadPlugins {
+            url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar")
+
+            // 1.20 - 1.20.4 testing
+            //url("https://github.com/dmulloy2/ProtocolLib/releases/download/5.2.0/ProtocolLib.jar")
+
+            // 1.20.5 - latest testing
+            url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
+        }
+
+        minecraftVersion("1.21.1")
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/common/src/main/java/xyz/ineanto/nicko/Nicko.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/Nicko.java
rename to common/src/main/java/xyz/ineanto/nicko/Nicko.java
diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/common/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java
rename to common/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java
diff --git a/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java b/common/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java
rename to common/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java
diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/common/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java
rename to common/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java
diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/common/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java
rename to common/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java
diff --git a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java b/common/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/command/NickoCommand.java
rename to common/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java
diff --git a/src/main/java/xyz/ineanto/nicko/config/Configuration.java b/common/src/main/java/xyz/ineanto/nicko/config/Configuration.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/config/Configuration.java
rename to common/src/main/java/xyz/ineanto/nicko/config/Configuration.java
diff --git a/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java b/common/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java
rename to common/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java
diff --git a/src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java b/common/src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java
rename to common/src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java
diff --git a/src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java b/common/src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java
rename to common/src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java
diff --git a/src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java b/common/src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java
rename to common/src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java
diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/common/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java
rename to common/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java
diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java b/common/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java
rename to common/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java
diff --git a/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java b/common/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java
rename to common/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java b/common/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java b/common/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/common/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java
rename to common/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java
diff --git a/src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java b/common/src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java
rename to common/src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java
diff --git a/src/main/java/xyz/ineanto/nicko/language/Language.java b/common/src/main/java/xyz/ineanto/nicko/language/Language.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/language/Language.java
rename to common/src/main/java/xyz/ineanto/nicko/language/Language.java
diff --git a/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java b/common/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/language/LanguageKey.java
rename to common/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java
diff --git a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java b/common/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java
rename to common/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java
diff --git a/src/main/java/xyz/ineanto/nicko/language/Translation.java b/common/src/main/java/xyz/ineanto/nicko/language/Translation.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/language/Translation.java
rename to common/src/main/java/xyz/ineanto/nicko/language/Translation.java
diff --git a/common/src/main/java/xyz/ineanto/nicko/mapping/Mapping.java b/common/src/main/java/xyz/ineanto/nicko/mapping/Mapping.java
new file mode 100644
index 0000000..38dd0ea
--- /dev/null
+++ b/common/src/main/java/xyz/ineanto/nicko/mapping/Mapping.java
@@ -0,0 +1,18 @@
+package xyz.ineanto.nicko.mapping;
+
+import org.bukkit.entity.Player;
+import xyz.ineanto.nicko.Nicko;
+import xyz.ineanto.nicko.storage.PlayerDataStore;
+import xyz.ineanto.nicko.storage.name.PlayerNameStore;
+
+import java.util.Set;
+
+public abstract class Mapping {
+    private final Nicko instance = Nicko.getInstance();
+    private final PlayerDataStore dataStore = instance.getDataStore();
+    private final PlayerNameStore nameStore = instance.getNameStore();
+
+    public abstract void respawn(Player player);
+
+    public abstract Set<String> supportedVersions();
+}
diff --git a/common/src/main/java/xyz/ineanto/nicko/mapping/MappingManager.java b/common/src/main/java/xyz/ineanto/nicko/mapping/MappingManager.java
new file mode 100644
index 0000000..e4da76f
--- /dev/null
+++ b/common/src/main/java/xyz/ineanto/nicko/mapping/MappingManager.java
@@ -0,0 +1,20 @@
+package xyz.ineanto.nicko.mapping;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Server;
+import xyz.ineanto.nicko.mapping.v1_20.Mapping1_20;
+
+import java.util.List;
+import java.util.Optional;
+
+public class MappingManager {
+    private final List<Mapping> mappings = List.of(
+            new Mapping1_20()
+    );
+
+    public Optional<Mapping> getMappingFor(Server server) {
+        return mappings.stream()
+                .filter(mapping -> mapping.supportedVersions().contains(Bukkit.getMinecraftVersion()))
+                .findFirst();
+    }
+}
diff --git a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java b/common/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java
rename to common/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java
diff --git a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java b/common/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java
rename to common/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java
diff --git a/src/main/java/xyz/ineanto/nicko/migration/Migrator.java b/common/src/main/java/xyz/ineanto/nicko/migration/Migrator.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/migration/Migrator.java
rename to common/src/main/java/xyz/ineanto/nicko/migration/Migrator.java
diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java
rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java
diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java
rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java
diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java
rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java
diff --git a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java b/common/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java
rename to common/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java
diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/common/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java
rename to common/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/Cache.java b/common/src/main/java/xyz/ineanto/nicko/storage/Cache.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/Cache.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/Cache.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java b/common/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/Storage.java b/common/src/main/java/xyz/ineanto/nicko/storage/Storage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/Storage.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/Storage.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java b/common/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java b/common/src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java b/common/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java b/common/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java b/common/src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java b/common/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java
diff --git a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java b/common/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java
rename to common/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java
diff --git a/src/main/java/xyz/ineanto/nicko/version/Version.java b/common/src/main/java/xyz/ineanto/nicko/version/Version.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/version/Version.java
rename to common/src/main/java/xyz/ineanto/nicko/version/Version.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java
diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java
similarity index 100%
rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java
rename to common/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java
diff --git a/mappings/v1_20/build.gradle.kts b/mappings/v1_20/build.gradle.kts
new file mode 100644
index 0000000..0a82a94
--- /dev/null
+++ b/mappings/v1_20/build.gradle.kts
@@ -0,0 +1,9 @@
+plugins {
+    id("java")
+    id("io.papermc.paperweight.userdev") version "1.7.2"
+}
+
+dependencies {
+    paperweight.paperDevBundle("1.20-R0.1-SNAPSHOT")
+    implementation(project(":common"))
+}
\ No newline at end of file
diff --git a/mappings/v1_20/src/main/java/xyz/ineanto/nicko/mapping/v1_20/Mapping1_20.java b/mappings/v1_20/src/main/java/xyz/ineanto/nicko/mapping/v1_20/Mapping1_20.java
new file mode 100644
index 0000000..fba7bae
--- /dev/null
+++ b/mappings/v1_20/src/main/java/xyz/ineanto/nicko/mapping/v1_20/Mapping1_20.java
@@ -0,0 +1,83 @@
+package xyz.ineanto.nicko.mapping.v1_20;
+
+import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
+import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
+import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
+import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.server.level.ServerPlayerGameMode;
+import net.minecraft.server.players.PlayerList;
+import net.minecraft.world.effect.MobEffectInstance;
+import net.minecraft.world.level.biome.BiomeManager;
+import org.bukkit.entity.Player;
+import xyz.ineanto.nicko.mapping.Mapping;
+
+import java.util.List;
+import java.util.Set;
+
+public class Mapping1_20 extends Mapping {
+    @Override
+    public void respawn(Player player) {
+        final ServerPlayer entityPlayer = (ServerPlayer) player;
+
+        final ServerLevel world = entityPlayer.serverLevel();
+        final ServerPlayerGameMode gameMode = entityPlayer.gameMode;
+
+        // Really Mojang...? (also applies to Bukkit/Spigot maintainers)
+        // I'll have to do this everytime I want to update Nicko for the foreseeable future.
+        // (until ProtocolLib has reworked its API to be more maintainable that said)
+
+        // I already when through this hassle with NickReloaded back in 2017,
+        // when mappings were not included by default, mind you.
+
+        // I had to rework the entire project structure and build process just for... you.
+
+        // I can't be bothered with fighting your game anymore.
+        // We need an easy and reliable way to send packets across multiple server versions.
+        // And I know that this is easier said than done, the game protocol needs
+        // to evolve and be updated, I get it. But I think you can at least try.
+
+        // You made a step forward by providing the mappings for Java, this I can agree with.
+        // (and still stripped them from Bedrock against community feedback, haha f*ck you.)
+        // However, we still need a stable and reliable Packet API (and so much more!) one day.
+
+        final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(
+                world.dimensionTypeId(),
+                world.dimension(),
+                BiomeManager.obfuscateSeed(world.getSeed()),
+                gameMode.getGameModeForPlayer(),
+                gameMode.getPreviousGameModeForPlayer(),
+                world.isDebug(),
+                world.isFlat(),
+                ClientboundRespawnPacket.KEEP_ALL_DATA,
+                entityPlayer.getLastDeathLocation(),
+                entityPlayer.getPortalCooldown()
+        );
+
+        entityPlayer.connection.send(new ClientboundPlayerInfoRemovePacket(List.of(player.getUniqueId())));
+        entityPlayer.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityPlayer)));
+
+        entityPlayer.connection.send(respawn);
+
+        entityPlayer.onUpdateAbilities();
+        entityPlayer.connection.teleport(player.getLocation());
+
+        entityPlayer.resetSentInfo();
+
+        final PlayerList playerList = entityPlayer.server.getPlayerList();
+        playerList.sendPlayerPermissionLevel(entityPlayer);
+        playerList.sendLevelInfo(entityPlayer, world);
+        playerList.sendAllPlayerInfo(entityPlayer);
+
+        // Resend their effects
+        for (MobEffectInstance effect : entityPlayer.getActiveEffects()) {
+            entityPlayer.connection.send(new ClientboundUpdateMobEffectPacket(entityPlayer.getId(), effect));
+        }
+    }
+
+    @Override
+    public Set<String> supportedVersions() {
+        return Set.of("1.20", "1.20.1");
+    }
+}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 4549581..a0f8a4d 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,2 +1,34 @@
 rootProject.name = "nicko"
 
+setOf(
+    "1_20"
+).forEach {
+    include("mappings:v$it")
+}
+
+include("common", "api")
+
+dependencyResolutionManagement {
+    repositories {
+        mavenCentral()
+        mavenLocal()
+        maven { url = uri("https://jitpack.io") }
+        maven {
+            name = "xenondevs"
+            url = uri("https://repo.xenondevs.xyz/releases")
+        }
+        maven {
+            name = "papermc"
+            url = uri("https://repo.papermc.io/repository/maven-public/")
+        }
+        maven {
+            name = "codemc"
+            url = uri("https://repo.codemc.io/repository/maven-snapshots/")
+        }
+        maven {
+            name = "placeholderapi"
+            url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
+        }
+    }
+}
+include("v1_20")
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
deleted file mode 100644
index 5f56371..0000000
--- a/src/main/resources/config.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# Nicko ${version} - Config:
-
-# Specifies the configuration version, don't change.
-version: "1.0.9"
-
-#
-# Language
-#
-
-# Nicko will copy the English locale as "lang.yml"
-# and will use the translations in that file when "Server Custom"
-# is selected as the player's locale.
-# Accepted values: false (Disabled), true (Enabled)
-customLocale: false
-
-#
-# Storage
-#
-
-sql:
-  # Indicates wherever the data will be stored locally
-  # inside a .json file or in an SQL database.
-  # Accepted values: false (Disabled), true (Enabled)
-  enabled: false
-  # Toggles between the MariaDB and MySQL drivers.
-  # If you use the MySQL database engine, switch this to off.
-  # Accepted values: false (Disabled), true (Enabled)
-  mariadb: true
-  # SQL database's address
-  # Accepted values: valid IP address (e.g. localhost, 127.0.0.1)
-  address: "localhost"
-  # SQL database's port
-  # Accepted values: valid integer (e.g. 3306, 25565)
-  port: 3306
-  # SQL database's username.
-  # Accepted values: any string
-  username: "username"
-  # SQL database's password.
-  # Accepted values: any string
-  password: "password"
-
-# This configuration section manages Redis (enabled BungeeCord support).
-# It is used to transfer data between multiple servers.
-redis:
-  # Indicates wherever the data will be stored through
-  # Redis to transfer whenever a player switches server.
-  # Accepted values: false (Disabled), true (Enabled)
-  enabled: false
-  # Redis server's address
-  # Accepted values: valid IP address (e.g.: localhost, 127.0.0.1)
-  address: "localhost"
-  # Redis server's port
-  # Accepted values: valid integer (e.g. 3306, 25565)
-  port: 6379
-  # Redis server's username
-  # Accepted values: any string
-  username: "username"
-  # Redis server's password
-  # Accepted values: any string
-  password: "password"
\ No newline at end of file
diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml
deleted file mode 100644
index 91704f4..0000000
--- a/src/main/resources/en.yml
+++ /dev/null
@@ -1,153 +0,0 @@
-# Nicko ${version} - Language File:
-
-# Specifies the configuration version, don't change.
-version: "1.1.4"
-
-prefix: "<b><gradient:#01a97c:#8ffd54>NICKO</gradient></b>"
-whoosh: "<b><gradient:#01a97c:#8ffd54>WHOOSH!</gradient></b>"
-oops: "<b><color:#ff4640>OOPS!</color></b>"
-
-error:
-  permission: "<gray>You're missing the permission to do that.</gray>"
-  invalid_username: "<gray>This is an invalid Minecraft username.</gray>"
-  mojang_name: "<gray>There's is not Minecraft account with this username.</gray>"
-  mojang_skin: "<gray>This Minecraft account has no skin.</gray>"
-  cache: "<gray>Unable to get data from the cache.</gray>"
-
-event:
-  settings:
-    error: "<gray>Wasn''t able to update your settings! ({0})</gray>"
-  appearance:
-    set:
-      error: "<gray>Wasn''t able to apply your disguise! ({0})</gray>"
-      ok: "<gray>You're now disguised.</gray>"
-    restore:
-      error: "<gray>Wasn''t able to apply the previous disguise! ({0})</gray>"
-      ok: "<gray>Disguise restored from last time.</gray>"
-    remove:
-      error: "<gray>Wasn''t able to remove your disguise!.</gray>"
-      missing: "<gray>You''re not currently disguised.</gray>"
-      ok: "<gray>Undisguised successfully.</gray>"
-  admin:
-    cache:
-      invalidate_cache: "<gray>Cache purged.</gray>"
-      invalidate_entry: "<gray>{0} was purged.</gray>"
-    check:
-      remove_skin: "<gray>Skin removed from player.</gray>"
-
-gui:
-  title:
-    home: "Nicko - Home"
-    settings: "Settings"
-    admin: "Administration"
-    check: "Player Management"
-    confirm: "Are you sure?"
-    cache: "Cache Management"
-    invalidate_skin: "Purge cache..."
-
-  exit:
-    name: "Exit"
-  go_back:
-    name: "Back"
-  unavailable:
-    name: "Unavailable"
-    lore:
-      - "<gray><i>This button is disabled.</i></gray>"
-  error:
-    name: "Error!"
-    lore:
-      - "<gray>The item failed to load, but it might still work.</gray>"
-  loading:
-    name: "<gray><i>Loading...</i></gray>"
-  choice:
-    confirm:
-      name: "<green>Confirm</green>"
-    choose:
-      name: "<gold><i>Choose an option...</i></gold>"
-    cancel:
-      name: "<red>Cancel</red>"
-  scroll_up:
-    name: "Scroll up"
-    lore:
-      - "<dark_gray><i>(You can't scroll any higher.)</i></dark_gray>"
-  scroll_down:
-    name: "Scroll down"
-    lore:
-      - "<dark_gray><i>(You can't scroll any further down.)</i></dark_gray>"
-  new_skin:
-    name: "New skin..."
-  new_name:
-    name: "New name..."
-  home:
-    admin:
-      name: "Administration panel"
-      lore:
-        - "<gray>Configure and manage Nicko.</gray>"
-    settings:
-      name: "Settings"
-      lore:
-        - "<gray>Fine tune your experience with Nicko.</gray>"
-    change_name:
-      name: "Change your <gold>nickname</gold>"
-    change_skin:
-      name: "Change your <gold>skin</gold>"
-    change_both:
-      name: "Change <gold>both</gold>"
-    random_skin:
-      name: "<rainbow>Get a random appearance!</rainbow>"
-    reset:
-      name: "Reset appearance"
-      lore:
-        - "<gray>Completely remove your disguise.</gray>"
-  admin:
-    manage_cache:
-      name: "Manage the <gold>skin</gold> cache..."
-      lore:
-        - "<gray>View and manage the skin cache.</gray>"
-    manage_player:
-      name: "Inspect a player..."
-      lore:
-        - "<gray>See players' disguise information.</gray>"
-    check:
-      name: "<gold>{0}</gold>"
-      lore:
-        - "<red>Nicked:</red> {1}"
-        - "<red>Name:</red> <gold>{2}</gold>"
-        - "<red>Skin:</red> <gold>{3}</gold>"
-        - " "
-        - "<gray><i>Click to remove skin!</i></gray>"
-    cache:
-      statistics:
-        name: "Statistics"
-        lore:
-          - "Request count: <aqua>{0}</aqua>"
-          - "Number of skin cached: <aqua>{1}</aqua>"
-          - "<dark_gray><i>Cache is cleared every 24 hours.</i></dark_gray>"
-      invalidate_cache:
-        name: "Invalidate cache"
-        lore:
-          - "<red><i>NOT RECOMMENDED</i></red>"
-          - "<gray>Invalidate the entirety of the skin cache.</gray>"
-          - "<gray>This doesn't reset player's disguises.</gray>"
-      invalidate_skin:
-        name: "Invalidate a skin..."
-        lore:
-          - "<gray>Select a specific skin to invalidate.</gray>"
-          - "<gray>Useful if a skin has been recently updated.</gray>"
-      entry:
-        name: "<gold>{0}</gold>"
-        lore:
-          - "<gray>Click to invalidate...</gray>"
-  settings:
-    toggleable_button:
-      lore:
-        - "{0} Disabled"
-        - "{1} Enabled"
-    cycling_choices:
-      lore:
-        - "<gray><i>Cycle through the values</i></gray>"
-        - "<gray><i>by left or right clicking.</i></gray>"
-    language:
-      name: "Language"
-    random_skin:
-      name: "Random skin on login"
\ No newline at end of file
diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml
deleted file mode 100644
index 9f9419f..0000000
--- a/src/main/resources/fr.yml
+++ /dev/null
@@ -1,155 +0,0 @@
-# Nicko ${version} - Fichier de langue:
-
-# Précise la version de la configuration, ne pas changer.
-version: "1.1.4"
-
-prefix: "<b><gradient:#01a97c:#8ffd54>NICKO</gradient></b>"
-whoosh: "<b><gradient:#01a97c:#8ffd54>WHOOSH!</gradient></b>"
-oops: "<b><color:#ff4640>OOPS!</color></b>"
-
-error:
-  permission: "<gray>Vous n'avez pas la permission de faire cela.<gray>"
-  invalid_username: "<gray>Nom d'utilisateur Minecraft invalide.<gray>"
-  mojang_name: "<gray>Aucun compte Minecraft associé à ce nom d'utilisateur.<gray>"
-  mojang_skin: "<gray>Ce compte Minecraft n'a pas de skin.<gray>"
-  cache: "<gray>Impossible de récupérer les données depuis le cache.<gray>"
-
-event:
-  settings:
-    error: "<gray>Impossible de mettre à jour vos paramètres ! ({0})</gray>"
-  appearance:
-    set:
-      error: "<gray>Impossible d''appliquer votre déguisement ! ({0})</gray>"
-      ok: "<gray>Déguisement appliqué avec succès.</gray>"
-    restore:
-      error: "<gray>Impossible d''appliquer le précédent déguisement ! ({0})</gray>"
-      ok: "<gray>Votre précédent déguisement a été appliqué.<gray>"
-    remove:
-      error: "<gray>Impossible de retirer votre déguisement.</gray>"
-      missing: "<gray>Vous n''avez pas de déguisement.</gray>"
-      ok: "<gray>Déguisement retiré.</gray>"
-  admin:
-    cache:
-      invalidate_cache: "<gray>Cache complet invalidé.</gray>"
-      invalidate_entry: "<gray>{0} a été invalidé.</gray>"
-    check:
-      remove_skin: "<gray>Déguisement retiré au joueur.</gray>"
-
-gui:
-  title:
-    home: "Nicko - Accueil"
-    settings: "Paramètres"
-    admin: "Administration"
-    check: "Gestion des Joueurs"
-    confirm: "Êtes-vous sûr ?"
-    cache: "Gestion du Cache"
-    invalidate_skin: "Purge du cache..."
-
-  exit:
-    name: "Quitter"
-  go_back:
-    name: "Retour"
-  unavailable:
-    name: "Indisponible"
-    lore:
-      - "<gray><i>Ce boutton est désactivé.</i></gray>"
-  error:
-    name: "Erreur !"
-    lore:
-      - "<gray>La texture de l'objet n'a pas chargé</gray>"
-      - "<gray>correctement mais il fonctionne encore.</gray>"
-  loading:
-    name: "<gray><i>Chargement...</i></gray>"
-  choice:
-    confirm:
-      name: "<green>Confirmer</green>"
-    choose:
-      name: "<gold><i>Choisissez une option...</i></gold>"
-    cancel:
-      name: "<red>Annuler</red>"
-  scroll_up:
-    name: "Défiler vers le haut"
-    lore:
-      - "<dark_gray><i>(Impossible de défiler plus haut.)</i></dark_gray>"
-  scroll_down:
-    name: "Défiler vers le bas"
-    lore:
-      - "<dark_gray><i>(Impossible de défiler plus bas.)</i></dark_gray>"
-  new_skin:
-    name: "Nouveau skin..."
-  new_name:
-    name: "Nouveau nom..."
-  home:
-    admin:
-      name: "Panel d'administration"
-      lore:
-        - "<gray>Configurez et gérez Nicko.</gray>"
-    settings:
-      name: "Paramètres"
-      lore:
-        - "<gray>Gérez votre expérience avec Nicko.</gray>"
-    change_name:
-      name: "Changer le <gold>pseudo</gold>"
-    change_skin:
-      name: "Changer le <gold>skin</gold>"
-    change_both:
-      name: "Changer les <gold>deux</gold>"
-    random_skin:
-      name: "<rainbow>Obtenir une apparence aléatoire !</rainbow>"
-    reset:
-      name: "Réinitialiser l'apparence"
-      lore:
-        - "<gray>Supprime complètement votre déguisement.</gray>"
-  admin:
-    manage_cache:
-      name: "Gérer le cache de <gold>skin...</gold>"
-      lore:
-        - "<gray>Consultez et gérez le cache de skin.</gray>"
-    manage_player:
-      name: "Vérifier un joueur..."
-      lore:
-        - "<gray>Vérifiez les informations de déguisement d'un joueur.</gray>"
-    check:
-      name: "<gold>{0}</gold>"
-      lore:
-        - "<red>Déguisé:</red> {1}"
-        - "<red>Nom:</red> <gold>{2}</gold>"
-        - "<red>Skin:</red> <gold>{3}</gold>"
-        - " "
-        - "<gray><i>Cliquez pour retirer le skin !</i></gray>"
-    cache:
-      statistics:
-        name: "Statistiques"
-        lore:
-          - "Nombre de requêtes: <aqua>{0}</aqua>"
-          - "Nb. de skin dans le cache: <aqua>{1}</aqua>"
-          - "<dark_gray><i>Le cache est vidé toutes les 24 heures.</i></dark_gray>"
-      invalidate_cache:
-        name: "Purger le cache"
-        lore:
-          - "<red><i>DÉCONSEILLÉ</i></red>"
-          - "<gray>Purge l'entièreté du cache des skin.</gray>"
-          - "<gray>Ne retire pas les déguisements des joueurs.</gray>"
-      invalidate_skin:
-        name: "Invalider un skin..."
-        lore:
-          - "<gray>Sélectionnez une apparence spécifique à</gray>"
-          - "<gray>invalider. Utile dans le cas où un skin</gray>"
-          - "<gray>a récemment été mis à jour.</gray>"
-      entry:
-        name: "<gold>{0}</gold>"
-        lore:
-          - "<gray>Cliquez pour invalider...</gray>"
-  settings:
-    toggleable_button:
-      lore:
-        - "{0} Désactivé"
-        - "{1} Activé"
-    cycling_choices:
-      lore:
-        - "<gray><i>Parcourez les valeurs</i></gray>"
-        - "<gray><i>avec un clique gauche/droit.</i></gray>"
-    language:
-      name: "Langage"
-    random_skin:
-      name: "Apparence aléatoire à la connexion"
\ No newline at end of file
diff --git a/src/main/resources/names.txt b/src/main/resources/names.txt
deleted file mode 100644
index 0d54e92..0000000
--- a/src/main/resources/names.txt
+++ /dev/null
@@ -1,490 +0,0 @@
-w4nderlost
-TooParanoids
-Der_OG_31er
-9xxDaRkShAdOwxx9
-giiiaan_
-Jqstinnn
-Tillysboy92
-AlwaysCello
-SyndrexG0D
-Peypeycake
-ThePerjurer
-Tioe
-Elternbaum
-BarkersRover_16
-pebsso
-cyrus6950
-Bigest_guy
-RV0REU
-R379
-Shetell
-_HEAPASS_
-Iamaloner21
-TheFardoxGamerHD
-Flyboi43
-Cha0smusik
-kat00
-Infreat
-Crummymoofin
-MijnVriend
-momsrightkidney
-dmacrado
-Elephantman321
-ii_hamoudi_YT
-FaurePavane
-ambiezzz
-XD_Bandit695_XD
-Nabingo
-Cyl0re
-ku5
-SrAragon
-StarlightDream9
-CJ5370
-rainbees
-KeroTheWolf
-Andrews9722
-cursed_Assyrian
-yamateni
-ProgramEXE
-exprso
-harrypanda
-LookerMD
-migykins
-Wintrous
-ZzGaBi
-Flayber
-Grenixal
-maeve_wells
-Creeper10fr
-10Chairs
-2525lock
-Shqipe
-XenitsuZen
-Berno17_
-wolle1313
-HalfDogHalfCat1
-NachoGarcia
-popsicoal
-NemesiSevil2006
-AnywayOj
-Tanko12345
-Samdweck
-LYRECODE123
-Resulten
-SirBastii
-Maku056
-ItzArnizzz
-Brsh3620
-Masonita
-kapplanium
-shoezo
-Mansur203
-Waterboy15217
-redragonne
-ghko325
-HopePVP_tw7
-xtka
-NimwenxZ
-Hiro0408
-PanderaWz
-Shesu
-_Aniste_NY_
-Besceste
-3ee3
-ArcticGalaxy123
-snooze_mingo
-LizzyLomnh
-FaZeChulupa
-LineZeeK
-liabilaty
-BlackSheep1610
-Simif69
-Aficionado
-riekin
-XLuggas
-MathExams
-6fq
-Marveel
-lolme51
-TaioSayUwU
-Fonklift
-blvw
-Po1204
-Pierre_Rabbit
-mifimasters
-MrRidge1
-arnqen
-Nick_cage102
-Geo_9918
-SSShudder
-Nicolas_Mom
-WolfMatrix101
-frictionless_
-Gughik
-gold_dragon_4
-nealxero
-ClonedPickle
-SourWatermelonxX
-devilunion
-Daryifuny
-joaomarcos11
-Dekeef
-PadfootTheDog
-DarkScopez80
-flowers220
-Gaiiya
-The_Yeet_
-juuuuwu
-MrMafioz
-Surpasses
-TypicalOwen
-0lober
-Zerfixy
-Sunny3803b
-neostanley
-Creeper_Kart
-minestin
-Goldenfredster
-Vju
-MrArchI_YT
-Casper1709
-Backiii_
-DrCreate
-Nova_Lux1
-Jayvin_Blanco
-ShadowMan1770
-0KOPO40K
-Silk_Altermann69
-Alu____
-Honey_MilkExe112
-T0XEI
-CB_13
-Paragorn
-HaGiang
-Shivendra8i
-Mayflower47
-Not_Someguy
-raxx111bg
-IceyGlaceon
-grasseffect
-PoopTNTpvp
-codecyber
-Shrumpkin13
-Shqdown
-Cmartin82
-KTCXD_5p0tty
-rockesalt
-goldjeong
-TheRealAKD
-NamiSwaaan
-yaaratol
-Dikiy_Flexer
-PoLecker24
-_SakuraTree
-PikkOgP0rno
-HawksFang
-BlueWinterWolf
-hskmerk
-gurmaw
-Lunggor
-clashfield
-Zelaste
-ACommonMouse
-TJ_Mystery
-Dizzy3312
-Raindropsss
-minecraftxiaoju
-sachilovebbh
-Celina_LaZyCxt
-firered6
-55000000
-Illunarnati
-Jedidiah2003
-setomz1
-basically_e
-TommyGreif02
-Bongrip42069
-Coco_Keopi
-Lt_Colt
-Kuurotta
-GqmeKnight
-WinCo_Foods
-FKDLZ
-IanPumpkin
-tastywtf
-natedawg0
-ZQLFenyx
-GamerMaster110
-papajobi9
-Yucaroon
-Xion_69
-AirJaw
-funfun321234
-khalleesii
-Pozisch
-thorso15
-kyumisoup
-Leonqrd
-BmwDreamer
-TehRos
-pitplayer69
-_ve0
-Miss_Yuka
-I_am_a_Bucket
-nicolas_bean
-xHorizonGC
-RTX3060_
-Borec188
-c8to
-megan3groCENG
-ventriloquize
-galczin
-Scorch3dEarth3d
-nightstarLP
-VittyGam3r
-GLaDOS__
-hydrelo
-JustACarter
-MikeDropperPlay
-NorthernWest
-_Skelesam_
-ZX_Style
-Tamas_Boi
-taylub
-VyacheslavO_O
-trippyaubs
-udtpic
-Lunarglow
-Stoolman
-legendary_meow
-Loganii
-CaptainStain56
-FoofieGeto
-Judgeavapl
-OneBigDigger
-Sorem13
-Raisonneur
-IlkoalI
-Naxa
-craigbabyonebay
-NicholasG04
-UtopianCrisi
-CalamarPasGenti
-ryluh_
-Aceslimz
-Howardygh99927
-brandon257
-MarcoswildHD
-x_XSkylerX_x
-Bronco09
-That_Kookie_
-Danigtz
-Ricky_lol
-999keyt
-Thilow15
-Difesito
-ostehovl
-isacano_12
-big_esra
-secretbaguette
-MrCommunism
-Jekube
-GrandeMaster
-DrGrip
-TheArnek
-JacsMars
-Lliam14
-MrGameandWatch84
-Rinzap
-XrazzeD
-ukknown
-ZohanPrent
-Naspo
-Rajem
-VepiGHG
-matoureal
-BrianChen87
-Jrocky
-stivo999
-Des_cole
-ReqGames
-Kingja1912
-issssyy
-Apache424
-Nick_Zockt_
-Mr_Haider_10
-ValentineBun
-fedorPro228
-xTilz
-blockbuster02k
-4ck
-FrostedTree
-VegasTortoise
-ZBellaV12121
-paypales
-qDread
-itsRiven
-i8oreo
-_kimcream_
-Phisuss
-Oscargray
-Elsiff
-callofdutydog00
-BruhTheMoment
-Pazmaa
-MythicalOak
-komuchi33
-awf4
-Jacobsaurus21
-itsjohannaa
-Jello12
-Adrien183
-jajazzywazzy
-Jorjie22
-SuperBrawlr5788
-KaraageV
-_Hanime_tv
-Padilhao
-Tikkas
-ordinaryducky
-Mothytix95
-renopotouwu
-1000voices
-niclas05
-Felipstein
-DoutorBauer
-FireballPlaysMC
-vapelordsheep
-Aboain
-ImGrexy
-Aivokolo
-SuperAmazing101
-va75a77a
-_DawYans_
-AceT1223
-Livvyboo7
-Saaaaaaaaaaaaans
-okaychill
-AwesomeBro1122
-absolutesnek
-jogie5000
-curtainSenpai
-gabbyisaloser
-gamergurl6969
-ZeusDk
-FranaRibas
-Discoboss
-SYZ_1
-Nakoe
-FIU_Captive
-xSiFan_
-ilyDeathxz
-da_fipsi
-Lochy
-The_Lavie37
-Tonion
-vnvrchy
-xX0meg4Xx
-haohxtheone
-VtTronic
-xDaniGum
-tikkelill
-DatYoshi
-eyehamstewpit
-nicholas460_
-Memsly445
-nugunugu
-AndreSlayz
-jashik1
-Qweenoftheocean
-Coltable
-treblaclef
-Kisaxx
-69Dxddy69
-RaulCuh
-3Wheat
-_OscarTheGrouch
-oIsqk
-Blockbusterweng
-AntoineDegauss
-ValeIsTheBest
-SwaggyCrabby
-DieOfSanity
-SirenMC
-Jade_Jewel
-Tropic44
-666splendor
-TallnessTallness
-breadgang9827
-Muffin_Worlds
-DedicatedVeggie
-Gonzalox_7
-datrandomasian
-Chasemon01
-Nyavix
-Lonely_Summers
-_RoveN
-ok_kyro
-LN_hunter
-saharsabz
-Roselilianna
-Gadx
-xtytan
-RoRo_levosgien88
-Bowsesqe_21
-Bennett528
-TheShipSailsWest
-KaiserGaming
-Layna_Shinozaki
-OP_greatly
-D3rpTaco
-Loufink
-Jorlmungus
-Snichol1801
-Ludixeo
-Imoeto
-MarshallNebunu
-crazycrystals
-Parapatus
-HahaDani
-MrQuaring
-DonTurnt
-SailorRoberts101
-FluffieBear
-TripleThick
-KingSparta
-MummysHome
-Cooga3
-Technosista
-Youmerstudios
-SkyyRaine
-criss102
-mrfailt
-CraftingBasic
-qnxkdifh
-Igorex2k20
-LaLisette
-ReBoredGamer
-warlordwest
-ExoTemporal
-KingLonmc
-666Horus
-IslandCity2
-TheBigSavage1
-Trishke2003
-skyrowin
-Krissy3D
-AntonWTobias
-SaddyWasTaken
-Ahoy_Peko_Hao_Yo
-T4nTr1Ss
-aleciolike
-ninja_shenley
-Lordmord1337
-eatmypoopfather
-Ktanner
-The42OWeedGOD
-CooperBee
-_MikuMiku_
-althume
-Tr3bba93
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
deleted file mode 100644
index 6f525c4..0000000
--- a/src/main/resources/plugin.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: Nicko
-main: xyz.ineanto.nicko.Nicko
-version: ${version}
-author: Ineanto
-description: "The feature packed, next generation disguise plugin for Minecraft."
-api-version: 1.20
-softdepend: [ PlaceholderAPI ]
-depend:
-  - ProtocolLib
-load: POSTWORLD
-commands:
-  nicko:
-    description: "Opens Nicko's GUI."
-    permission: nicko.use
-permissions:
-  nicko.*:
-    default: op
-    children:
-      - nicko.use
-  nicko.use:
-    default: false
\ No newline at end of file
diff --git a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java
deleted file mode 100644
index 5ce3aea..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package xyz.ineanto.nicko.test;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-public class NickoPluginTest {
-    private static Nicko plugin;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = Configuration.DEFAULT;
-        MockBukkit.mock();
-        plugin = MockBukkit.load(Nicko.class, config);
-    }
-
-    @Test
-    @DisplayName("Plugin Initialization")
-    public void initializePlugin() {
-        assertNotNull(plugin);
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java
deleted file mode 100644
index 057c076..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package xyz.ineanto.nicko.test.appearance;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.appearance.random.RandomNameFetcher;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.mojang.MojangUtils;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class RandomNameTest {
-    private static Nicko plugin;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = Configuration.DEFAULT;
-        MockBukkit.mock();
-        plugin = MockBukkit.load(Nicko.class, config);
-    }
-
-    @Test
-    @DisplayName("Get random name")
-    public void getRandomName() {
-        final RandomNameFetcher randomNameFetcher = new RandomNameFetcher(plugin);
-        final String username = randomNameFetcher.getRandomUsername();
-        assertNotNull(username);
-        assertFalse(MojangUtils.isUsernameInvalid(username));
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java
deleted file mode 100644
index 4a371fa..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package xyz.ineanto.nicko.test.config;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-
-public class ConfigurationTest {
-    private static Nicko plugin;
-
-    @BeforeAll
-    public static void setup() {
-        MockBukkit.mock();
-        final Configuration config = Configuration.DEFAULT;
-        plugin = MockBukkit.load(Nicko.class, config);
-    }
-
-    @Test
-    @DisplayName("Read configuration")
-    public void readConfiguration() {
-        final Configuration configuration = plugin.getNickoConfig();
-        assertFalse(configuration.getSqlConfiguration().isEnabled());
-        assertFalse(configuration.getRedisConfiguration().isEnabled());
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java
deleted file mode 100644
index d13fa80..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package xyz.ineanto.nicko.test.config;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.config.DefaultDataSources;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class ConfigurationVersionTest {
-    @BeforeAll
-    public static void setup() {
-        MockBukkit.mock();
-        final Configuration configuration = Configuration.DEFAULT;
-        MockBukkit.load(Nicko.class, configuration);
-    }
-
-    @Test
-    @DisplayName("Compare configuration version")
-    public void compareConfigurationVersion() {
-        final Configuration configuration = Configuration.DEFAULT;
-        assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 0);
-    }
-
-    @Test
-    @DisplayName("Compare newer configuration version")
-    public void compareNewerConfigurationVersion() {
-        final Configuration configuration = new Configuration("24.1.0",
-                DefaultDataSources.SQL_EMPTY,
-                DefaultDataSources.REDIS_EMPTY,
-                false);
-        assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 1);
-    }
-
-    @Test
-    @DisplayName("Compare older configuration version")
-    public void compareOlderConfigurationVersion() {
-        final Configuration configuration = new Configuration("0.23.3",
-                DefaultDataSources.SQL_EMPTY,
-                DefaultDataSources.REDIS_EMPTY,
-                false);
-        assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1);
-    }
-
-    @Test
-    @DisplayName("Compare unknown configuration version")
-    public void compareUnknownConfigurationVersion() {
-        final Configuration configuration = new Configuration(null,
-                DefaultDataSources.SQL_EMPTY,
-                DefaultDataSources.REDIS_EMPTY,
-                false);
-        assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1);
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java
deleted file mode 100644
index 3c17c5d..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package xyz.ineanto.nicko.test.i18n;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import be.seeseemelk.mockbukkit.entity.PlayerMock;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.language.Language;
-import xyz.ineanto.nicko.language.PlayerLanguage;
-import xyz.ineanto.nicko.language.LanguageKey;
-import xyz.ineanto.nicko.language.Translation;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class ItemTranslationTest {
-    private static PlayerMock player;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = Configuration.DEFAULT;
-        MockBukkit.mock();
-        MockBukkit.load(Nicko.class, config);
-    }
-
-    @Test
-    @DisplayName("Translate Item Without Lore")
-    public void translateItemTranslationWithoutLore() {
-        final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH);
-        final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.GO_BACK);
-        assertTrue(translation.lore().isEmpty());
-        assertEquals(translation.name(), "Retour");
-    }
-
-    @Test
-    @DisplayName("Translate Item")
-    public void translateItemLore() {
-        final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH);
-
-        final Translation test = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST");
-        test.lore().forEach(System.out::println);
-
-        final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.Admin.Cache.STATISTICS, "1", "1");
-        assertFalse(translation.lore().isEmpty());
-        assertEquals("Nombre de requêtes: <aqua>1</aqua>", translation.lore().get(0));
-        assertEquals("Nb. de skin dans le cache: <aqua>1</aqua>", translation.lore().get(1));
-        assertEquals("<dark_gray><i>Le cache est vidé toutes les 24 heures.</i></dark_gray>", translation.lore().get(2));
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java
deleted file mode 100644
index bac0c45..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package xyz.ineanto.nicko.test.i18n;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.language.Language;
-import xyz.ineanto.nicko.language.PlayerLanguage;
-import xyz.ineanto.nicko.language.LanguageKey;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class TranslationTest {
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = Configuration.DEFAULT;
-        MockBukkit.mock();
-        MockBukkit.load(Nicko.class, config);
-    }
-
-    @Test
-    @DisplayName("Translate Line With Replacement")
-    public void translateItemTranslationWithoutLore() {
-        final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH);
-        final String translation = playerLanguage.translate(LanguageKey.Event.Settings.ERROR, false, "Test");
-        assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation);
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java
deleted file mode 100644
index 170f367..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package xyz.ineanto.nicko.test.migration;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.config.DefaultDataSources;
-import xyz.ineanto.nicko.language.CustomLanguage;
-import xyz.ineanto.nicko.migration.CustomLocaleMigrator;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-public class MigrationTest {
-    private static Nicko plugin;
-
-    private static File folder;
-    private static File localeFile;
-
-    @BeforeAll
-    public static void setup() throws IOException {
-        MockBukkit.mock();
-        final Configuration configuration = new Configuration(Configuration.VERSION.toString(),
-                DefaultDataSources.SQL_EMPTY,
-                DefaultDataSources.REDIS_EMPTY,
-                true);
-        plugin = MockBukkit.load(Nicko.class, configuration);
-        folder = new File(plugin.getDataFolder(), "/locale/");
-        localeFile = new File(folder, "locale.yml");
-        folder.mkdirs();
-        localeFile.createNewFile();
-    }
-
-    @Test
-    public void testLanguageFileMigration() throws IOException {
-        final String content = """
-                # Nicko - Language File:
-                
-                # hello I'm the invalid version
-                version: "1.0.0"
-                """;
-
-        BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localeFile));
-        outputStream.write(content.getBytes(StandardCharsets.UTF_8));
-        outputStream.flush();
-
-        // Get wrong locale
-        final CustomLanguage customLanguageBeforeMigration = new CustomLanguage();
-        assertEquals(customLanguageBeforeMigration.getVersion(), "1.0.0");
-
-        // Migrate the wrong locale to the correct one
-        final CustomLocaleMigrator localeMigrator = new CustomLocaleMigrator(plugin, customLanguageBeforeMigration);
-        localeMigrator.migrate();
-
-        // Get the migrated locale
-        final CustomLanguage customLanguageMigrated = new CustomLanguage();
-        assertEquals(customLanguageMigrated.getVersion(), "1.1.0");
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-        folder.delete();
-        localeFile.delete();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java
deleted file mode 100644
index 2cc8ca7..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package xyz.ineanto.nicko.test.storage;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import be.seeseemelk.mockbukkit.ServerMock;
-import be.seeseemelk.mockbukkit.entity.PlayerMock;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.profile.NickoProfile;
-
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class MapCacheTest {
-    private static Nicko plugin;
-    private static PlayerMock player;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = Configuration.DEFAULT;
-        final ServerMock server = MockBukkit.mock();
-        plugin = MockBukkit.load(Nicko.class, config);
-        player = server.addPlayer();
-    }
-
-    @Test
-    @DisplayName("Cache Player Data")
-    public void cachePlayerData() {
-        final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
-        assertTrue(optionalProfile.isPresent());
-        assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId()));
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java
deleted file mode 100644
index a5ce971..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package xyz.ineanto.nicko.test.storage;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import be.seeseemelk.mockbukkit.ServerMock;
-import be.seeseemelk.mockbukkit.entity.PlayerMock;
-import org.junit.jupiter.api.*;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.appearance.ActionResult;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.config.DataSourceConfiguration;
-import xyz.ineanto.nicko.config.DefaultDataSources;
-import xyz.ineanto.nicko.profile.NickoProfile;
-import xyz.ineanto.nicko.storage.PlayerDataStore;
-import xyz.ineanto.nicko.storage.redis.RedisCacheProvider;
-
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-public class RedisCacheTest {
-    private static Nicko plugin;
-    private static PlayerMock player;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = new Configuration(
-                "",
-                DefaultDataSources.SQL_EMPTY,
-                new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""),
-                false);
-        final ServerMock server = MockBukkit.mock();
-        plugin = MockBukkit.load(Nicko.class, config);
-        player = server.addPlayer();
-        assertInstanceOf(RedisCacheProvider.class, plugin.getDataStore().getCache().getProvider());
-    }
-
-    @Test
-    @DisplayName("Cache Profile")
-    @Order(1)
-    public void cacheProfile() {
-        final Optional<NickoProfile> optionalProfile = plugin.getDataStore().getData(player.getUniqueId());
-        assertTrue(optionalProfile.isPresent());
-        assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId()));
-    }
-
-    @Test
-    @DisplayName("Update Cache Profile")
-    @Order(2)
-    public void updateCache() {
-        final Optional<NickoProfile> optionalProfile = NickoProfile.get(player);
-        assertTrue(optionalProfile.isPresent());
-
-        final NickoProfile profile = optionalProfile.get();
-        final PlayerDataStore dataStore = plugin.getDataStore();
-        profile.setName("Notch");
-        dataStore.updateCache(player.getUniqueId(), profile);
-
-        final Optional<NickoProfile> retrieve = dataStore.getCache().retrieve(player.getUniqueId());
-        assertTrue(retrieve.isPresent());
-        final NickoProfile retrieved = retrieve.get();
-        assertEquals(retrieved.getName(), "Notch");
-    }
-
-    @Test
-    @DisplayName("Delete Cache Profile")
-    @Order(3)
-    public void deleteCache() {
-        final PlayerDataStore dataStore = plugin.getDataStore();
-        final ActionResult cacheDelete = dataStore.getCache().delete(player.getUniqueId());
-        assertFalse(cacheDelete.isError());
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java
deleted file mode 100644
index 0bd04ba..0000000
--- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package xyz.ineanto.nicko.test.storage;
-
-import be.seeseemelk.mockbukkit.MockBukkit;
-import org.junit.jupiter.api.*;
-import xyz.ineanto.nicko.Nicko;
-import xyz.ineanto.nicko.appearance.ActionResult;
-import xyz.ineanto.nicko.config.Configuration;
-import xyz.ineanto.nicko.config.DefaultDataSources;
-import xyz.ineanto.nicko.config.SQLDataSourceConfiguration;
-import xyz.ineanto.nicko.language.Language;
-import xyz.ineanto.nicko.profile.NickoProfile;
-import xyz.ineanto.nicko.storage.PlayerDataStore;
-import xyz.ineanto.nicko.storage.mariadb.MariaDBStorageProvider;
-
-import java.util.Optional;
-import java.util.UUID;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-public class SQLStorageTest {
-    private static PlayerDataStore dataStore;
-    private static UUID uuid;
-
-    @BeforeAll
-    public static void setup() {
-        final Configuration config = new Configuration(
-                "",
-                new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345", true),
-                DefaultDataSources.REDIS_EMPTY,
-                false);
-
-        MockBukkit.mock();
-
-        final Nicko plugin = MockBukkit.load(Nicko.class, config);
-        dataStore = plugin.getDataStore();
-        uuid = UUID.randomUUID();
-        assertInstanceOf(MariaDBStorageProvider.class, dataStore.getStorage().getProvider());
-    }
-
-    @Test
-    @DisplayName("Create tables")
-    @Order(1)
-    public void createTables() {
-        assertFalse(dataStore.getStorage().isError());
-    }
-
-    @Test
-    @DisplayName("Store empty profile")
-    @Order(2)
-    public void storeEmptyProfile() {
-        final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
-        assertTrue(optionalProfile.isPresent());
-    }
-
-    @Test
-    @DisplayName("Update profile")
-    @Order(3)
-    public void updateProfile() {
-        final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
-        assertTrue(optionalProfile.isPresent());
-
-        final NickoProfile profile = optionalProfile.get();
-        assertNull(profile.getName());
-        assertNull(profile.getSkin());
-        assertEquals(profile.getLocale(), Language.ENGLISH);
-        assertTrue(profile.isRandomSkin());
-
-        profile.setName("Notch");
-        profile.setSkin("Notch");
-        profile.setLocale(Language.FRENCH);
-        profile.setRandomSkin(false);
-
-        final ActionResult result = dataStore.getStorage().store(uuid, profile);
-        assertFalse(result.isError());
-    }
-
-    @Test
-    @DisplayName("Get updated profile")
-    @Order(4)
-    public void hasProfileBeenUpdated() {
-        final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
-        assertTrue(optionalProfile.isPresent());
-
-        final NickoProfile updatedProfile = optionalProfile.get();
-        assertEquals(updatedProfile.getName(), "Notch");
-        assertEquals(updatedProfile.getSkin(), "Notch");
-        assertEquals(updatedProfile.getLocale(), Language.FRENCH);
-        assertFalse(updatedProfile.isRandomSkin());
-    }
-
-    @Test
-    @DisplayName("Delete profile")
-    @Order(5)
-    public void deleteProfile() {
-        final ActionResult sqlDelete = dataStore.getStorage().delete(uuid);
-        assertFalse(sqlDelete.isError());
-    }
-
-    @AfterAll
-    public static void shutdown() {
-        MockBukkit.unmock();
-    }
-}
\ No newline at end of file
diff --git a/src/test/resources/en.yml b/src/test/resources/en.yml
deleted file mode 100644
index 7b83c58..0000000
--- a/src/test/resources/en.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-# Nicko ${version} - Language File:
-
-# hello I'm the good version
-version: "1.1.0"
\ No newline at end of file