diff --git a/build.gradle.kts b/build.gradle.kts index 8659aa2..1347968 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,19 @@ +import io.papermc.paperweight.util.constants.PAPERCLIP_CONFIG + plugins { java - id("com.github.johnrengelman.shadow") version "8.1.0" apply false + `maven-publish` + id("com.github.johnrengelman.shadow") version "8.1.1" apply false id("io.papermc.paperweight.patcher") version "1.5.3" } repositories { mavenCentral() - maven("https://papermc.io/repo/repository/maven-public/") + maven("https://papermc.io/repo/repository/maven-public/") { + content { + onlyForConfigurations(PAPERCLIP_CONFIG) + } + } } dependencies { @@ -18,13 +25,32 @@ dependencies { subprojects { apply(plugin = "java") - java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } + } +} +subprojects { tasks.withType().configureEach { options.encoding = "UTF-8" options.release.set(17) } + tasks.withType { + options.encoding = Charsets.UTF_8.name() + } + + tasks.withType { + filteringCharset = Charsets.UTF_8.name() + } + + tasks.withType { + minHeapSize = "2g" + maxHeapSize = "2g" + } + repositories { mavenCentral() maven("https://oss.sonatype.org/content/groups/public/") @@ -33,9 +59,10 @@ subprojects { maven("https://repo.aikar.co/content/groups/aikar") maven("https://repo.md-5.net/content/repositories/releases/") maven("https://hub.spigotmc.org/nexus/content/groups/public/") - maven("https://oss.sonatype.org/content/repositories/snapshots/") maven("https://jitpack.io") + maven("https://oss.sonatype.org/content/repositories/snapshots/") } + } paperweight { @@ -44,19 +71,18 @@ paperweight { remapRepo.set("https://maven.fabricmc.net/") decompileRepo.set("https://files.minecraftforge.net/maven/") - useStandardUpstream("pufferfish") { - url.set(github("pufferfish-gg", "Pufferfish")) - ref.set(providers.gradleProperty("pufferfishRef")) + useStandardUpstream("purpur") { + url.set(github("PurpurMC", "Purpur")) + ref.set(providers.gradleProperty("purpurRef")) withStandardPatcher { - apiSourceDirPath.set("pufferfish-api") - serverSourceDirPath.set("pufferfish-server") + baseName("Purpur") apiPatchDir.set(layout.projectDirectory.dir("patches/api")) - serverPatchDir.set(layout.projectDirectory.dir("patches/server")) + apiOutputDir.set(layout.projectDirectory.dir("DivineMC-API")) - apiOutputDir.set(layout.projectDirectory.dir("divinemc-api")) - serverOutputDir.set(layout.projectDirectory.dir("divinemc-server")) + serverPatchDir.set(layout.projectDirectory.dir("patches/server")) + serverOutputDir.set(layout.projectDirectory.dir("DivineMC-Server")) } } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 7634759..0bf3301 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group=gq.bxteam.divinemc version=1.19.4-R0.1-SNAPSHOT mcVersion=1.19.4 -pufferfishRef=d032415ca6fd0736d7cb0da28e3134b957fb83a0 +purpurRef=49d99462fa663a4afc253e5525bb97092b6038de org.gradle.jvmargs=-Xmx2G org.gradle.caching=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e583..ccebba7 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6d7cd..bdc9a83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists \ No newline at end of file +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb..79a61d4 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index f127cfd..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/patches/api/0001-Add-last-tick-time-API.patch b/patches/removed/1.19.4/api/0001-Add-last-tick-time-API.patch similarity index 100% rename from patches/api/0001-Add-last-tick-time-API.patch rename to patches/removed/1.19.4/api/0001-Add-last-tick-time-API.patch diff --git a/patches/api/0002-Paper-PR-BoneMeal-API.patch b/patches/removed/1.19.4/api/0002-Paper-PR-BoneMeal-API.patch similarity index 100% rename from patches/api/0002-Paper-PR-BoneMeal-API.patch rename to patches/removed/1.19.4/api/0002-Paper-PR-BoneMeal-API.patch diff --git a/patches/api/0003-EMC-Add-ChatColor.getById.patch b/patches/removed/1.19.4/api/0003-EMC-Add-ChatColor.getById.patch similarity index 100% rename from patches/api/0003-EMC-Add-ChatColor.getById.patch rename to patches/removed/1.19.4/api/0003-EMC-Add-ChatColor.getById.patch diff --git a/patches/api/0004-Paper-PR-Add-Entity-hidden-by-default-API.patch b/patches/removed/1.19.4/api/0004-Paper-PR-Add-Entity-hidden-by-default-API.patch similarity index 100% rename from patches/api/0004-Paper-PR-Add-Entity-hidden-by-default-API.patch rename to patches/removed/1.19.4/api/0004-Paper-PR-Add-Entity-hidden-by-default-API.patch diff --git a/patches/removed/1.19.4/server/0001-Divine-Branding.patch b/patches/removed/1.19.4/server/0001-Divine-Branding.patch new file mode 100644 index 0000000..6acad42 --- /dev/null +++ b/patches/removed/1.19.4/server/0001-Divine-Branding.patch @@ -0,0 +1,671 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> +Date: Fri, 4 Nov 2022 17:00:07 +0300 +Subject: [PATCH] Divine Branding + + +diff --git a/build.gradle.kts b/build.gradle.kts +index 3c8293f002f11b430083502362fdc801f44aa138..506456fd003dda0d544c9800301b1210a5d18457 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -7,7 +7,7 @@ plugins { + } + + dependencies { +- implementation(project(":pufferfish-api")) // Pufferfish // Paper ++ implementation(project(":divinemc-api")) // DivineMC // Pufferfish // Paper + // Pufferfish start + implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") +@@ -82,7 +82,7 @@ tasks.jar { + attributes( + "Main-Class" to "org.bukkit.craftbukkit.Main", + "Implementation-Title" to "CraftBukkit", +- "Implementation-Version" to "git-Pufferfish-$implementationVersion", // Pufferfish ++ "Implementation-Version" to "git-DivineMC-$implementationVersion", // DivineMC // Pufferfish + "Implementation-Vendor" to date, // Paper + "Specification-Title" to "Bukkit", + "Specification-Version" to project.version, +diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java +index 692c962193cf9fcc6801fc93f3220bdc673d527b..2bf46834536d3702fa2ae49ce276a163a5cd1456 100644 +--- a/src/main/java/com/destroystokyo/paper/Metrics.java ++++ b/src/main/java/com/destroystokyo/paper/Metrics.java +@@ -593,7 +593,7 @@ public class Metrics { + boolean logFailedRequests = config.getBoolean("logFailedRequests", false); + // Only start Metrics, if it's enabled in the config + if (config.getBoolean("enabled", true)) { +- Metrics metrics = new Metrics("Pufferfish", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish ++ Metrics metrics = new Metrics("DivineMC", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // DivineMC + + metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { + String minecraftVersion = Bukkit.getVersion(); +diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +index c5d5648f4ca603ef2b1df723b58f9caf4dd3c722..05478a1ea04ec0396bc8c97090edef4a2aced2a9 100644 +--- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java ++++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +@@ -17,7 +17,7 @@ public final class PaperConsole extends SimpleTerminalConsole { + @Override + protected LineReader buildReader(LineReaderBuilder builder) { + builder +- .appName("Paper") ++ .appName("DivineMC") // DivineMC + .variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history")) + .completer(new ConsoleCommandCompleter(this.server)) + .option(LineReader.Option.COMPLETE_IN_WORD, true); +diff --git a/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625b5ca334a +--- /dev/null ++++ b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java +@@ -0,0 +1,137 @@ ++package gq.bxteam.divinemc; ++ ++import com.destroystokyo.paper.VersionHistoryManager; ++import com.destroystokyo.paper.util.VersionFetcher; ++import com.google.gson.Gson; ++import com.google.gson.JsonObject; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.JoinConfiguration; ++import net.kyori.adventure.text.format.NamedTextColor; ++import net.kyori.adventure.text.format.TextDecoration; ++import org.bukkit.craftbukkit.CraftServer; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.io.IOException; ++import java.net.URI; ++import java.net.http.HttpClient; ++import java.net.http.HttpRequest; ++import java.net.http.HttpResponse; ++import java.nio.charset.StandardCharsets; ++import java.util.concurrent.TimeUnit; ++import java.util.logging.Level; ++import java.util.logging.Logger; ++ ++import static net.kyori.adventure.text.Component.text; ++import static net.kyori.adventure.text.format.NamedTextColor.GREEN; ++import static net.kyori.adventure.text.format.NamedTextColor.RED; ++ ++public class DivineVersionFetcher implements VersionFetcher { ++ private static final Logger LOGGER = Logger.getLogger("DivineVersionFetcher"); ++ private static final HttpClient client = HttpClient.newHttpClient(); ++ ++ private static final URI JENKINS_URI = URI.create("https://raw.githubusercontent.com/DivineMC/Website/dev/latestBuild"); ++ private static final String GITHUB_FORMAT = "https://api.github.com/repos/DivineMC/DivineMC/compare/ver/1.19.3...%s"; ++ ++ private static final HttpResponse.BodyHandler JSON_OBJECT_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers.mapping( ++ HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8), ++ string -> new Gson().fromJson(string, JsonObject.class) ++ ); ++ ++ @Override ++ public long getCacheTime() { ++ return TimeUnit.MINUTES.toMillis(30); ++ } ++ ++ @Override ++ public @NotNull Component getVersionMessage(final @NotNull String serverVersion) { ++ final String[] parts = CraftServer.class.getPackage().getImplementationVersion().split("-"); ++ @NotNull Component component; ++ ++ if (parts.length != 3) { ++ component = text("Unknown server version.", RED); ++ } else { ++ final String versionString = parts[2]; ++ ++ try { ++ component = this.fetchJenkinsVersion(Integer.parseInt(versionString)); ++ } catch (NumberFormatException e) { ++ component = this.fetchGithubVersion(versionString.substring(1, versionString.length() - 1)); ++ } ++ } ++ ++ final @Nullable Component history = this.getHistory(); ++ return history != null ? Component.join(JoinConfiguration.noSeparators(), component, Component.newline(), this.getHistory()) : component; ++ } ++ ++ private @NotNull ++ Component fetchJenkinsVersion(final int versionNumber) { ++ final HttpRequest request = HttpRequest.newBuilder(JENKINS_URI).build(); ++ try { ++ final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); ++ if (response.statusCode() != 200) { ++ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); ++ } ++ ++ int latestVersionNumber; ++ try { ++ latestVersionNumber = Integer.parseInt(response.body()); ++ } catch (NumberFormatException e) { ++ LOGGER.log(Level.WARNING, "Received invalid response from Jenkins \"" + response.body() + "\"."); ++ return text("Received invalid response from server.", RED); ++ } ++ ++ final int versionDiff = latestVersionNumber - versionNumber; ++ return this.getResponseMessage(versionDiff); ++ } catch (IOException | InterruptedException e) { ++ LOGGER.log(Level.WARNING, "Failed to look up version from Jenkins", e); ++ return text("Failed to retrieve version from server.", RED); ++ } ++ } ++ ++ // Based off code contributed by Techcable in Paper/GH-65 ++ private @NotNull ++ Component fetchGithubVersion(final @NotNull String hash) { ++ final URI uri = URI.create(String.format(GITHUB_FORMAT, hash)); ++ final HttpRequest request = HttpRequest.newBuilder(uri).build(); ++ try { ++ final HttpResponse response = client.send(request, JSON_OBJECT_BODY_HANDLER); ++ if (response.statusCode() != 200) { ++ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); ++ } ++ ++ final JsonObject obj = response.body(); ++ final int versionDiff = obj.get("behind_by").getAsInt(); ++ ++ return this.getResponseMessage(versionDiff); ++ } catch (IOException | InterruptedException e) { ++ LOGGER.log(Level.WARNING, "Failed to look up version from GitHub", e); ++ return text("Failed to retrieve version from server.", RED); ++ } ++ } ++ ++ private @NotNull ++ Component getResponseMessage(final int versionDiff) { ++ return switch (Math.max(-1, Math.min(1, versionDiff))) { ++ case -1 -> text("You are running an unsupported version of DivineMC.", RED); ++ case 0 -> text("You are on the latest version!", GREEN); ++ default -> text("You are running " + versionDiff + " version" + (versionDiff == 1 ? "" : "s") + " beyond. " + ++ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", RED); ++ }; ++ } ++ ++ private @Nullable ++ Component getHistory() { ++ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData(); ++ if (data == null) { ++ return null; ++ } ++ ++ final String oldVersion = data.getOldVersion(); ++ if (oldVersion == null) { ++ return null; ++ } ++ ++ return text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); ++ } ++} +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 6d5e9400892b86562519a893349ca55e566bfb24..9945d6efac1e1ea0d22d6fdfe8aa5d2805c615b2 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1683,7 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! ++ return "DivineMC"; // DivineMC - DivineMC > // Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! + } + + public SystemReport fillSystemReport(SystemReport details) { +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index b2d94582037c091bd6a04451bf62b3f9c4923d19..efc137a8a9f1da4a7ffff6028af368cc7f90d20a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -256,7 +256,7 @@ import javax.annotation.Nullable; // Paper + import javax.annotation.Nonnull; // Paper + + public final class CraftServer implements Server { +- private final String serverName = "Pufferfish"; // Paper // Pufferfish ++ private final String serverName = "DivineMC"; // Paper // Pufferfish // DivineMC + private final String serverVersion; + private final String bukkitVersion = Versioning.getBukkitVersion(); + private final Logger logger = Logger.getLogger("Minecraft"); +diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java +index 4966a1e3dd35357a8ea6a7d2944c84c9c3e9058e..5b4d42fd74a32e4e97690f0cd9a33c66dc1ae141 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -285,7 +285,7 @@ public class Main { + if (buildDate.before(deadline.getTime())) { + // Paper start - This is some stupid bullshit + System.err.println("*** Warning, you've not updated in a while! ***"); +- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper ++ System.err.println("*** Please download a new build from https://github.com/DivineMC/DivineMC/releases/latest ***"); // DivineMC + //System.err.println("*** Server will start in 20 seconds ***"); + //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); + // Paper End +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index d4f62940504e3ef7a70e13b1f4a7726f23b4c637..bd21dd728b6d47d354aeb879b083394e186d6a5c 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -464,7 +464,7 @@ public final class CraftMagicNumbers implements UnsafeValues { + + @Override + public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { +- return new gg.pufferfish.pufferfish.PufferfishVersionFetcher(); // Pufferfish ++ return new gq.bxteam.divinemc.DivineVersionFetcher(); // DivineMC + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +index 80553face9c70c2a3d897681e7761df85b22d464..60ac52c6e12ee346133930394e9de8bf74e77ee6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +@@ -11,7 +11,7 @@ public final class Versioning { + public static String getBukkitVersion() { + String result = "Unknown-Version"; + +- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gg.pufferfish.pufferfish/pufferfish-api/pom.properties"); // Pufferfish ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gq.bxteam.divinemc/divinemc-api/pom.properties"); // DivineMC + Properties properties = new Properties(); + + if (stream != null) { +diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png +index a7d785f60c884ee4ee487cc364402d66c3dc2ecc..f54753531b3bf2e8b5377f342465e727c7da98f2 100644 +GIT binary patch +literal 6677 +zcmZ`ecT^MIvk65y(vr|S0wD$n1T=z3m0m+wF=$9cr3j%}P!W;dMd>0)Cy6mZP(Xpu +z`KXEn5Jf2hLO#R>ih{iOJMX-A-XCxG+?_jjX7=vRopyIq-Cd813CjzEKp-&(dmB#> +z2#omK1bMk5u9dOJxq$DSrHds9#LO1i@#p8_sw8_)7Z51s00J|A35u(#^8|4ULRXr{u5ar-vE3hmqE3r=>bw!l> +zCLnNFgew+2R&lAAi)cmJ0#RrDqXICbhyX4Cp$t%{gN6nNQN~z96O4fg24$*eV1O|& +z`24~m`2Pr82s;ya_R9Y+a5FP`iYwq7063g=aRI@(eL)aESPJx4yI}4K0?UK`s+8LU +zIf51br|${Y`EMQ`5Qs-kkkt%z@DqvQS0OciO<6(B~X-Ttj8^Ly;I +zo6TV6_jdf1w>dz}4f>(bF>w9Nl+(tmyuNjboV5a{jFW#sdhZ3z{C6FC!V#*o?@AZ* +z6@#2M7W4S(D=_e$&8q=XmdM!qgOR%?ntYTjPFBys6aK5aZOW9A-@mVhM4$Tn#+hCB +zNpgxYSKw4B-@=Ml8HJRuwG70o3_~8YcHFp3NRQPixJk)8jWlBG`$)0fR?<9ouc(Iq +z@M>AWUQmUPC;T+To4^Nb6>2S#hFq7L&p%!1Cs%tkSst0NNYZm;6BFuVg$q)J!)F7( +z%(e_;?{knc?~C+ODT}S?y_c3y-kj+)Wgt5{`{U-T!|fUc+rlYhRs);U0u{fq@D7>$ +z_>Lp=enScNrA5b3pV^mFIh4g1^)G(S4aMb`J2kRvHwN--6UVxbA8uFjF<}pE*7ZMK +zD7IlonkOy3AIJvqJ+^v3B{iHk+09aQ#>kl{ +zmaISJQBQP8%5~(PD4NTU;H% +zN4-1eLAj|t8F9I*tOJKM3*6eu_ik{zyQXVr`+F=q1YAwrdHH=#%BbwO{yyyY;)#O9 +zGoK`Ujx6-fNTj483E1!FGtYVz6zXJkTq}>qH=7wK@z<-uMz+lx_|+jFzKR&rwU*h7 +z-SX~-k+=i6A(lrB*0r`9T8GUNIhfO&-z;_$ZArSIsvPp?xN$s|$dHe^`OM^F>B%4e +z+B+^26JapEmg)E{;0#))&Eg{uHb-Q`84A;T-g<0_D1txOzm@fAkH7Bi)a>I9KNL*w +z8u{ixFO8tyq?{r4KmQm +zSNiE?)c%L{xJxhP4&5oKhr-|T5c1%mU!3b24|v+PPTx7XiKE<3_og)W8hwd4bQ{h> +zw@BZ$Vn;F^AsxsUQYH4)WS37yHJ(jv^McSfJ!KYWI{j#p^1Z|(l4aXFHm%b)_D;p6 +zeK-F2{zQ2YFT{AfE%kmcleZA9 +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 +zKQC*8IZKJ85gXf`D@XmrZ}z0B4$-% +z#5u_aJlT~Rz#nDlIJ6PugYP20>(80*@KTjt2Lvz5mZ0M7$)CcUk@p_s$^h?o_rF$>!zEoV+I-e)}5CY2o9PEjay* +zV>Cj8ZChL}gx7qpb>?}aNx}GS69W2l#$e=$@mq@2rNQ3ZaqlTtH2F0b9YVEg_&cmp +z9vx$cf7u~q1PkZir56Xw60;6fM=X)hnQ`bvgB}QZiFos!aZPc!EHRvJhPYeZiG3_? +zjZbnKVSm#-9*)S}?Zz7Ix5mdiDb3_8pG#x{I61G8qoRfu1(?S9zqVOT5UPa0RFVoy +zxGZG6EN57Ym|95?5w#v3susU+2$|LdW!O*>lhl?!cqW?wb$~FN*e&rbyxv*?dCe5X +zA3X1$($YNfAX74Uu7Tv&Y0zVaUwg5SyFa7>J}6Pc<8{{Dz36a2cWZ@ziU|3oYtGnA +znJD06B5HU9wr-RKbRVXY{N@dMhVhN*V%+a3VjRb0wX;hVazYu=%el;UduXEp%w^7< +zb|+!8yUq+Ya!HO6tIB5eqD~poR2H$D+@pe77pwERgEIA +z0!|y>AQ6FFu;Cr?4;OGC36S8`-RHRs!ojv|9~nbh^^c7~^@OJH?SB5}xeQZzNnGTp +zU${G$vNFg^JlLjxT2*m!{P!2zieBFsmDoj7By5jYgbdVWx_kcpnE-OIb+w^e5#s*~ +DA-Nv< + +literal 14310 +zcmXY21yoy2uugDycPmm{N^yd_Q`}vP7YOd|PH`>8wLo!q*HRn`6f5rV?*HD)IX5{c +zxpy-=`|Zxo_svGBD$Agwkf4A-AaprdNp;|J21vifLD%hMrT$lZeEex|7Xe0mqFAZArC{!qp)zJmbab@utqA`6 +z61Z~|e!k$IbXNT?PvGuuzT7G514$8e!}lsR>%nURMm+~pde``@(!O=ISt0%B93;Ez +za-qRi4n0Q>zQ2#2^_y08QOl3jT*!Ir5@<8VrFx(6f9sP|H8ttjftN;wrX>jP4BcG1;MfU5x^L`zc09u!bDBt#+ll=7@ +zB;}A$BKgu}V?#qfHvm`~pt%wG2y{MOc%B!8I`p|pc +zO#?sq!Zd&j8UPmvY4RQnfo>!6{a}GFV!}g@qu<3Wu$07X(O`vikNW$~q!ngF23Ls2 +z53p8js<-B_Qd?xX6rtq43Mdz(jOg2QXx#Wng_9^1^^~KqFNq{Kvb@Ap9}bf&xFA-C +z5+#cQ`#v$A=kd0O=agATcleBaxXf_(dnqbQz|cL9R&&Ni1omTs+6~YApmk)MCghxj +z1}mq&IU>1nEiF=q=PI`%jQbyRd=hVI83Sm{E-4uTc#w;NNwEW)C(C`xvWzY_%`_MmO +zD&g-sEaE)}6(&g)y-N&rNy;5@+{M`}!{60Y8wMgF5;HmO#B~hG`W$;7xLG*yF((rq +zxP6I#r#o`B3FppK{v(q1!C+YLFSfySDcHyoW!}EfzuCB1B|C5+oP}dtocnwkcNy1EZ6#5JX4=ePl&cu~0tMnt&79+I4%PaK>VqFx;r!QdNmnxlEqdU-QR%Nmu{aWP +zJxwXvt5fFTCOVgB)Zq +z%H0U=9q7Y0lu&1kc4zYT3*lHA@XJfoK>3WFM&WWf2u6^+wCm8##D$x@Gkw+t^HoO( +z4pxDRqg;$5S=t^k22H5^V3V0Qfy%Ogl8I%LD$52=7)J>Ki9Ej1HyEi_ujELlz8$-+?cdD1Zxi02kW0 +zaY=caFq4~s^R?zxcc3Z0X|az}Aww<{P$>6rk+5Di5J7$kWor0{Q&>+DWSBH^Gf`SP +zT{4}IOFh-hB7xwBdewq%de)q6QvxorV(()2>@j8i!kj)=^hN +zl_N{$9xTHHA;V&Zx#tX&1pOO;v^NiOP#_UK@J;;lp+OOhOOO2mlMdxM;Qv-mWG+^vzox|8t`w| +z=gPlM3)y6G*hfV1WwuMe>bO-vP9g`h5BqgO9x{ROBD;aPl>XDmvt(3PUxt|4RFRpK +z5OEtRz{(Oa_W_!Z4XHf#h;Z-~71XM7wlF*L!-#h_Uy2tGuy-rAZ)4{qE~feNkp}qf +zgvBtLkFPI~I7%C=OHZfPZz$j>L9)rb;l +z@J^dxncy52;wmHg=wC3|Xn6jPYCR7xc}~D0wNjoYxmoRh_zh=6@8coM1UQIa_z*1)cZPw4v40qoZQp-uy#DLv=oP +zX9b3vzFA2r8}|_AO8W1(OMG__0{1AUD&Z%&7-(>s+Z-X6Sv}G5QguIbZ3mYa--?09 +z;wNw?n=yAag4%m#w$$-YZ{(ZJUcwHfzu&!gykNjG)e}!=q8xy2_KS=ULsQwv45NK! +zVqqD8#S{vRjg4(Q6HM_F&tihNIQns<%DVjE$cv33ET>Dvc^#{z&#u&&9RgXO?ZLuebczKv#;! +zCS|2lIa37Bp#3RWj0$V3=I2>o40{(J^LD|EUH?!2;Z&HS*>7*V%{v1)wHaUP85mcX +z%q!K}Ntr*IzJD%++btJ;VQO*OjJL1t{GvR3cy@OC-~pe^bV?N`z0QKCr?Tom)4u%A +z3mi2k&eIgh0^rGI#Di+&3lrsy-r+}zwBkDQtswtPbkj!Y^l`{f!# +zLseC0M;DiifDa!({-G4{W$Wxsgv*(NX%HMyXhArVwY105dUHg?+=@6Sy8n@slS76x +zU7%PI8ToKm#qahfR;7kn#|t@9y(0EkooWBDqA1(mpO)>BBz))giBi8xVHlj#dR9U8 +zRo%`iBdlj8%_tRn^qa%T>{nsLLwTNld&WHLyfbPzv2W62m6q=Nsdxnk +z#{P==5!Lidx3bcr_qlUl%BX!xjywA?jv>FU^mJDa0zQT9Kw8RRHq>7B +zb~DXw0(oqBrOQunsm2ghWV2i1VmN{F?)U;0%*j{FEUxazAJ3)KSWomuhklkDi?5h*MTLDS5ma_Nk1sNZYzZ#$maGRyiXBzjG@(G__fuyBl(^A>s&{jF+J%5| +zv#7nD1XK806#_U_4#N2ANAxznk%;U$Y$z#{K*O07mADqx6LjACqwP<`HFV#C6Q*wx +z8JVP_qGF}V7B?^8)f*2F5AON7v$L~Kr?2}oPai_kG!_6MI(U`LS~+Mo*CSyrw>pPE +zllqxy +z^&rnDn4XA@AUY7~`1lwTCrm8KlVRqX&!kZFH&;i9@=R}UDxNSh*)Iq2U+#9}@ag1t +z%KUOEw0DXT)>hQoLTprY^z=BC=8NAyi3pZWT7A`?;rI<3%65Nqb93%pJ=!+dNtB>W +z7f3O-e-S7ZBgBntcyt~wOG_p$AU2zlGH8=%TEm+z8kLYReEMTkIo#2YiA=iKWrH); +zS%uT3xAyyY=!U)0Evpgx{{38MPR2nN<3913M<0O#YCO=TSt^4IzV3^D%2zC>t_OO} +z_h~AVOk+IIi$Ov;-g93a4j@WaekCC#HFm2_Vu9s)8-GbYtr{LgrxnSIN^PW9)!jYX +z?%-yssA~&R3F)C)wj5i|@!atCx?Qy%P1QEGSZm;iUNai`-F(8a%y+_a>CMzx$XEKx +z>sW|JbN36s+Y{4SZsrspH%UH=+Q6J`c&_-JLGL&5|$XUA1vFOC+rgoc&xT{dFT&pMaEBKwyD;plX0>2nla;jTlQ{!fn2M=Ak*=K*g% +zBm0-$ly1~}CT-5gv){jex9)7&b8u!a+vYHXU>=NF2>g3+_rN{(LUMGwRWKk49sS$v +zazyX8zZ1hwZ|U*5{fK@i@hRl*U%Q2cg+!iIfb)6W%S5F{91qinEZE%~4Gl>rBw9S< +zMP5$exl1jESyt}d~jo?hf`z^32b!}UGtJH+w9(0UrI#~Ei*ii&6z(AVE?(}k_A +zE9Z@mj7HF-ch46I0ipe3gapRj{=zk_J1E^b_JwdrhKi4ytBuwP)m>e$@9v`A{1N{h +zwUN6H=_W+h(a?rGaQ%%LP5C4)XiZ*`1uUwgqWvk`LyDD!Ps#Q5oI($KDJ%8n5kBi- +zghsLx`~mf<>WT)6-cJBbp|htk1NfkZ@e#B4@l?UH7!MDMpO?1NETGk_Eg{z!N3!D< +zWg8gtgS%b(0Bg7dw9u35xq)1vNdnM8iu7Eje*u?#sZ~%^q*HDaZC?5z4ZzhSA%ndS +z4&$M&7(|(9nWY%QShCnuN0 +z`n9&UeypypUgx;R+x;XM#8uDM{p`9~j<49)^dotHJVO*A@HL&g7F={FP#trj@{dzm +zeQUiqRWJ&pkKkA1O-|vOf8O1UQ$$0lIExffio|}F@ROV#MXcPH$ +z?$$kxAF@B#KT}u;R@SVyIO>1sw1!i?C(_013w9@?8$bKaLQi34zC$g*^}F&(%NEO6 +zQzD-^6}HQMnGJ{h$J*)HjSxjblWegsW&rLC8Ov_r_20jLjUS$Ptnm|p9fK%r0j+4; +z57^mjL&lISh8>DC;eB$B69$h4XxE3qU4T&zUpDeV@4g>or%D-x@qhie>6mqD959ck74(h?S0BA0}YQ18d?hr6}%}y{%ZNJ^-(?=Op~; +z#2-UNh)jH9>RXmvPJ(Y!8(uhyW|sFpyvv)AaNeljHj^Fx+RC +z!`@c->W1C^FUKHmG2w_atkdsMnzY+l!CV8havQ8-Gu)<8t{#V*2Pwp4h?ayXsi5Z> +zo!guta>TA~iv#iJpQkN>#)QF%As@2WgU&V_Y^qm#E*O}M_ijJfFWq}ts)-l4>D)kCqJJ@MG2$69ph0jzwI8ry1u8D@CyinC$oT?7S*Z}Eg +zYs}PWLqr4u@)w}#!{cMx;KxO6W2H6~3k$laJjAt+C{0mmCRnfs=OJYbh}HMh&e`#> +zj;jrpjqKCh41OK{FOS`@_sPP$iCm46G^EMNk8(l-1f>!gEV+4vMVRZ#8infUenP+k +zL^tBOHF^=)k&U-Tw{gfijqQ&^ +z-RHHII5yp}2|o8pTsf6x7$teW9Em!~iy2DN?D@|U)g%I6VG%JBO$|~;c~1Q^3|x`1 +z6HRbq1#~Ke)wWpALcc&@P;m+*sGavR0{aOx3=IwUE3YPWAwV45pzD$~02inxi7(6X +z$zk683M=_r#M*+6fQ)&FK0y|lm7JLwS)K=t&ZJk!U_-y%_o@fhr{s37MUEQOF*M)3 +zB$;4>Zx;Xk*(hwFjb>1iJ1f*D#nyWL{=>{2|9*^vCNN!%bF8Oe<`xz#s;jFz?;I}4M3lL;!fy_;J-E96Of+;sG%K=fZdR)99pJ}fM( +zq%(s8UrsEL{NrdF`!#RY+VjFyPpE_vtqPMM!MQ+QnE)+_g9Z^{4^;k&Sa^=w*yuxB_*Z!U%!3{_9Qr)Jfz4IeS#io4oj_Kqhq`HCUub|Ke!v$1-$v=kc+O#rlCej?%dhY +zxxKUTsFPG1nfoFp3%7@gh9S?vM0N27#*fpJyaX;Vy{!pt*}!9_mX9uC#J5RyjknW2Dm3dCvZYU +zSW?0kvI9!o2un}*%`AYhr^CQT1aZF=-Nt^atn@Kt%b2!hT(pK!|MclbBv3-<+6{>_ +z8toMfWc9rpOk(8|KW>Z-k>Fr(xc_+q9ocf`8!_n}XYUrW?Ax|*_|=5m*4F0V+46wJ +z1IGS^Z5t=0Zj86J2MfJc +zUq#WKCfhoB<;P2&&`*_G4^_0uqDR20m!>T8ay_rxSzA&9_v5##g6tzXTkx+KRfz32 +z9vvpp?+YxHTxDthCBu7)&Q052y4s9*$M4_2w-OdPyK?F-EBoUuSsIk@@(!gA*A_!0 +z2eu1y;-Q$Ut(M>8FCOtw?vZR-%*ly^x)<95vK@P0tJoZws@+M*NGhg_NU`!}DZnWBHQz%*@6))$BWN;EM0xAF+B4Mph#S??J?K+&viwPmes*n^HGDL9iBf +zCk|mDu46wwughN!isu&G((DO>Ws`(VLY?^#w=RONxUgFGby--Y=5NJ|(>qXOS`;lZhmXyMEyBdVM@jJh71E-})~`?t4w8^Kwy) +z<+KACjs!F^TS-;FT24_iWF+=l(nR}j7U#;Vd +z)IT3=b&}A}1PUKFa6DKfgHkJci!~7u?a%k9h7Rri^{y`|;;xNDoQbV}+oJ=LdApL}|77o@C= +z;~aed)XpbrMtt1x3gHPWxbliQH4nKBCew{9 +z*-_PTyn~`1VrwKcc4ZrhI^!MsZ{D0O0%O2!SHHi^Dfyr9*x*DGFKwc()b;q6nM*M7 +zvA$x_?$BMJJHN5HIn9Ps{_7-sn79~BZegaa5V;s(BA<5BnU?^AeJHXtd)cIj_UCjA +zW|N@MjV~vrJz{sE0Dzv}tXxUDQAXm)1(kX7C_ZVFX%!TlZ850i(P1A0BxaJu)#LcH +zoxMFRzxoxw$bM=B6gpuMD#vcsa^00?%=D+T9-dQqV*=zD|)W!3BLun2&^n)~$ +z2_^{i9~sGXOAsF_S=k&4mWJ@`mD+G%MiPTlhuomboeFNwHb(< +zVpVR!mwf;JmpO3JL|B%L-!;@7TG}+`HZA;-{VIlQGY|T=f|!9!S=!c?sq5|KeEQ*~ +zm!1xeZcJPbSsfjU9e>K|=Ni<+YgrIG!|5@|Z>4bjx+`1j^O-{QK8XARf +zUG$nLRiTEtt;)9F30rvw>nj)@vCF{$d7>o2n>}~Y2^^C79l@s`uXRZOcuy>^%2@t- +zRGv={pKlDXFUgvG_^DWGR==il1rIzn{$p4r(FVOQxZi!_*Ksfl2hR{Aj>01RbFAM= +zpr0wzMwlOwlkt4|JLK)$>VL+{4nv>^`yMa)T;(9f*B(9;{T+)_=M4dN>M&&hS-#(G +z)-sW(WxVkHR)`x#g)25Lu7qnN;~Q-bvKDZ=;^fyLy@okDpvt&ZU{!U)WVtmnp +zAN-CzM{jPFWep9NAKDDq@=kynkGi_GQ@Z2y_Wn)xc_q3-&+9`qdGy_{PF-2c^$)%x +zd0sonEJhtG*2|P*Q-f_3`Akk96HzBz2 +z!5tnJaCcA2hGQrSw*{F)epvfYX?7toP=O0dN +zizY2w`>O@4Vqff!dBhQ^><#TjMP}loM9ProiD-Og@$V=*zQ|Avg0D!+96lr^u(1fl +z3J52PHoJYDdvdiIW?q?JIC*r?88VruLx#bp0lys39v$(c6uC*j}2IFFh +zViOX|K+DH18cd9%Rgjs$*sXuoW<>p^Fv-7CV|zpgTUnj812pyyX-nhA4TZ^UyYY9; +z?}BOarTT1q;0xSTjV_DPWE11?Y2+wSA*ybzebDoy8JwhznKa6SvYxE$WswX7Z6pG$ +zsA2GgHFFL3^zA@XTYK{a+6$Q8di%@1-|q9U15y+~R-L7Kwx8*xr(FP{g*JDPa`e((jSl#~?Rx=3ne(nLfeP9k0grubJK +zU4euzZqt~$Cl%k^{-!e6YQZi|D3#+MUS}VsYZ)0S>y@)kyqRI?A_esvAu-{`1Uq@! +zC+b`wnMK&<_mitl+k@e*$*{&S>vayX*>D>Q5sw2FZ?l(8ff%(8lo<^mBMrwQXOXe+ +z*7sZdWzBTIwZO$y^F)qZL1XbOMY<@M_a56y{({Vg@YN<_y}toq41V%~w=+4ZQvg)X +zVw~l$z-sId^nKU%dlk7W(mG}eS&KV2BdYqNJnX-p=YrG&&`_m0fzA_|iKD${5?oL* +zdS$heR@%Q+(3!!T&k;tIN|v2j=UI))rgkvyC7MTTrKP3g>Fma@_R0`GE5(tL%sS$7 +zG41ag%(Y(xZ5cjlk=R~(3XC+$25r*Fo=G5OhGgR}i!nDoG?^sult?Eo*x$x6CH-3L@LtZ0dfq!Bbbw-S}RwlN%lpH8c=4l2qH +z1wRszHSPh~=esnWvXD8B{D4<}?}6cA+@Ob1760Is6`g!zl@WL(L&={LA}SxAt0>Tw +z%b7i^&yNKM;(vGcNwuxAK{g|S3Y1&pH_6U1G +z3M4zx5FU=O;=l_?VzQ-~bx~xN1axPgYI0am3d25BjYmfSTX7Q}==Vcryl6@Se0(Jv +zxKW_o%H`jdnC7QXlkFbCsACHN1Dx=0gf<~@PW-&<=`1Hd)@#ypH7%OpalDj-P=ts+3^~yWs~TV}BD20HjkW6zc1L +z0#HzMkn3JV%7N-18_@tgE82*YnmEzxirriDSx#_|<|q1vL{k}7>^mRzO(ueTSN2~H +zG}kxp)Qn!&)><3|e>62+GXSpQKcemfqU!&BHZ5Ca;DT<63bBM&uV1BDS?MM$M;x8w>gShAPMxJM^BbMZn}Unm{OC9^4x3%% +zlmX8!km-u$N4fQXQ>jRe`7)3+RFGjhz +z18zf(Fo2<>YV^7LJO^UTZ2Ivd#mpN}o?7pBV&q=f%ID>haV7M8R3jsF*@a%iwIy>| +zsZ!-y{!%&j7`B?W8TcF4NH-RHH1xZ{;7BsA<#APu!;cND)te)FhoXz$BIU}2&^7WP +zT}TX>ZO58$VNPuh6JV7~s(W$vAj`^%AtUamex3YdVl3~4+pqk?G)qUibNMrj0*M25 +zY>5Ac|Dnv6xBQmV#$3JA?&HTN(lYl~J}@$l{*TY^kORrCB)3dDO}^^v!dcLf^CHty +zanjllIQeSLmpuG+h&ae`r*v!C*0A&W^a&q>93?BAXzG7n +z2*3TGPIcN`-_hY9&oaiv#fiv~>}7`T`4=pInEqWX*3e8+yPm^9h-tr&ts55$l+388 +zW)~F}2JH!}VLbQ>?6~H@&k`MnSsTeVj0TRVP4jGbP*!!CwM6`Z11c)yI2w$+R0zxo +zT|obYS1&&`{>>Z9(jnVU&=yI*%PGe*f78ie*_9oap?sd7fx7{r^WT>=XHF +zl`f{=UJEn2?tRw`Fem?eRE6#*nOes(ebRcmaK3~a3{a3EyE1zXSF0p7I_iDJ&%;3V +zU;AS}e?*mH#Yh2P9E3QBigIqu2iXf=@t)2+I~f*_E^JtEP1@IR{CBfTj%T}E3e#n% +zUa{@vU?D$l4DEANwkkK@ruP4ta)E*e^KLGg%$PizyPmHvKNMWtuJQ6sPXY=(1m#>W +z7V?9E!Vj}>a|KfQx5ESpH+q6$@gAp-P#~lbz`aj1_?xinN>3o8b2-Z3w>UZ3QZ}W0 +zWg-!>p>AADDcU^4;0*L4UFgB0QLlXd^y1E&4>txV!T|!`RwjZGl`;-4ZgFf>luHIy +zZ8d8Rh{I3r!g-ht6mAZxMB6VxRqnA0UY`h|mJZy2 +z17BazT$jMKFL3J6Ue_HL1^)4s%$Jj~Qx~1HG#tS@kwL(KP_ZI3dWz0SH(sqj#-*TNGsIWqPj>cj?!GyWvfdEiNOu4$>MIqL=F&Cc0{g*~L5 +zA1wt)=_zMFUkCT5$l!G{1-Y9QtGQ#qm5E(3fYPms_EP*sSVI)bfXN|uNO`BqVuCvd +zv)z8IGRgtM1<_trndVhQ^xA)wn~*W~#d*X@E=W)jcQWI8+?kdzHe;DZ`%+JE%gE}m +z6H=FO8rJxM{N90S=Gi!Mel)TyanxPa;E}C?hJl@e9UWad->;S|v;axgFjrY$z3(rV{MiJ}3M)t;Q?P5wZy0e3G{dcDO7n}3slDXLMrB$;#*W@Qv)D$=?Xs$F(8eTcyGIQ~IWgD%Gn&E>F9y#o>cR-7spE;Rur<_E~Pu)e0I +z#&y1|@8D~8c55<|KMf;&x;hg!A%VOZ38_+uk`jH4#=b9M&xcpxV-7cMN{jXVRnKSe +zlKJJ%=VBV{$DNeI1QkiA;DfdVT?$;O#22z6v6bTK9)fjrfIh!Hq__l~KzuNqT{&kA +zKs@YV6^1ZLGjTgR%(=NHS-DvWnnP)NM#qbHINqmQdCE5??co$3nuikqgm=s7*#Kd*+j_weKrZjMeLeHEoiJm>zuDRU` +zh~ggr^knneWU!Nn}AQt=0Id6Hk; +z4bJqse|V$H`stT?NS0yreYvaZ9YF!fw+N}{3#yXRU!C7?exl35BDC%+!jDMGT^DN# +zN9FGd#5t#;$h}5UgQ?q-Gr15>C6=nLUszle9<+_!!oi_m@_L^-R>_Qty7_g|C%m|5 +z-7^5X5V_ARi?h9_LW%2vByD3X_IvUktqBv{%SYXO1&;e&O#Ll_cfC`Wv1u+l_#RI< +zQ5Kly0;P`%TXaQN(heOg~>V&L{d+ZDA%eq-UKo#1)$rkjSm=nzAE2r +z5--RyKhxfXoGVU3^ab{5XGlyL1+26foG)4HZvN +zG@&I3h0fnK5lIjcrg*XxPy1(gK3_TN`&VYnxP;C|j$~0rT$0f|*#=OzM^NbE-1T5D +z%Csnt)n!sx3N#b(8G&+G3W~Q_B#StA6jZZ=p#wuu`DrAMXm{T@#S;ku4Dme@{Njmk +zCtrh3z6O>o)~o{&Htx+6kn*)$NNBH-biu^aYtWUq +z(G>4rCEKr#tO>!x8A@%W@6g)Xs%2Hq!y#Mbb@9R2@GDWi&!{jhZvzQ1D9nMuPoOS+ +z+cj{9nx5X{jJOIavbFf)Kz5Jnbe5Bu#(XE-z$j&iaP%c9W59OoT0~|N#D*(N2kz={ +zs(|)nH!_+_g1)#ZH2xk>ZTG#6WN#qa3BxZM{NWxq`*#$H255k6Ky?hw*hSA6`c_fl +zT@Ua%E5Ez3;~`kQFmrC#$Nlvc_Uy3#yzhd-6UYuuIwgIBZZC-`dwOBJbfurL(FfhH +z{YkjE+9OrOveY`{t{sGw&51YO1@{iO4)Ki=!Z5#q=m_Hi)_j0`>?;t2j);vv%BUif +z;wpTZdLQLsGvZ()DCdxYudn^Pt;BZ}Rin$4F8h{R`HxT2z`uc&aMXIQOvwgA5%{&) +zFW52MiN!$!EXgx}Px~e1!EMp;#&kY65oDho95j~!qD%YJr`+aK4jCJ4UJ^;q>w@Lf +zvDfg|M`S^@DGxu+7aR3Cx#;%?advj&1~L-m +zJqCP9&TW3migV*`Z$#)Qa>3>Jf)g9D6Ki28P@iX(uso)hic8Dp1F< +zeF;(n8Po8A*~^T{De(J)Z2nqLl@Vv3yoSlGwq0aeOg4ymI(KIkTeur-=J-yp9z?qe)it6gq-wl@I +z0D-_I{|T<5kwD9uH3yf1GWXp5*8eOgJf*q0IRoK|+r{}Fug&0WpNDKMTC@(Xc)9K8 +zy`lByMn!1fnY)1KYP(0Je1)c~WilUuh<&Q8^OE?L9Q^xK*Y@M$`6D6TDCZ^@l8{|} +zxmmNw)mng$hYBii+&ZqedxWT0dnV#LG4zC%+kzcK+-??vEHT>Q-T8zu|s_1IbA#OV)^+1pg1OmmZn` + diff --git a/patches/server/0002-Divine-Configuration.patch b/patches/removed/1.19.4/server/0002-Divine-Configuration.patch similarity index 100% rename from patches/server/0002-Divine-Configuration.patch rename to patches/removed/1.19.4/server/0002-Divine-Configuration.patch diff --git a/patches/server/0003-Fix-legacy-colors-in-console.patch b/patches/removed/1.19.4/server/0003-Fix-legacy-colors-in-console.patch similarity index 100% rename from patches/server/0003-Fix-legacy-colors-in-console.patch rename to patches/removed/1.19.4/server/0003-Fix-legacy-colors-in-console.patch diff --git a/patches/server/0004-Time-Utilities.patch b/patches/removed/1.19.4/server/0004-Time-Utilities.patch similarity index 100% rename from patches/server/0004-Time-Utilities.patch rename to patches/removed/1.19.4/server/0004-Time-Utilities.patch diff --git a/patches/server/0005-lithium-fast-util.patch b/patches/removed/1.19.4/server/0005-lithium-fast-util.patch similarity index 100% rename from patches/server/0005-lithium-fast-util.patch rename to patches/removed/1.19.4/server/0005-lithium-fast-util.patch diff --git a/patches/server/0006-lithium-HashedReferenceList.patch b/patches/removed/1.19.4/server/0006-lithium-HashedReferenceList.patch similarity index 100% rename from patches/server/0006-lithium-HashedReferenceList.patch rename to patches/removed/1.19.4/server/0006-lithium-HashedReferenceList.patch diff --git a/patches/server/0007-Add-last-tick-time-API.patch b/patches/removed/1.19.4/server/0007-Add-last-tick-time-API.patch similarity index 100% rename from patches/server/0007-Add-last-tick-time-API.patch rename to patches/removed/1.19.4/server/0007-Add-last-tick-time-API.patch diff --git a/patches/server/0008-lithium-shapes.blockstate_cache.patch b/patches/removed/1.19.4/server/0008-lithium-shapes.blockstate_cache.patch similarity index 100% rename from patches/server/0008-lithium-shapes.blockstate_cache.patch rename to patches/removed/1.19.4/server/0008-lithium-shapes.blockstate_cache.patch diff --git a/patches/server/0009-lithium-ai.raid.patch b/patches/removed/1.19.4/server/0009-lithium-ai.raid.patch similarity index 100% rename from patches/server/0009-lithium-ai.raid.patch rename to patches/removed/1.19.4/server/0009-lithium-ai.raid.patch diff --git a/patches/server/0010-Stop-wasting-resources-on-JsonList-get.patch b/patches/removed/1.19.4/server/0010-Stop-wasting-resources-on-JsonList-get.patch similarity index 100% rename from patches/server/0010-Stop-wasting-resources-on-JsonList-get.patch rename to patches/removed/1.19.4/server/0010-Stop-wasting-resources-on-JsonList-get.patch diff --git a/patches/server/0011-Don-t-create-new-random-instance.patch b/patches/removed/1.19.4/server/0011-Don-t-create-new-random-instance.patch similarity index 100% rename from patches/server/0011-Don-t-create-new-random-instance.patch rename to patches/removed/1.19.4/server/0011-Don-t-create-new-random-instance.patch diff --git a/patches/server/0012-Fix-rotating-UP-DOWN-CW-and-CCW.patch b/patches/removed/1.19.4/server/0012-Fix-rotating-UP-DOWN-CW-and-CCW.patch similarity index 100% rename from patches/server/0012-Fix-rotating-UP-DOWN-CW-and-CCW.patch rename to patches/removed/1.19.4/server/0012-Fix-rotating-UP-DOWN-CW-and-CCW.patch diff --git a/patches/server/0013-Fix-vanilla-command-permission-handler.patch b/patches/removed/1.19.4/server/0013-Fix-vanilla-command-permission-handler.patch similarity index 100% rename from patches/server/0013-Fix-vanilla-command-permission-handler.patch rename to patches/removed/1.19.4/server/0013-Fix-vanilla-command-permission-handler.patch diff --git a/patches/server/0014-Remove-Spigot-tick-limiter.patch b/patches/removed/1.19.4/server/0014-Remove-Spigot-tick-limiter.patch similarity index 100% rename from patches/server/0014-Remove-Spigot-tick-limiter.patch rename to patches/removed/1.19.4/server/0014-Remove-Spigot-tick-limiter.patch diff --git a/patches/server/0015-Don-t-save-Fireworks.patch b/patches/removed/1.19.4/server/0015-Don-t-save-Fireworks.patch similarity index 100% rename from patches/server/0015-Don-t-save-Fireworks.patch rename to patches/removed/1.19.4/server/0015-Don-t-save-Fireworks.patch diff --git a/patches/server/0016-Paper-PR-BoneMeal-API.patch b/patches/removed/1.19.4/server/0016-Paper-PR-BoneMeal-API.patch similarity index 100% rename from patches/server/0016-Paper-PR-BoneMeal-API.patch rename to patches/removed/1.19.4/server/0016-Paper-PR-BoneMeal-API.patch diff --git a/patches/server/0017-Do-not-drop-items-from-Give-command.patch b/patches/removed/1.19.4/server/0017-Do-not-drop-items-from-Give-command.patch similarity index 100% rename from patches/server/0017-Do-not-drop-items-from-Give-command.patch rename to patches/removed/1.19.4/server/0017-Do-not-drop-items-from-Give-command.patch diff --git a/patches/server/0018-Fix-cow-rotation-when-shearing-mooshroom.patch b/patches/removed/1.19.4/server/0018-Fix-cow-rotation-when-shearing-mooshroom.patch similarity index 100% rename from patches/server/0018-Fix-cow-rotation-when-shearing-mooshroom.patch rename to patches/removed/1.19.4/server/0018-Fix-cow-rotation-when-shearing-mooshroom.patch diff --git a/patches/server/0019-End-gateway-should-check-if-entity-can-use-portal.patch b/patches/removed/1.19.4/server/0019-End-gateway-should-check-if-entity-can-use-portal.patch similarity index 100% rename from patches/server/0019-End-gateway-should-check-if-entity-can-use-portal.patch rename to patches/removed/1.19.4/server/0019-End-gateway-should-check-if-entity-can-use-portal.patch diff --git a/patches/server/0020-Arrows-should-not-reset-despawn-counter.patch b/patches/removed/1.19.4/server/0020-Arrows-should-not-reset-despawn-counter.patch similarity index 100% rename from patches/server/0020-Arrows-should-not-reset-despawn-counter.patch rename to patches/removed/1.19.4/server/0020-Arrows-should-not-reset-despawn-counter.patch diff --git a/patches/server/0021-Skip-cloning-loot-parameters.patch b/patches/removed/1.19.4/server/0021-Skip-cloning-loot-parameters.patch similarity index 100% rename from patches/server/0021-Skip-cloning-loot-parameters.patch rename to patches/removed/1.19.4/server/0021-Skip-cloning-loot-parameters.patch diff --git a/patches/server/0022-Dont-eat-blocks-in-non-ticking-chunks.patch b/patches/removed/1.19.4/server/0022-Dont-eat-blocks-in-non-ticking-chunks.patch similarity index 100% rename from patches/server/0022-Dont-eat-blocks-in-non-ticking-chunks.patch rename to patches/removed/1.19.4/server/0022-Dont-eat-blocks-in-non-ticking-chunks.patch diff --git a/patches/server/0023-carpetfixes-BiomeAccess-prediction.patch b/patches/removed/1.19.4/server/0023-carpetfixes-BiomeAccess-prediction.patch similarity index 100% rename from patches/server/0023-carpetfixes-BiomeAccess-prediction.patch rename to patches/removed/1.19.4/server/0023-carpetfixes-BiomeAccess-prediction.patch diff --git a/patches/server/0024-Fix-MC-121706.patch b/patches/removed/1.19.4/server/0024-Fix-MC-121706.patch similarity index 100% rename from patches/server/0024-Fix-MC-121706.patch rename to patches/removed/1.19.4/server/0024-Fix-MC-121706.patch diff --git a/patches/server/0025-Fix-hunger-saturation-depleting-on-peaceful.patch b/patches/removed/1.19.4/server/0025-Fix-hunger-saturation-depleting-on-peaceful.patch similarity index 100% rename from patches/server/0025-Fix-hunger-saturation-depleting-on-peaceful.patch rename to patches/removed/1.19.4/server/0025-Fix-hunger-saturation-depleting-on-peaceful.patch diff --git a/patches/server/0026-Fix-mobs-attacking-themselves.patch b/patches/removed/1.19.4/server/0026-Fix-mobs-attacking-themselves.patch similarity index 100% rename from patches/server/0026-Fix-mobs-attacking-themselves.patch rename to patches/removed/1.19.4/server/0026-Fix-mobs-attacking-themselves.patch diff --git a/patches/server/0027-PaperPR-Optimize-VarInts.patch b/patches/removed/1.19.4/server/0027-PaperPR-Optimize-VarInts.patch similarity index 100% rename from patches/server/0027-PaperPR-Optimize-VarInts.patch rename to patches/removed/1.19.4/server/0027-PaperPR-Optimize-VarInts.patch diff --git a/patches/server/0028-Fix-MC-238526.patch b/patches/removed/1.19.4/server/0028-Fix-MC-238526.patch similarity index 100% rename from patches/server/0028-Fix-MC-238526.patch rename to patches/removed/1.19.4/server/0028-Fix-MC-238526.patch diff --git a/patches/server/0029-lithium-cached-hashcode.patch b/patches/removed/1.19.4/server/0029-lithium-cached-hashcode.patch similarity index 100% rename from patches/server/0029-lithium-cached-hashcode.patch rename to patches/removed/1.19.4/server/0029-lithium-cached-hashcode.patch diff --git a/patches/server/0030-vmp-skip-entity-move-if-movement-is-zero.patch b/patches/removed/1.19.4/server/0030-vmp-skip-entity-move-if-movement-is-zero.patch similarity index 100% rename from patches/server/0030-vmp-skip-entity-move-if-movement-is-zero.patch rename to patches/removed/1.19.4/server/0030-vmp-skip-entity-move-if-movement-is-zero.patch diff --git a/patches/server/0031-lithium-suffocation.patch b/patches/removed/1.19.4/server/0031-lithium-suffocation.patch similarity index 100% rename from patches/server/0031-lithium-suffocation.patch rename to patches/removed/1.19.4/server/0031-lithium-suffocation.patch diff --git a/patches/server/0032-lithium-ai.sensor.secondary_poi.patch b/patches/removed/1.19.4/server/0032-lithium-ai.sensor.secondary_poi.patch similarity index 100% rename from patches/server/0032-lithium-ai.sensor.secondary_poi.patch rename to patches/removed/1.19.4/server/0032-lithium-ai.sensor.secondary_poi.patch diff --git a/patches/server/0033-lithium-store-gamerules-in-fastutil-hashmap.patch b/patches/removed/1.19.4/server/0033-lithium-store-gamerules-in-fastutil-hashmap.patch similarity index 100% rename from patches/server/0033-lithium-store-gamerules-in-fastutil-hashmap.patch rename to patches/removed/1.19.4/server/0033-lithium-store-gamerules-in-fastutil-hashmap.patch diff --git a/patches/server/0034-lithium-precompute-shape-arrays.patch b/patches/removed/1.19.4/server/0034-lithium-precompute-shape-arrays.patch similarity index 100% rename from patches/server/0034-lithium-precompute-shape-arrays.patch rename to patches/removed/1.19.4/server/0034-lithium-precompute-shape-arrays.patch diff --git a/patches/server/0035-lithium-entity.fast_elytra_check.patch b/patches/removed/1.19.4/server/0035-lithium-entity.fast_elytra_check.patch similarity index 100% rename from patches/server/0035-lithium-entity.fast_elytra_check.patch rename to patches/removed/1.19.4/server/0035-lithium-entity.fast_elytra_check.patch diff --git a/patches/server/0036-lithium-entity.fast_hand_swing.patch b/patches/removed/1.19.4/server/0036-lithium-entity.fast_hand_swing.patch similarity index 100% rename from patches/server/0036-lithium-entity.fast_hand_swing.patch rename to patches/removed/1.19.4/server/0036-lithium-entity.fast_hand_swing.patch diff --git a/patches/server/0037-lithium-entity.fast_powder_snow_check.patch b/patches/removed/1.19.4/server/0037-lithium-entity.fast_powder_snow_check.patch similarity index 100% rename from patches/server/0037-lithium-entity.fast_powder_snow_check.patch rename to patches/removed/1.19.4/server/0037-lithium-entity.fast_powder_snow_check.patch diff --git a/patches/server/0038-lithium-collections.attributes.patch b/patches/removed/1.19.4/server/0038-lithium-collections.attributes.patch similarity index 100% rename from patches/server/0038-lithium-collections.attributes.patch rename to patches/removed/1.19.4/server/0038-lithium-collections.attributes.patch diff --git a/patches/server/0039-lithium-collections.entity_by_type.patch b/patches/removed/1.19.4/server/0039-lithium-collections.entity_by_type.patch similarity index 100% rename from patches/server/0039-lithium-collections.entity_by_type.patch rename to patches/removed/1.19.4/server/0039-lithium-collections.entity_by_type.patch diff --git a/patches/server/0040-lithium-collections.entity_filtering.patch b/patches/removed/1.19.4/server/0040-lithium-collections.entity_filtering.patch similarity index 100% rename from patches/server/0040-lithium-collections.entity_filtering.patch rename to patches/removed/1.19.4/server/0040-lithium-collections.entity_filtering.patch diff --git a/patches/server/0041-lithium-chunk.serialization.patch b/patches/removed/1.19.4/server/0041-lithium-chunk.serialization.patch similarity index 100% rename from patches/server/0041-lithium-chunk.serialization.patch rename to patches/removed/1.19.4/server/0041-lithium-chunk.serialization.patch diff --git a/patches/server/0042-lithium-cache-iterate-outwards.patch b/patches/removed/1.19.4/server/0042-lithium-cache-iterate-outwards.patch similarity index 100% rename from patches/server/0042-lithium-cache-iterate-outwards.patch rename to patches/removed/1.19.4/server/0042-lithium-cache-iterate-outwards.patch diff --git a/patches/server/0043-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch b/patches/removed/1.19.4/server/0043-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch similarity index 100% rename from patches/server/0043-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch rename to patches/removed/1.19.4/server/0043-vmp-use-linked-map-for-entity-trackers-for-faster-it.patch diff --git a/patches/server/0044-lithium-block.moving_block_shapes.patch b/patches/removed/1.19.4/server/0044-lithium-block.moving_block_shapes.patch similarity index 100% rename from patches/server/0044-lithium-block.moving_block_shapes.patch rename to patches/removed/1.19.4/server/0044-lithium-block.moving_block_shapes.patch diff --git a/patches/server/0045-Fix-MC-93826.patch b/patches/removed/1.19.4/server/0045-Fix-MC-93826.patch similarity index 100% rename from patches/server/0045-Fix-MC-93826.patch rename to patches/removed/1.19.4/server/0045-Fix-MC-93826.patch diff --git a/patches/server/0046-Optimize-default-values-for-configs.patch b/patches/removed/1.19.4/server/0046-Optimize-default-values-for-configs.patch similarity index 100% rename from patches/server/0046-Optimize-default-values-for-configs.patch rename to patches/removed/1.19.4/server/0046-Optimize-default-values-for-configs.patch diff --git a/patches/server/0047-Dynamic-minecart-speed.patch b/patches/removed/1.19.4/server/0047-Dynamic-minecart-speed.patch similarity index 100% rename from patches/server/0047-Dynamic-minecart-speed.patch rename to patches/removed/1.19.4/server/0047-Dynamic-minecart-speed.patch diff --git a/patches/server/0048-Increase-manual-minecart-speed.patch b/patches/removed/1.19.4/server/0048-Increase-manual-minecart-speed.patch similarity index 100% rename from patches/server/0048-Increase-manual-minecart-speed.patch rename to patches/removed/1.19.4/server/0048-Increase-manual-minecart-speed.patch diff --git a/patches/server/0049-Allow-placing-rails-on-more-surfaces.patch b/patches/removed/1.19.4/server/0049-Allow-placing-rails-on-more-surfaces.patch similarity index 100% rename from patches/server/0049-Allow-placing-rails-on-more-surfaces.patch rename to patches/removed/1.19.4/server/0049-Allow-placing-rails-on-more-surfaces.patch diff --git a/patches/server/0050-Paper-PR-Add-Entity-hidden-by-default-flag.patch b/patches/removed/1.19.4/server/0050-Paper-PR-Add-Entity-hidden-by-default-flag.patch similarity index 100% rename from patches/server/0050-Paper-PR-Add-Entity-hidden-by-default-flag.patch rename to patches/removed/1.19.4/server/0050-Paper-PR-Add-Entity-hidden-by-default-flag.patch diff --git a/patches/server/0001-Divine-Branding.patch b/patches/server/0001-Divine-Branding.patch index 6acad42..77d960d 100644 --- a/patches/server/0001-Divine-Branding.patch +++ b/patches/server/0001-Divine-Branding.patch @@ -5,56 +5,56 @@ Subject: [PATCH] Divine Branding diff --git a/build.gradle.kts b/build.gradle.kts -index 3c8293f002f11b430083502362fdc801f44aa138..506456fd003dda0d544c9800301b1210a5d18457 100644 +index 22470f0ab8354a9f31a0f195f3fe80f2f5ee2f0e..be5d1d43fb3924fc1e48d9bb64aafdd237995f83 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } dependencies { -- implementation(project(":pufferfish-api")) // Pufferfish // Paper -+ implementation(project(":divinemc-api")) // DivineMC // Pufferfish // Paper - // Pufferfish start - implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") { - exclude("io.papermc.paper", "paper-api") -@@ -82,7 +82,7 @@ tasks.jar { +- implementation(project(":purpur-api")) // Purpur ++ implementation(project(":divinemc-api")) // DivineMC + implementation("io.papermc.paper:paper-mojangapi:1.19.4-R0.1-SNAPSHOT") // Purpur + // Paper start + implementation("org.jline:jline-terminal-jansi:3.21.0") +@@ -81,7 +81,7 @@ tasks.jar { attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", "Implementation-Title" to "CraftBukkit", -- "Implementation-Version" to "git-Pufferfish-$implementationVersion", // Pufferfish -+ "Implementation-Version" to "git-DivineMC-$implementationVersion", // DivineMC // Pufferfish +- "Implementation-Version" to "git-Purpur-$implementationVersion", // Pufferfish // Purpur ++ "Implementation-Version" to "git-DivineMC-$implementationVersion", // Pufferfish // Purpur // DivineMC "Implementation-Vendor" to date, // Paper "Specification-Title" to "Bukkit", "Specification-Version" to project.version, diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index 692c962193cf9fcc6801fc93f3220bdc673d527b..2bf46834536d3702fa2ae49ce276a163a5cd1456 100644 +index 8cde30544e14f8fc2dac32966ae3c21f8cf3a551..ad62e0b7deb141d22be4f19ea30f61440b192af2 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java @@ -593,7 +593,7 @@ public class Metrics { boolean logFailedRequests = config.getBoolean("logFailedRequests", false); // Only start Metrics, if it's enabled in the config if (config.getBoolean("enabled", true)) { -- Metrics metrics = new Metrics("Pufferfish", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish -+ Metrics metrics = new Metrics("DivineMC", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // DivineMC +- Metrics metrics = new Metrics("Purpur", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // Purpur ++ Metrics metrics = new Metrics("DivineMC", serverUUID, logFailedRequests, Bukkit.getLogger()); // Pufferfish // Purpur // DivineMC metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { String minecraftVersion = Bukkit.getVersion(); diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java -index c5d5648f4ca603ef2b1df723b58f9caf4dd3c722..05478a1ea04ec0396bc8c97090edef4a2aced2a9 100644 +index 3cb56595822799926a8141e60a42f5d1edfc6de5..05478a1ea04ec0396bc8c97090edef4a2aced2a9 100644 --- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java @@ -17,7 +17,7 @@ public final class PaperConsole extends SimpleTerminalConsole { @Override protected LineReader buildReader(LineReaderBuilder builder) { builder -- .appName("Paper") +- .appName("Purpur") // Purpur + .appName("DivineMC") // DivineMC .variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history")) .completer(new ConsoleCommandCompleter(this.server)) .option(LineReader.Option.COMPLETE_IN_WORD, true); diff --git a/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java new file mode 100644 -index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625b5ca334a +index 0000000000000000000000000000000000000000..953451b808fc134b047dcf7b3b1379bc5aba4399 --- /dev/null +++ b/src/main/java/gq/bxteam/divinemc/DivineVersionFetcher.java @@ -0,0 +1,137 @@ @@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625 + private static final HttpClient client = HttpClient.newHttpClient(); + + private static final URI JENKINS_URI = URI.create("https://raw.githubusercontent.com/DivineMC/Website/dev/latestBuild"); -+ private static final String GITHUB_FORMAT = "https://api.github.com/repos/DivineMC/DivineMC/compare/ver/1.19.3...%s"; ++ private static final String GITHUB_FORMAT = "https://api.github.com/repos/DivineMC/DivineMC/compare/ver/1.19.4...%s"; + + private static final HttpResponse.BodyHandler JSON_OBJECT_BODY_HANDLER = responseInfo -> HttpResponse.BodySubscribers.mapping( + HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8), @@ -130,14 +130,14 @@ index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625 + try { + final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { -+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); ++ return text("Received invalid status code (" response.statusCode() ") from server.", RED); + } + + int latestVersionNumber; + try { + latestVersionNumber = Integer.parseInt(response.body()); + } catch (NumberFormatException e) { -+ LOGGER.log(Level.WARNING, "Received invalid response from Jenkins \"" + response.body() + "\"."); ++ LOGGER.log(Level.WARNING, "Received invalid response from Jenkins \"" response.body() "\"."); + return text("Received invalid response from server.", RED); + } + @@ -157,7 +157,7 @@ index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625 + try { + final HttpResponse response = client.send(request, JSON_OBJECT_BODY_HANDLER); + if (response.statusCode() != 200) { -+ return text("Received invalid status code (" + response.statusCode() + ") from server.", RED); ++ return text("Received invalid status code (" response.statusCode() ") from server.", RED); + } + + final JsonObject obj = response.body(); @@ -175,8 +175,8 @@ index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625 + return switch (Math.max(-1, Math.min(1, versionDiff))) { + case -1 -> text("You are running an unsupported version of DivineMC.", RED); + case 0 -> text("You are on the latest version!", GREEN); -+ default -> text("You are running " + versionDiff + " version" + (versionDiff == 1 ? "" : "s") + " beyond. " + -+ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", RED); ++ default -> text("You are running " versionDiff " version" (versionDiff == 1 ? "" : "s") " beyond. " ++ "Please update your server when possible to maintain stability, security, and receive the latest optimizations.", RED); + }; + } + @@ -192,74 +192,84 @@ index 0000000000000000000000000000000000000000..0dc13e363448d7a0f20993e0576af625 + return null; + } + -+ return text("Previous version: " + oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); ++ return text("Previous version: " oldVersion, NamedTextColor.GRAY, TextDecoration.ITALIC); + } +} -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 6d5e9400892b86562519a893349ca55e566bfb24..9945d6efac1e1ea0d22d6fdfe8aa5d2805c615b2 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1683,7 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! -+ return "DivineMC"; // DivineMC - DivineMC > // Pufferfish - Pufferfish > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! - } - - public SystemReport fillSystemReport(SystemReport details) { +\ No newline at end of file diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b2d94582037c091bd6a04451bf62b3f9c4923d19..efc137a8a9f1da4a7ffff6028af368cc7f90d20a 100644 +index bc1a2df0a7ddaf030917e4723994464d77e55d02..2caf9913a22dbc895aca060e89c53b8ec21a85d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -256,7 +256,7 @@ import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper public final class CraftServer implements Server { -- private final String serverName = "Pufferfish"; // Paper // Pufferfish -+ private final String serverName = "DivineMC"; // Paper // Pufferfish // DivineMC +- private final String serverName = "Purpur"; // Paper // Pufferfish // Purpur ++ private final String serverName = "DivineMC"; // Paper // Pufferfish // Purpur // DivineMC private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); -diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 4966a1e3dd35357a8ea6a7d2944c84c9c3e9058e..5b4d42fd74a32e4e97690f0cd9a33c66dc1ae141 100644 ---- a/src/main/java/org/bukkit/craftbukkit/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -285,7 +285,7 @@ public class Main { - if (buildDate.before(deadline.getTime())) { - // Paper start - This is some stupid bullshit - System.err.println("*** Warning, you've not updated in a while! ***"); -- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper -+ System.err.println("*** Please download a new build from https://github.com/DivineMC/DivineMC/releases/latest ***"); // DivineMC - //System.err.println("*** Server will start in 20 seconds ***"); - //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); - // Paper End diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d4f62940504e3ef7a70e13b1f4a7726f23b4c637..bd21dd728b6d47d354aeb879b083394e186d6a5c 100644 +index 1dd7f923dd6adb41eafc3ea0c063e3aae6670124..bd21dd728b6d47d354aeb879b083394e186d6a5c 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -464,7 +464,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { -- return new gg.pufferfish.pufferfish.PufferfishVersionFetcher(); // Pufferfish +- return new com.destroystokyo.paper.PaperVersionFetcher(); // Purpur + return new gq.bxteam.divinemc.DivineVersionFetcher(); // DivineMC } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 80553face9c70c2a3d897681e7761df85b22d464..60ac52c6e12ee346133930394e9de8bf74e77ee6 100644 +index 99597258e8e88cd9e2c901c4ac3ff7faeeabee2b..b79b9f27c5cf09dfcf4cb0bdf7a3aa507db2b0c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -11,7 +11,7 @@ public final class Versioning { public static String getBukkitVersion() { String result = "Unknown-Version"; -- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gg.pufferfish.pufferfish/pufferfish-api/pom.properties"); // Pufferfish -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gq.bxteam.divinemc/divinemc-api/pom.properties"); // DivineMC +- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.purpurmc.purpur/purpur-api/pom.properties"); // Pufferfish // Purpur ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/gq.bxteam.divinemc/divinemc-api/pom.properties"); // Pufferfish // Purpur // DivineMC Properties properties = new Properties(); if (stream != null) { +diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +index 0bcbe1f07ff8e552d2abd6e432af5710005acc04..cfcf5334a801b8ba90d3a1f55d3e3ede49c4befc 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +@@ -227,7 +227,7 @@ public class PurpurConfig { + deathMessageOnlyBroadcastToAffectedPlayer = getBoolean("settings.broadcasts.death.only-broadcast-to-affected-player", deathMessageOnlyBroadcastToAffectedPlayer); + } + +- public static String serverModName = "Purpur"; ++ public static String serverModName = "DivineMC"; // DivineMC + private static void serverModName() { + serverModName = getString("settings.server-mod-name", serverModName); + } +diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java +index a810bfd3b8d6bd4d8f2ef8797e4281ae4fe8a67f..9d2e47bcc1aa258a1797a6816c0ac59524cd7af3 100644 +--- a/src/main/java/org/spigotmc/WatchdogThread.java ++++ b/src/main/java/org/spigotmc/WatchdogThread.java +@@ -185,7 +185,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa + // Paper end + } else + { +- log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PURPUR - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); // Purpur ++ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO DIVINEMC - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); // Purpur // DivineMC + log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump"); + } + // Paper end - Different message for short timeout +@@ -206,7 +206,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa + WatchdogThread.dumpThread( thread, log ); + } + } else { +- log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PURPUR - THIS IS NOT A BUG OR A CRASH ---"); // Purpur ++ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO DIVINEMC - THIS IS NOT A BUG OR A CRASH ---"); // Purpur // DivineMC + } + + log.log( Level.SEVERE, "------------------------------" ); diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png index a7d785f60c884ee4ee487cc364402d66c3dc2ecc..f54753531b3bf2e8b5377f342465e727c7da98f2 100644 GIT binary patch diff --git a/settings.gradle.kts b/settings.gradle.kts index cc6b0e8..f731feb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,5 @@ +import java.util.Locale + pluginManagement { repositories { mavenLocal() @@ -8,4 +10,8 @@ pluginManagement { rootProject.name = "DivineMC" -include("divinemc-api", "divinemc-server") \ No newline at end of file +for (name in listOf("DivineMC-API", "DivineMC-Server")) { + val projName = name.toLowerCase(Locale.ENGLISH) + include(projName) + findProject(":$projName")!!.projectDir = file(name) +} \ No newline at end of file