diff --git a/.gitignore b/.gitignore index 6b3caedca..e42963b87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# JVM crash related +core.* +hs_err_pid* + # Intellij .idea/ *.iml @@ -14,6 +18,12 @@ out/ nbproject/ nbactions.xml +# Gradle +!gradle-wrapper.jar +.gradle/ +build/ +*/build/ + # we use maven! build.xml @@ -46,3 +56,5 @@ Purpur-Server Purpur-API mc-dev purpurclip.jar +*clip.jar +last-paper diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac38cf9e9..1bc61dbf5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,14 +8,15 @@ Patches to Purpur are very simple, but center around the directories 'Purpur-API Assuming you already have forked the repository: 1. Pull the latest changes from the main repository -2. Type `./purpur patch` in git bash to apply the changes from upstream -3. cd into `Purpur-Server` for server changes, and `Purpur-API` for API changes +2. Update the Paper submodule if necessary: `git submodule update --init --recursive` and `./gradlew setupUpstream` +3. Type `./gradlew applyPatches` to apply the latest Purpur patches +4. cd into `Purpur-Server` for server changes, and `Purpur-API` for API changes These directories aren't git repositories in the traditional sense: - Every single commit in Purpur-Server/API is a patch. - 'origin/master' points to a directory similar to Purpur-Server/API but for Paper -- Typing `git status` should show that we are 10 or 11 commits ahead of master, meaning we have 10 or 11 patches that Purpur doesn't +- Typing `git status` should show that we are 10 or 11 commits ahead of master, meaning we have 10 or 11 patches that Paper doesn't - If it says something like `212 commits ahead, 207 commits behind`, then type `git fetch` to update purpur ## Adding Patches @@ -26,7 +27,7 @@ Adding patches to Purpur is very simple: 3. Type `git add .` to add your changes 4. Run `git commit` with the desired patch message 5. `cd ../` to get back to the project root -6. Run `./purpur rebuild` in the main directory to convert your commit into a new patch +6. Run `./gradlew rebuildPatches` in the main directory to convert your commit into a new patch 7. PR your patches back to this repository Your commit will be converted into a patch that you can then PR into Purpur @@ -39,18 +40,17 @@ just need to add it to our import script to be ran during the patch process. 1. Save (rebuild) any patches you are in the middle of working on! 2. Identify the names of the files you want to import. - A complete list of all possible file names can be found at ```./Paper/work/Minecraft/$MCVER/net/minecraft/server``` -3. Open the file at `./scripts/importmcdev.sh` and add the name of your file to the script near the end. -4. Update the project to rebuild with the new imports `./purpur up` -5. Re-patch the server `./purpur patch` -6. Edit away! +3. Open the file at `./buildSrc/src/main/kotlin/MCDevImports.kt` and add the name of your file to the `nmsImports` set. +4. Re-patch the server to make the imports take effect `./gradlew applyPatches` +5. Edit away! -This change is temporary! DO NOT COMMIT CHANGES TO THE `importmcdev.sh` FILE! -Once you have made your changes to the new file, and rebuilt patches, you may undo your changes to `importmcdev.sh` +This change is temporary! DO NOT COMMIT CHANGES TO THE `MCDevImports.kt` FILE! +Once you have made your changes to the new file, and rebuilt patches, you may undo your changes to `MCDevImports.kt` Any file modified in a patch file gets automatically imported, so you only need this temporarily to import it to create the first patch. -To undo your changes to the file, type `git checkout scripts/importmcdev.sh`, or just remove the import lines you added previously. +To undo your changes to the file, type `git checkout buildSrc/src/main/kotlin/MCDevImports.kt`, or just remove the import lines you added previously. ## Modifying Patches Modifying previous patches is a bit more complex: @@ -62,7 +62,7 @@ However, while in the middle of an edit, unless you also reset your API to a rel 1. If you have changes you are working on type `git stash` to store them for later. - Later you can type `git stash pop` to get them back. -2. Type `git rebase -i upstream/upstream` +2. Type `git rebase -i origin/master` - It should show something like [this](https://gist.github.com/zachbr/21e92993cb99f62ffd7905d7b02f3159). 3. Replace `pick` with `edit` for the commit/patch you want to modify, and "save" the changes. - Only do this for one commit at a time. @@ -72,7 +72,7 @@ However, while in the middle of an edit, unless you also reset your API to a rel - **MAKE SURE TO ADD `--amend`** or else a new patch will be created. - You can also modify the commit message here. 7. Type `git rebase --continue` to finish rebasing. -8. Type `./purpur rebuild` in the main directory. +8. Type `./gradlew rebuildPatches` in the main directory. - This will modify the appropriate patches based on your commits. 9. PR your modifications back to this project. @@ -83,9 +83,9 @@ This method has the benefit of being able to compile to test your change without 1. Make your change while at HEAD 2. Make a temporary commit. You don't need to make a message for this. -3. Type `git rebase -i upstream/upstream`, move (cut) your temporary commit and move it under the line of the patch you wish to modify. +3. Type `git rebase -i origin/master`, move (cut) your temporary commit and move it under the line of the patch you wish to modify. 4. Change the `pick` with `f` (fixup) or `s` (squash) if you need to edit the commit message -5. Type `./purpur rebuild` in the main directory +5. Type `./gradlew rebuildPatches` in the main directory - This will modify the appropriate patches based on your commits 6. PR your modifications back to this project. diff --git a/README.md b/README.md index aa2794ddb..87971f48f 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Downloads API endpoints: Everything is licensed under the MIT license, and is free to be used in your own fork. -See [starlis/empirecraft](https://github.com/starlis/empirecraft) and [electronicboy/byof](https://github.com/electronicboy/byof) +See [starlis/empirecraft](https://github.com/starlis/empirecraft), [electronicboy/byof](https://github.com/electronicboy/byof), and [mikroskeemsrealm/Toothpick](https://github.com/mikroskeemsrealm/Toothpick) for the license of material used/modified by this project. ## bStats @@ -76,14 +76,15 @@ Purpur API maven dependency: ``` Purpur API gradle dependency: -```groovy -maven { - name 'purpur' - url 'https://repo.pl3x.net/' +```kotlin +repositories { + maven("https://repo.pl3x.net/") } ``` -```groovy -compileOnly 'net.pl3x.purpur:purpur-api:1.16.4-R0.1-SNAPSHOT' +```kotlin +dependencies { + compileOnly("net.pl3x.purpur", "purpur-api", "1.16.4-R0.1-SNAPSHOT") +} ``` Yes, this also includes all API provided by Paper, Spigot, and Bukkit. @@ -94,14 +95,12 @@ Yes, this also includes all API provided by Paper, Spigot, and Bukkit. Run the following commands in the root directory: ``` -git submodule update --init -./purpur up -./purpur patch +./gradlew applyPatches ``` #### Creating a patch Patches are effectively just commits in either `Purpur-API` or `Purpur-Server`. -To create one, just add a commit to either repo and run `./purpur rb`, and a +To create one, just add a commit to either repo and run `./gradlew rebuildPatches`, and a patch will be placed in the patches folder. Modifying commits will also modify its corresponding patch file. @@ -110,7 +109,8 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more detailed information. #### Compiling -Use the command `./purpur build` to build the api and server. Compiled jars -will be placed under `Purpur-API/target` and `Purpur-Server/target`. +Use the command `./gradlew build` to build the api and server. Compiled jars +will be placed under `Purpur-API/build/libs` and `Purpur-Server/build/libs`. -To get a purpurclip jar, run `./purpur jar`. +To get a purpurclip jar, run `./gradlew paperclip`. +To install the `purpur-api` and `purpur` dependencies to your local maven repo, run `./gradlew publishToMavenLocal` diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..3e6781615 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + `java-library` + toothpick +} + +toothpick { + forkName = "Purpur" + groupId = "net.pl3x.purpur" + val versionTag = System.getenv("BUILD_NUMBER") + ?: "\"${gitCmd("rev-parse", "--short", "HEAD").output}\"" + forkVersion = "git-$forkName-$versionTag" + + minecraftVersion = "1.16.4" + nmsRevision = "R0.1-SNAPSHOT" + + upstream = "Paper" + server { + project = project(":$forkNameLowercase-server") + patchesDir = rootProject.projectDir.resolve("patches/server") + } + api { + project = project(":$forkNameLowercase-api") + patchesDir = rootProject.projectDir.resolve("patches/api") + } +} + +subprojects { + repositories { + mavenCentral() + maven("https://repo.aikar.co/content/groups/aikar/") + maven("https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/") + maven("https://libraries.minecraft.net") + mavenLocal() + } + + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + withSourcesJar() + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..2db113861 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,26 @@ +val kotlinxDomVersion = "0.0.10" +val shadowVersion = "6.1.0" + +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + jcenter() + maven("https://plugins.gradle.org/m2/") +} + +dependencies { + implementation("org.jetbrains.kotlinx:kotlinx.dom:$kotlinxDomVersion") + implementation("com.github.jengelman.gradle.plugins:shadow:$shadowVersion") +} + +gradlePlugin { + plugins { + register("Toothpick") { + id = "toothpick" + implementationClass = "Toothpick" + } + } +} diff --git a/buildSrc/src/main/kotlin/ConfigureSubprojects.kt b/buildSrc/src/main/kotlin/ConfigureSubprojects.kt new file mode 100644 index 000000000..b79e3a7a0 --- /dev/null +++ b/buildSrc/src/main/kotlin/ConfigureSubprojects.kt @@ -0,0 +1,105 @@ +import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer +import org.gradle.api.Project +import org.gradle.api.plugins.JavaLibraryPlugin +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin +import org.gradle.api.publish.maven.tasks.GenerateMavenPom +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.attributes +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.getValue +import org.gradle.kotlin.dsl.getting + +internal fun Project.configureSubprojects() { + subprojects { + apply() + apply() + + extensions.configure(PublishingExtension::class.java) { + publications { + create("mavenJava") { + artifactId = if (project.name.endsWith("server")) rootProject.name else project.name + groupId = rootProject.group as String + version = rootProject.version as String + from(components["java"]) + pom { + name.set(project.name) + url.set("https://github.com/pl3xgaming/Purpur") + } + } + } + } + + when { + project.name.endsWith("server") -> configureServerProject() + project.name.endsWith("api") -> configureApiProject() + } + } +} + +private fun Project.configureServerProject() { + apply() + + val generatePomFileForMavenJavaPublication by tasks.getting(GenerateMavenPom::class) { + destination = project.buildDir.resolve("tmp/pom.xml") + } + + @Suppress("UNUSED_VARIABLE") + val test by tasks.getting(Test::class) { + // didn't bother to look into why these fail. paper excludes them in paperweight as well though + exclude("org/bukkit/craftbukkit/inventory/ItemStack*Test.class") + } + + val shadowJar by tasks.getting(ShadowJar::class) { + dependsOn(generatePomFileForMavenJavaPublication) + transform(Log4j2PluginsCacheFileTransformer::class.java) + manifest { + attributes( + "Main-Class" to "org.bukkit.craftbukkit.Main", + "Implementation-Title" to "CraftBukkit", + "Implementation-Version" to toothpick.forkVersion, + "Implementation-Vendor" to java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + .format(java.util.Date()), + "Specification-Title" to "Bukkit", + "Specification-Version" to "${project.version}", + "Specification-Vendor" to "Bukkit Team" + ) + } + from(project.buildDir.resolve("tmp/pom.xml")) { + // dirty hack to make "java -Dpaperclip.install=true -jar paperclip.jar" work without forking paperclip + into("META-INF/maven/io.papermc.paper/paper") + } + + // Don't like to do this but sadly have to do this for compatibility reasons + val relocVersion = toothpick.minecraftVersion.replace(".", "_") + relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.v$relocVersion") { + exclude("org.bukkit.craftbukkit.Main*") + } + relocate("net.minecraft.server", "net.minecraft.server.v$relocVersion") + } + tasks.getByName("build") { + dependsOn(shadowJar) + } +} + +@Suppress("UNUSED_VARIABLE") +private fun Project.configureApiProject() { + val jar by this.tasks.getting(Jar::class) { + doFirst { + buildDir.resolve("tmp/pom.properties") + .writeText("version=${project.version}") + } + from(buildDir.resolve("tmp/pom.properties")) { + into("META-INF/maven/${project.group}/${project.name}") + } + manifest { + attributes("Automatic-Module-Name" to "org.bukkit") + } + } +} diff --git a/buildSrc/src/main/kotlin/Constants.kt b/buildSrc/src/main/kotlin/Constants.kt new file mode 100644 index 000000000..e579b850e --- /dev/null +++ b/buildSrc/src/main/kotlin/Constants.kt @@ -0,0 +1,2 @@ +const val taskGroup = "toothpick" +const val internalTaskGroup = "toothpick_internal" diff --git a/buildSrc/src/main/kotlin/DependencyLoading.kt b/buildSrc/src/main/kotlin/DependencyLoading.kt new file mode 100644 index 000000000..828fcebc1 --- /dev/null +++ b/buildSrc/src/main/kotlin/DependencyLoading.kt @@ -0,0 +1,66 @@ +import kotlinx.dom.elements +import kotlinx.dom.parseXml +import kotlinx.dom.search +import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.kotlin.dsl.DependencyHandlerScope +import org.gradle.kotlin.dsl.maven +import org.gradle.kotlin.dsl.project + +fun RepositoryHandler.loadRepositories(project: Project) { + val pomFile = project.projectDir.resolve("pom.xml") + if (!pomFile.exists()) return + val dom = parseXml(pomFile) + val repositoriesBlock = dom.search("repositories").firstOrNull() ?: return + + // Load repositories + repositoriesBlock.elements("repository").forEach { repositoryElem -> + val url = repositoryElem.search("url").firstOrNull()?.textContent ?: return@forEach + maven(url) + } +} + +fun DependencyHandlerScope.loadDependencies(project: Project) { + val pomFile = project.projectDir.resolve("pom.xml") + if (!pomFile.exists()) return + val dom = parseXml(pomFile) + + val dependenciesBlock = dom.search("dependencies").firstOrNull() ?: return + + // Load dependencies + dependenciesBlock.elements("dependency").forEach { dependencyElem -> + val groupId = dependencyElem.search("groupId").firstOrNull()!!.textContent + val artifactId = dependencyElem.search("artifactId").firstOrNull()!!.textContent + val version = dependencyElem.search("version").firstOrNull()!!.textContent.applyReplacements( + mapOf( + "project.version" to "${project.toothpick.minecraftVersion}-${project.toothpick.nmsRevision}", + "minecraft.version" to project.toothpick.minecraftVersion + ) + ) + val scope = dependencyElem.search("scope").firstOrNull()?.textContent + val classifier = dependencyElem.search("classifier").firstOrNull()?.textContent + + val dependencyString = "${groupId}:${artifactId}:${version}${classifier?.run { ":$this" } ?: ""}" + project.logger.debug("Read dependency '{}' from '{}'", dependencyString, pomFile.absolutePath) + + // Special case API + if (artifactId == "${project.toothpick.forkNameLowercase}-api" + || artifactId == "${project.toothpick.upstreamLowercase}-api" + ) { + if (project.name.endsWith("-server")) { + add("api", project(":${project.toothpick.forkNameLowercase}-api")) + } + return@forEach + } + + when (scope) { + "compile", null -> add("api", dependencyString) + "provided" -> { + add("compileOnly", dependencyString) + add("testImplementation", dependencyString) + } + "runtime" -> add("runtimeOnly", dependencyString) + "test" -> add("testImplementation", dependencyString) + } + } +} diff --git a/buildSrc/src/main/kotlin/InitTasks.kt b/buildSrc/src/main/kotlin/InitTasks.kt new file mode 100644 index 000000000..4104022c7 --- /dev/null +++ b/buildSrc/src/main/kotlin/InitTasks.kt @@ -0,0 +1,68 @@ +import org.gradle.api.Project +import task.createApplyPatchesTask +import task.createImportMCDevTask +import task.createInitGitSubmodulesTask +import task.createPaperclipTask +import task.createRebuildPatchesTask +import task.createSetupUpstreamTask +import task.createUpdateUpstreamTask +import task.createUpstreamCommitTask + +@Suppress("UNUSED_VARIABLE") +internal fun Project.initToothpickTasks() { + if (project.hasProperty("fast")) { + gradle.taskGraph.whenReady { + gradle.taskGraph.allTasks.filter { + it.name == "test" || it.name.contains("javadoc", ignoreCase = true) + }.forEach { + it.onlyIf { false } + } + } + } + + tasks.getByName("build") { + doFirst { + val readyToBuild = + upstreamDir.resolve(".git").exists() + && toothpick.subprojects.values.all { it.projectDir.exists() && it.baseDir.exists() } + if (!readyToBuild) { + error("Workspace has not been setup. Try running `./gradlew applyPatches` first") + } + } + } + + val initGitSubmodules = createInitGitSubmodulesTask() + + val setupUpstream = createSetupUpstreamTask { + dependsOn(initGitSubmodules) + } + + val importMCDev = createImportMCDevTask { + mustRunAfter(setupUpstream) + } + + val paperclip = createPaperclipTask { + dependsOn(tasks.getByName("build")) + dependsOn(subprojects.map { it.tasks.getByName("build") }) + } + + val applyPatches = createApplyPatchesTask { + // If Paper has not been setup yet or if we modified the submodule (i.e. upstream update), patch + if (!lastUpstream.exists() + || !upstreamDir.resolve(".git").exists() + || lastUpstream.readText() != gitHash(upstreamDir) + ) { + dependsOn(setupUpstream) + } + mustRunAfter(setupUpstream) + dependsOn(importMCDev) + } + + val rebuildPatches = createRebuildPatchesTask() + + val updateUpstream = createUpdateUpstreamTask { + finalizedBy(setupUpstream) + } + + val upstreamCommit = createUpstreamCommitTask() +} diff --git a/buildSrc/src/main/kotlin/MCDevImports.kt b/buildSrc/src/main/kotlin/MCDevImports.kt new file mode 100644 index 000000000..d4be94165 --- /dev/null +++ b/buildSrc/src/main/kotlin/MCDevImports.kt @@ -0,0 +1,28 @@ +/** + * This is the set of extra NMS files which will be imported as part of the patch process + * + * See `./Paper/work/Minecraft/$MCVER/net/minecraft/server` for a list of possible files + * + * The `.java` extension is always assumed and should be excluded + * + * NOTE: Do not commit changes to this set! Instead make changes, rebuild patches, and commit the modified patches. + * Files already modified in existing patches will be imported automatically. + */ +val nmsImports = setOf( + // ex: + //"EntityZombieVillager" +) + +data class LibraryImport(val group: String, val library: String, val prefix: String, val file: String) + +/** + * This is the set of extra files to import into the server workspace from libraries + * + * Changes to this set should be committed to the repo, as these won't be automatically imported. + */ +val libraryImports = setOf( + LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier", "CommandDispatcher"), + LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/tree", "LiteralCommandNode"), + LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/suggestion", "SuggestionsBuilder"), + LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/arguments", "BoolArgumentType") +) diff --git a/buildSrc/src/main/kotlin/Toothpick.kt b/buildSrc/src/main/kotlin/Toothpick.kt new file mode 100644 index 000000000..c58299627 --- /dev/null +++ b/buildSrc/src/main/kotlin/Toothpick.kt @@ -0,0 +1,9 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.create + +class Toothpick : Plugin { + override fun apply(project: Project) { + project.extensions.create("toothpick", project.objects) + } +} diff --git a/buildSrc/src/main/kotlin/ToothpickExtension.kt b/buildSrc/src/main/kotlin/ToothpickExtension.kt new file mode 100644 index 000000000..3afc3d118 --- /dev/null +++ b/buildSrc/src/main/kotlin/ToothpickExtension.kt @@ -0,0 +1,52 @@ +import org.gradle.api.Project +import org.gradle.api.model.ObjectFactory +import java.io.File +import java.util.Locale + +@Suppress("UNUSED_PARAMETER") +open class ToothpickExtension(objects: ObjectFactory) { + lateinit var project: Project + lateinit var forkName: String + val forkNameLowercase + get() = forkName.toLowerCase(Locale.ENGLISH) + lateinit var forkVersion: String + lateinit var groupId: String + lateinit var minecraftVersion: String + lateinit var nmsRevision: String + + lateinit var upstream: String + val upstreamLowercase + get() = upstream.toLowerCase(Locale.ENGLISH) + + lateinit var serverProject: ToothpickSubproject + fun server(receiver: ToothpickSubproject.() -> Unit) { + serverProject = ToothpickSubproject() + receiver(serverProject) + } + + lateinit var apiProject: ToothpickSubproject + fun api(receiver: ToothpickSubproject.() -> Unit) { + apiProject = ToothpickSubproject() + receiver(apiProject) + } + + val subprojects: Map + get() = if (::forkName.isInitialized) mapOf( + "$forkName-API" to apiProject, + "$forkName-Server" to serverProject + ) else emptyMap() + + val paperDir: File by lazy { + if (upstream == "Paper") { + project.upstreamDir + } else { + project.upstreamDir.walk().find { + it.name == "Paper" && it.isDirectory + && it.resolve("work/Minecraft/${minecraftVersion}").exists() + } ?: error("Failed to find Paper directory!") + } + } + + val paperWorkDir: File + get() = paperDir.resolve("work/Minecraft/${minecraftVersion}") +} diff --git a/buildSrc/src/main/kotlin/ToothpickExtensions.kt b/buildSrc/src/main/kotlin/ToothpickExtensions.kt new file mode 100644 index 000000000..804979178 --- /dev/null +++ b/buildSrc/src/main/kotlin/ToothpickExtensions.kt @@ -0,0 +1,30 @@ +import org.gradle.api.Project +import org.gradle.kotlin.dsl.findByType +import java.io.File +import java.nio.file.Path + +val Project.toothpick: ToothpickExtension + get() = rootProject.extensions.findByType(ToothpickExtension::class)!! + +fun Project.toothpick(receiver: ToothpickExtension.() -> Unit) { + toothpick.project = this + receiver(toothpick) + allprojects { + group = toothpick.groupId + version = "${toothpick.minecraftVersion}-${toothpick.nmsRevision}" + } + configureSubprojects() + initToothpickTasks() +} + +val Project.lastUpstream: File + get() = rootProject.projectDir.resolve("last-${toothpick.upstreamLowercase}") + +val Project.rootProjectDir: File + get() = rootProject.projectDir + +val Project.upstreamDir: File + get() = rootProject.projectDir.resolve(toothpick.upstream) + +val Project.projectPath: Path + get() = projectDir.toPath() diff --git a/buildSrc/src/main/kotlin/ToothpickSubproject.kt b/buildSrc/src/main/kotlin/ToothpickSubproject.kt new file mode 100644 index 000000000..df34f33e9 --- /dev/null +++ b/buildSrc/src/main/kotlin/ToothpickSubproject.kt @@ -0,0 +1,20 @@ +import org.gradle.api.Project +import java.io.File + +class ToothpickSubproject { + lateinit var project: Project + + val baseDir: File by lazy { + val name = project.name + val upstream = project.toothpick.upstream + val suffix = if (name.endsWith("server")) "Server" else "API" + project.upstreamDir.resolve("$upstream-$suffix") + } + val projectDir: File + get() = project.projectDir + lateinit var patchesDir: File + + operator fun component1(): File = baseDir + operator fun component2(): File = projectDir + operator fun component3(): File = patchesDir +} diff --git a/buildSrc/src/main/kotlin/Util.kt b/buildSrc/src/main/kotlin/Util.kt new file mode 100644 index 000000000..c0942a97a --- /dev/null +++ b/buildSrc/src/main/kotlin/Util.kt @@ -0,0 +1,86 @@ +import org.gradle.api.Project +import java.io.File +import java.util.LinkedList +import kotlin.streams.asSequence + +data class CmdResult(val exitCode: Int, val output: String?) + +fun Project.cmd( + vararg args: String, + dir: File = rootProject.projectDir, + printOut: Boolean = false +): CmdResult { + val process = ProcessBuilder() + .command(*args) + .redirectErrorStream(true) + .directory(dir) + .start() + val output = process.inputStream.bufferedReader().use { reader -> + reader.lines().asSequence() + .onEach { + if (printOut) { + logger.lifecycle(it) + } else { + logger.debug(it) + } + } + .toCollection(LinkedList()) + .joinToString(separator = "\n") + } + val exit = process.waitFor() + return CmdResult(exit, output) +} + +fun ensureSuccess( + cmd: CmdResult, + errorHandler: CmdResult.() -> Unit = {} +): String? { + val (exit, output) = cmd + if (exit != 0) { + errorHandler(cmd) + error("Failed to run command, exit code is $exit") + } + return output +} + +fun Project.gitCmd( + vararg args: String, + dir: File = rootProject.projectDir, + printOut: Boolean = false +): CmdResult = + cmd("git", *args, dir = dir, printOut = printOut) + +fun Project.bashCmd( + vararg args: String, + dir: File = rootProject.projectDir, + printOut: Boolean = false +): CmdResult = + cmd("bash", "-c", *args, dir = dir, printOut = printOut) + +internal fun String.applyReplacements(replacements: Map): String { + var result = this + for ((key, value) in replacements) { + result = result.replace("\${$key}", value) + } + return result +} + +private fun Project.gitSigningEnabled(repo: File): Boolean = + gitCmd("config", "commit.gpgsign", dir = repo).output?.toBoolean() == true + +internal fun Project.temporarilyDisableGitSigning(repo: File): Boolean { + val isCurrentlyEnabled = gitSigningEnabled(repo) + if (isCurrentlyEnabled) { + gitCmd("config", "commit.gpgsign", "false", dir = repo) + } + return isCurrentlyEnabled +} + +internal fun Project.reEnableGitSigning(repo: File) { + gitCmd("config", "commit.gpgsign", "true", dir = repo) +} + +fun Project.gitHash(repo: File): String = + gitCmd("rev-parse", "HEAD", dir = repo).output ?: "" + +val jenkins = System.getenv("JOB_NAME") != null diff --git a/buildSrc/src/main/kotlin/task/ApplyPatches.kt b/buildSrc/src/main/kotlin/task/ApplyPatches.kt new file mode 100644 index 000000000..a4f423e7d --- /dev/null +++ b/buildSrc/src/main/kotlin/task/ApplyPatches.kt @@ -0,0 +1,52 @@ +package task + +import ensureSuccess +import gitCmd +import org.gradle.api.Project +import org.gradle.api.Task +import reEnableGitSigning +import taskGroup +import temporarilyDisableGitSigning +import toothpick +import java.nio.file.Files + +internal fun Project.createApplyPatchesTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("applyPatches") { + receiver(this) + group = taskGroup + doLast { + for ((name, subproject) in toothpick.subprojects) { + val (sourceRepo, projectDir, patchesDir) = subproject + + // Reset or initialize subproject + logger.lifecycle(">>> Resetting subproject $name") + if (projectDir.exists()) { + ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = projectDir)) + } else { + ensureSuccess(gitCmd("clone", sourceRepo.absolutePath, projectDir.absolutePath)) + } + logger.lifecycle(">>> Done resetting subproject $name") + + // Apply patches + val patchPaths = Files.newDirectoryStream(patchesDir.toPath()) + .map { it.toFile() } + .filter { it.name.endsWith(".patch") } + .sorted() + .takeIf { it.isNotEmpty() } ?: continue + val patches = patchPaths.map { it.absolutePath }.toTypedArray() + + val wasGitSigningEnabled = temporarilyDisableGitSigning(projectDir) + + logger.lifecycle(">>> Applying patches to $name") + + val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace", *patches) + ensureSuccess(gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true)) { + if (wasGitSigningEnabled) reEnableGitSigning(projectDir) + } + + if (wasGitSigningEnabled) reEnableGitSigning(projectDir) + logger.lifecycle(">>> Done applying patches to $name") + } + } +} diff --git a/buildSrc/src/main/kotlin/task/ImportMCDev.kt b/buildSrc/src/main/kotlin/task/ImportMCDev.kt new file mode 100644 index 000000000..a126b7e24 --- /dev/null +++ b/buildSrc/src/main/kotlin/task/ImportMCDev.kt @@ -0,0 +1,84 @@ +package task + +import LibraryImport +import ensureSuccess +import gitCmd +import internalTaskGroup +import libraryImports +import nmsImports +import org.gradle.api.Project +import org.gradle.api.Task +import toothpick + +internal fun Project.createImportMCDevTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("importMCDev") { + receiver(this) + group = internalTaskGroup + val upstreamServer = toothpick.serverProject.baseDir + val importLog = arrayListOf("Extra mc-dev imports") + + fun importNMS(className: String) { + logger.lifecycle("Importing n.m.s.$className") + importLog.add("Imported n.m.s.$className") + val source = toothpick.paperWorkDir.resolve("spigot/net/minecraft/server/$className.java") + if (!source.exists()) error("Missing NMS: $className") + val target = upstreamServer.resolve("src/main/java/net/minecraft/server/$className.java") + source.copyTo(target) + } + + fun importLibrary(import: LibraryImport) { + val (group, lib, prefix, file) = import + logger.lifecycle("Importing $group.$lib $prefix/$file") + importLog.add("Imported $group.$lib $prefix/$file") + val source = toothpick.paperWorkDir.resolve("libraries/$group/$lib/$prefix/$file.java") + if (!source.exists()) error("Missing Base: $lib $prefix/$file") + val targetDir = upstreamServer.resolve("src/main/java/$prefix") + val target = targetDir.resolve("$file.java") + targetDir.mkdirs() + source.copyTo(target) + } + + doLast { + logger.lifecycle(">>> Importing mc-dev") + val lastCommitIsMCDev = gitCmd( + "log", "-1", "--oneline", + dir = upstreamServer + ).output?.contains("Extra mc-dev imports") == true + if (lastCommitIsMCDev) { + ensureSuccess( + gitCmd( + "reset", "--hard", "origin/master", + dir = upstreamServer, + printOut = true + ) + ) + } + + (toothpick.serverProject.patchesDir.listFiles() ?: error("No patches in server?")).asSequence() + .flatMap { it.readLines().asSequence() } + .filter { it.startsWith("+++ b/src/main/java/net/minecraft/server/") } + .distinct() + .map { it.substringAfter("/server/").substringBefore(".java") } + .filter { !upstreamServer.resolve("src/main/java/net/minecraft/server/$it.java").exists() } + .map { toothpick.paperWorkDir.resolve("spigot/net/minecraft/server/$it.java") } + .filter { + val exists = it.exists() + if (!it.exists()) logger.lifecycle("NMS ${it.nameWithoutExtension} is either missing, or is a new file added through a patch") + exists + } + .map { it.nameWithoutExtension } + .forEach(::importNMS) + + // Imports from MCDevImports.kt + nmsImports.forEach(::importNMS) + libraryImports.forEach(::importLibrary) + + val add = gitCmd("add", ".", "-A", dir = upstreamServer).exitCode == 0 + val commit = gitCmd("commit", "-m", importLog.joinToString("\n"), dir = upstreamServer).exitCode == 0 + if (!add || !commit) { + logger.lifecycle(">>> Didn't import any extra files") + } + logger.lifecycle(">>> Done importing mc-dev") + } +} diff --git a/buildSrc/src/main/kotlin/task/InitGitSubmodules.kt b/buildSrc/src/main/kotlin/task/InitGitSubmodules.kt new file mode 100644 index 000000000..84e56585d --- /dev/null +++ b/buildSrc/src/main/kotlin/task/InitGitSubmodules.kt @@ -0,0 +1,21 @@ +package task + +import gitCmd +import org.gradle.api.Project +import org.gradle.api.Task +import taskGroup +import upstreamDir + +internal fun Project.createInitGitSubmodulesTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("initGitSubmodules") { + receiver(this) + group = taskGroup + onlyIf { !upstreamDir.resolve(".git").exists() } + doLast { + val exit = gitCmd("submodule", "update", "--init", "--recursive", printOut = true).exitCode + if (exit != 0) { + error("Failed to checkout git submodules: git exited with code $exit") + } + } +} diff --git a/buildSrc/src/main/kotlin/task/Paperclip.kt b/buildSrc/src/main/kotlin/task/Paperclip.kt new file mode 100644 index 000000000..666473cf9 --- /dev/null +++ b/buildSrc/src/main/kotlin/task/Paperclip.kt @@ -0,0 +1,39 @@ +package task + +import cmd +import ensureSuccess +import jenkins +import org.gradle.api.Project +import org.gradle.api.Task +import rootProjectDir +import taskGroup +import toothpick + +internal fun Project.createPaperclipTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("paperclip") { + receiver(this) + group = taskGroup + doLast { + val workDir = toothpick.paperDir.resolve("work") + val paperclipDir = workDir.resolve("Paperclip") + val vanillaJarPath = + workDir.resolve("Minecraft/${toothpick.minecraftVersion}/${toothpick.minecraftVersion}.jar").absolutePath + val patchedJarPath = toothpick.serverProject.projectDir.resolve( + "build/libs/${toothpick.forkNameLowercase}-server-$version-all.jar" + ).absolutePath + logger.lifecycle(">>> Building paperclip") + val paperclipCmd = arrayListOf( + "mvn", "clean", "package", + "-Dmcver=${toothpick.minecraftVersion}", + "-Dpaperjar=$patchedJarPath", + "-Dvanillajar=$vanillaJarPath" + ) + if (jenkins) paperclipCmd.add("-Dstyle.color=never") + ensureSuccess(cmd(*paperclipCmd.toTypedArray(), dir = paperclipDir, printOut = true)) + val paperClip = paperclipDir.resolve("assembly/target/paperclip-${toothpick.minecraftVersion}.jar") + val destination = rootProjectDir.resolve("${toothpick.forkNameLowercase}-paperclip.jar") + paperClip.copyTo(destination, overwrite = true) + logger.lifecycle(">>> ${toothpick.forkNameLowercase}-paperclip.jar saved to root project directory") + } +} diff --git a/buildSrc/src/main/kotlin/task/RebuildPatches.kt b/buildSrc/src/main/kotlin/task/RebuildPatches.kt new file mode 100644 index 000000000..157cfe039 --- /dev/null +++ b/buildSrc/src/main/kotlin/task/RebuildPatches.kt @@ -0,0 +1,45 @@ +package task + +import ensureSuccess +import gitCmd +import org.gradle.api.Project +import org.gradle.api.Task +import taskGroup +import toothpick + +@Suppress("UNUSED_VARIABLE") +internal fun Project.createRebuildPatchesTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("rebuildPatches") { + receiver(this) + group = taskGroup + doLast { + for ((name, subproject) in toothpick.subprojects) { + val (sourceRepo, projectDir, patchesDir) = subproject + + if (!patchesDir.exists()) { + patchesDir.mkdirs() + } + + logger.lifecycle(">>> Rebuilding patches for $name") + + // Nuke old patches + patchesDir.listFiles() + ?.filter { it.name.endsWith(".patch") } + ?.forEach { it.delete() } + + // And generate new + ensureSuccess( + gitCmd( + "format-patch", + "--no-stat", "--zero-commit", "--full-index", "--no-signature", "-N", + "-o", patchesDir.absolutePath, "origin/master", + dir = projectDir, + printOut = true + ) + ) + + logger.lifecycle(">>> Done rebuilding patches for $name") + } + } +} diff --git a/buildSrc/src/main/kotlin/task/SetupUpstream.kt b/buildSrc/src/main/kotlin/task/SetupUpstream.kt new file mode 100644 index 000000000..942a049f6 --- /dev/null +++ b/buildSrc/src/main/kotlin/task/SetupUpstream.kt @@ -0,0 +1,29 @@ +package task + +import bashCmd +import gitHash +import lastUpstream +import org.gradle.api.Project +import org.gradle.api.Task +import taskGroup +import toothpick +import upstreamDir + +internal fun Project.createSetupUpstreamTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("setupUpstream") { + receiver(this) + group = taskGroup + doLast { + // this whole thing assumes we're forking either paper or a byof project atm + val result = bashCmd( + "./${toothpick.upstreamLowercase} patch", + dir = upstreamDir, + printOut = true + ) + if (result.exitCode != 0) { + error("Failed to apply upstream patches: script exited with code ${result.exitCode}") + } + lastUpstream.writeText(gitHash(upstreamDir)) + } +} diff --git a/buildSrc/src/main/kotlin/task/UpdateUpstream.kt b/buildSrc/src/main/kotlin/task/UpdateUpstream.kt new file mode 100644 index 000000000..a0860998d --- /dev/null +++ b/buildSrc/src/main/kotlin/task/UpdateUpstream.kt @@ -0,0 +1,23 @@ +package task + +import ensureSuccess +import gitCmd +import org.gradle.api.Project +import org.gradle.api.Task +import rootProjectDir +import taskGroup +import toothpick +import upstreamDir + +internal fun Project.createUpdateUpstreamTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("updateUpstream") { + receiver(this) + group = taskGroup + doLast { + ensureSuccess(gitCmd("fetch", dir = upstreamDir, printOut = true)) + ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = upstreamDir, printOut = true)) + ensureSuccess(gitCmd("add", toothpick.upstream, dir = rootProjectDir, printOut = true)) + ensureSuccess(gitCmd("submodule", "update", "--init", "--recursive", dir = upstreamDir, printOut = true)) + } +} diff --git a/buildSrc/src/main/kotlin/task/UpstreamCommit.kt b/buildSrc/src/main/kotlin/task/UpstreamCommit.kt new file mode 100644 index 000000000..3d6696e56 --- /dev/null +++ b/buildSrc/src/main/kotlin/task/UpstreamCommit.kt @@ -0,0 +1,33 @@ +package task + +import ensureSuccess +import gitCmd +import org.gradle.api.Project +import org.gradle.api.Task +import taskGroup +import toothpick +import upstreamDir + +internal fun Project.createUpstreamCommitTask( + receiver: Task.() -> Unit = {} +): Task = tasks.create("upstreamCommit") { + receiver(this) + group = taskGroup + doLast { + val oldRev = ensureSuccess(gitCmd("ls-tree", "HEAD", toothpick.upstream)) + ?.substringAfter("commit ")?.substringBefore("\t") + val gitChangelog = + ensureSuccess(gitCmd("log", "--oneline", "$oldRev...HEAD", printOut = true, dir = upstreamDir)) { + logger.lifecycle("No upstream changes to commit?") + } + val commitMessage = """ + |Updated Upstream (${toothpick.upstream}) + | + |Upstream has released updates that appear to apply and compile correctly + | + |${toothpick.upstream} Changes: + |$gitChangelog + """.trimMargin() + ensureSuccess(gitCmd("commit", "-m", commitMessage, printOut = true)) + } +} diff --git a/current-paper b/current-paper deleted file mode 100644 index 5c569dfae..000000000 --- a/current-paper +++ /dev/null @@ -1 +0,0 @@ -1.16.4--8ff078813db86d42db9fd900c0f093f05b9594c4 diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..a5950be8c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.daemon=true +org.gradle.jvmargs=-Xmx2G diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..e708b1c02 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..4d9ca1649 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..4f906e0c8 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# 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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..107acd32c --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/patches/api/0003-Purpur-config-files.patch b/patches/api/0002-Purpur-config-files.patch similarity index 100% rename from patches/api/0003-Purpur-config-files.patch rename to patches/api/0002-Purpur-config-files.patch diff --git a/patches/api/0002-Rebrand.patch b/patches/api/0002-Rebrand.patch deleted file mode 100644 index 2dbb02e73..000000000 --- a/patches/api/0002-Rebrand.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 4 May 2019 00:57:16 -0500 -Subject: [PATCH] Rebrand - - -diff --git a/pom.xml b/pom.xml -index 4516ba097e8afc3e422efc368311fa66e967c05a..f0696d8c1dede705f6dd3fd0162864dfd42d2fdf 100644 ---- a/pom.xml -+++ b/pom.xml -@@ -1,20 +1,19 @@ -- - - 4.0.0 - -- com.tuinity -- tuinity-parent -+ net.pl3x.purpur -+ purpur-parent - dev-SNAPSHOT - ../pom.xml - - -- tuinity-api -+ purpur-api - 1.16.4-R0.1-SNAPSHOT - jar - -- Tuinity-API -- https://github.com/Spottedleaf/Tuinity -+ Purpur-API -+ https://github.com/pl3xgaming/Purpur - An enhanced plugin API for Minecraft servers. - - -@@ -149,7 +148,7 @@ - - - -- clean install -+ clean install javadoc:javadoc - - - net.md-5 -@@ -227,6 +226,14 @@ - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 -+ -+ -+ attach-javadocs -+ -+ jar -+ -+ -+ - - - https://guava.dev/releases/21.0/api/docs/ -@@ -234,6 +241,7 @@ - https://javadoc.io/doc/org.jetbrains/annotations-java5/19.0.0/ - https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.3/ - -+ -Xdoclint:none - - - diff --git a/patches/api/0004-Default-permissions.patch b/patches/api/0003-Default-permissions.patch similarity index 100% rename from patches/api/0004-Default-permissions.patch rename to patches/api/0003-Default-permissions.patch diff --git a/patches/api/0005-Allow-inventory-resizing.patch b/patches/api/0004-Allow-inventory-resizing.patch similarity index 100% rename from patches/api/0005-Allow-inventory-resizing.patch rename to patches/api/0004-Allow-inventory-resizing.patch diff --git a/patches/api/0006-Advancement-API.patch b/patches/api/0005-Advancement-API.patch similarity index 100% rename from patches/api/0006-Advancement-API.patch rename to patches/api/0005-Advancement-API.patch diff --git a/patches/api/0007-Llama-API.patch b/patches/api/0006-Llama-API.patch similarity index 100% rename from patches/api/0007-Llama-API.patch rename to patches/api/0006-Llama-API.patch diff --git a/patches/api/0008-AFK-API.patch b/patches/api/0007-AFK-API.patch similarity index 100% rename from patches/api/0008-AFK-API.patch rename to patches/api/0007-AFK-API.patch diff --git a/patches/api/0009-Bring-back-server-name.patch b/patches/api/0008-Bring-back-server-name.patch similarity index 100% rename from patches/api/0009-Bring-back-server-name.patch rename to patches/api/0008-Bring-back-server-name.patch diff --git a/patches/api/0010-ExecuteCommandEvent.patch b/patches/api/0009-ExecuteCommandEvent.patch similarity index 100% rename from patches/api/0010-ExecuteCommandEvent.patch rename to patches/api/0009-ExecuteCommandEvent.patch diff --git a/patches/api/0011-LivingEntity-safeFallDistance.patch b/patches/api/0010-LivingEntity-safeFallDistance.patch similarity index 100% rename from patches/api/0011-LivingEntity-safeFallDistance.patch rename to patches/api/0010-LivingEntity-safeFallDistance.patch diff --git a/patches/api/0012-Lagging-threshold.patch b/patches/api/0011-Lagging-threshold.patch similarity index 100% rename from patches/api/0012-Lagging-threshold.patch rename to patches/api/0011-Lagging-threshold.patch diff --git a/patches/api/0013-ItemFactory-getMonsterEgg.patch b/patches/api/0012-ItemFactory-getMonsterEgg.patch similarity index 100% rename from patches/api/0013-ItemFactory-getMonsterEgg.patch rename to patches/api/0012-ItemFactory-getMonsterEgg.patch diff --git a/patches/api/0014-PlayerSetSpawnerTypeWithEggEvent.patch b/patches/api/0013-PlayerSetSpawnerTypeWithEggEvent.patch similarity index 100% rename from patches/api/0014-PlayerSetSpawnerTypeWithEggEvent.patch rename to patches/api/0013-PlayerSetSpawnerTypeWithEggEvent.patch diff --git a/patches/api/0015-EMC-MonsterEggSpawnEvent.patch b/patches/api/0014-EMC-MonsterEggSpawnEvent.patch similarity index 100% rename from patches/api/0015-EMC-MonsterEggSpawnEvent.patch rename to patches/api/0014-EMC-MonsterEggSpawnEvent.patch diff --git a/patches/api/0016-Villager-resetOffers.patch b/patches/api/0015-Villager-resetOffers.patch similarity index 100% rename from patches/api/0016-Villager-resetOffers.patch rename to patches/api/0015-Villager-resetOffers.patch diff --git a/patches/api/0017-PaperPR-PlayerItemCooldownEvent.patch b/patches/api/0016-PaperPR-PlayerItemCooldownEvent.patch similarity index 100% rename from patches/api/0017-PaperPR-PlayerItemCooldownEvent.patch rename to patches/api/0016-PaperPR-PlayerItemCooldownEvent.patch diff --git a/patches/api/0018-EntityMoveEvent.patch b/patches/api/0017-EntityMoveEvent.patch similarity index 100% rename from patches/api/0018-EntityMoveEvent.patch rename to patches/api/0017-EntityMoveEvent.patch diff --git a/patches/api/0019-Player-invulnerabilities.patch b/patches/api/0018-Player-invulnerabilities.patch similarity index 100% rename from patches/api/0019-Player-invulnerabilities.patch rename to patches/api/0018-Player-invulnerabilities.patch diff --git a/patches/api/0020-Anvil-API.patch b/patches/api/0019-Anvil-API.patch similarity index 100% rename from patches/api/0020-Anvil-API.patch rename to patches/api/0019-Anvil-API.patch diff --git a/patches/api/0021-ItemStack-convenience-methods.patch b/patches/api/0020-ItemStack-convenience-methods.patch similarity index 100% rename from patches/api/0021-ItemStack-convenience-methods.patch rename to patches/api/0020-ItemStack-convenience-methods.patch diff --git a/patches/api/0022-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch b/patches/api/0021-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch similarity index 100% rename from patches/api/0022-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch rename to patches/api/0021-Phantoms-attracted-to-crystals-and-crystals-shoot-ph.patch diff --git a/patches/api/0023-ChatColor-conveniences.patch b/patches/api/0022-ChatColor-conveniences.patch similarity index 100% rename from patches/api/0023-ChatColor-conveniences.patch rename to patches/api/0022-ChatColor-conveniences.patch diff --git a/patches/api/0024-DragonEggPlaceEvent.patch b/patches/api/0023-DragonEggPlaceEvent.patch similarity index 100% rename from patches/api/0024-DragonEggPlaceEvent.patch rename to patches/api/0023-DragonEggPlaceEvent.patch diff --git a/patches/api/0025-Ridables.patch b/patches/api/0024-Ridables.patch similarity index 100% rename from patches/api/0025-Ridables.patch rename to patches/api/0024-Ridables.patch diff --git a/patches/api/0026-Configurable-permission-message-upgrades.patch b/patches/api/0025-Configurable-permission-message-upgrades.patch similarity index 100% rename from patches/api/0026-Configurable-permission-message-upgrades.patch rename to patches/api/0025-Configurable-permission-message-upgrades.patch diff --git a/patches/api/0027-LivingEntity-broadcastItemBreak.patch b/patches/api/0026-LivingEntity-broadcastItemBreak.patch similarity index 100% rename from patches/api/0027-LivingEntity-broadcastItemBreak.patch rename to patches/api/0026-LivingEntity-broadcastItemBreak.patch diff --git a/patches/api/0028-Item-entity-immunities.patch b/patches/api/0027-Item-entity-immunities.patch similarity index 100% rename from patches/api/0028-Item-entity-immunities.patch rename to patches/api/0027-Item-entity-immunities.patch diff --git a/patches/api/0029-Spigot-Improve-output-of-plugins-command.patch b/patches/api/0028-Spigot-Improve-output-of-plugins-command.patch similarity index 100% rename from patches/api/0029-Spigot-Improve-output-of-plugins-command.patch rename to patches/api/0028-Spigot-Improve-output-of-plugins-command.patch diff --git a/patches/api/0030-Add-option-to-disable-zombie-aggressiveness-towards-.patch b/patches/api/0029-Add-option-to-disable-zombie-aggressiveness-towards-.patch similarity index 100% rename from patches/api/0030-Add-option-to-disable-zombie-aggressiveness-towards-.patch rename to patches/api/0029-Add-option-to-disable-zombie-aggressiveness-towards-.patch diff --git a/patches/api/0031-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch b/patches/api/0030-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch similarity index 100% rename from patches/api/0031-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch rename to patches/api/0030-Add-predicate-to-recipe-s-ExactChoice-ingredient.patch diff --git a/patches/api/0032-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch b/patches/api/0031-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch similarity index 100% rename from patches/api/0032-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch rename to patches/api/0031-Add-critical-hit-check-to-EntityDamagedByEntityEvent.patch diff --git a/patches/api/0033-Left-handed-API.patch b/patches/api/0032-Left-handed-API.patch similarity index 100% rename from patches/api/0033-Left-handed-API.patch rename to patches/api/0032-Left-handed-API.patch diff --git a/patches/api/0034-Alphabetize-in-game-plugins-list.patch b/patches/api/0033-Alphabetize-in-game-plugins-list.patch similarity index 100% rename from patches/api/0034-Alphabetize-in-game-plugins-list.patch rename to patches/api/0033-Alphabetize-in-game-plugins-list.patch diff --git a/patches/api/0035-Rabid-Wolf-API.patch b/patches/api/0034-Rabid-Wolf-API.patch similarity index 100% rename from patches/api/0035-Rabid-Wolf-API.patch rename to patches/api/0034-Rabid-Wolf-API.patch diff --git a/patches/server/0002-Rebrand.patch b/patches/server/0002-Rebrand.patch index 3fdd4d779..a9c6b207e 100644 --- a/patches/server/0002-Rebrand.patch +++ b/patches/server/0002-Rebrand.patch @@ -5,85 +5,22 @@ Subject: [PATCH] Rebrand diff --git a/pom.xml b/pom.xml -index 78c2a8bbcc0132f891c8aa545529d20aa0d9eb57..0c982c3f0eb9430fcec47477de1babe6f253f2aa 100644 +index 78c2a8bbcc0132f891c8aa545529d20aa0d9eb57..422bed88a0860f768e162a38a1c16265451f5990 100644 --- a/pom.xml +++ b/pom.xml -@@ -1,11 +1,11 @@ - - 4.0.0 -- tuinity -+ purpur - jar - 1.16.4-R0.1-SNAPSHOT -- Tuinity-Server -- https://github.com/Spottedleaf/Tuinity -+ Purpur-Server -+ https://github.com/pl3xgaming/Purpur - - - -@@ -18,16 +18,16 @@ - - - -- com.tuinity -- tuinity-parent -+ net.pl3x.purpur -+ purpur-parent - dev-SNAPSHOT - ../pom.xml - +@@ -26,8 +26,10 @@ - com.tuinity - tuinity-api ++ + net.pl3x.purpur + purpur-api ++ ${project.version} compile -@@ -50,6 +50,20 @@ - ${minecraft.version}-SNAPSHOT - compile - -+ -+ -+ org.mozilla -+ rhino -+ 1.7.7.1 -+ compile -+ -+ -+ cat.inspiracio -+ rhino-js-engine -+ 1.7.7.1 -+ compile -+ -+ - - net.minecrell - terminalconsoleappender -@@ -175,15 +189,15 @@ - - - -- tuinity-${minecraft.version} -- install -+ purpur-${minecraft.version} -+ clean install - - - com.lukegb.mojo - gitdescribe-maven-plugin - 1.3 - -- git-Tuinity- -+ git-Purpur- - .. - - diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java index 74ed02fa9296583977bb721014b10ff8b708b43c..c1280478ee4565003883df9607d4a8a0e8fe4faa 100644 --- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 61b8b038f..000000000 --- a/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - 4.0.0 - - net.pl3x.purpur - purpur-parent - dev-SNAPSHOT - pom - Purpur (Parent) - - - - aikar - https://repo.aikar.co/content/groups/aikar/ - - - velocity-snapshots - https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/ - - - - - clean install - ${project.artifactId} - - - Purpur-API - Purpur-Server - - diff --git a/purpur b/purpur deleted file mode 100755 index ae50ef9a4..000000000 --- a/purpur +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env bash - -# get base dir regardless of execution location -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -SOURCE=$([[ "$SOURCE" == /* ]] && echo "$SOURCE" || echo "$PWD/${SOURCE#./}") -basedir=$(dirname "$SOURCE") -. "$basedir"/scripts/init.sh - -purpurstash() { - STASHED=$(git stash) -} - -purpurunstash() { - if [[ "$STASHED" != "No local changes to save" ]]; then - git stash pop - fi -} - -case "$1" in -"p" | "patch" | "apply") - ( - set -e - cd "$basedir" - scripts/apply.sh "$basedir" - ) - ;; -"b" | "bu" | "build") - ( - basedir - mvn -N install - cd Purpur-API - mvn -e clean install - cd ../Paper/Paper-MojangAPI - mvn -e clean install - cd ../../Purpur-Server - mvn -e clean install - ) - ;; - -"rb" | "rbp" | "rebuild") - ( - set -e - cd "$basedir" - scripts/rebuildpatches.sh "$basedir" - ) - ;; -"am" | "amend") - ( - cd "$basedir"/Purpur-API/ - git add . - git commit --amend --no-edit - cd "$basedir"/Purpur-Server/ - git add . - git commit --amend --no-edit - cd "$basedir" - scripts/rebuildpatches.sh "$basedir" - ) - ;; -"up" | "upstream") - ( - cd "$basedir" - scripts/upstream.sh "$2" - ) - ;; -"jar" | "purpurclip") - ( - basedir - cd "$basedir" - if [ "$2" != "fast" ]; then - scripts/upstream.sh - ./scripts/apply.sh "$basedir" - cd "$basedir" - mvn -N install - cd Purpur-API - mvn -e clean install - cd ../Paper/Paper-MojangAPI - mvn -e clean install - cd ../../Purpur-Server - mvn -e clean install - cd "$basedir" - fi - ./scripts/purpurclip.sh - ) - ;; -*) - echo "Purpur build tool command. This provides a variety of commands to build and manage the Purpur build" - echo "environment. For all of the functionality of this command to be available, you must first run the" - echo "'setup' command. View below for details. For essential building and patching, you do not need to do the setup." - echo "" - echo " Normal commands:" - echo " * p, patch | Apply all patches to top of Paper without building it" - echo " * b, build | Build Purpur API and Server" - echo " * rb, rebuild | Rebuild patches" - echo " * am, amend | Amend current edits to last patches" - echo " * up, upstream | Build Paper upstream, pass arg up to update paper" - echo " * jar, purpurclip | Apply all patches and build the project, purpurclip.jar will be output" - ;; -esac - -unset -f purpurstash -unset -f purpurunstash diff --git a/scripts/apply.sh b/scripts/apply.sh deleted file mode 100755 index bf80b9424..000000000 --- a/scripts/apply.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -# get base dir regardless of execution location -# resolve shell-specifics -case "$(echo "$SHELL" | sed -E 's|/usr(/local)?||g')" in - "/bin/zsh") - RCPATH="$HOME/.zshrc" - SOURCE="${BASH_SOURCE[0]:-${(%):-%N}}" - ;; - *) - RCPATH="$HOME/.bashrc" - if [[ -f "$HOME/.bash_aliases" ]]; then - RCPATH="$HOME/.bash_aliases" - fi - SOURCE="${BASH_SOURCE[0]}" - ;; -esac - -# get base dir regardless of execution location - -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -. "$(dirname "$SOURCE")/init.sh" -PS1="$" - -paperVer=$(cat current-paper) -gpgsign="$(git config commit.gpgsign || echo "false")" -echo "Rebuilding Forked projects.... " -function applyPatch { - what=$1 - what_name=$(basename "$what") - target=$2 - branch=$3 - patch_folder=$4 - - cd "$basedir/$what" || exit - git fetch --all - git branch -f upstream "$branch" >/dev/null - - cd "$basedir" || exit - if [ ! -d "$basedir/$target" ]; then - mkdir "$basedir/$target" - cd "$basedir/$target" || exit - git init - git remote add origin "$5" - cd "$basedir" || exit - fi - cd "$basedir/$target" || exit - - # Disable GPG signing before AM, slows things down and doesn't play nicely. - # There is also zero rational or logical reason to do so for these sub-repo AMs. - # Calm down kids, it's re-enabled (if needed) immediately after, pass or fail. - git config commit.gpgsign false - - echo "Resetting $target to $what_name..." - git remote rm upstream > /dev/null 2>&1 - git remote add upstream "$basedir"/"$what" >/dev/null 2>&1 - git checkout master 2>/dev/null || git checkout -b master - git fetch upstream >/dev/null 2>&1 - git reset --hard upstream/upstream - echo " Applying patches to $target..." - git am --abort >/dev/null 2>&1 - if ! git am --3way --ignore-whitespace "$basedir/patches/$patch_folder/"*.patch - then - echo " Something did not apply cleanly to $target." - echo " Please review above details and finish the apply then" - echo " save the changes with rebuildPatches.sh" - exit 1 - else - echo " Patches applied cleanly to $target" - fi -} - -function enableCommitSigningIfNeeded { - if [[ "$gpgsign" == "true" ]]; then - git config commit.gpgsign true - fi -} - - echo "Importing MC-DEV" - ./scripts/importmcdev.sh "$basedir" || exit 1 -( - (applyPatch Paper/Paper-API Purpur-API HEAD api "$API_REPO" && - applyPatch Paper/Paper-Server Purpur-Server HEAD server "$SERVER_REPO") || exit 1 - enableCommitSigningIfNeeded -) || ( - echo "Failed to apply patches" - enableCommitSigningIfNeeded - exit 1 -) || exit 1 diff --git a/scripts/generatesources.sh b/scripts/generatesources.sh deleted file mode 100755 index 66ab42e41..000000000 --- a/scripts/generatesources.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -. "$(dirname "$SOURCE")/init.sh" - -cd "$basedir" || exit -paperVer=$(cat current-paper) - -minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4) -decompile="Paper/work/Minecraft/$minecraftversion/spigot" - -mkdir -p mc-dev/src/net/minecraft/server - -cd mc-dev || exit -if [ ! -d ".git" ]; then - git init -fi - -rm src/net/minecraft/server/*.java -cp "$basedir"/"$decompile"/net/minecraft/server/*.java src/net/minecraft/server - -base="$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server" -cd "$basedir"/mc-dev/src/net/minecraft/server/ || exit -for file in $(/bin/ls "$base"); do - if [ -f "$file" ]; then - rm -f "$file" - fi -done -cd "$basedir"/mc-dev || exit -git add . -A -git commit . -m "mc-dev" -git tag -a "$paperVer" -m "$paperVer" 2>/dev/null diff --git a/scripts/importmcdev.sh b/scripts/importmcdev.sh deleted file mode 100755 index fd6933818..000000000 --- a/scripts/importmcdev.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -. "$(dirname "$SOURCE")/init.sh" - -workdir=$basedir/Paper/work -minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4) -decompiledir=$workdir/Minecraft/$minecraftversion/spigot - -nms="net/minecraft/server" -export MODLOG="" -cd "$basedir" || exit - -function containsElement() { - local e - for e in "${@:2}"; do - [[ "$e" == "$1" ]] && return 0 - done - return 1 -} - -export importedmcdev="" -function import() { - if [ -f "$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server/$1.java" ]; then - echo "ALREADY IMPORTED $1" - return 0 - fi - export importedmcdev="$importedmcdev $1" - file="${1}.java" - target="$basedir/Paper/Paper-Server/src/main/java/$nms/$file" - base="$decompiledir/$nms/$file" - - if [[ ! -f "$target" ]]; then - export MODLOG="$MODLOG Imported $file from mc-dev\n" - echo "$(bashColor 1 32) Copying $(bashColor 1 34)$base $(bashColor 1 32)to$(bashColor 1 34) $target $(bashColorReset)" - cp "$base" "$target" - else - echo "$(bashColor 1 33) UN-NEEDED IMPORT STATEMENT:$(bashColor 1 34) $file $(bashColorReset)" - fi -} - -function importLibrary() { - group=$1 - lib=$2 - prefix=$3 - shift 3 - for file in "$@"; do - file="$prefix/$file" - target="$basedir/Paper/Paper-Server/src/main/java/$file" - targetdir=$(dirname "$target") - mkdir -p "${targetdir}" - base="$workdir/Minecraft/$minecraftversion/libraries/${group}/${lib}/$file" - if [ ! -f "$base" ]; then - echo "Missing $base" - exit 1 - fi - export MODLOG="$MODLOG Imported $file from $lib\n" - sed 's/\r$//' "$base" >"$target" || exit 1 - done -} - -( - cd Paper/Paper-Server/ || exit - lastlog=$(git log -1 --oneline) - if [[ "$lastlog" == *"Purpur-Extra mc-dev Imports"* ]]; then - git reset --hard HEAD^ - fi -) - -files=$(cat patches/server/* | grep "+++ b/src/main/java/net/minecraft/server/" | sort | uniq | sed 's/\+\+\+ b\/src\/main\/java\/net\/minecraft\/server\///g' | sed 's/.java//g') - -nonnms=$(cat patches/server/* | grep "create mode " | grep -Po "src/main/java/net/minecraft/server/(.*?).java" | sort | uniq | sed 's/src\/main\/java\/net\/minecraft\/server\///g' | sed 's/.java//g') - -for f in $files; do - containsElement "$f" "${nonnms[@]}" - if [ "$?" == "1" ]; then - if [ ! -f "$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server/$f.java" ]; then - if [ ! -f "$decompiledir/$nms/$f.java" ] && [ true ]; then - echo "$(bashColor 1 31) ERROR!!! Missing NMS$(bashColor 1 34) $f $(bashColorReset)" - else - import "$f" - fi - fi - fi -done - -############################################################################################### -############################################################################################### -#################### ADD TEMPORARY ADDITIONS HERE ############################################# -############################################################################################### -############################################################################################### - -# import Foo - -######################################################## -######################################################## -######################################################## -# LIBRARY IMPORTS -# These must always be mapped manually, no automatic stuff -# -# # group # lib # prefix # many files - -#importLibrary com.mojang datafixerupper com/mojang/datafixers/util Either.java -importLibrary com.mojang brigadier com/mojang/brigadier CommandDispatcher.java -importLibrary com.mojang brigadier com/mojang/brigadier/tree LiteralCommandNode.java -importLibrary com.mojang brigadier com/mojang/brigadier/suggestion SuggestionsBuilder.java -importLibrary com.mojang brigadier com/mojang/brigadier/arguments BoolArgumentType.java - -################ -( - cd Paper/Paper-Server/ || exit - rm -rf nms-patches - git add src -A - echo -e "Purpur-Extra mc-dev Imports\n\n$MODLOG" | git commit src -F - -) diff --git a/scripts/init.sh b/scripts/init.sh deleted file mode 100755 index 5c5e25b61..000000000 --- a/scripts/init.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -sourceBase=$(dirname "$SOURCE")/../ -cd "${basedir:-$sourceBase}" || exit - -basedir=$(pwd -P) -cd - || exit - -function bashColor() { - if [ "$2" ]; then - echo -e "\e[$1;$2m" - else - echo -e "\e[$1m" - fi -} -function bashColorReset() { - echo -e "\e[m" -} - -function cleanupPatches() { - cd "$1" || exit - for patch in *.patch; do - gitver=$(tail -n 2 "$patch" | grep -ve "^$" | tail -n 1) - diffs=$(git diff --staged "$patch" | grep -E "^(\+|\-)" | grep -Ev "(From [a-z0-9]{32,}|\-\-\- a|\+\+\+ b|.index|Date\: )") - - testver=$(echo "$diffs" | tail -n 2 | grep -ve "^$" | tail -n 1 | grep "$gitver") - if [ "x$testver" != "x" ]; then - diffs=$(echo "$diffs" | tail -n +3) - fi - - if [ "x$diffs" == "x" ]; then - git reset HEAD "$patch" >/dev/null - git checkout -- "$patch" >/dev/null - fi - done -} -function basedir() { - cd "$basedir" || exit -} -function gethead() { - ( - cd "$1" || exit - git log -1 --oneline - ) -} diff --git a/scripts/purpurclip.sh b/scripts/purpurclip.sh deleted file mode 100755 index 786dfd590..000000000 --- a/scripts/purpurclip.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -# Copied from https://github.com/PaperMC/Paper/blob/d54ce6c17fb7a35238d6b9f734d30a4289886773/scripts/paperclip.sh -# License from Paper applies to this file - -( - set -e - basedir="$(cd "$1" && pwd -P)" - workdir="$basedir/Paper/work" - mcver=$(grep <"$workdir/BuildData/info.json" minecraftVersion | cut -d '"' -f 4) - purpurjar="$basedir/Purpur-Server/target/purpur-$mcver.jar" - vanillajar="$workdir/Minecraft/$mcver/$mcver.jar" - - ( - cd "$workdir/Paperclip" - mvn clean package "-Dmcver=$mcver" "-Dpaperjar=$purpurjar" "-Dvanillajar=$vanillajar" - ) - cp "$workdir/Paperclip/assembly/target/paperclip-${mcver}.jar" "$basedir/purpurclip.jar" - - echo "" - echo "" - echo "" - echo "Build success!" - echo "Copied final jar to $(cd "$basedir" && pwd -P)/purpurclip.jar" -) || exit 1 diff --git a/scripts/rebuildpatches.sh b/scripts/rebuildpatches.sh deleted file mode 100755 index 987eb777e..000000000 --- a/scripts/rebuildpatches.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -# get base dir regardless of execution location -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -. "$(dirname "$SOURCE")/init.sh" - -PS1="$" -echo "Rebuilding patch files from current fork state..." -function savePatches() { - what=$1 - cd "$basedir"/"$what"/ || exit - - mkdir -p "$basedir"/patches/"$2" - if [ -d ".git/rebase-apply" ]; then - # in middle of a rebase, be smarter - echo "REBASE DETECTED - PARTIAL SAVE" - last=$(cat ".git/rebase-apply/last") - next=$(cat ".git/rebase-apply/next") - declare -a files=("$basedir/patches/$2/"*.patch) - for i in $(seq -f "%04g" 1 1 "$last"); do - if [ "$i" -lt "$next" ]; then - rm "${files[$(("$i" - 1))]}" - fi - done - else - rm "$basedir"/patches/"$2"/*.patch - fi - - git format-patch --no-signature --zero-commit --no-stat --full-index -N -o "$basedir/patches/$2" upstream/upstream - cd "$basedir" || exit - git add -A "$basedir"/patches/"$2" - echo " Patches saved for $what to patches/$2" -} - -savePatches Purpur-API api -savePatches Purpur-Server server diff --git a/scripts/upstream.sh b/scripts/upstream.sh deleted file mode 100755 index 31196c9b5..000000000 --- a/scripts/upstream.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# get base dir regardless of execution location -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -. "$(dirname "$SOURCE")/init.sh" - -if [[ "$1" == up* ]]; then - ( - cd "$basedir/Paper/" || exit - git fetch && git reset --hard origin/master - cd ../ - git add Paper - ) -fi - -paperVer=$(gethead Paper) -cd "$basedir/Paper/" || exit - -./paper patch - -cd "Paper-Server" || exit -mcVer=$(mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=minecraft_version | sed -n -e '/^\[.*\]/ !{ /^[0-9]/ { p; q } }') - -basedir -. "$basedir"/scripts/importmcdev.sh - -minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4) -version=$(echo -e "Paper: $paperVer\nmc-dev:$importedmcdev") -tag="${minecraftversion}-${mcVer}-$(echo -e "$version" | shasum | awk '{print $1}')" -echo "$tag" >"$basedir"/current-paper - -"$basedir"/scripts/generatesources.sh - -cd Paper/ || exit - -function tag() { - ( - cd "$1" || exit - if [ "$2" == "1" ]; then - git tag -d "$tag" 2>/dev/null - fi - echo -e "$(date)\n\n$version" | git tag -a "$tag" -F - 2>/dev/null - ) -} -echo "Tagging as $tag" -echo -e "$version" - -forcetag=0 -if [ "$(cat "$basedir"/current-paper)" != "$tag" ]; then - forcetag=1 -fi - -tag Paper-API $forcetag -tag Paper-Server $forcetag diff --git a/scripts/upstreamCommit.sh b/scripts/upstreamCommit.sh deleted file mode 100755 index ac6c662e0..000000000 --- a/scripts/upstreamCommit.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -( - set -e - PS1="$" - - function changelog() { - base=$(git ls-tree HEAD "$1" | cut -d' ' -f3 | cut -f1) - cd "$1" && git log --oneline "${base}"...HEAD - } - paper=$(changelog Paper) - - updated="" - logsuffix="" - if [ -n "$paper" ]; then - logsuffix="$logsuffix\n\nPaper Changes:\n$paper" - if [ -z "$updated" ]; then updated="Paper"; else updated="$updated/Paper"; fi - fi - disclaimer="Upstream has released updates that appear to apply and compile correctly" - - if [ -n "$1" ]; then - disclaimer=("$@") - fi - - log="${UP_LOG_PREFIX}Updated Upstream ($updated)\n\n${disclaimer[*]}${logsuffix}" - - echo -e "$log" | git commit -F - - -) || exit 1 diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..83f072a00 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,20 @@ +import java.util.Locale + +val forkName = "Purpur" +val forkNameLowercase = forkName.toLowerCase(Locale.ENGLISH) + +rootProject.name = forkNameLowercase + +setupSubproject("$forkNameLowercase-api") { + projectDir = File("$forkName-API") + buildFileName = "../subprojects/api.gradle.kts" +} +setupSubproject("$forkNameLowercase-server") { + projectDir = File("$forkName-Server") + buildFileName = "../subprojects/server.gradle.kts" +} + +inline fun setupSubproject(name: String, block: ProjectDescriptor.() -> Unit) { + include(name) + project(":$name").apply(block) +} diff --git a/subprojects/api.gradle.kts b/subprojects/api.gradle.kts new file mode 100644 index 000000000..51f0b4619 --- /dev/null +++ b/subprojects/api.gradle.kts @@ -0,0 +1,11 @@ +repositories { + loadRepositories(project) +} + +dependencies { + loadDependencies(project) +} + +java { + withJavadocJar() +} diff --git a/subprojects/server.gradle.kts b/subprojects/server.gradle.kts new file mode 100644 index 000000000..6799d88d6 --- /dev/null +++ b/subprojects/server.gradle.kts @@ -0,0 +1,8 @@ +repositories { + loadRepositories(project) +} + +dependencies { + loadDependencies(project) + implementation("cat.inspiracio", "rhino-js-engine", "1.7.7.1") +}