diff --git a/build.gradle.kts b/build.gradle.kts index 095ea86..d8eea2f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,18 +38,24 @@ subprojects { } paperweight { - serverProject.set(project(":Matter-Server")) + serverProject.set(project(":matter-purpur-server")) remapRepo.set("https://maven.fabricmc.net/") decompileRepo.set("https://files.minecraftforge.net/maven/") - usePaperUpstream(providers.gradleProperty("paperRef")) { - withPaperPatcher { + useStandardUpstream("purpur") { + url.set(github("PurpurMC", "Purpur")) + ref.set(providers.gradleProperty("purpurRef")) + + withStandardPatcher { + apiSourceDirPath.set("Purpur-API") + serverSourceDirPath.set("Purpur-Server") + apiPatchDir.set(layout.projectDirectory.dir("patches/api")) serverPatchDir.set(layout.projectDirectory.dir("patches/server")) - apiOutputDir.set(layout.projectDirectory.dir("Matter-API")) - serverOutputDir.set(layout.projectDirectory.dir("Matter-Server")) + apiOutputDir.set(layout.projectDirectory.dir("matter-purpur-api")) + serverOutputDir.set(layout.projectDirectory.dir("matter-purpur-server")) } } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a130b13..640981c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version = 1.18-R0.1-SNAPSHOT mcVersion = 1.18 packageVersion = 1_18_R1 -paperRef = 51d168752bc22bc37ade1d4577355cad6146ba56 +purpurRef = aa425ecbe841d821e67e5a9938674e66b89743ec org.gradle.jvmargs=-Xmx2G diff --git a/patches/server/0001-Feature-Secure-Seed.patch b/patches/server/0001-Feature-Secure-Seed.patch index fcdae43..3a6e604 100644 --- a/patches/server/0001-Feature-Secure-Seed.patch +++ b/patches/server/0001-Feature-Secure-Seed.patch @@ -4,117 +4,6 @@ Date: Thu, 9 Dec 2021 02:18:17 +0800 Subject: [PATCH] Feature Secure Seed -diff --git a/build.gradle.kts b/build.gradle.kts -index 5678a9f8d2aa8a7afbc5729570ec297b12acf75d..295ba0dde16850ddd80877e693cd7af2457663f5 100644 ---- a/build.gradle.kts -+++ b/build.gradle.kts -@@ -18,8 +18,14 @@ repositories { - } - - dependencies { -- implementation(project(":paper-api")) -- implementation(project(":paper-mojangapi")) -+ -+ // Matter start -+ implementation(project(":Matter-API")) -+ implementation("io.papermc.paper:paper-mojangapi:1.18-R0.1-SNAPSHOT") { -+ exclude("io.papermc.paper", "paper-api") -+ } -+ // Matter end -+ - // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") - implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -67,7 +73,7 @@ tasks.jar { - attributes( - "Main-Class" to "org.bukkit.craftbukkit.Main", - "Implementation-Title" to "CraftBukkit", -- "Implementation-Version" to "git-Paper-$implementationVersion", -+ "Implementation-Version" to "git-Matter-$implementationVersion", // Matter - "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 218f5bafeed8551b55b91c7fccaf6935c8b631ca..b070ba6f008ecd85dcb994043438113d2ebf379d 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("Paper", serverUUID, logFailedRequests, Bukkit.getLogger()); -+ Metrics metrics = new Metrics("Matter", serverUUID, logFailedRequests, Bukkit.getLogger()); // Matter - - metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { - String minecraftVersion = Bukkit.getVersion(); -@@ -603,7 +603,7 @@ public class Metrics { - - metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size())); - metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : "offline")); -- metrics.addCustomChart(new Metrics.SimplePie("paper_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); -+ metrics.addCustomChart(new Metrics.SimplePie("matter_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); - - metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { - Map> map = new HashMap<>(); -diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java -index e0b1f0671d16ddddcb6725acd25a1d1d69e42701..63384b9353e71e9d310528235f1a39d58489ae55 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("Matter") // Matter - .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/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 481a5dbad82f3f8dd5b1bf8ab207d82ec73d5bbd..cea84576f966d5d1ba528bcd3e4b43fd7c73aa15 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1709,7 +1709,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop // Spigot - Spigot > // CraftBukkit - cb > vanilla! -+ return "Matter"; // Matter - Matter > // Paper - Paper > // Spigot - Spigot > // CraftBukkit - cb > vanilla! - } - - public SystemReport fillSystemReport(SystemReport details) { -diff --git a/src/main/java/net/minecraft/server/commands/SeedCommand.java b/src/main/java/net/minecraft/server/commands/SeedCommand.java -index 6f4aa3fce42a53883db1485731e03822887cadc0..6d519ce617c99410c32ab2f9cd28fc4e3cb9f6f7 100644 ---- a/src/main/java/net/minecraft/server/commands/SeedCommand.java -+++ b/src/main/java/net/minecraft/server/commands/SeedCommand.java -@@ -10,6 +10,7 @@ import net.minecraft.network.chat.ComponentUtils; - import net.minecraft.network.chat.HoverEvent; - import net.minecraft.network.chat.TextComponent; - import net.minecraft.network.chat.TranslatableComponent; -+import su.plo.matter.Globals; - - public class SeedCommand { - public static void register(CommandDispatcher dispatcher, boolean dedicated) { -@@ -20,7 +21,20 @@ public class SeedCommand { - Component component = ComponentUtils.wrapInSquareBrackets((new TextComponent(String.valueOf(l))).withStyle((style) -> { - return style.withColor(ChatFormatting.GREEN).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.valueOf(l))).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))).withInsertion(String.valueOf(l)); - })); -+ -+ // Matter start -+ Globals.setupGlobals(context.getSource().getLevel()); -+ String seedStr = Globals.seedToString(Globals.worldSeed); -+ Component result = ComponentUtils.wrapInSquareBrackets(new TranslatableComponent("chat.copy.click")).withStyle(style -> { -+ return style.withColor(ChatFormatting.GREEN) -+ .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, seedStr)) -+ .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))) -+ .withInsertion(seedStr); -+ }); -+ - context.getSource().sendSuccess(new TranslatableComponent("commands.seed.success", component), false); -+ context.getSource().sendSuccess(new TranslatableComponent("Feature seed: %s", result), false); -+ // Matter end - return (int)l; - })); - } diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java index e7e110b53e79e0606262982555dd9eb096c7c4a8..bb7e77e22b58250b687d9df429a982ca038c9aa7 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -138,10 +27,10 @@ index e7e110b53e79e0606262982555dd9eb096c7c4a8..bb7e77e22b58250b687d9df429a982ca } diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java -index 5722d9b30223fb229b80f54d7fb9edf41254a7f7..f0dc9c709659293d5e7b78a5e8f4fa6c5c980a5f 100644 +index d49ba154d173aa7bf5a679b7bfcc55de851ea34b..c077fced547ea2c8bb9826ca353208961f020e7d 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Slime.java +++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java -@@ -336,7 +336,7 @@ public class Slime extends Mob implements Enemy { +@@ -397,7 +397,7 @@ public class Slime extends Mob implements Enemy { } ChunkPos chunkcoordintpair = new ChunkPos(pos); @@ -151,7 +40,7 @@ index 5722d9b30223fb229b80f54d7fb9edf41254a7f7..f0dc9c709659293d5e7b78a5e8f4fa6c if (random.nextInt(10) == 0 && flag && pos.getY() < 40) { return checkMobSpawnRules(type, world, spawnReason, pos, random); diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java -index 96cb3e8cad9e7a5edd2a448ea88f2447104fbb5a..c715706633508817a194ee1d5c29a21394adf8db 100644 +index 5aeaaae6f15050a2da271fe196d0a234ecafc8a1..ea720517a1adfb164d540c2743aaec2a058d13b8 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java @@ -36,12 +36,7 @@ import net.minecraft.world.level.block.Block; @@ -207,7 +96,7 @@ index 96cb3e8cad9e7a5edd2a448ea88f2447104fbb5a..c715706633508817a194ee1d5c29a213 for (int i = 0; i < sectionArray.length; ++i) { if (sectionArray[i] == null) { diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java -index e4591c0b3c8547cc6f4e2a0891fc378ee4334d9e..d05d67240a368e3a7352fe59a5803893f5bd6eba 100644 +index fe0f14b363f4e6b583cd079f2cf627605731f764..11519b8cdfa20839a8aa76cbb3e6cd4fe473fcdc 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -68,6 +68,8 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature; @@ -960,7 +849,7 @@ index 66dc81f3116b10df660fc37c392ce55bde0e2ffe..59e2ece2367e138aec88b8ac09d5b8db int j = context.chunkPos().getMinBlockZ() + worldgenRandom.nextInt(16); int k = context.chunkGenerator().getSeaLevel(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java -index b4f7b91ac165e3171ffcf7d6a993af248d268959..a8cd2286e32a613ad897464c3e5bfac334248ab4 100644 +index d51476ca2aad08a0dd93a2e772dd7750afc939dc..b33d3e8be3aa95b83a7ce6f8f04d773380637038 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -205,7 +205,7 @@ public class CraftChunk implements Chunk { @@ -972,53 +861,6 @@ index b4f7b91ac165e3171ffcf7d6a993af248d268959..a8cd2286e32a613ad897464c3e5bfac3 } @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index d91abf93f2a06f73d3124f4fcff2491fe8d36655..e253d0d0fb45a59178a80001cc445c0e54dbb9bf 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -253,7 +253,7 @@ import javax.annotation.Nullable; // Paper - import javax.annotation.Nonnull; // Paper - - public final class CraftServer implements Server { -- private final String serverName = "Paper"; // Paper -+ private final String serverName = "Matter"; // Paper // Matter - 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/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d51c63496b55d64ac7ee6175bc364012df897891..99f19de8f66818589dd3a6444f917d372faf38e8 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -50,6 +50,7 @@ import org.bukkit.inventory.ItemStack; - import org.bukkit.material.MaterialData; - import org.bukkit.plugin.InvalidPluginException; - import org.bukkit.plugin.PluginDescriptionFile; -+import su.plo.matter.MatterVersionFetcher; - - @SuppressWarnings("deprecation") - public final class CraftMagicNumbers implements UnsafeValues { -@@ -394,7 +395,7 @@ public final class CraftMagicNumbers implements UnsafeValues { - - @Override - public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { -- return new com.destroystokyo.paper.PaperVersionFetcher(); -+ return new MatterVersionFetcher(); // Matter - } - - @Override -diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java -index 774556a62eb240da42e84db4502e2ed43495be17..524dafef05c7989a896f48a2307ab741eb9c24f8 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/io.papermc.paper/paper-api/pom.properties"); -+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/su.plo.matter/Matter-API/pom.properties"); - Properties properties = new Properties(); - - if (stream != null) { diff --git a/src/main/java/su/plo/matter/Globals.java b/src/main/java/su/plo/matter/Globals.java new file mode 100644 index 0000000000000000000000000000000000000000..744c6072ee1b6bf87d4d7af6f25650dc81e6a2d1 @@ -1186,150 +1028,6 @@ index 0000000000000000000000000000000000000000..d18b15ca0b6585f08b30b019c8c17a0f + internalState[posB] = Long.rotateRight(internalState[posB] ^ internalState[posC], 63); // replaces 11 of BLAKE + } +} -diff --git a/src/main/java/su/plo/matter/MatterVersionFetcher.java b/src/main/java/su/plo/matter/MatterVersionFetcher.java -new file mode 100644 -index 0000000000000000000000000000000000000000..4124b5dd7ee5ed1316c10d3961c9ac9c73eba276 ---- /dev/null -+++ b/src/main/java/su/plo/matter/MatterVersionFetcher.java -@@ -0,0 +1,137 @@ -+package su.plo.matter; -+ -+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 MatterVersionFetcher implements VersionFetcher { -+ private static final Logger LOGGER = Logger.getLogger("MatterVersionFetcher"); -+ private static final HttpClient client = HttpClient.newHttpClient(); -+ -+ private static final URI JENKINS_URI = URI.create("https://matter.plo.su/job/Matter-1.18/lastSuccessfulBuild/buildNumber"); -+ private static final String GITHUB_FORMAT = "https://api.github.com/repos/plasmoapp/matter/compare/ver/master...%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 Matter.", 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); -+ } -+} -\ No newline at end of file diff --git a/src/main/java/su/plo/matter/WorldgenCryptoRandom.java b/src/main/java/su/plo/matter/WorldgenCryptoRandom.java new file mode 100644 index 0000000000000000000000000000000000000000..56a1dccabd29543199fb0eca772fd3ad3ef7104a diff --git a/patches/server/0002-Matter-Branding.patch b/patches/server/0002-Matter-Branding.patch new file mode 100644 index 0000000..df39266 --- /dev/null +++ b/patches/server/0002-Matter-Branding.patch @@ -0,0 +1,245 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Apehum +Date: Thu, 16 Dec 2021 00:16:49 +0800 +Subject: [PATCH] Matter Branding + + +diff --git a/build.gradle.kts b/build.gradle.kts +index e5cba810a2f207d7bb57d946573acbee1e8013c7..f2015b6639f01d15f2ed2a049466d8a792c4897d 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -19,7 +19,7 @@ repositories { + + dependencies { + // Purpur start +- implementation(project(":purpur-api")) ++ implementation(project(":matter-purpur-api")) // Matter + implementation("io.papermc.paper:paper-mojangapi:1.18-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") + } +@@ -74,7 +74,7 @@ tasks.jar { + attributes( + "Main-Class" to "org.bukkit.craftbukkit.Main", + "Implementation-Title" to "CraftBukkit", +- "Implementation-Version" to "git-Purpur-$implementationVersion", // Purpur ++ "Implementation-Version" to "git-Matter-Purpur-$implementationVersion", // Purpur // Matter + "Implementation-Vendor" to date, // Paper + "Specification-Title" to "Bukkit", + "Specification-Version" to project.version, +diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +index 8c3c68465197fafc14849dc38a572e309931e2a2..a6d857b907ecc261a7684a1446b735b9b2256cf4 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("Purpur") // Purpur ++ .appName("Matter-Purpur") // Purpur // Matter + .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/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 959cb69b37921c62a9012642acaf2d0295915e1f..f4a90865d62390fcda71f2339aa49b5d98a6a284 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -253,7 +253,7 @@ import javax.annotation.Nullable; // Paper + import javax.annotation.Nonnull; // Paper + + public final class CraftServer implements Server { +- private final String serverName = "Purpur"; // Paper // Purpur ++ private final String serverName = "Matter-Purpur"; // Paper // Purpur // Matter + 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/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +index 90e68a8cfd00e4ad7ffaddfc8e8d5df26c49cf7a..248b62685a263a2e6d3feeaa002afcc24dee9ac2 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +@@ -50,6 +50,7 @@ import org.bukkit.inventory.ItemStack; + import org.bukkit.material.MaterialData; + import org.bukkit.plugin.InvalidPluginException; + import org.bukkit.plugin.PluginDescriptionFile; ++import su.plo.matter.MatterVersionFetcher; + + @SuppressWarnings("deprecation") + public final class CraftMagicNumbers implements UnsafeValues { +@@ -394,7 +395,7 @@ public final class CraftMagicNumbers implements UnsafeValues { + + @Override + public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { +- return new com.destroystokyo.paper.PaperVersionFetcher(); ++ return new MatterVersionFetcher(); // Matter + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +index fb87620c742ff7912f5e8ccd2a7930dd605576d9..350fcb92af9068a6b059684d80a441be7160985c 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/org.purpurmc.purpur/purpur-api/pom.properties"); // Purpur ++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/su.plo.matter/matter-purpur-api/pom.properties"); // Purpur // Matter + 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 141a46499eb2cba73a3f71fb50926bc08f37f9f0..5a5897d31c60aab2329a3dc50244b39a0fb962d9 100644 +--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java ++++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java +@@ -209,7 +209,7 @@ public class PurpurConfig { + if (!TimingsManager.hiddenConfigs.contains("settings.seed")) TimingsManager.hiddenConfigs.add("settings.seed"); + } + +- public static String serverModName = "Purpur"; ++ public static String serverModName = "Matter-Purpur"; // Matter + private static void serverModName() { + serverModName = getString("settings.server-mod-name", serverModName); + } +diff --git a/src/main/java/su/plo/matter/MatterVersionFetcher.java b/src/main/java/su/plo/matter/MatterVersionFetcher.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4124b5dd7ee5ed1316c10d3961c9ac9c73eba276 +--- /dev/null ++++ b/src/main/java/su/plo/matter/MatterVersionFetcher.java +@@ -0,0 +1,137 @@ ++package su.plo.matter; ++ ++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 MatterVersionFetcher implements VersionFetcher { ++ private static final Logger LOGGER = Logger.getLogger("MatterVersionFetcher"); ++ private static final HttpClient client = HttpClient.newHttpClient(); ++ ++ private static final URI JENKINS_URI = URI.create("https://matter.plo.su/job/Matter-1.18/lastSuccessfulBuild/buildNumber"); ++ private static final String GITHUB_FORMAT = "https://api.github.com/repos/plasmoapp/matter/compare/ver/master...%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 Matter.", 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); ++ } ++} +\ No newline at end of file diff --git a/patches/server/0003-Matter-Metrics.patch b/patches/server/0003-Matter-Metrics.patch new file mode 100644 index 0000000..3463789 --- /dev/null +++ b/patches/server/0003-Matter-Metrics.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Apehum +Date: Thu, 16 Dec 2021 00:18:33 +0800 +Subject: [PATCH] Matter Metrics + + +diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java +index 7bc497bcae6a6a752e3c432178cb1e3c633e0bec..71f8e1474919d6e805adc27c47a0b9216b72908a 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("Purpur", serverUUID, logFailedRequests, Bukkit.getLogger()); // Purpur ++ Metrics metrics = new Metrics("Matter", serverUUID, logFailedRequests, Bukkit.getLogger()); // Purpur // Matter + metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { + String minecraftVersion = Bukkit.getVersion(); + minecraftVersion = minecraftVersion.substring(minecraftVersion.indexOf("MC: ") + 4, minecraftVersion.length() - 1); +@@ -602,7 +602,8 @@ public class Metrics { + + metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size())); + metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : (PaperConfig.isProxyOnlineMode() ? "bungee" : "offline"))); // Purpur +- metrics.addCustomChart(new Metrics.SimplePie("purpur_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); // Purpur ++ metrics.addCustomChart(new Metrics.SimplePie("matter_type", () -> "Purpur")); // Matter ++ metrics.addCustomChart(new Metrics.SimplePie("matter_version", () -> (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown")); // Purpur // Matter + + metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> { + Map> map = new HashMap<>(); diff --git a/patches/server/0004-Seed-Command.patch b/patches/server/0004-Seed-Command.patch new file mode 100644 index 0000000..4b92f8e --- /dev/null +++ b/patches/server/0004-Seed-Command.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Apehum +Date: Thu, 16 Dec 2021 00:52:48 +0800 +Subject: [PATCH] Seed Command + + +diff --git a/src/main/java/net/minecraft/server/commands/SeedCommand.java b/src/main/java/net/minecraft/server/commands/SeedCommand.java +index 6f4aa3fce42a53883db1485731e03822887cadc0..84dd717767bcf04c56b26bc872d4f05352c30a8f 100644 +--- a/src/main/java/net/minecraft/server/commands/SeedCommand.java ++++ b/src/main/java/net/minecraft/server/commands/SeedCommand.java +@@ -10,6 +10,7 @@ import net.minecraft.network.chat.ComponentUtils; + import net.minecraft.network.chat.HoverEvent; + import net.minecraft.network.chat.TextComponent; + import net.minecraft.network.chat.TranslatableComponent; ++import su.plo.matter.Globals; + + public class SeedCommand { + public static void register(CommandDispatcher dispatcher, boolean dedicated) { +@@ -20,8 +21,21 @@ public class SeedCommand { + Component component = ComponentUtils.wrapInSquareBrackets((new TextComponent(String.valueOf(l))).withStyle((style) -> { + return style.withColor(ChatFormatting.GREEN).withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, String.valueOf(l))).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))).withInsertion(String.valueOf(l)); + })); ++ ++ // Matter start ++ Globals.setupGlobals(context.getSource().getLevel()); ++ String seedStr = Globals.seedToString(Globals.worldSeed); ++ Component result = ComponentUtils.wrapInSquareBrackets(new TranslatableComponent("chat.copy.click")).withStyle(style -> { ++ return style.withColor(ChatFormatting.GREEN) ++ .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, seedStr)) ++ .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent("chat.copy.click"))) ++ .withInsertion(seedStr); ++ }); ++ + context.getSource().sendSuccess(new TranslatableComponent("commands.seed.success", component), false); +- return (int)l; ++ context.getSource().sendSuccess(new TranslatableComponent("Feature seed: %s", result), false); ++ // Matter end ++ return (int) l; + })); + } + } diff --git a/settings.gradle.kts b/settings.gradle.kts index 83cc4fa..5e9d6d3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,4 +8,4 @@ pluginManagement { rootProject.name = "Matter" -include("Matter-API", "Matter-Server") \ No newline at end of file +include("matter-purpur-api", "matter-purpur-server") \ No newline at end of file