mirror of
https://github.com/sekwah41/Advanced-Portals.git
synced 2024-12-27 03:17:46 +01:00
8f29d203e2
If you are using 1.12 or lower you are unaffected as the features causing this issue were not implemented back then. Thanks to rooter.rs for notifying me of these issues as well as helping code and test a fix for this. Velocity was unaffected by this issue if you had the plugin on the proxy though due to the likelihood that may not be the case I have decided to disable this for everyone by default If you are on bungee you will 100% want to update to this version right away. For a full writeup by roote.rs see https://roote.rs/posts/advancedportals/
424 lines
14 KiB
Groovy
424 lines
14 KiB
Groovy
import com.google.gson.Gson
|
|
import org.apache.commons.codec.Charsets
|
|
import org.apache.http.HttpEntity
|
|
import org.apache.http.HttpResponse
|
|
import org.apache.http.client.HttpClient
|
|
import org.apache.http.client.config.CookieSpecs
|
|
import org.apache.http.client.config.RequestConfig
|
|
import org.apache.http.client.methods.CloseableHttpResponse
|
|
import org.apache.http.client.methods.HttpGet
|
|
import org.apache.http.client.methods.HttpPost
|
|
import org.apache.http.entity.ContentType
|
|
import org.apache.http.entity.mime.MultipartEntityBuilder
|
|
import org.apache.http.impl.client.CloseableHttpClient
|
|
import org.apache.http.impl.client.HttpClientBuilder
|
|
import org.apache.http.impl.client.HttpClients
|
|
|
|
import java.util.regex.Matcher
|
|
import java.util.regex.Pattern
|
|
|
|
import java.nio.file.Files
|
|
import java.nio.file.Paths
|
|
import java.nio.file.StandardCopyOption
|
|
import java.nio.file.StandardOpenOption
|
|
|
|
|
|
buildscript {
|
|
repositories {
|
|
maven { url "https://plugins.gradle.org/m2/" }
|
|
mavenCentral()
|
|
mavenLocal()
|
|
jcenter()
|
|
}
|
|
dependencies {
|
|
classpath "org.apache.httpcomponents:httpmime:4.5.14"
|
|
classpath "com.google.code.gson:gson:2.10.1"
|
|
classpath "org.apache.httpcomponents:httpclient:4.5.14"
|
|
}
|
|
}
|
|
|
|
plugins {
|
|
id 'dev.s7a.gradle.minecraft.server' version '1.2.0'
|
|
id 'net.researchgate.release' version '2.8.1'
|
|
}
|
|
|
|
apply plugin: 'java'
|
|
apply plugin: 'idea'
|
|
|
|
def branch = System.getenv("GITHUB_REF");
|
|
if (branch != null) {
|
|
branch = branch.replace('refs/heads/', '')
|
|
}
|
|
def isCanary = version.toString().contains('canary')
|
|
|
|
group = 'com.sekwah.advancedportals'
|
|
|
|
description = ""
|
|
|
|
sourceCompatibility = 1.8
|
|
targetCompatibility = 1.8
|
|
|
|
tasks.withType(JavaCompile) {
|
|
options.encoding = 'UTF-8'
|
|
}
|
|
|
|
String getPluginData(String tag) {
|
|
File file = file("src/main/resources/plugin.yml")
|
|
String version = "notfound"
|
|
file.readLines("UTF-8").each { String line ->
|
|
line = line.trim()
|
|
if (line.startsWith(tag)) {
|
|
version = line.substring(tag.length() + 2, line.length())
|
|
}
|
|
}
|
|
println "Advanced Portals v" + version
|
|
return version
|
|
}
|
|
|
|
configurations {
|
|
// configuration that holds jars to copy into lib
|
|
includeLibs
|
|
}
|
|
|
|
repositories {
|
|
maven { url "https://repo.maven.apache.org/maven2" }
|
|
maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }
|
|
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
|
maven { url "https://nexus.velocitypowered.com/repository/maven-public/" }
|
|
maven { url 'https://papermc.io/repo/repository/maven-public/' }
|
|
maven { url 'https://maven.enginehub.org/repo/' } // WorldEdit
|
|
}
|
|
|
|
// includeLibs just says to include the library in the final jar
|
|
dependencies {
|
|
|
|
//implementation "org.bukkit:bukkit:1.16.1-R0.1-SNAPSHOT"
|
|
implementation "org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT"
|
|
implementation "net.md-5:bungeecord-api:1.16-R0.4"
|
|
|
|
implementation "com.velocitypowered:velocity-api:3.1.1"
|
|
annotationProcessor "com.velocitypowered:velocity-api:3.1.1"
|
|
|
|
implementation "io.netty:netty-all:4.1.91.Final"
|
|
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
|
|
|
|
implementation "com.sk89q.worldedit:worldedit-bukkit:7.2.14"
|
|
//compile fileTree(dir: 'libs', include: ['*.jar'])
|
|
}
|
|
|
|
/** For pre-releases and testers to be able to try the latest commits if they want.
|
|
* If the builds start exceeding 8MB then we may want to upload to s3 instead and periodically clear.
|
|
* TODO possibly add a task that announces when builds are made?
|
|
* Though add a note that it may take a while for Curse to approve the files.
|
|
*/
|
|
task discordupload {
|
|
dependsOn(jar)
|
|
doLast {
|
|
String discordWebhook = System.getenv("DISCORD_WEBHOOK")
|
|
|
|
if (discordWebhook != null) {
|
|
println("Logging Into Discord")
|
|
|
|
CloseableHttpClient httpClient = HttpClients.createDefault()
|
|
HttpPost uploadFile = new HttpPost(discordWebhook)
|
|
|
|
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
|
|
|
|
if (isCanary) {
|
|
builder.addTextBody("content", "New canary Build")
|
|
} else {
|
|
builder.addTextBody("content", "New release build\n\n" +
|
|
"Current Features: <${project.github}/blob/${branch}/CHANGELOG.md>")
|
|
}
|
|
|
|
builder.addBinaryBody("file", file(jar.archiveFile).newInputStream(), ContentType.APPLICATION_OCTET_STREAM, jar.archiveName)
|
|
|
|
HttpEntity multipart = builder.build()
|
|
|
|
uploadFile.setEntity(multipart)
|
|
CloseableHttpResponse response = httpClient.execute(uploadFile)
|
|
response.getEntity()
|
|
|
|
println("Posted build")
|
|
|
|
} else {
|
|
println("Discord webhook unspecified")
|
|
}
|
|
}
|
|
}
|
|
|
|
minecraftServerConfig {
|
|
//jarUrl.set('https://download.getbukkit.org/spigot/spigot-1.19.3.jar')
|
|
jarUrl.set('https://api.papermc.io/v2/projects/paper/versions/1.19.3/builds/381/downloads/paper-1.19.3-381.jar')
|
|
jvmArgument = ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-DIReallyKnowWhatIAmDoingISwear=true"]
|
|
}
|
|
|
|
|
|
String getValueFromCurseAPI(apiKey, endpoint) {
|
|
String API_BASE_URL = 'https://minecraft.curseforge.com'
|
|
|
|
Gson gson = new Gson()
|
|
|
|
HttpClient client = HttpClientBuilder.create()
|
|
.setDefaultRequestConfig(RequestConfig.custom()
|
|
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build()).build()
|
|
|
|
HttpGet get = new HttpGet(API_BASE_URL + endpoint)
|
|
get.setHeader('X-Api-Token', apiKey)
|
|
|
|
HttpResponse response = client.execute(get)
|
|
|
|
int statusCode = response.statusLine.statusCode
|
|
|
|
if (statusCode == 200) {
|
|
byte[] data = response.entity.content.bytes
|
|
return new String(data, Charsets.UTF_8)
|
|
} else {
|
|
if (response.getFirstHeader('content-type').value.contains('json')) {
|
|
InputStreamReader reader = new InputStreamReader(response.entity.content)
|
|
reader.close()
|
|
throw new RuntimeException("[CurseForge] Error")
|
|
} else {
|
|
throw new RuntimeException("[CurseForge] HTTP Error Code $response.statusLine.statusCode: $response.statusLine.reasonPhrase")
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
/**
|
|
* Upload a single file (in case you also want to upload the other files like source n stuff)
|
|
* @param json
|
|
* @param file
|
|
* @return
|
|
* @throws IOException
|
|
* @throws URISyntaxException
|
|
*/
|
|
UploadResponse uploadFile(Metadata metadata, File file, String apiKey, Gson gson) throws IOException, URISyntaxException {
|
|
String API_BASE_URL = 'https://minecraft.curseforge.com'
|
|
String UPLOAD_URL = "/api/projects/%s/upload-file"
|
|
// Upload
|
|
// Important info
|
|
String uploadUrl = String.format(API_BASE_URL + UPLOAD_URL, project.curse_project_id)
|
|
|
|
HttpClient client = HttpClientBuilder.create()
|
|
.setDefaultRequestConfig(RequestConfig.custom()
|
|
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build()).build()
|
|
|
|
HttpPost post = new HttpPost(uploadUrl)
|
|
post.setHeader('X-Api-Token', apiKey)
|
|
|
|
|
|
// https://support.curseforge.com/en/support/solutions/articles/9000197321-curseforge-api
|
|
post.setEntity(MultipartEntityBuilder.create()
|
|
.addTextBody('metadata', gson.toJson(metadata), ContentType.APPLICATION_JSON)
|
|
.addBinaryBody('file', file)
|
|
.build())
|
|
|
|
HttpResponse response = client.execute(post)
|
|
InputStreamReader reader = new InputStreamReader(response.entity.content)
|
|
UploadResponse uploadResponse = gson.fromJson(reader, UploadResponse)
|
|
reader.close()
|
|
return uploadResponse
|
|
}
|
|
|
|
class GameVersion {
|
|
int id
|
|
int gameVersionTypeID
|
|
String name
|
|
String slug
|
|
}
|
|
|
|
/**
|
|
* As described here https://support.curseforge.com/en/support/solutions/articles/9000197321-curseforge-api
|
|
*/
|
|
class Metadata {
|
|
String changelog
|
|
String changelogType
|
|
int[] gameVersions
|
|
String releaseType
|
|
}
|
|
|
|
class UploadResponse {
|
|
int id;
|
|
}
|
|
|
|
|
|
// Based on https://github.com/matthewprenger/CurseGradle as it didnt support Bukkit uploads at the time.
|
|
task curseforge {
|
|
dependsOn(jar)
|
|
doLast {
|
|
String apiKey = null
|
|
|
|
if (System.getenv("CURSE_API") != null) {
|
|
apiKey = System.getenv("CURSE_API")
|
|
}
|
|
|
|
if (apiKey != null) {
|
|
|
|
Gson gson = new Gson()
|
|
|
|
//String VERSION_TYPES_URL = "/api/game/version-types"
|
|
int gameVersionTypeID = 1
|
|
String VERSION_URL = "/api/game/versions"
|
|
println("Uploading to CurseForge")
|
|
|
|
// Get game versions
|
|
String gameVersionsString = getValueFromCurseAPI(apiKey, VERSION_URL)
|
|
GameVersion[] gameVersions = gson.fromJson(gameVersionsString, GameVersion[].class)
|
|
def versions = gameVersions.findAll { it.gameVersionTypeID == gameVersionTypeID }
|
|
|
|
String[] supportedVersions = [
|
|
"1.18",
|
|
"1.17",
|
|
"1.16",
|
|
"1.15",
|
|
"1.14",
|
|
"1.13"
|
|
]
|
|
|
|
def supportedGameVersions = versions.findAll { supportedVersions.contains(it.name) }
|
|
int[] supportedGameVersionIds = supportedGameVersions.collect { it.id }.toArray()
|
|
|
|
println("Supported Version Id's ${supportedGameVersionIds}")
|
|
|
|
Metadata uploadMetadata = new Metadata();
|
|
|
|
uploadMetadata.changelog = "${project.github}/blob/${branch}/CHANGELOG.md"
|
|
uploadMetadata.changelogType = "markdown"
|
|
uploadMetadata.releaseType = "release"
|
|
uploadMetadata.gameVersions = supportedGameVersionIds
|
|
|
|
def uploadId = uploadFile(uploadMetadata, file(jar.archiveFile), apiKey, gson)
|
|
|
|
println("Uploaded with ID: ${uploadId.id}")
|
|
|
|
println("Published build")
|
|
|
|
} else {
|
|
println("Discord webhook unspecified")
|
|
}
|
|
}
|
|
// id = project.curse_project_id
|
|
// // TODO add code to reference this but also cut the latest change logs in for the files
|
|
// changelogType = 'markdown'
|
|
// releaseType = 'release'
|
|
}
|
|
|
|
/**
|
|
* Will build then copy it to the minecraft server folder for use with the launch task and dev tools plugin
|
|
*/
|
|
tasks.register('copyPlugin') {
|
|
dependsOn(build)
|
|
doLast {
|
|
copy {
|
|
def sourceFilePath = Paths.get("$buildDir/libs/Advanced-Portals-${getVersion()}.jar")
|
|
def destinationFilePath = Paths.get("$buildDir/MinecraftServer/plugins/Advanced-Portals.jar")
|
|
|
|
println "Handling file: $destinationFilePath"
|
|
|
|
byte[] newContent = Files.readAllBytes(sourceFilePath)
|
|
|
|
if (Files.exists(destinationFilePath)) {
|
|
println "File exists. Overwriting with new binary content."
|
|
|
|
Files.write(destinationFilePath, newContent, StandardOpenOption.TRUNCATE_EXISTING)
|
|
} else {
|
|
println "File does not exist. Copying from source."
|
|
|
|
Files.copy(sourceFilePath, destinationFilePath, StandardCopyOption.REPLACE_EXISTING)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set SPIGOT_LOC to the location of your server and SPIGOT_JAR as the name of the jar file in the server you want to run
|
|
// DIReallyKnowWhatIAmDoingISwear is to remove the stupid pause spigot has at the start
|
|
task runJar() {
|
|
doLast {
|
|
if (System.env.MC_SERVER_LOC == null || System.env.MC_SERVER_JAR == null) {
|
|
throw new Exception('You must set the server location and jar to use MC_SERVER_LOC and MC_SERVER_JAR')
|
|
}
|
|
javaexec {
|
|
main "-jar"
|
|
args "${System.env.MC_SERVER_LOC}\\${System.env.MC_SERVER_JAR}.jar"
|
|
jvmArgs = ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-DIReallyKnowWhatIAmDoingISwear=true"]
|
|
workingDir "${System.env.MC_SERVER_LOC}"
|
|
}
|
|
}
|
|
}
|
|
|
|
task publish {
|
|
doLast {
|
|
println "This is a dummy task to run others for version: ${version}"
|
|
}
|
|
}
|
|
|
|
// https://github.com/researchgate/gradle-release
|
|
// Only other plugin I can find using auto & gradle https://github.com/intuit/hooks
|
|
release {
|
|
failOnPublishNeeded = false
|
|
failOnSnapshotDependencies = false
|
|
git {
|
|
requireBranch = ''
|
|
}
|
|
|
|
|
|
// Disable tasks because something we have is causing -x to be ignored
|
|
createReleaseTag.enabled = false
|
|
preTagCommit.enabled = false
|
|
commitNewVersion.enabled = false
|
|
}
|
|
|
|
task cleanbuildfolder {
|
|
doFirst {
|
|
println "Cleaning up previous builds (to stop publishing old ones by mistake)"
|
|
project.delete(files("${buildDir}/libs"))
|
|
}
|
|
}
|
|
|
|
void updateFileVersion(String fileLoc, Pattern pattern, Closure<String> stringClosure) {
|
|
File file = new File(projectDir, fileLoc)
|
|
Matcher m = pattern.matcher(file.text)
|
|
if (m.find()) {
|
|
def newVersion = stringClosure.call(m)
|
|
println "Replacing ${pattern.toString()} in ${fileLoc} with '${newVersion}'"
|
|
file.text = file.text.replaceAll(pattern, newVersion)
|
|
}
|
|
}
|
|
|
|
// Just to keep all numbers the same (as they are dotted all over the place)
|
|
task updateVersionNumbers {
|
|
doFirst {
|
|
def versionRegex = ~/(\nversion:\s)([0-9.-]+)/
|
|
def velocityVersionRegex = ~/(\sversion\s=\s")([0-9.-]+)("\))/
|
|
|
|
updateFileVersion("src/main/resources/bungee.yml", versionRegex,
|
|
{ Matcher m ->
|
|
return "${m.group(1)}${getVersion()}"
|
|
})
|
|
|
|
updateFileVersion("src/main/resources/plugin.yml", versionRegex,
|
|
{ Matcher m ->
|
|
return "${m.group(1)}${getVersion()}"
|
|
})
|
|
|
|
updateFileVersion("src/main/java/com/sekwah/advancedportals/velocity/AdvancedPortalsPlugin.java",
|
|
velocityVersionRegex,
|
|
{ Matcher m ->
|
|
return "${m.group(1)}${getVersion()}${m.group(3)}"
|
|
})
|
|
}
|
|
}
|
|
|
|
updateVersion.finalizedBy 'updateVersionNumbers'
|
|
|
|
compileJava.dependsOn 'cleanbuildfolder'
|
|
|
|
// Publish rules
|
|
// Current behavior seems to be canary or release. Though pre-releases may break this pattern.
|
|
publish.dependsOn 'build'
|
|
publish.finalizedBy 'discordupload'
|
|
if (!isCanary) {
|
|
publish.finalizedBy 'curseforge'
|
|
}
|