From 12b3c4d7ff5a3ead82b155a9eb8aab81d35ac9b4 Mon Sep 17 00:00:00 2001 From: Nova <100384210+CCSNova@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:01:04 +0000 Subject: [PATCH] Implement a config system for Gradle... , add many more platforms (Bungee, Minestom and Velocity), use a better logger and just general improvements --- API/build.gradle | 11 +- .../net/kore/pronouns/api/PronounsAPI.java | 1 + .../net/kore/pronouns/api/PronounsLogger.java | 74 ++++---- Bungee/build.gradle | 35 ++++ .../kore/pronouns/bungee/BungeePronouns.java | 47 +++++ .../pronouns/bungee/BungeePronounsAPI.java | 177 +++++++++++++++++ Bungee/src/main/resources/config.conf | 59 ++++++ Bungee/src/main/resources/plugin.yml | 4 + Fabric/build.gradle | 9 +- .../pronouns/fabric/FabricPronounsAPI.java | 1 - Fabric/src/main/resources/fabric.mod.json | 2 +- Minestom/build.gradle | 30 +++ .../pronouns/minestom/MinestomPronouns.java | 42 ++++ .../minestom/MinestomPronounsAPI.java | 179 ++++++++++++++++++ Minestom/src/main/resources/config.conf | 59 ++++++ Minestom/src/main/resources/extension.json | 13 ++ Paper/build.gradle | 9 +- Paper/src/main/resources/paper-plugin.yml | 2 +- Sponge/build.gradle | 9 +- Velocity/build.gradle | 37 ++++ .../pronouns/velocity/VelocityPronouns.java | 63 ++++++ .../velocity/VelocityPronounsAPI.java | 175 +++++++++++++++++ Velocity/src/main/resources/config.conf | 59 ++++++ build | 5 +- build.bat | 2 +- build.gradle | 9 +- config.json | 4 + settings.gradle | 6 +- src/main/java/net/kore/Main.java | 2 +- 29 files changed, 1068 insertions(+), 57 deletions(-) create mode 100644 Bungee/build.gradle create mode 100644 Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronouns.java create mode 100644 Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronounsAPI.java create mode 100644 Bungee/src/main/resources/config.conf create mode 100644 Bungee/src/main/resources/plugin.yml create mode 100644 Minestom/build.gradle create mode 100644 Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronouns.java create mode 100644 Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronounsAPI.java create mode 100644 Minestom/src/main/resources/config.conf create mode 100644 Minestom/src/main/resources/extension.json create mode 100644 Velocity/build.gradle create mode 100644 Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronouns.java create mode 100644 Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronounsAPI.java create mode 100644 Velocity/src/main/resources/config.conf create mode 100644 config.json diff --git a/API/build.gradle b/API/build.gradle index 2297589..d2fe902 100644 --- a/API/build.gradle +++ b/API/build.gradle @@ -1,11 +1,16 @@ +import groovy.json.JsonSlurper + plugins { id 'java' id "maven-publish" id 'com.github.johnrengelman.shadow' version '8.1.1' } -group = 'net.kore' -version = '0.1.0' +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String repositories { mavenCentral() @@ -15,6 +20,8 @@ dependencies { implementation 'com.google.code.gson:gson:2.10.1' implementation "org.spongepowered:configurate-hocon:4.1.2" implementation "org.apache.logging.log4j:log4j-api:2.17.0" + implementation 'org.slf4j:slf4j-api:2.0.12' + implementation "net.kyori:adventure-api:4.16.0" } shadowJar { diff --git a/API/src/main/java/net/kore/pronouns/api/PronounsAPI.java b/API/src/main/java/net/kore/pronouns/api/PronounsAPI.java index ffd136d..01dbcfb 100644 --- a/API/src/main/java/net/kore/pronouns/api/PronounsAPI.java +++ b/API/src/main/java/net/kore/pronouns/api/PronounsAPI.java @@ -23,6 +23,7 @@ public static void setInstance(PronounsAPI i) { abstract public String getReflexive(UUID uuid); public String formatPlayer(String input, String name) { + if (name == null) name = "null"; return input.replace("${player}", name); } } diff --git a/API/src/main/java/net/kore/pronouns/api/PronounsLogger.java b/API/src/main/java/net/kore/pronouns/api/PronounsLogger.java index b0dd61f..f9a6453 100644 --- a/API/src/main/java/net/kore/pronouns/api/PronounsLogger.java +++ b/API/src/main/java/net/kore/pronouns/api/PronounsLogger.java @@ -1,60 +1,60 @@ package net.kore.pronouns.api; +import net.kyori.adventure.text.Component; + import java.util.logging.Logger; public class PronounsLogger { - private static boolean isL4J = false; - private static Logger javaLogger = null; - private static org.apache.logging.log4j.Logger l4JLogger = null; - - public static void setLogger(Logger logger) { - javaLogger = logger; - } - - public static void setLogger(org.apache.logging.log4j.Logger logger) { - l4JLogger = logger; - isL4J = true; - } + private static Object LOGGER; + public static void setLogger(Object l) { LOGGER = l; } public static void info(String info) { - if (isL4J) { - l4JLogger.info(info); - } else if (javaLogger != null) { - javaLogger.info(info); - } else { - throw new IllegalStateException("Logger not ready."); + try { + LOGGER.getClass().getMethod("info", String.class).invoke(LOGGER, info); + } catch (Throwable ee) { + try { + LOGGER.getClass().getMethod("info", Component.class).invoke(LOGGER, Component.text(info)); + } catch (Throwable e) { + throw new IllegalStateException("Logger couldn't be executed.", e); + } } } public static void warn(String info) { - if (isL4J) { - l4JLogger.warn(info); - } else if (javaLogger != null) { - javaLogger.warning(info); - } else { - throw new IllegalStateException("Logger not ready."); + try { + LOGGER.getClass().getMethod("warning", String.class).invoke(LOGGER, info); + } catch (Throwable eee) { + try { + LOGGER.getClass().getMethod("warn", String.class).invoke(LOGGER, info); + } catch (Throwable ee) { + try { + LOGGER.getClass().getMethod("warn", Component.class).invoke(LOGGER, Component.text(info)); + } catch (Throwable e) { + throw new IllegalStateException("Logger couldn't be executed.", e); + } + } } } public static void error(String info) { - if (isL4J) { - l4JLogger.error(info); - } else if (javaLogger != null) { - javaLogger.severe(info); - } else { - throw new IllegalStateException("Logger not ready."); + try { + LOGGER.getClass().getMethod("severe", String.class).invoke(LOGGER, info); + } catch (Throwable eee) { + try { + LOGGER.getClass().getMethod("error", String.class).invoke(LOGGER, info); + } catch (Throwable ee) { + try { + LOGGER.getClass().getMethod("error", Component.class).invoke(LOGGER, Component.text(info)); + } catch (Throwable e) { + throw new IllegalStateException("Logger couldn't be executed.", e); + } + } } } public static void debug(String info) { if (PronounsConfig.get().node("debug-logging").getBoolean(false)) { - if (isL4J) { - l4JLogger.info(info); - } else if (javaLogger != null) { - javaLogger.info(info); - } else { - throw new IllegalStateException("Logger not ready."); - } + info(info); } } } diff --git a/Bungee/build.gradle b/Bungee/build.gradle new file mode 100644 index 0000000..aa35b43 --- /dev/null +++ b/Bungee/build.gradle @@ -0,0 +1,35 @@ +import groovy.json.JsonSlurper + +plugins { + id 'java' + id 'com.github.johnrengelman.shadow' version '8.1.1' +} + +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String + +shadowJar { + archiveBaseName.set('Pronouns-Bungee') + archiveClassifier.set('') + archiveVersion.set(version) + destinationDirectory.set(new File(rootDir, "output")) +} + +repositories { + mavenCentral() + maven { + url = "https://oss.sonatype.org/content/groups/public/" + } + maven { + url = "https://libraries.minecraft.net" + } +} + +dependencies { + implementation project(path: ':API') + compileOnly 'net.md-5:bungeecord-api:1.20-R0.3-SNAPSHOT' + implementation "org.spongepowered:configurate-hocon:4.1.2" +} \ No newline at end of file diff --git a/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronouns.java b/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronouns.java new file mode 100644 index 0000000..772945f --- /dev/null +++ b/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronouns.java @@ -0,0 +1,47 @@ +package net.kore.pronouns.bungee; + +import com.google.common.io.Resources; +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; +import net.md_5.bungee.api.plugin.Plugin; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.hocon.HoconConfigurationLoader; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class BungeePronouns extends Plugin { + private static BungeePronouns INSTANCE; + public static BungeePronouns getInstance() { + return INSTANCE; + } + + @Override + public void onEnable() { + PronounsLogger.setLogger(getLogger()); + + File configFile = new File(getDataFolder(), "config.conf"); + if (!configFile.exists() || !configFile.isDirectory()) { + try { + Files.copy(Paths.get(Resources.getResource("config.conf").toURI()), configFile.toPath()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + HoconConfigurationLoader loader = HoconConfigurationLoader.builder() + .file(configFile) + .build(); + + try { + PronounsConfig.set(loader.load()); + } catch (ConfigurateException e) { + throw new RuntimeException(e); + } + + INSTANCE = this; + + BungeePronounsAPI.get(); + } +} \ No newline at end of file diff --git a/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronounsAPI.java b/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronounsAPI.java new file mode 100644 index 0000000..71e7e98 --- /dev/null +++ b/Bungee/src/main/java/net/kore/pronouns/bungee/BungeePronounsAPI.java @@ -0,0 +1,177 @@ +package net.kore.pronouns.bungee; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import net.kore.pronouns.api.CachedPronouns; +import net.kore.pronouns.api.PronounsAPI; +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +public class BungeePronounsAPI extends PronounsAPI { + private BungeePronounsAPI() { + BungeePronouns.getInstance().getProxy().getScheduler().schedule(BungeePronouns.getInstance(), () -> { + PronounsLogger.debug("Refreshing cache..."); + cache.clear(); + for (ProxiedPlayer player : BungeePronouns.getInstance().getProxy().getPlayers()) { + getPronouns(player.getUniqueId()); + } + }, 0L, PronounsConfig.get().node("refresh").getLong(5), TimeUnit.MINUTES); + } + private static BungeePronounsAPI INSTANCE; + private static final List cache = new ArrayList<>(); + + public static BungeePronounsAPI get() { + if (INSTANCE == null) { + INSTANCE = new BungeePronounsAPI(); + PronounsAPI.setInstance(INSTANCE); + } + return INSTANCE; + } + + private String getPronounsFromJA(JsonArray ja, int limit) { + List ls = new ArrayList<>(); + + for (JsonElement je : ja) { + if (ls.size() == limit) break; + String pronoun = je.getAsString(); + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + ls.add(p1); + } + + return String.join("/", ls); + } + + public String getPronounFromShort(String pronoun) { + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + String p2 = PronounsConfig.get().node(pronoun, "overridep2").getString(PronounsConfig.get().node(pronoun, "personal-2").getString("No pronoun for "+pronoun+" defined in config.conf")); + return p1+"/"+p2; + } + + private JsonObject getObj(UUID uuid) { + try { + URL url = new URL("https://pronoundb.org/api/v2/lookup?platform=minecraft&ids="+uuid.toString()); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("Content-Type", "application/json"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder content = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + con.disconnect(); + + String response = content.toString(); + + return JsonParser.parseString(response).getAsJsonObject(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private void check() { + cache.removeIf(cp -> Instant.now().toEpochMilli() - cp.timeCached() > 300000L); + } + + private JsonArray getCached(UUID uuid) { + Optional ocp = cache.stream().filter(cp -> cp.uuid().equals(uuid)).findFirst(); + return ocp.map(CachedPronouns::pronouns).orElse(null); + } + + private JsonArray getJsonArray(UUID uuid) { + check(); + JsonArray cached = getCached(uuid); + if (cached != null) { + return cached; + } + JsonObject jo = getObj(uuid); + if (jo == null) { + return null; + } + if (!jo.has(uuid.toString())) { + return null; + } + JsonArray ja = new JsonArray(); + for (JsonElement je : jo.get(uuid.toString()).getAsJsonObject().get("sets").getAsJsonObject().get("en").getAsJsonArray()) { + ja.add(formatPlayer(je.getAsString(), BungeePronouns.getInstance().getProxy().getPlayer(uuid).getName())); + } + + if (cache.size() == PronounsConfig.get().node("max-cache").getLong()) { + PronounsLogger.debug("Cache has hit max, now flooding cache to prevent max cache hit."); + cache.clear(); + } + cache.add(new CachedPronouns(uuid, ja, Instant.now().toEpochMilli())); + return ja; + } + + public String getPronounsLimit(UUID uuid, int limit) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + if (ja.size() == 1 || limit == 1) return getPronounFromShort(ja.get(0).getAsString()); + + return getPronounsFromJA(ja, limit); + } + + public String getPronouns(UUID uuid) { + return getPronounsLimit(uuid, 3); + } + + public String getShortPronouns(UUID uuid) { + return getPronounsLimit(uuid, 2); + } + + public String getPersonal1(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-1").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPersonal2(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-2").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPossessive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "possessive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getReflexive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "reflexive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } +} \ No newline at end of file diff --git a/Bungee/src/main/resources/config.conf b/Bungee/src/main/resources/config.conf new file mode 100644 index 0000000..d2941fc --- /dev/null +++ b/Bungee/src/main/resources/config.conf @@ -0,0 +1,59 @@ +# Pronouns - Pronouns in Minecraft +# Link Minecraft to your PronounDB account and go! +# +# ${player} - Player's name +# + +debug-logging: false //i will never make the same mistake again, i promise :sob: + +# Will display this if the user has no pronouns +no-pronouns: "Not Linked to PronounDB" + +# How many minutes until the plugin refreshes the pronouns of all online players and empties the cache +refresh: 5 + +# Max amount of pronouns the plugin should cache, if it goes higher then the cache is cleared +max-cache: 500; + +any.personal-1: "They" +any.personal-2: "Them" +any.possessive: "Theirs" +any.reflexive: "Themself" + +# Will override the use of personal-1 in short pronouns like He/They (In this example it would go from He/They to He/Any) +any.overridep1: "Any" + +ask.personal-1: "${player}" +ask.personal-2: "${player}" +ask.possessive: "${player}'s" +ask.reflexive: "${player}'s self" + +avoid.personal-1: "${player}" +avoid.personal-2: "${player}" +avoid.possessive: "${player}'s" +avoid.reflexive: "${player}'s self" + +he.personal-1: "He" +he.personal-2: "Him" +he.possessive: "His" +he.reflexive: "Himself" + +it.personal-1: "It" +it.personal-2: "Its" +it.possessive: "It's" +it.reflexive: "Itself" + +other.personal-1: "${player}" +other.personal-2: "${player}" +other.possessive: "${player}'s" +other.reflexive: "${player}'s self" + +she.personal-1: "She" +she.personal-2: "Her" +she.possessive: "Hers" +she.reflexive: "Herself" + +they.personal-1: "They" +they.personal-2: "Them" +they.possessive: "Theirs" +they.reflexive: "Themself" \ No newline at end of file diff --git a/Bungee/src/main/resources/plugin.yml b/Bungee/src/main/resources/plugin.yml new file mode 100644 index 0000000..e73fe70 --- /dev/null +++ b/Bungee/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: Pronouns +main: net.kore.pronouns.bungee.BungeePronouns +version: 0.1.1 +author: 'Kore Team' \ No newline at end of file diff --git a/Fabric/build.gradle b/Fabric/build.gradle index fb41221..57c16ba 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -1,10 +1,15 @@ +import groovy.json.JsonSlurper + plugins { id 'fabric-loom' version '1.5-SNAPSHOT' id 'maven-publish' } -group = 'net.kore' -version = '0.1.0' +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String repositories { // Add repositories to retrieve artifacts from in here. diff --git a/Fabric/src/main/java/net/kore/pronouns/fabric/FabricPronounsAPI.java b/Fabric/src/main/java/net/kore/pronouns/fabric/FabricPronounsAPI.java index da85ba4..50cfee3 100644 --- a/Fabric/src/main/java/net/kore/pronouns/fabric/FabricPronounsAPI.java +++ b/Fabric/src/main/java/net/kore/pronouns/fabric/FabricPronounsAPI.java @@ -113,7 +113,6 @@ private JsonArray getJsonArray(UUID uuid) { return cached; } JsonObject jo = getObj(uuid); - FabricPronouns.getLogger().info(String.valueOf(jo)); if (jo == null) { return null; } diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 88820e5..f86fa54 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "kore_pronouns", - "version": "0.1.0", + "version": "0.1.1", "name": "Pronouns", "description": "", "authors": [], diff --git a/Minestom/build.gradle b/Minestom/build.gradle new file mode 100644 index 0000000..3f4d537 --- /dev/null +++ b/Minestom/build.gradle @@ -0,0 +1,30 @@ +import groovy.json.JsonSlurper + +plugins { + id 'java' + id 'com.github.johnrengelman.shadow' version '8.1.1' +} + +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String + +shadowJar { + archiveBaseName.set('Pronouns-Minestom-Extension') + archiveClassifier.set('') + archiveVersion.set(version) + destinationDirectory.set(new File(rootDir, "output")) +} + +repositories { + mavenCentral() + maven { url 'https://jitpack.io' } +} + +dependencies { + implementation project(path: ':API') + implementation "org.spongepowered:configurate-hocon:4.1.2" + compileOnly "com.github.minestom.minestom:Minestom:2cdb3911b0" +} \ No newline at end of file diff --git a/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronouns.java b/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronouns.java new file mode 100644 index 0000000..fd4b701 --- /dev/null +++ b/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronouns.java @@ -0,0 +1,42 @@ +package net.kore.pronouns.minestom; + +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; +import net.minestom.server.extensions.Extension; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.hocon.HoconConfigurationLoader; + +import java.io.File; + +public class MinestomPronouns extends Extension { + @Override + public void initialize() { + File configFolder = getDataDirectory().toFile(); + if (!configFolder.exists()) { + configFolder.mkdirs(); + } + + File configFile = new File(configFolder, "config.conf"); + if (!configFile.exists()) { + getResource("config.conf"); + } + + HoconConfigurationLoader loader = HoconConfigurationLoader.builder() + .file(configFile) + .build(); + + try { + PronounsConfig.set(loader.load()); + } catch (ConfigurateException e) { + throw new RuntimeException(e); + } + + PronounsLogger.setLogger(getLogger()); + MinestomPronounsAPI.get(); + } + + @Override + public void terminate() { + + } +} \ No newline at end of file diff --git a/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronounsAPI.java b/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronounsAPI.java new file mode 100644 index 0000000..1bb2b1d --- /dev/null +++ b/Minestom/src/main/java/net/kore/pronouns/minestom/MinestomPronounsAPI.java @@ -0,0 +1,179 @@ +package net.kore.pronouns.minestom; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import net.kore.pronouns.api.CachedPronouns; +import net.kore.pronouns.api.PronounsAPI; +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.Player; +import net.minestom.server.timer.ExecutionType; +import net.minestom.server.timer.TaskSchedule; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + +public class MinestomPronounsAPI extends PronounsAPI { + private MinestomPronounsAPI() { + MinecraftServer.getSchedulerManager().scheduleTask(() -> { + PronounsLogger.debug("Refreshing cache..."); + cache.clear(); + for (Player player : MinecraftServer.getConnectionManager().getOnlinePlayers()) { + getPronouns(player.getUuid()); + } + }, TaskSchedule.nextTick(), TaskSchedule.minutes(PronounsConfig.get().node("refresh").getLong(5)), ExecutionType.ASYNC); + } + private static MinestomPronounsAPI INSTANCE; + private static final List cache = new ArrayList<>(); + + public static MinestomPronounsAPI get() { + if (INSTANCE == null) { + INSTANCE = new MinestomPronounsAPI(); + PronounsAPI.setInstance(INSTANCE); + } + return INSTANCE; + } + + private String getPronounsFromJA(JsonArray ja, int limit) { + List ls = new ArrayList<>(); + + for (JsonElement je : ja) { + if (ls.size() == limit) break; + String pronoun = je.getAsString(); + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + ls.add(p1); + } + + return String.join("/", ls); + } + + public String getPronounFromShort(String pronoun) { + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + String p2 = PronounsConfig.get().node(pronoun, "overridep2").getString(PronounsConfig.get().node(pronoun, "personal-2").getString("No pronoun for "+pronoun+" defined in config.conf")); + return p1+"/"+p2; + } + + private JsonObject getObj(UUID uuid) { + try { + URL url = new URL("https://pronoundb.org/api/v2/lookup?platform=minecraft&ids="+uuid.toString()); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("Content-Type", "application/json"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder content = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + con.disconnect(); + + String response = content.toString(); + + return JsonParser.parseString(response).getAsJsonObject(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private void check() { + cache.removeIf(cp -> Instant.now().toEpochMilli() - cp.timeCached() > 300000L); + } + + private JsonArray getCached(UUID uuid) { + Optional ocp = cache.stream().filter(cp -> cp.uuid().equals(uuid)).findFirst(); + return ocp.map(CachedPronouns::pronouns).orElse(null); + } + + private JsonArray getJsonArray(UUID uuid) { + check(); + JsonArray cached = getCached(uuid); + if (cached != null) { + return cached; + } + JsonObject jo = getObj(uuid); + if (jo == null) { + return null; + } + if (!jo.has(uuid.toString())) { + return null; + } + JsonArray ja = new JsonArray(); + for (JsonElement je : jo.get(uuid.toString()).getAsJsonObject().get("sets").getAsJsonObject().get("en").getAsJsonArray()) { + ja.add(formatPlayer(je.getAsString(), MinecraftServer.getConnectionManager().getPlayer(uuid).getUsername())); + } + if (cache.size() == PronounsConfig.get().node("max-cache").getLong()) { + PronounsLogger.debug("Cache has hit max, now flooding cache to prevent max cache hit."); + cache.clear(); + } + cache.add(new CachedPronouns(uuid, ja, Instant.now().toEpochMilli())); + return ja; + } + + public String getPronounsLimit(UUID uuid, int limit) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + if (ja.size() == 1 || limit == 1) return getPronounFromShort(ja.get(0).getAsString()); + + return getPronounsFromJA(ja, limit); + } + + public String getPronouns(UUID uuid) { + return getPronounsLimit(uuid, 3); + } + + public String getShortPronouns(UUID uuid) { + return getPronounsLimit(uuid, 2); + } + + public String getPersonal1(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-1").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPersonal2(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-2").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPossessive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "possessive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getReflexive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "reflexive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } +} diff --git a/Minestom/src/main/resources/config.conf b/Minestom/src/main/resources/config.conf new file mode 100644 index 0000000..d2941fc --- /dev/null +++ b/Minestom/src/main/resources/config.conf @@ -0,0 +1,59 @@ +# Pronouns - Pronouns in Minecraft +# Link Minecraft to your PronounDB account and go! +# +# ${player} - Player's name +# + +debug-logging: false //i will never make the same mistake again, i promise :sob: + +# Will display this if the user has no pronouns +no-pronouns: "Not Linked to PronounDB" + +# How many minutes until the plugin refreshes the pronouns of all online players and empties the cache +refresh: 5 + +# Max amount of pronouns the plugin should cache, if it goes higher then the cache is cleared +max-cache: 500; + +any.personal-1: "They" +any.personal-2: "Them" +any.possessive: "Theirs" +any.reflexive: "Themself" + +# Will override the use of personal-1 in short pronouns like He/They (In this example it would go from He/They to He/Any) +any.overridep1: "Any" + +ask.personal-1: "${player}" +ask.personal-2: "${player}" +ask.possessive: "${player}'s" +ask.reflexive: "${player}'s self" + +avoid.personal-1: "${player}" +avoid.personal-2: "${player}" +avoid.possessive: "${player}'s" +avoid.reflexive: "${player}'s self" + +he.personal-1: "He" +he.personal-2: "Him" +he.possessive: "His" +he.reflexive: "Himself" + +it.personal-1: "It" +it.personal-2: "Its" +it.possessive: "It's" +it.reflexive: "Itself" + +other.personal-1: "${player}" +other.personal-2: "${player}" +other.possessive: "${player}'s" +other.reflexive: "${player}'s self" + +she.personal-1: "She" +she.personal-2: "Her" +she.possessive: "Hers" +she.reflexive: "Herself" + +they.personal-1: "They" +they.personal-2: "Them" +they.possessive: "Theirs" +they.reflexive: "Themself" \ No newline at end of file diff --git a/Minestom/src/main/resources/extension.json b/Minestom/src/main/resources/extension.json new file mode 100644 index 0000000..dbbd3b3 --- /dev/null +++ b/Minestom/src/main/resources/extension.json @@ -0,0 +1,13 @@ +{ + "entrypoint": "net.kore.pronouns.minestom.MinestomPronouns", + "name": "Pronouns", + "version": "0.1.1", + "externalDependencies": { + "repositories": [ + {"name": "Central", "url": "https://repo1.maven.org/maven2/"} + ], + "artifacts": [ + "com.squareup:javapoet:1.13.0" + ] + } +} \ No newline at end of file diff --git a/Paper/build.gradle b/Paper/build.gradle index 6e10fa6..513175d 100644 --- a/Paper/build.gradle +++ b/Paper/build.gradle @@ -1,10 +1,15 @@ +import groovy.json.JsonSlurper + plugins { id 'java' id 'com.github.johnrengelman.shadow' version '8.1.1' } -group = 'net.kore' -version = '0.1.0' +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String shadowJar { archiveBaseName.set('Pronouns-Paper') diff --git a/Paper/src/main/resources/paper-plugin.yml b/Paper/src/main/resources/paper-plugin.yml index 7328cc1..b83f975 100644 --- a/Paper/src/main/resources/paper-plugin.yml +++ b/Paper/src/main/resources/paper-plugin.yml @@ -1,5 +1,5 @@ name: Pronouns -version: '0.1.0' +version: '0.1.1' main: net.kore.pronouns.paper.PaperPronouns api-version: '1.20' diff --git a/Sponge/build.gradle b/Sponge/build.gradle index b7e8ca4..36c0295 100644 --- a/Sponge/build.gradle +++ b/Sponge/build.gradle @@ -1,10 +1,15 @@ +import groovy.json.JsonSlurper + plugins { id 'java' id 'com.github.johnrengelman.shadow' version '8.1.1' } -group = 'net.kore' -version = '0.1.0' +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String shadowJar { archiveBaseName.set('Pronouns-Sponge') diff --git a/Velocity/build.gradle b/Velocity/build.gradle new file mode 100644 index 0000000..e83fddb --- /dev/null +++ b/Velocity/build.gradle @@ -0,0 +1,37 @@ +import groovy.json.JsonSlurper + +plugins { + id 'java' + id 'com.github.johnrengelman.shadow' version '8.1.1' +} + +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String + +shadowJar { + archiveBaseName.set('Pronouns-Velocity') + archiveClassifier.set('') + archiveVersion.set(version) + destinationDirectory.set(new File(rootDir, "output")) +} + +repositories { + mavenCentral() + maven { + name = "papermc-repo" + url = "https://repo.papermc.io/repository/maven-public/" + } + + maven { + url = "https://oss.sonatype.org/content/groups/public/" + } +} + +dependencies { + implementation project(path: ':API') + compileOnly "com.velocitypowered:velocity-api:3.3.0-SNAPSHOT" + implementation "org.spongepowered:configurate-hocon:4.1.2" +} \ No newline at end of file diff --git a/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronouns.java b/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronouns.java new file mode 100644 index 0000000..f613a2e --- /dev/null +++ b/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronouns.java @@ -0,0 +1,63 @@ +package net.kore.pronouns.velocity; + +import com.google.common.io.Resources; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.hocon.HoconConfigurationLoader; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +@Plugin(id = "kore-pronouns", name = "Pronouns", version = "0.1.1", + description = "PronounDB in Minecraft!", authors = {"Nova", "Kore Team"}) +public class VelocityPronouns { + private final ProxyServer server; + public ProxyServer getServer() { + return server; + } + private static VelocityPronouns INSTANCE; + public static VelocityPronouns getInstance() { + return INSTANCE; + } + + @Inject + public VelocityPronouns(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { + this.server = server; + PronounsLogger.setLogger(logger); + + File configFile = new File(dataDirectory.toFile(), "config.conf"); + if (!configFile.exists() || !configFile.isDirectory()) { + try { + Files.copy(Paths.get(Resources.getResource("config.conf").toURI()), configFile.toPath()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + HoconConfigurationLoader loader = HoconConfigurationLoader.builder() + .file(configFile) + .build(); + + try { + PronounsConfig.set(loader.load()); + } catch (ConfigurateException e) { + throw new RuntimeException(e); + } + } + + @Subscribe + public void onProxyInitialization(ProxyInitializeEvent event) { + INSTANCE = this; + VelocityPronounsAPI.get(); + } +} diff --git a/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronounsAPI.java b/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronounsAPI.java new file mode 100644 index 0000000..4bd31e6 --- /dev/null +++ b/Velocity/src/main/java/net/kore/pronouns/velocity/VelocityPronounsAPI.java @@ -0,0 +1,175 @@ +package net.kore.pronouns.velocity; + +import com.google.gson.*; +import com.velocitypowered.api.proxy.Player; +import net.kore.pronouns.api.CachedPronouns; +import net.kore.pronouns.api.PronounsAPI; +import net.kore.pronouns.api.PronounsConfig; +import net.kore.pronouns.api.PronounsLogger; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.time.Instant; +import java.util.*; +import java.util.concurrent.TimeUnit; + +@SuppressWarnings("unused") +public class VelocityPronounsAPI extends PronounsAPI { + private VelocityPronounsAPI() { + VelocityPronouns.getInstance().getServer().getScheduler() + .buildTask(VelocityPronouns.getInstance(), () -> { + PronounsLogger.debug("Refreshing cache..."); + cache.clear(); + for (Player player : VelocityPronouns.getInstance().getServer().getAllPlayers()) { + getPronouns(player.getUniqueId()); + } + }) + .repeat(PronounsConfig.get().node("refresh").getLong(5), TimeUnit.MINUTES) + .schedule(); + } + private static VelocityPronounsAPI INSTANCE; + private static final List cache = new ArrayList<>(); + + public static VelocityPronounsAPI get() { + if (INSTANCE == null) { + INSTANCE = new VelocityPronounsAPI(); + PronounsAPI.setInstance(INSTANCE); + } + return INSTANCE; + } + + private String getPronounsFromJA(JsonArray ja, int limit) { + List ls = new ArrayList<>(); + + for (JsonElement je : ja) { + if (ls.size() == limit) break; + String pronoun = je.getAsString(); + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + ls.add(p1); + } + + return String.join("/", ls); + } + + public String getPronounFromShort(String pronoun) { + String p1 = PronounsConfig.get().node(pronoun, "overridep1").getString(PronounsConfig.get().node(pronoun, "personal-1").getString("No pronoun for "+pronoun+" defined in config.conf")); + String p2 = PronounsConfig.get().node(pronoun, "overridep2").getString(PronounsConfig.get().node(pronoun, "personal-2").getString("No pronoun for "+pronoun+" defined in config.conf")); + return p1+"/"+p2; + } + + private JsonObject getObj(UUID uuid) { + try { + URL url = new URL("https://pronoundb.org/api/v2/lookup?platform=minecraft&ids="+uuid.toString()); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("Content-Type", "application/json"); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder content = new StringBuilder(); + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + con.disconnect(); + + String response = content.toString(); + + return JsonParser.parseString(response).getAsJsonObject(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private void check() { + cache.removeIf(cp -> Instant.now().toEpochMilli() - cp.timeCached() > 300000L); + } + + private JsonArray getCached(UUID uuid) { + Optional ocp = cache.stream().filter(cp -> cp.uuid().equals(uuid)).findFirst(); + return ocp.map(CachedPronouns::pronouns).orElse(null); + } + + private JsonArray getJsonArray(UUID uuid) { + check(); + JsonArray cached = getCached(uuid); + if (cached != null) { + return cached; + } + JsonObject jo = getObj(uuid); + if (jo == null) { + return null; + } + if (!jo.has(uuid.toString())) { + return null; + } + JsonArray ja = new JsonArray(); + for (JsonElement je : jo.get(uuid.toString()).getAsJsonObject().get("sets").getAsJsonObject().get("en").getAsJsonArray()) { + ja.add(formatPlayer(je.getAsString(), VelocityPronouns.getInstance().getServer().getPlayer(uuid).orElseGet(null).getUsername())); + } + + if (cache.size() == PronounsConfig.get().node("max-cache").getLong()) { + PronounsLogger.debug("Cache has hit max, now flooding cache to prevent max cache hit."); + cache.clear(); + } + cache.add(new CachedPronouns(uuid, ja, Instant.now().toEpochMilli())); + return ja; + } + + public String getPronounsLimit(UUID uuid, int limit) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + if (ja.size() == 1 || limit == 1) return getPronounFromShort(ja.get(0).getAsString()); + + return getPronounsFromJA(ja, limit); + } + + public String getPronouns(UUID uuid) { + return getPronounsLimit(uuid, 3); + } + + public String getShortPronouns(UUID uuid) { + return getPronounsLimit(uuid, 2); + } + + public String getPersonal1(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-1").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPersonal2(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "personal-2").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getPossessive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "possessive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } + + public String getReflexive(UUID uuid) { + JsonArray ja = getJsonArray(uuid); + if (ja == null) { + return PronounsConfig.get().node("no-pronouns").getString("\"no-pronouns\" is not defined in config.conf"); + } + + return PronounsConfig.get().node(ja.get(0).getAsString(), "reflexive").getString("No pronoun defined for " + ja.get(0).getAsString() + "in config.conf"); + } +} diff --git a/Velocity/src/main/resources/config.conf b/Velocity/src/main/resources/config.conf new file mode 100644 index 0000000..d2941fc --- /dev/null +++ b/Velocity/src/main/resources/config.conf @@ -0,0 +1,59 @@ +# Pronouns - Pronouns in Minecraft +# Link Minecraft to your PronounDB account and go! +# +# ${player} - Player's name +# + +debug-logging: false //i will never make the same mistake again, i promise :sob: + +# Will display this if the user has no pronouns +no-pronouns: "Not Linked to PronounDB" + +# How many minutes until the plugin refreshes the pronouns of all online players and empties the cache +refresh: 5 + +# Max amount of pronouns the plugin should cache, if it goes higher then the cache is cleared +max-cache: 500; + +any.personal-1: "They" +any.personal-2: "Them" +any.possessive: "Theirs" +any.reflexive: "Themself" + +# Will override the use of personal-1 in short pronouns like He/They (In this example it would go from He/They to He/Any) +any.overridep1: "Any" + +ask.personal-1: "${player}" +ask.personal-2: "${player}" +ask.possessive: "${player}'s" +ask.reflexive: "${player}'s self" + +avoid.personal-1: "${player}" +avoid.personal-2: "${player}" +avoid.possessive: "${player}'s" +avoid.reflexive: "${player}'s self" + +he.personal-1: "He" +he.personal-2: "Him" +he.possessive: "His" +he.reflexive: "Himself" + +it.personal-1: "It" +it.personal-2: "Its" +it.possessive: "It's" +it.reflexive: "Itself" + +other.personal-1: "${player}" +other.personal-2: "${player}" +other.possessive: "${player}'s" +other.reflexive: "${player}'s self" + +she.personal-1: "She" +she.personal-2: "Her" +she.possessive: "Hers" +she.reflexive: "Herself" + +they.personal-1: "They" +they.personal-2: "Them" +they.possessive: "Theirs" +they.reflexive: "Themself" \ No newline at end of file diff --git a/build b/build index b3450e1..52c83a5 100644 --- a/build +++ b/build @@ -1,6 +1,3 @@ #!/bin/sh -gradlew API:shadowJar -gradlew Paper:shadowJar -gradlew Sponge:shadowJar -gradlew Fabric:build \ No newline at end of file +gradlew API:shadowJar Paper:shadowJar Sponge:shadowJar Fabric:build \ No newline at end of file diff --git a/build.bat b/build.bat index 991b229..5be1361 100644 --- a/build.bat +++ b/build.bat @@ -1 +1 @@ -gradlew API:shadowJar && gradlew Paper:shadowJar && gradlew Sponge:shadowJar && gradlew Fabric:build \ No newline at end of file +gradlew API:shadowJar Paper:shadowJar Sponge:shadowJar Fabric:build Velocity:shadowJar Bungee:shadowJar \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9d48a45..7976bf5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,14 @@ +import groovy.json.JsonSlurper + plugins { id 'java' } -group = 'net.kore' -version = '0.0.4' +def jsonSlurper = new JsonSlurper() +def config = jsonSlurper.parse(new File(rootDir, 'config.json')) + +group = config.group as String +version = config.version as String repositories { mavenCentral() diff --git a/config.json b/config.json new file mode 100644 index 0000000..b98ddfd --- /dev/null +++ b/config.json @@ -0,0 +1,4 @@ +{ + "group": "net.kore", + "version": "0.1.1" +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index cb2204a..0b3ede8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,4 +12,8 @@ rootProject.name = 'Pronouns' include 'API' include 'Paper' include 'Sponge' -include 'Fabric' \ No newline at end of file +include 'Fabric' +include 'Velocity' +include 'Bungee' +include 'Minestom' + diff --git a/src/main/java/net/kore/Main.java b/src/main/java/net/kore/Main.java index 86be4c7..2605f24 100644 --- a/src/main/java/net/kore/Main.java +++ b/src/main/java/net/kore/Main.java @@ -2,6 +2,6 @@ public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); + System.out.println("How did you get here?"); } } \ No newline at end of file