Gradle 6.7, initial patch remap (not working)
This commit is contained in:
parent
1a94055556
commit
a25958b31e
68 changed files with 3498 additions and 1658 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -5,4 +5,3 @@ gradlew text eol=lf
|
|||
*.bat text eol=crlf
|
||||
|
||||
*.jar binary
|
||||
|
||||
|
|
143
.gitignore
vendored
143
.gitignore
vendored
|
@ -1,25 +1,14 @@
|
|||
### Intellij ###
|
||||
# IntelliJ
|
||||
.idea/
|
||||
out/
|
||||
|
||||
# File-based project format
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### Eclipse ###
|
||||
|
||||
# Eclipse
|
||||
.metadata
|
||||
.project
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
|
@ -30,143 +19,27 @@ local.properties
|
|||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated
|
||||
|
||||
.sts4-cache/
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Windows ###
|
||||
# Windows
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
### Gradle ###
|
||||
# Gradle
|
||||
.gradle
|
||||
/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||
# gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.ja
|
||||
|
|
|
@ -4,7 +4,6 @@ plugins {
|
|||
idea
|
||||
eclipse
|
||||
maven
|
||||
kotlin("jvm") version "1.3.70"
|
||||
`kotlin-dsl`
|
||||
id("net.minecrell.licenser") version "0.4.1"
|
||||
id("com.github.johnrengelman.shadow") version "6.0.0"
|
||||
|
@ -16,43 +15,36 @@ version = "1.0.0-SNAPSHOT"
|
|||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
maven("https://files.minecraftforge.net/maven/")
|
||||
}
|
||||
|
||||
val mcInjector: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
compileOnly(gradleApi())
|
||||
compileOnly(gradleKotlinDsl())
|
||||
implementation("org.apache.httpcomponents:httpclient:4.5.12")
|
||||
|
||||
// Utils
|
||||
implementation("net.sf.opencsv:opencsv:2.3")
|
||||
implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
|
||||
|
||||
// ASM for inspection
|
||||
implementation("org.ow2.asm:asm:8.0.1")
|
||||
|
||||
// Cadix
|
||||
implementation("org.cadixdev:lorenz:0.5.4-SNAPSHOT")
|
||||
implementation("org.cadixdev:lorenz-asm:0.5.3")
|
||||
implementation("org.cadixdev:mercury:0.1.0-SNAPSHOT")
|
||||
implementation("org.cadixdev:atlas:0.2.0")
|
||||
implementation("org.cadixdev:at:0.1.0-SNAPSHOT")
|
||||
|
||||
implementation("org.cadixdev:mercury:0.1.0-SNAPSHOT")
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
val mcinjectorJar by tasks.registering(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) {
|
||||
configurations = listOf(mcInjector)
|
||||
archiveBaseName.set("mcinjector-shadowed")
|
||||
archiveVersion.set("")
|
||||
archiveClassifier.set("")
|
||||
manifest {
|
||||
attributes(mapOf("Main-Class" to "de.oceanlabs.mcp.mcinjector.MCInjector"))
|
||||
}
|
||||
kotlinOptions.freeCompilerArgs = listOf("-Xjvm-default=enable")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
from(mcinjectorJar)
|
||||
archiveBaseName.set("io.papermc.paperweight.gradle.plugin")
|
||||
}
|
||||
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
53
gradlew
vendored
53
gradlew
vendored
|
@ -1,5 +1,21 @@
|
|||
#!/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
|
||||
|
@ -28,7 +44,7 @@ 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=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
@ -66,6 +82,7 @@ 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
|
||||
|
@ -109,10 +126,11 @@ if $darwin; then
|
|||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# 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
|
||||
|
@ -138,19 +156,19 @@ if $cygwin ; then
|
|||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
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" ;;
|
||||
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
|
||||
|
||||
|
@ -159,14 +177,9 @@ save () {
|
|||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
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"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
43
gradlew.bat
vendored
43
gradlew.bat
vendored
|
@ -1,3 +1,19 @@
|
|||
@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
|
||||
|
@ -13,15 +29,18 @@ 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=
|
||||
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 init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -35,7 +54,7 @@ goto fail
|
|||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
|
@ -45,28 +64,14 @@ echo location of your Java installation.
|
|||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
: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 %CMD_LINE_ARGS%
|
||||
"%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
|
||||
|
|
|
@ -2,7 +2,6 @@ paperweight is a Gradle plugin for the PaperMC project. It uses
|
|||
some code and systems originally from ForgeGradle.
|
||||
|
||||
Copyright (C) 2020 Kyle Wood
|
||||
Copyright (C) 2018 Forge Development LLC
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -25,149 +24,264 @@
|
|||
|
||||
package io.papermc.paperweight
|
||||
|
||||
import com.github.salomonbrys.kotson.array
|
||||
import com.github.salomonbrys.kotson.fromJson
|
||||
import com.github.salomonbrys.kotson.get
|
||||
import com.github.salomonbrys.kotson.string
|
||||
import com.google.gson.JsonObject
|
||||
import io.papermc.paperweight.ext.PaperweightExtension
|
||||
import io.papermc.paperweight.tasks.AddMissingSpigotClassMappings
|
||||
import io.papermc.paperweight.tasks.ApplyAccessTransform
|
||||
import io.papermc.paperweight.tasks.ApplyDiffPatches
|
||||
import io.papermc.paperweight.tasks.ApplyGitPatches
|
||||
import io.papermc.paperweight.tasks.ApplyMcpPatches
|
||||
import io.papermc.paperweight.tasks.ApplyPaperPatches
|
||||
import io.papermc.paperweight.tasks.ApplySourceAt
|
||||
import io.papermc.paperweight.tasks.DecompileVanillaJar
|
||||
import io.papermc.paperweight.tasks.DownloadMcLibraries
|
||||
import io.papermc.paperweight.tasks.DownloadMcpFiles
|
||||
import io.papermc.paperweight.tasks.DownloadMcpTools
|
||||
import io.papermc.paperweight.tasks.DownloadServerJar
|
||||
import io.papermc.paperweight.tasks.ExtractMcpData
|
||||
import io.papermc.paperweight.tasks.ExtractMcpMappings
|
||||
import io.papermc.paperweight.tasks.DownloadSpigotDependencies
|
||||
import io.papermc.paperweight.tasks.DownloadTask
|
||||
import io.papermc.paperweight.tasks.ExtractMappings
|
||||
import io.papermc.paperweight.tasks.ExtractMcp
|
||||
import io.papermc.paperweight.tasks.Filter
|
||||
import io.papermc.paperweight.tasks.FilterExcludes
|
||||
import io.papermc.paperweight.tasks.GatherBuildData
|
||||
import io.papermc.paperweight.tasks.GenerateSpigotSrgs
|
||||
import io.papermc.paperweight.tasks.GenerateSrgs
|
||||
import io.papermc.paperweight.tasks.GetRemoteJsons
|
||||
import io.papermc.paperweight.tasks.InspectVanillaJar
|
||||
import io.papermc.paperweight.tasks.Merge
|
||||
import io.papermc.paperweight.tasks.MergeAccessTransforms
|
||||
import io.papermc.paperweight.tasks.PatchMcpCsv
|
||||
import io.papermc.paperweight.tasks.RemapSources
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSrg
|
||||
import io.papermc.paperweight.tasks.RemapAccessTransform
|
||||
import io.papermc.paperweight.tasks.RemapSpigotAt
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSpigot
|
||||
import io.papermc.paperweight.tasks.RunForgeFlower
|
||||
import io.papermc.paperweight.tasks.RunMcInjector
|
||||
import io.papermc.paperweight.tasks.SetupMcpDependencies
|
||||
import io.papermc.paperweight.tasks.SetupSpigotDependencies
|
||||
import io.papermc.paperweight.tasks.RunSpecialSource
|
||||
import io.papermc.paperweight.tasks.SetupMcLibraries
|
||||
import io.papermc.paperweight.tasks.WriteLibrariesFile
|
||||
import io.papermc.paperweight.tasks.patchremap.ApplyAccessTransform
|
||||
import io.papermc.paperweight.tasks.patchremap.RemapPatches
|
||||
import io.papermc.paperweight.tasks.sourceremap.RemapSources
|
||||
import io.papermc.paperweight.util.BuildDataInfo
|
||||
import io.papermc.paperweight.util.Constants
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.tasks.RemapSrgSources
|
||||
import io.papermc.paperweight.tasks.RemapVanillaJarSpigot
|
||||
import io.papermc.paperweight.util.MinecraftManifest
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.contents
|
||||
import io.papermc.paperweight.util.ext
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.registering
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Delete
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.api.tasks.bundling.Zip
|
||||
import org.gradle.kotlin.dsl.maven
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import util.BuildDataInfo
|
||||
import java.io.File
|
||||
|
||||
class Paperweight : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
target.extensions.create(Constants.EXTENSION, PaperweightExtension::class.java, target)
|
||||
target.extensions.create(Constants.EXTENSION, PaperweightExtension::class.java, target.objects, target.layout)
|
||||
|
||||
createConfigurations(target)
|
||||
setupMcpDeps(target)
|
||||
|
||||
createTasks(target)
|
||||
|
||||
target.tasks.register("cleanCache").configure {
|
||||
destroyables.register(target.cache)
|
||||
doLast {
|
||||
target.delete(target.cache)
|
||||
}
|
||||
}
|
||||
target.tasks.register<Delete>("cleanCache") {
|
||||
delete(target.layout.cache)
|
||||
}
|
||||
|
||||
private fun createConfigurations(project: Project) {
|
||||
project.repositories.apply {
|
||||
// Make sure the submodules are initialized
|
||||
Git(target.projectDir)("submodule", "update", "--init").execute()
|
||||
|
||||
target.repositories.apply {
|
||||
mavenCentral()
|
||||
// Both of these are needed for Spigot
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
maven("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
maven {
|
||||
name = "forge"
|
||||
url = project.uri(Constants.FORGE_MAVEN_URL)
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "minecraft"
|
||||
url = project.uri(Constants.MC_LIBRARY_URL)
|
||||
}
|
||||
}
|
||||
|
||||
project.configurations.register(Constants.MCP_MAPPINGS_CONFIG)
|
||||
project.configurations.register(Constants.MCP_DATA_CONFIG)
|
||||
project.configurations.register(Constants.SPIGOT_DEP_CONFIG)
|
||||
project.configurations.create(Constants.MINECRAFT_DEP_CONFIG)
|
||||
project.configurations.register(Constants.FORGE_FLOWER_CONFIG)
|
||||
project.configurations.create(Constants.MCINJECT_CONFIG)
|
||||
target.createTasks()
|
||||
}
|
||||
|
||||
private fun setupMcpDeps(project: Project) {
|
||||
project.dependencies.add(Constants.MCP_DATA_CONFIG, project.provider {
|
||||
mapOf(
|
||||
"group" to "de.oceanlabs.mcp",
|
||||
"name" to "mcp_config",
|
||||
"version" to "${project.ext.mcpMinecraftVersion.get()}-${project.ext.mcpVersion.get()}",
|
||||
"ext" to "zip"
|
||||
private fun Project.createTasks() {
|
||||
val extension = ext
|
||||
|
||||
val initialTasks = createInitialTasks()
|
||||
val generalTasks = createGeneralTasks()
|
||||
val mcpTasks = createMcpTasks(initialTasks, generalTasks)
|
||||
val spigotTasks = createSpigotTasks(initialTasks, generalTasks, mcpTasks)
|
||||
|
||||
createPatchRemapTasks(initialTasks, generalTasks, mcpTasks, spigotTasks)
|
||||
|
||||
val applySourceAt by tasks.registering<ApplySourceAt> {
|
||||
inputZip.set(mcpTasks.applyMcpPatches.flatMap { it.outputZip })
|
||||
vanillaJar.set(generalTasks.downloadServerJar.flatMap { it.outputJar })
|
||||
vanillaRemappedSrgJar.set(mcpTasks.remapVanillaJarSrg.flatMap { it.outputJar })
|
||||
atFile.set(spigotTasks.mergeGeneratedAts.flatMap { it.outputFile })
|
||||
}
|
||||
|
||||
val mergeRemappedSources by tasks.registering<Merge> {
|
||||
inputJars.add(spigotTasks.remapSpigotSources.flatMap { it.outputZip })
|
||||
inputJars.add(applySourceAt.flatMap { it.outputZip })
|
||||
}
|
||||
|
||||
val patchPaperApi by tasks.registering<ApplyGitPatches> {
|
||||
branch.set("HEAD")
|
||||
upstreamBranch.set("upstream")
|
||||
upstream.set(spigotTasks.patchSpigotApi.flatMap { it.outputDir })
|
||||
patchDir.set(extension.paper.spigotApiPatchDir)
|
||||
printOutput.set(true)
|
||||
|
||||
outputDir.set(extension.paper.paperApiDir)
|
||||
}
|
||||
|
||||
val patchPaperServer by tasks.registering<ApplyPaperPatches> {
|
||||
patchDir.set(extension.paper.spigotServerPatchDir)
|
||||
remappedSource.set(mergeRemappedSources.flatMap { it.outputJar })
|
||||
templateGitIgnore.set(layout.projectDirectory.file(".gitignore"))
|
||||
|
||||
outputDir.set(extension.paper.paperServerDir)
|
||||
}
|
||||
|
||||
val patchPaper by tasks.registering<Task> {
|
||||
dependsOn(patchPaperApi, patchPaperServer)
|
||||
}
|
||||
|
||||
/*
|
||||
* Not bothering mapping away from SRG until everything is stable under SRG
|
||||
* Moving off of SRG will make things a lot more fragile
|
||||
val remapSrgSourcesSpigotVanilla by tasks.registering<RemapSrgSources> {
|
||||
inputZips.add(ZipTarget.base(applyMcpPatches.flatMap { outputZip }))
|
||||
methodsCsv.set(mcpRewrites.flatMap { methodsCsv })
|
||||
fieldsCsv.set(mcpRewrites.flatMap { fieldsCsv })
|
||||
paramsCsv.set(mcpRewrites.flatMap { paramsCsv })
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Shared task containers
|
||||
data class InitialTasks(
|
||||
val setupMcLibraries: TaskProvider<SetupMcLibraries>,
|
||||
val extractMcp: Provider<ExtractMcp>,
|
||||
val mcpMappings: Provider<ExtractMappings>,
|
||||
val downloadMcpTools: TaskProvider<DownloadMcpTools>
|
||||
)
|
||||
})
|
||||
|
||||
project.dependencies.add(Constants.MCP_MAPPINGS_CONFIG, project.provider {
|
||||
mapOf(
|
||||
"group" to "de.oceanlabs.mcp",
|
||||
"name" to "mcp_${project.ext.mcpMappingsChannel.get()}",
|
||||
"version" to project.ext.mcpMappingsVersion.get(),
|
||||
"ext" to "zip"
|
||||
data class GeneralTasks(
|
||||
val buildDataInfo: Provider<BuildDataInfo>,
|
||||
val downloadServerJar: TaskProvider<DownloadServerJar>,
|
||||
val filterVanillaJar: TaskProvider<Filter>
|
||||
)
|
||||
|
||||
data class McpTasks(
|
||||
val generateSrgs: TaskProvider<GenerateSrgs>,
|
||||
val remapVanillaJarSrg: TaskProvider<RunSpecialSource>,
|
||||
val applyMcpPatches: TaskProvider<ApplyMcpPatches>
|
||||
)
|
||||
|
||||
data class SpigotTasks(
|
||||
val generateSpigotSrgs: TaskProvider<GenerateSpigotSrgs>,
|
||||
val decompileVanillaJarSpigot: TaskProvider<DecompileVanillaJar>,
|
||||
val patchSpigotApi: TaskProvider<ApplyGitPatches>,
|
||||
val patchSpigotServer: TaskProvider<ApplyGitPatches>,
|
||||
val remapSpigotSources: TaskProvider<RemapSources>,
|
||||
val mergeGeneratedAts: TaskProvider<MergeAccessTransforms>
|
||||
)
|
||||
|
||||
private fun Project.createInitialTasks(): InitialTasks {
|
||||
val cache: File = layout.cache
|
||||
val extension: PaperweightExtension = ext
|
||||
|
||||
val downloadMcManifest by tasks.registering<DownloadTask> {
|
||||
url.set(Constants.MC_MANIFEST_URL)
|
||||
outputFile.set(cache.resolve(Constants.MC_MANIFEST))
|
||||
}
|
||||
|
||||
val mcManifest = downloadMcManifest.flatMap { it.outputFile }.map { gson.fromJson<MinecraftManifest>(it) }
|
||||
|
||||
val downloadMcVersionManifest by tasks.registering<DownloadTask> {
|
||||
url.set(mcManifest.zip(extension.minecraftVersion) { manifest, version ->
|
||||
manifest.versions.first { it.id == version }.url
|
||||
})
|
||||
outputFile.set(cache.resolve(Constants.VERSION_JSON))
|
||||
}
|
||||
|
||||
// Types are specified in this method to hopefully improve editor performance a little, though I don't think it helps
|
||||
private fun createTasks(project: Project) {
|
||||
val cache: File = project.cache
|
||||
val extension: PaperweightExtension = project.ext
|
||||
val versionManifest = downloadMcVersionManifest.flatMap { it.outputFile }.map { gson.fromJson<JsonObject>(it) }
|
||||
|
||||
val initGitSubmodules: TaskProvider<Task> = project.tasks.register("initGitSubmodules") {
|
||||
outputs.upToDateWhen { false }
|
||||
doLast {
|
||||
Git(project.projectDir)("submodule", "update", "--init").execute()
|
||||
val setupMcLibraries by tasks.registering<SetupMcLibraries> {
|
||||
dependencies.set(versionManifest.map { version ->
|
||||
version["libraries"].array.map { library ->
|
||||
library["name"].string
|
||||
}.filter { !it.contains("lwjgl") } // we don't need these on the server
|
||||
})
|
||||
outputFile.set(cache.resolve(Constants.MC_LIBRARIES))
|
||||
}
|
||||
}
|
||||
val gatherBuildData: TaskProvider<GatherBuildData> = project.tasks.register<GatherBuildData>("gatherBuildData") {
|
||||
dependsOn(initGitSubmodules)
|
||||
buildDataInfoFile.set(extension.craftBukkit.buildDataInfo)
|
||||
}
|
||||
val buildDataInfo: Provider<BuildDataInfo> = gatherBuildData.flatMap { it.buildDataInfo }
|
||||
|
||||
val extractMcpData: TaskProvider<ExtractMcpData> = project.tasks.register<ExtractMcpData>("extractMcpData") {
|
||||
config.set(Constants.MCP_DATA_CONFIG)
|
||||
val downloadMcpFiles by tasks.registering<DownloadMcpFiles> {
|
||||
mcpMinecraftVersion.set(extension.mcpMinecraftVersion)
|
||||
mcpConfigVersion.set(extension.mcpConfigVersion)
|
||||
mcpMappingsChannel.set(extension.mcpMappingsChannel)
|
||||
mcpMappingsVersion.set(extension.mcpMappingsVersion)
|
||||
|
||||
configZip.set(cache.resolve(Constants.MCP_ZIPS_PATH).resolve("McpConfig.zip"))
|
||||
mappingsZip.set(cache.resolve(Constants.MCP_ZIPS_PATH).resolve("McpMappings.zip"))
|
||||
}
|
||||
|
||||
val extractMcpConfig by tasks.registering<ExtractMcp> {
|
||||
inputFile.set(downloadMcpFiles.flatMap { it.configZip })
|
||||
outputDir.set(cache.resolve(Constants.MCP_DATA_DIR))
|
||||
}
|
||||
|
||||
val setupMcpDependencies: TaskProvider<SetupMcpDependencies> = project.tasks.register<SetupMcpDependencies>("setupMcpDependencies") {
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
forgeFlowerConfig.set(Constants.FORGE_FLOWER_CONFIG)
|
||||
mcInjectorConfig.set(Constants.MCINJECT_CONFIG)
|
||||
}
|
||||
|
||||
val extractMcpMappings: TaskProvider<ExtractMcpMappings> = project.tasks.register<ExtractMcpMappings>("extractMcpMappings") {
|
||||
config.set(Constants.MCP_MAPPINGS_CONFIG)
|
||||
val extractMcpMappings by tasks.registering<ExtractMappings> {
|
||||
inputFile.set(downloadMcpFiles.flatMap { it.mappingsZip })
|
||||
outputDir.set(cache.resolve(Constants.MCP_MAPPINGS_DIR))
|
||||
}
|
||||
|
||||
val getRemoteJsons: TaskProvider<GetRemoteJsons> = project.tasks.register<GetRemoteJsons>("getRemoteJsons") {
|
||||
config.set(Constants.MINECRAFT_DEP_CONFIG)
|
||||
val downloadMcpTools by tasks.registering<DownloadMcpTools> {
|
||||
configFile.set(extractMcpConfig.flatMap { it.configFile })
|
||||
|
||||
val toolsPath = cache.resolve(Constants.MCP_TOOLS_PATH)
|
||||
forgeFlowerFile.set(toolsPath.resolve("ForgeFlower.jar"))
|
||||
mcInjectorFile.set(toolsPath.resolve("McInjector.jar"))
|
||||
specialSourceFile.set(toolsPath.resolve("SpecialSource.jar"))
|
||||
}
|
||||
|
||||
val mcpRewrites: TaskProvider<PatchMcpCsv> = project.tasks.register<PatchMcpCsv>("mcpRewrites") {
|
||||
fieldsCsv.set(extractMcpMappings.flatMap { it.fieldsCsv })
|
||||
methodsCsv.set(extractMcpMappings.flatMap { it.methodsCsv })
|
||||
paramsCsv.set(extractMcpMappings.flatMap { it.paramsCsv })
|
||||
return InitialTasks(
|
||||
setupMcLibraries,
|
||||
extractMcpConfig,
|
||||
extractMcpMappings,
|
||||
downloadMcpTools
|
||||
)
|
||||
}
|
||||
|
||||
private fun Project.createGeneralTasks(): GeneralTasks {
|
||||
val buildDataInfo: Provider<BuildDataInfo> = contents(ext.craftBukkit.buildDataInfo) {
|
||||
gson.fromJson(it)
|
||||
}
|
||||
|
||||
val downloadServerJar by tasks.registering<DownloadServerJar> {
|
||||
downloadUrl.set(buildDataInfo.map { it.serverUrl })
|
||||
hash.set(buildDataInfo.map { it.minecraftHash })
|
||||
}
|
||||
|
||||
val filterVanillaJar by tasks.registering<Filter> {
|
||||
inputJar.set(downloadServerJar.flatMap { it.outputJar })
|
||||
includes.set(listOf("/*.class", "/net/minecraft/**"))
|
||||
}
|
||||
|
||||
return GeneralTasks(buildDataInfo, downloadServerJar, filterVanillaJar)
|
||||
}
|
||||
|
||||
private fun Project.createMcpTasks(initialTasks: InitialTasks, generalTasks: GeneralTasks): McpTasks {
|
||||
val filterVanillaJar: TaskProvider<Filter> = generalTasks.filterVanillaJar
|
||||
val cache: File = layout.cache
|
||||
val extension: PaperweightExtension = ext
|
||||
|
||||
val mcpRewrites by tasks.registering<PatchMcpCsv> {
|
||||
fieldsCsv.set(initialTasks.mcpMappings.flatMap { it.fieldsCsv })
|
||||
methodsCsv.set(initialTasks.mcpMappings.flatMap { it.methodsCsv })
|
||||
paramsCsv.set(initialTasks.mcpMappings.flatMap { it.paramsCsv })
|
||||
changesFile.set(extension.paper.mcpRewritesFile)
|
||||
|
||||
paperFieldCsv.set(cache.resolve(Constants.PAPER_FIELDS_CSV))
|
||||
|
@ -175,8 +289,9 @@ class Paperweight : Plugin<Project> {
|
|||
paperParamCsv.set(cache.resolve(Constants.PAPER_PARAMS_CSV))
|
||||
}
|
||||
|
||||
val generateSrgs: TaskProvider<GenerateSrgs> = project.tasks.register<GenerateSrgs>("generateSrgs") {
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
val generateSrgs by tasks.registering<GenerateSrgs> {
|
||||
inSrg.set(initialTasks.extractMcp.flatMap { it.mappings })
|
||||
|
||||
methodsCsv.set(mcpRewrites.flatMap { it.paperMethodCsv })
|
||||
fieldsCsv.set(mcpRewrites.flatMap { it.paperFieldCsv })
|
||||
extraNotchSrgMappings.set(extension.paper.extraNotchSrgMappings)
|
||||
|
@ -189,20 +304,78 @@ class Paperweight : Plugin<Project> {
|
|||
mcpToSrg.set(cache.resolve(Constants.MCP_TO_SRG))
|
||||
}
|
||||
|
||||
val addMissingSpigotClassMappings: TaskProvider<AddMissingSpigotClassMappings> = project.tasks.register<AddMissingSpigotClassMappings>("addMissingSpigotClassMappings") {
|
||||
val remapVanillaJarSrg by tasks.registering<RunSpecialSource> {
|
||||
inputJar.set(filterVanillaJar.flatMap { it.outputJar })
|
||||
mappings.set(generateSrgs.flatMap { it.notchToSrg })
|
||||
|
||||
executable.set(initialTasks.downloadMcpTools.flatMap { it.specialSourceFile })
|
||||
configFile.set(initialTasks.extractMcp.flatMap { it.configFile })
|
||||
}
|
||||
|
||||
val injectVanillaJarSrg by tasks.registering<RunMcInjector> {
|
||||
executable.set(initialTasks.downloadMcpTools.flatMap { it.mcInjectorFile })
|
||||
configFile.set(initialTasks.extractMcp.flatMap { it.configFile })
|
||||
|
||||
exceptions.set(initialTasks.extractMcp.flatMap { it.exceptions })
|
||||
access.set(initialTasks.extractMcp.flatMap { it.access })
|
||||
constructors.set(initialTasks.extractMcp.flatMap { it.constructors })
|
||||
|
||||
inputJar.set(remapVanillaJarSrg.flatMap { it.outputJar })
|
||||
}
|
||||
|
||||
val downloadMcLibraries by tasks.registering<DownloadMcLibraries> {
|
||||
mcLibrariesFile.set(initialTasks.setupMcLibraries.flatMap { it.outputFile })
|
||||
mcRepo.set(Constants.MC_LIBRARY_URL)
|
||||
outputDir.set(cache.resolve(Constants.MINECRAFT_JARS_PATH))
|
||||
}
|
||||
|
||||
val writeLibrariesFile by tasks.registering<WriteLibrariesFile> {
|
||||
libraries.set(downloadMcLibraries.flatMap { it.outputDir })
|
||||
}
|
||||
|
||||
val decompileVanillaJarSrg by tasks.registering<RunForgeFlower> {
|
||||
executable.set(initialTasks.downloadMcpTools.flatMap { it.forgeFlowerFile })
|
||||
configFile.set(initialTasks.extractMcp.flatMap { it.configFile })
|
||||
|
||||
inputJar.set(injectVanillaJarSrg.flatMap { it.outputJar })
|
||||
libraries.set(writeLibrariesFile.flatMap { it.outputFile })
|
||||
}
|
||||
|
||||
val applyMcpPatches by tasks.registering<ApplyMcpPatches> {
|
||||
inputZip.set(decompileVanillaJarSrg.flatMap { it.outputJar })
|
||||
serverPatchDir.set(initialTasks.extractMcp.flatMap { it.patchDir })
|
||||
configFile.set(cache.resolve(Constants.MCP_CONFIG_JSON))
|
||||
}
|
||||
|
||||
return McpTasks(generateSrgs, remapVanillaJarSrg, applyMcpPatches)
|
||||
}
|
||||
|
||||
private fun Project.createSpigotTasks(initialTasks: InitialTasks, generalTasks: GeneralTasks, mcpTasks: McpTasks): SpigotTasks {
|
||||
val cache: File = layout.cache
|
||||
val extension: PaperweightExtension = ext
|
||||
|
||||
val (buildDataInfo, downloadServerJar, filterVanillaJar) = generalTasks
|
||||
val (generateSrgs, _, _) = mcpTasks
|
||||
|
||||
val addMissingSpigotClassMappings by tasks.registering<AddMissingSpigotClassMappings> {
|
||||
classSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings }))
|
||||
memberSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.memberMappings }))
|
||||
missingClassEntriesSrg.set(extension.paper.missingClassEntriesSrgFile)
|
||||
missingMemberEntriesSrg.set(extension.paper.missingMemberEntriesSrgFile)
|
||||
}
|
||||
|
||||
val generateSpigotSrgs: TaskProvider<GenerateSpigotSrgs> = project.tasks.register<GenerateSpigotSrgs>("generateSpigotSrgs") {
|
||||
val inspectVanillaJar by tasks.registering<InspectVanillaJar> {
|
||||
inputJar.set(downloadServerJar.flatMap { it.outputJar })
|
||||
}
|
||||
|
||||
val generateSpigotSrgs by tasks.registering<GenerateSpigotSrgs> {
|
||||
notchToSrg.set(generateSrgs.flatMap { it.notchToSrg })
|
||||
srgToMcp.set(generateSrgs.flatMap { it.srgToMcp })
|
||||
classMappings.set(addMissingSpigotClassMappings.flatMap { it.outputClassSrg })
|
||||
memberMappings.set(addMissingSpigotClassMappings.flatMap { it.outputMemberSrg })
|
||||
packageMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.packageMappings }))
|
||||
extraSpigotSrgMappings.set(extension.paper.extraSpigotSrgMappings)
|
||||
loggerFields.set(inspectVanillaJar.flatMap { it.outputFile })
|
||||
|
||||
spigotToSrg.set(cache.resolve(Constants.SPIGOT_TO_SRG))
|
||||
spigotToMcp.set(cache.resolve(Constants.SPIGOT_TO_MCP))
|
||||
|
@ -212,25 +385,8 @@ class Paperweight : Plugin<Project> {
|
|||
notchToSpigot.set(cache.resolve(Constants.NOTCH_TO_SPIGOT))
|
||||
}
|
||||
|
||||
val downloadServerJar: TaskProvider<DownloadServerJar> = project.tasks.register<DownloadServerJar>("downloadServerJar") {
|
||||
dependsOn(gatherBuildData)
|
||||
downloadUrl.set(buildDataInfo.map { it.serverUrl })
|
||||
hash.set(buildDataInfo.map { it.minecraftHash })
|
||||
}
|
||||
|
||||
val filterVanillaJar: TaskProvider<Zip> = project.tasks.register<Zip>("filterVanillaJar") {
|
||||
dependsOn(downloadServerJar) // the from() block below doesn't set up this dependency
|
||||
archiveFileName.set("filterVanillaJar.jar")
|
||||
destinationDirectory.set(cache.resolve(Constants.TASK_CACHE))
|
||||
|
||||
from(project.zipTree(downloadServerJar.flatMap { it.outputJar })) {
|
||||
include("/*.class")
|
||||
include("/net/minecraft/**")
|
||||
}
|
||||
}
|
||||
|
||||
val remapVanillaJar: TaskProvider<RemapVanillaJarSpigot> = project.tasks.register<RemapVanillaJarSpigot>("remapVanillaJar") {
|
||||
inputJar.set(project.layout.file(filterVanillaJar.map { it.outputs.files.singleFile }))
|
||||
val remapVanillaJarSpigot by tasks.registering<RemapVanillaJarSpigot> {
|
||||
inputJar.set(filterVanillaJar.flatMap { it.outputJar })
|
||||
classMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings }))
|
||||
memberMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.memberMappings }))
|
||||
packageMappings.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.packageMappings }))
|
||||
|
@ -246,18 +402,18 @@ class Paperweight : Plugin<Project> {
|
|||
finalMapCommand.set(buildDataInfo.map { it.finalMapCommand })
|
||||
}
|
||||
|
||||
val removeSpigotExcludes: TaskProvider<FilterExcludes> = project.tasks.register<FilterExcludes>("removeSpigotExcludes") {
|
||||
inputZip.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
val removeSpigotExcludes by tasks.registering<FilterExcludes> {
|
||||
inputZip.set(remapVanillaJarSpigot.flatMap { it.outputJar })
|
||||
excludesFile.set(extension.craftBukkit.excludesFile)
|
||||
}
|
||||
|
||||
val decompileVanillaJarSpigot: TaskProvider<DecompileVanillaJar> = project.tasks.register<DecompileVanillaJar>("decompileVanillaJarSpigot") {
|
||||
val decompileVanillaJarSpigot by tasks.registering<DecompileVanillaJar> {
|
||||
inputJar.set(removeSpigotExcludes.flatMap { it.outputZip })
|
||||
fernFlowerJar.set(extension.craftBukkit.fernFlowerJar)
|
||||
decompileCommand.set(buildDataInfo.map { it.decompileCommand })
|
||||
}
|
||||
|
||||
val patchCraftBukkit: TaskProvider<ApplyDiffPatches> = project.tasks.register<ApplyDiffPatches>("patchCraftBukkit") {
|
||||
val patchCraftBukkit by tasks.registering<ApplyDiffPatches> {
|
||||
sourceJar.set(decompileVanillaJarSpigot.flatMap { it.outputJar })
|
||||
sourceBasePath.set("net/minecraft/server")
|
||||
branch.set("patched")
|
||||
|
@ -266,7 +422,7 @@ class Paperweight : Plugin<Project> {
|
|||
outputDir.set(extension.craftBukkit.craftBukkitDir)
|
||||
}
|
||||
|
||||
val patchSpigotApi: TaskProvider<ApplyGitPatches> = project.tasks.register<ApplyGitPatches>("patchSpigotApi") {
|
||||
val patchSpigotApi by tasks.registering<ApplyGitPatches> {
|
||||
branch.set("HEAD")
|
||||
upstreamBranch.set("upstream")
|
||||
upstream.set(extension.craftBukkit.bukkitDir)
|
||||
|
@ -275,7 +431,7 @@ class Paperweight : Plugin<Project> {
|
|||
outputDir.set(extension.spigot.spigotApiDir)
|
||||
}
|
||||
|
||||
val patchSpigotServer: TaskProvider<ApplyGitPatches> = project.tasks.register<ApplyGitPatches>("patchSpigotServer") {
|
||||
val patchSpigotServer by tasks.registering<ApplyGitPatches> {
|
||||
branch.set(patchCraftBukkit.flatMap { it.branch })
|
||||
upstreamBranch.set("upstream")
|
||||
upstream.set(patchCraftBukkit.flatMap { it.outputDir })
|
||||
|
@ -284,78 +440,98 @@ class Paperweight : Plugin<Project> {
|
|||
outputDir.set(extension.spigot.spigotServerDir)
|
||||
}
|
||||
|
||||
val patchSpigot: TaskProvider<Task> = project.tasks.register("patchSpigot") {
|
||||
val patchSpigot by tasks.registering<Task> {
|
||||
dependsOn(patchSpigotApi, patchSpigotServer)
|
||||
}
|
||||
|
||||
val setupSpigotDependencies: TaskProvider<SetupSpigotDependencies> = project.tasks.register<SetupSpigotDependencies>("setupSpigotDependencies") {
|
||||
val downloadSpigotDependencies by tasks.registering<DownloadSpigotDependencies> {
|
||||
dependsOn(patchSpigot)
|
||||
spigotApi.set(patchSpigotApi.flatMap { it.outputDir })
|
||||
spigotServer.set(patchSpigotServer.flatMap { it.outputDir })
|
||||
configurationName.set(Constants.SPIGOT_DEP_CONFIG)
|
||||
apiPom.set(patchSpigotApi.flatMap { it.outputDir.file("pom.xml") })
|
||||
serverPom.set(patchSpigotServer.flatMap { it.outputDir.file("pom.xml") })
|
||||
apiOutputDir.set(cache.resolve(Constants.SPIGOT_API_JARS_PATH))
|
||||
serverOutputDir.set(cache.resolve(Constants.SPIGOT_SERVER_JARS_PATH))
|
||||
}
|
||||
|
||||
val remapSpigotJarSrg: TaskProvider<RemapVanillaJarSrg> = project.tasks.register<RemapVanillaJarSrg>("remapSpigotJarSrg") {
|
||||
// Basing off of the Spigot jar lets us inherit the AT modifications Spigot does before decompile
|
||||
inputJar.set(remapVanillaJar.flatMap { it.outputJar })
|
||||
mappings.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
val remapSpigotAt by tasks.registering<RemapSpigotAt> {
|
||||
inputJar.set(remapVanillaJarSpigot.flatMap { it.outputJar })
|
||||
mapping.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
spigotAt.set(extension.craftBukkit.atFile)
|
||||
}
|
||||
|
||||
val remapSpigotSources: TaskProvider<RemapSources> = project.tasks.register<RemapSources>("remapSpigotSources") {
|
||||
dependsOn(setupSpigotDependencies)
|
||||
val remapSpigotSources by tasks.registering<RemapSources> {
|
||||
spigotServerDir.set(patchSpigotServer.flatMap { it.outputDir })
|
||||
spigotApiDir.set(patchSpigotApi.flatMap { it.outputDir })
|
||||
mappings.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
vanillaJar.set(downloadServerJar.flatMap { it.outputJar })
|
||||
vanillaRemappedSpigotJar.set(removeSpigotExcludes.flatMap { it.outputZip })
|
||||
vanillaRemappedSrgJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
configuration.set(setupSpigotDependencies.flatMap { it.configurationName })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
spigotApiDeps.set(downloadSpigotDependencies.flatMap { it.apiOutputDir })
|
||||
spigotServerDeps.set(downloadSpigotDependencies.flatMap { it.serverOutputDir })
|
||||
constructors.set(initialTasks.extractMcp.flatMap { it.constructors })
|
||||
}
|
||||
|
||||
val fixVanillaJarAccess: TaskProvider<ApplyAccessTransform> = project.tasks.register<ApplyAccessTransform>("fixVanillaJarAccess") {
|
||||
inputJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
atFile.set(remapSpigotSources.flatMap { it.generatedAt })
|
||||
mapping.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
val remapGeneratedAt by tasks.registering<RemapAccessTransform> {
|
||||
inputFile.set(remapSpigotSources.flatMap { it.generatedAt })
|
||||
mappings.set(generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
}
|
||||
|
||||
val remapSrgSourcesSpigot: TaskProvider<RemapSrgSources> = project.tasks.register<RemapSrgSources>("remapSrgSourcesSpigot") {
|
||||
inputZip.set(remapSpigotSources.flatMap { it.outputZip })
|
||||
methodsCsv.set(mcpRewrites.flatMap { it.methodsCsv })
|
||||
fieldsCsv.set(mcpRewrites.flatMap { it.fieldsCsv })
|
||||
paramsCsv.set(mcpRewrites.flatMap { it.paramsCsv })
|
||||
val mergeGeneratedAts by tasks.registering<MergeAccessTransforms> {
|
||||
inputFiles.add(remapGeneratedAt.flatMap { it.outputFile })
|
||||
inputFiles.add(remapSpigotAt.flatMap { it.outputFile })
|
||||
}
|
||||
|
||||
val injectVanillaJarForge: TaskProvider<RunMcInjector> = project.tasks.register<RunMcInjector>("injectVanillaJarForge") {
|
||||
dependsOn(setupMcpDependencies)
|
||||
configuration.set(setupMcpDependencies.flatMap { it.mcInjectorConfig })
|
||||
inputJar.set(remapSpigotJarSrg.flatMap { it.outputJar })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
return SpigotTasks(
|
||||
generateSpigotSrgs,
|
||||
decompileVanillaJarSpigot,
|
||||
patchSpigotApi,
|
||||
patchSpigotServer,
|
||||
remapSpigotSources,
|
||||
mergeGeneratedAts
|
||||
)
|
||||
}
|
||||
|
||||
val writeLibrariesFile: TaskProvider<WriteLibrariesFile> = project.tasks.register<WriteLibrariesFile>("writeLibrariesFile") {
|
||||
dependsOn(getRemoteJsons)
|
||||
config.set(getRemoteJsons.flatMap { it.config })
|
||||
private fun Project.createPatchRemapTasks(
|
||||
initialTasks: InitialTasks,
|
||||
generalTasks: GeneralTasks,
|
||||
mcpTasks: McpTasks,
|
||||
spigotTasks: SpigotTasks
|
||||
) {
|
||||
val extension: PaperweightExtension = ext
|
||||
|
||||
/*
|
||||
* I don't remember what this is supposed to be for tbh
|
||||
val patchPaperServerForPatchRemap by tasks.registering<ApplyPaperPatches> {
|
||||
patchDir.set(extension.paper.spigotServerPatchDir)
|
||||
remappedSource.set(spigotTasks.remapSpigotSources.flatMap { it.outputZip })
|
||||
|
||||
outputDir.set(cache.resolve("patch-paper-server-for-remap"))
|
||||
}
|
||||
*/
|
||||
|
||||
val applyVanillaSrgAt by tasks.registering<ApplyAccessTransform> {
|
||||
inputJar.set(mcpTasks.remapVanillaJarSrg.flatMap { it.outputJar })
|
||||
atFile.set(spigotTasks.mergeGeneratedAts.flatMap { it.outputFile })
|
||||
}
|
||||
|
||||
val decompileVanillaJarForge: TaskProvider<RunForgeFlower> = project.tasks.register<RunForgeFlower>("decompileVanillaJarForge") {
|
||||
dependsOn(setupMcpDependencies)
|
||||
configuration.set(setupMcpDependencies.flatMap { it.forgeFlowerConfig })
|
||||
inputJar.set(injectVanillaJarForge.flatMap { it.outputJar })
|
||||
libraries.set(writeLibrariesFile.flatMap { it.outputFile })
|
||||
configFile.set(extractMcpData.flatMap { it.configJson })
|
||||
}
|
||||
val remapPatches by tasks.registering<RemapPatches> {
|
||||
inputPatchDir.set(extension.paper.unmappedSpigotServerPatchDir)
|
||||
sourceJar.set(spigotTasks.remapSpigotSources.flatMap { it.outputZip })
|
||||
apiPatchDir.set(extension.paper.spigotApiPatchDir)
|
||||
|
||||
// val applyMcpPatches: TaskProvider<ApplyMcpPatches> = project.tasks.register<ApplyMcpPatches>("applyMcpPatches") {
|
||||
// inputZips.add(ZipTarget.base(decompileVanillaJarForge.flatMap { it.outputJar }))
|
||||
// serverPatchDir.set(extractMcpData.flatMap { it.patches })
|
||||
// }
|
||||
//
|
||||
// val remapSrgSourcesSpigotVanilla: TaskProvider<RemapSrgSources> = project.tasks.register<RemapSrgSources>("remapSrgSourcesSpigotVanilla") {
|
||||
// inputZips.add(ZipTarget.base(applyMcpPatches.flatMap { outputZip }))
|
||||
// methodsCsv.set(mcpRewrites.flatMap { methodsCsv })
|
||||
// fieldsCsv.set(mcpRewrites.flatMap { fieldsCsv })
|
||||
// paramsCsv.set(mcpRewrites.flatMap { paramsCsv })
|
||||
// }
|
||||
mappingsFile.set(spigotTasks.generateSpigotSrgs.flatMap { it.spigotToSrg })
|
||||
|
||||
// Pull in as many jars as possible to reduce the possibility of type bindings not resolving
|
||||
classpathJars.add(generalTasks.downloadServerJar.flatMap { it.outputJar })
|
||||
classpathJars.add(spigotTasks.remapSpigotSources.flatMap { it.vanillaRemappedSpigotJar })
|
||||
classpathJars.add(applyVanillaSrgAt.flatMap { it.outputJar })
|
||||
|
||||
spigotApiDir.set(spigotTasks.patchSpigotApi.flatMap { it.outputDir })
|
||||
spigotServerDir.set(spigotTasks.patchSpigotServer.flatMap { it.outputDir })
|
||||
spigotDecompJar.set(spigotTasks.decompileVanillaJarSpigot.flatMap { it.outputJar })
|
||||
constructors.set(initialTasks.extractMcp.flatMap { it.constructors })
|
||||
|
||||
parameterNames.set(spigotTasks.remapSpigotSources.flatMap { it.parameterNames })
|
||||
|
||||
outputPatchDir.set(extension.paper.remappedSpigotServerPatchDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,18 +22,35 @@
|
|||
|
||||
package io.papermc.paperweight.ext
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
|
||||
open class CraftBukkitExtension(project: Project) {
|
||||
val bukkitDir: DirectoryProperty = project.dirWithDefault("work/Bukkit")
|
||||
var craftBukkitDir: DirectoryProperty = project.dirWithDefault("work/CraftBukkit")
|
||||
var patchDir: DirectoryProperty = project.dirWithDefault("work/CraftBukkit/nms-patches")
|
||||
var mappingsDir: DirectoryProperty = project.dirWithDefault("work/BuildData/mappings")
|
||||
val excludesFile: RegularFileProperty = project.fileWithDefault("work/BuildData/mappings/bukkit-1.16.1.exclude")
|
||||
var buildDataInfo: RegularFileProperty = project.fileWithDefault("work/BuildData/info.json")
|
||||
var fernFlowerJar: RegularFileProperty = project.fileWithDefault("work/BuildData/bin/fernflower.jar")
|
||||
var specialSourceJar: RegularFileProperty = project.fileWithDefault("work/BuildData/bin/SpecialSource.jar")
|
||||
var specialSource2Jar: RegularFileProperty = project.fileWithDefault("work/BuildData/bin/SpecialSource-2.jar")
|
||||
open class CraftBukkitExtension(objects: ObjectFactory, workDir: DirectoryProperty) {
|
||||
|
||||
val bukkitDir: DirectoryProperty = objects.dirFrom(workDir, "Bukkit")
|
||||
val craftBukkitDir: DirectoryProperty = objects.dirFrom(workDir, "CraftBukkit")
|
||||
val patchDir: DirectoryProperty = objects.dirFrom(craftBukkitDir, "nms-patches")
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val buildDataDir: DirectoryProperty = objects.dirFrom(workDir, "BuildData")
|
||||
val mappingsDir: DirectoryProperty = objects.dirFrom(buildDataDir, "mappings")
|
||||
val excludesFile: RegularFileProperty = objects.bukkitFileFrom(mappingsDir, "exclude")
|
||||
val atFile: RegularFileProperty = objects.bukkitFileFrom(mappingsDir, "at")
|
||||
val buildDataInfo: RegularFileProperty = objects.fileFrom(buildDataDir, "info.json")
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val buildDataBinDir: DirectoryProperty = objects.dirFrom(buildDataDir, "bin")
|
||||
val fernFlowerJar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "fernflower.jar")
|
||||
val specialSourceJar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "SpecialSource.jar")
|
||||
val specialSource2Jar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "SpecialSource-2.jar")
|
||||
|
||||
private fun ObjectFactory.bukkitFileFrom(base: DirectoryProperty, extension: String): RegularFileProperty =
|
||||
fileProperty().convention(base.flatMap { dir ->
|
||||
val file = dir.asFile.listFiles()?.firstOrNull { it.name.endsWith(extension) }
|
||||
if (file != null) {
|
||||
mappingsDir.file(file.name)
|
||||
} else {
|
||||
// empty
|
||||
fileProperty()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,25 +22,28 @@
|
|||
|
||||
package io.papermc.paperweight.ext
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
|
||||
open class PaperExtension(project: Project) {
|
||||
val spigotApiPatchDir: Property<String> = project.objects.property<String>().convention("Spigot-API-Patches")
|
||||
val spigotServerPatchDir: Property<String> = project.objects.property<String>().convention("Spigot-Server-Patches")
|
||||
val paperApiDir: Property<String> = project.objects.property<String>().convention("Paper-API")
|
||||
val paperServerDir: Property<String> = project.objects.property<String>().convention("Paper-Server")
|
||||
open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) {
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val baseTargetDir: DirectoryProperty = objects.dirWithDefault(layout, ".")
|
||||
val spigotApiPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Spigot-API-Patches")
|
||||
val spigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Spigot-Server-Patches")
|
||||
val remappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Spigot-Server-Patches-Remapped")
|
||||
val unmappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Spigot-Server-Patches-Unmapped")
|
||||
val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-API")
|
||||
val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-Server")
|
||||
|
||||
val mcpRewritesFile: RegularFileProperty = project.fileWithDefault("mcp/mcp-rewrites.txt")
|
||||
val missingClassEntriesSrgFile: RegularFileProperty = project.fileWithDefault("mcp/missing-spigot-class-mappings.csrg")
|
||||
val missingMemberEntriesSrgFile: RegularFileProperty = project.fileWithDefault("mcp/missing-spigot-member-mappings.csrg")
|
||||
val extraNotchSrgMappings: RegularFileProperty = project.fileWithDefault("mcp/extra-notch-srg.tsrg")
|
||||
val extraSpigotSrgMappings: RegularFileProperty = project.fileWithDefault("mcp/extra-spigot-srg.tsrg")
|
||||
val preMapSrgFile: RegularFileProperty = project.fileWithDefault("mcp/paper.srg")
|
||||
val removeListFile: RegularFileProperty = project.fileWithDefault("mcp/remove-list.txt")
|
||||
val memberMoveListFile: RegularFileProperty = project.fileWithDefault("mcp/member-moves.txt")
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val mcpDir: DirectoryProperty = objects.dirWithDefault(layout, "mcp")
|
||||
val mcpRewritesFile: RegularFileProperty = objects.fileFrom(mcpDir, "mcp-rewrites.txt")
|
||||
val missingClassEntriesSrgFile: RegularFileProperty = objects.fileFrom(mcpDir, "missing-spigot-class-mappings.csrg")
|
||||
val missingMemberEntriesSrgFile: RegularFileProperty = objects.fileFrom(mcpDir, "missing-spigot-member-mappings.csrg")
|
||||
val extraNotchSrgMappings: RegularFileProperty = objects.fileFrom(mcpDir, "extra-notch-srg.tsrg")
|
||||
val extraSpigotSrgMappings: RegularFileProperty = objects.fileFrom(mcpDir, "extra-spigot-srg.tsrg")
|
||||
|
||||
init {
|
||||
spigotApiPatchDir.disallowUnsafeRead()
|
||||
|
@ -50,8 +52,5 @@ open class PaperExtension(project: Project) {
|
|||
paperServerDir.disallowUnsafeRead()
|
||||
|
||||
mcpRewritesFile.disallowUnsafeRead()
|
||||
preMapSrgFile.disallowUnsafeRead()
|
||||
removeListFile.disallowUnsafeRead()
|
||||
memberMoveListFile.disallowUnsafeRead()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,26 +23,33 @@
|
|||
package io.papermc.paperweight.ext
|
||||
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class PaperweightExtension(project: Project) {
|
||||
open class PaperweightExtension(objects: ObjectFactory, layout: ProjectLayout) {
|
||||
|
||||
val minecraftVersion: Property<String> = project.objects.property()
|
||||
val mcpMinecraftVersion: Property<String> = project.objects.property<String>().convention(minecraftVersion)
|
||||
val mcpVersion: Property<String> = project.objects.property()
|
||||
val mcpMappingsChannel: Property<String> = project.objects.property()
|
||||
val mcpMappingsVersion: Property<String> = project.objects.property()
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work")
|
||||
|
||||
val craftBukkit = CraftBukkitExtension(project)
|
||||
val spigot = SpigotExtension(project)
|
||||
val paper = PaperExtension(project)
|
||||
val minecraftVersion: Property<String> = objects.property()
|
||||
val mcpMinecraftVersion: Property<String> = objects.property<String>().convention(minecraftVersion)
|
||||
val mcpConfigVersion: Property<String> = objects.property()
|
||||
val mcpMappingsChannel: Property<String> = objects.property()
|
||||
val mcpMappingsVersion: Property<String> = objects.property()
|
||||
|
||||
val mcpConfigFile: RegularFileProperty = objects.fileProperty().convention(null)
|
||||
|
||||
val craftBukkit = CraftBukkitExtension(objects, workDir)
|
||||
val spigot = SpigotExtension(objects, workDir)
|
||||
val paper = PaperExtension(objects, layout)
|
||||
|
||||
init {
|
||||
minecraftVersion.disallowUnsafeRead()
|
||||
mcpMinecraftVersion.disallowUnsafeRead()
|
||||
mcpVersion.disallowUnsafeRead()
|
||||
mcpMappingsChannel.disallowUnsafeRead()
|
||||
mcpMappingsVersion.disallowUnsafeRead()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,15 +22,15 @@
|
|||
|
||||
package io.papermc.paperweight.ext
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
|
||||
open class SpigotExtension(project: Project) {
|
||||
var spigotDir: DirectoryProperty = project.dirWithDefault("work/Spigot")
|
||||
var spigotApiDir: DirectoryProperty = project.dirWithDefault("work/Spigot/Spigot-API")
|
||||
var spigotServerDir: DirectoryProperty = project.dirWithDefault("work/Spigot/Spigot-Server")
|
||||
var bukkitPatchDir: DirectoryProperty = project.dirWithDefault("work/Spigot/Bukkit-Patches")
|
||||
var craftBukkitPatchDir: DirectoryProperty = project.dirWithDefault("work/Spigot/CraftBukkit-Patches")
|
||||
open class SpigotExtension(objects: ObjectFactory, workDir: DirectoryProperty) {
|
||||
var spigotDir: DirectoryProperty = objects.dirFrom(workDir, "Spigot")
|
||||
var spigotApiDir: DirectoryProperty = objects.dirFrom(spigotDir, "Spigot-API")
|
||||
var spigotServerDir: DirectoryProperty = objects.dirFrom(spigotDir, "Spigot-Server")
|
||||
var bukkitPatchDir: DirectoryProperty = objects.dirFrom(spigotDir, "Bukkit-Patches")
|
||||
var craftBukkitPatchDir: DirectoryProperty = objects.dirFrom(spigotDir, "CraftBukkit-Patches")
|
||||
|
||||
init {
|
||||
spigotDir.disallowUnsafeRead()
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,12 +22,16 @@
|
|||
|
||||
package io.papermc.paperweight.ext
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
|
||||
fun Project.dirWithDefault(path: String): DirectoryProperty =
|
||||
project.objects.directoryProperty().convention(layout.dir(provider { file(path) }))
|
||||
fun ObjectFactory.dirWithDefault(layout: ProjectLayout, path: String): DirectoryProperty =
|
||||
directoryProperty().convention(layout.projectDirectory.dir(path))
|
||||
|
||||
fun Project.fileWithDefault(path: String): RegularFileProperty =
|
||||
project.objects.fileProperty().convention(layout.file(provider { file(path) }))
|
||||
fun ObjectFactory.dirFrom(base: DirectoryProperty, name: String): DirectoryProperty =
|
||||
directoryProperty().convention(base.dir(name))
|
||||
|
||||
fun ObjectFactory.fileFrom(base: DirectoryProperty, name: String): RegularFileProperty =
|
||||
fileProperty().convention(base.file(name))
|
||||
|
|
|
@ -1,48 +1,73 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import io.papermc.paperweight.util.fileOrNull
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
|
||||
open class AddMissingSpigotClassMappings : DefaultTask() {
|
||||
abstract class AddMissingSpigotClassMappings : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val classSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val memberSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val classSrg: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val memberSrg: RegularFileProperty
|
||||
@get:Optional
|
||||
@get:InputFile
|
||||
abstract val missingClassEntriesSrg: RegularFileProperty
|
||||
@get:Optional
|
||||
@get:InputFile
|
||||
abstract val missingMemberEntriesSrg: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val missingClassEntriesSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val missingMemberEntriesSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val outputClassSrg: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val outputMemberSrg: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputClassSrg: RegularFileProperty = defaultOutput("class.csrg")
|
||||
@OutputFile
|
||||
val outputMemberSrg: RegularFileProperty = defaultOutput("member.csrg")
|
||||
override fun init() {
|
||||
outputClassSrg.convention(defaultOutput("class.csrg"))
|
||||
outputMemberSrg.convention(defaultOutput("member.csrg"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
addLines(classSrg.file, missingClassEntriesSrg.file, outputClassSrg.file)
|
||||
addLines(memberSrg.file, missingMemberEntriesSrg.file, outputMemberSrg.file)
|
||||
addLines(classSrg.file, missingClassEntriesSrg.fileOrNull, outputClassSrg.file)
|
||||
addLines(memberSrg.file, missingMemberEntriesSrg.fileOrNull, outputMemberSrg.file)
|
||||
}
|
||||
|
||||
private fun addLines(inFile: File, appendFile: File, outputFile: File) {
|
||||
private fun addLines(inFile: File, appendFile: File?, outputFile: File) {
|
||||
val lines = mutableListOf<String>()
|
||||
inFile.bufferedReader().use { reader ->
|
||||
lines.addAll(reader.readLines())
|
||||
}
|
||||
appendFile.bufferedReader().use { reader ->
|
||||
lines.addAll(reader.readLines())
|
||||
}
|
||||
inFile.useLines { seq -> seq.forEach { lines.add(it) } }
|
||||
appendFile?.useLines { seq -> seq.forEach { lines.add(it) } }
|
||||
lines.sort()
|
||||
outputFile.bufferedWriter().use { writer ->
|
||||
lines.forEach(writer::appendln)
|
||||
lines.forEach { writer.appendln(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,10 +23,11 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.Command
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.util.UselessOutputStream
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
@ -36,33 +36,34 @@ import org.gradle.api.tasks.InputDirectory
|
|||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.util.Date
|
||||
|
||||
open class ApplyDiffPatches : DefaultTask() {
|
||||
abstract class ApplyDiffPatches : ControllableOutputTask() {
|
||||
|
||||
@InputFile
|
||||
val sourceJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@Input
|
||||
val sourceBasePath: Property<String> = project.objects.property()
|
||||
@InputDirectory
|
||||
val patchDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@Input
|
||||
val branch: Property<String> = project.objects.property()
|
||||
@get:InputFile
|
||||
abstract val sourceJar: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val sourceBasePath: Property<String>
|
||||
@get:InputDirectory
|
||||
abstract val patchDir: DirectoryProperty
|
||||
@get:Input
|
||||
abstract val branch: Property<String>
|
||||
|
||||
@OutputDirectory
|
||||
val outputDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
|
||||
override fun init() {
|
||||
printOutput.convention(false)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val git = Git(outputDir.file)
|
||||
git("checkout", "-B", branch.get(), "HEAD").executeSilently(silenceErr = true)
|
||||
|
||||
val uri = URI.create("jar:${sourceJar.file.toURI()}")
|
||||
|
||||
val basePatchDirFile = outputDir.file.resolve("src/main/java")
|
||||
val outputDirFile = basePatchDirFile.resolve(sourceBasePath.get())
|
||||
outputDirFile.deleteRecursively()
|
||||
|
@ -73,6 +74,7 @@ open class ApplyDiffPatches : DefaultTask() {
|
|||
}
|
||||
|
||||
// Copy in patch targets
|
||||
val uri = URI.create("jar:" + sourceJar.file.toURI())
|
||||
FileSystems.newFileSystem(uri, mapOf<String, Any>()).use { fs ->
|
||||
for (file in patchList) {
|
||||
val javaName = file.name.replaceAfterLast('.', "java")
|
||||
|
@ -88,19 +90,29 @@ open class ApplyDiffPatches : DefaultTask() {
|
|||
}
|
||||
}
|
||||
|
||||
git("add", "src").executeOut()
|
||||
git("commit", "-m", "Vanilla $ ${Date()}", "--author=Vanilla <auto@mated.null>").executeOut()
|
||||
git("add", "src").setupOut().execute()
|
||||
git("commit", "-m", "Vanilla $ ${Date()}", "--author=Vanilla <auto@mated.null>").setupOut().execute()
|
||||
|
||||
// Apply patches
|
||||
for (file in patchList) {
|
||||
val javaName = file.name.replaceAfterLast('.', "java")
|
||||
|
||||
if (printOutput.get()) {
|
||||
println("Patching ${javaName.removeSuffix(".java")}")
|
||||
git("apply", "--directory=${basePatchDirFile.relativeTo(outputDir.file).path}", file.absolutePath).executeOut()
|
||||
}
|
||||
git("apply", "--directory=${basePatchDirFile.relativeTo(outputDir.file).path}", file.absolutePath).setupOut().execute()
|
||||
}
|
||||
|
||||
git("add", "src").executeOut()
|
||||
git("commit", "-m", "CraftBukkit $ ${Date()}", "--author=CraftBukkit <auto@mated.null>").executeOut()
|
||||
git("checkout", "-f", "HEAD~2").executeSilently()
|
||||
git("add", "src").setupOut().execute()
|
||||
git("commit", "-m", "CraftBukkit $ ${Date()}", "--author=CraftBukkit <auto@mated.null>").setupOut().execute()
|
||||
git("checkout", "-f", "HEAD~2").setupOut().execute()
|
||||
}
|
||||
|
||||
private fun Command.setupOut() = apply {
|
||||
if (printOutput.get()) {
|
||||
setup(System.out, System.err)
|
||||
} else {
|
||||
setup(UselessOutputStream, UselessOutputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -26,7 +25,6 @@ package io.papermc.paperweight.tasks
|
|||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
|
@ -34,65 +32,79 @@ import org.gradle.api.tasks.InputDirectory
|
|||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import java.io.File
|
||||
|
||||
open class ApplyGitPatches : DefaultTask() {
|
||||
abstract class ApplyGitPatches : ControllableOutputTask() {
|
||||
|
||||
@Input
|
||||
val branch: Property<String> = project.objects.property()
|
||||
@Input
|
||||
val upstreamBranch: Property<String> = project.objects.property()
|
||||
@InputDirectory
|
||||
val upstream: DirectoryProperty = project.objects.directoryProperty()
|
||||
@InputDirectory
|
||||
val patchDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@get:Input
|
||||
abstract val branch: Property<String>
|
||||
@get:Input
|
||||
abstract val upstreamBranch: Property<String>
|
||||
@get:InputDirectory
|
||||
abstract val upstream: DirectoryProperty
|
||||
@get:InputDirectory
|
||||
abstract val patchDir: DirectoryProperty
|
||||
|
||||
@OutputDirectory
|
||||
val outputDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
|
||||
override fun init() {
|
||||
printOutput.convention(false)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
Git(upstream.file).let { git ->
|
||||
git("fetch").run()
|
||||
git("fetch").setupOut().run()
|
||||
git("branch", "-f", upstreamBranch.get(), branch.get()).runSilently()
|
||||
}
|
||||
|
||||
if (!outputDir.file.exists() || !outputDir.file.resolve(".git").exists()) {
|
||||
outputDir.file.deleteRecursively()
|
||||
Git(outputDir.file.parentFile)("clone", upstream.file.absolutePath, outputDir.file.name).runOut()
|
||||
Git(outputDir.file.parentFile)("clone", upstream.file.absolutePath, outputDir.file.name).setupOut().run()
|
||||
}
|
||||
|
||||
val target = outputDir.file.name
|
||||
|
||||
if (printOutput.get()) {
|
||||
println(" Resetting $target to ${upstream.file.name}...")
|
||||
}
|
||||
Git(outputDir.file).let { git ->
|
||||
git("remote", "rm", "upstream").runSilently(silenceErr = true)
|
||||
git("remote", "add", "upstream", upstream.file.absolutePath).runSilently(silenceErr = true)
|
||||
if (git("checkout", "master").runSilently(silenceOut = false, silenceErr = true) != 0) {
|
||||
git("checkout", "-b", "master").runOut()
|
||||
if (git("checkout", "master").setupOut(showError = false).run() != 0) {
|
||||
git("checkout", "-b", "master").setupOut().run()
|
||||
}
|
||||
git("fetch", "upstream").runSilently(silenceErr = true)
|
||||
git("reset", "--hard", "upstream/${upstreamBranch.get()}").runOut()
|
||||
git("reset", "--hard", "upstream/${upstreamBranch.get()}").setupOut().run()
|
||||
|
||||
applyGitPatches(git, target, outputDir.file, patchDir.file, printOutput.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ControllableOutputTask.applyGitPatches(git: Git, target: String, outputDir: File, patchDir: File, printOutput: Boolean) {
|
||||
if (printOutput) {
|
||||
println(" Applying patches to $target...")
|
||||
}
|
||||
|
||||
val statusFile = outputDir.file.resolve(".git/patch-apply-failed")
|
||||
val statusFile = outputDir.resolve(".git/patch-apply-failed")
|
||||
if (statusFile.exists()) {
|
||||
statusFile.delete()
|
||||
}
|
||||
git("am", "--abort").runSilently(silenceErr = true)
|
||||
|
||||
val patches = patchDir.file.listFiles { _, name -> name.endsWith(".patch") } ?: run {
|
||||
val patches = patchDir.listFiles { _, name -> name.endsWith(".patch") } ?: run {
|
||||
if (printOutput) {
|
||||
println("No patches found")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
patches.sort()
|
||||
|
||||
if (git("am", "--3way", "--ignore-whitespace", *patches.map { it.absolutePath }.toTypedArray()).runOut() != 0) {
|
||||
Thread.sleep(100) // Wait for git
|
||||
if (git("am", "--3way", "--ignore-whitespace", *patches.map { it.absolutePath }.toTypedArray()).showErrors().run() != 0) {
|
||||
statusFile.writeText("1")
|
||||
logger.error("*** Something did not apply cleanly to $target.")
|
||||
logger.error("*** Please review above details and finish the apply then")
|
||||
logger.error("*** save the changes with ./gradlew `rebuildPatches`")
|
||||
|
||||
|
@ -106,8 +118,9 @@ open class ApplyGitPatches : DefaultTask() {
|
|||
throw PaperweightException("Failed to apply patches")
|
||||
} else {
|
||||
statusFile.delete()
|
||||
if (printOutput) {
|
||||
println(" Patches applied cleanly to $target")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,39 +23,27 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import java.io.File
|
||||
|
||||
open class ApplyMcpPatches : ZippedTask() {
|
||||
abstract class ApplyMcpPatches : ZippedTask() {
|
||||
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
init {
|
||||
inputs.dir(configFile.map { mcpConfig(configFile) }.map { mcpFile(configFile, it.data.patches.server) })
|
||||
}
|
||||
@get:InputDirectory
|
||||
abstract val serverPatchDir: DirectoryProperty
|
||||
@get:InputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
val config = mcpConfig(configFile)
|
||||
val serverPatchDir = mcpFile(configFile, config.data.patches.server)
|
||||
|
||||
val git = Git(rootDir)
|
||||
|
||||
val extension = ".java.patch"
|
||||
project.fileTree(serverPatchDir).matching {
|
||||
include("*$extension")
|
||||
objects.fileTree().from(serverPatchDir).matching {
|
||||
include("**/*$extension")
|
||||
}.forEach { patch ->
|
||||
val patchName = patch.name
|
||||
print("Patching ${patchName.substring(0, extension.length)}")
|
||||
val exit = git("apply", "--ignore-whitespace", patch.absolutePath).setup(System.out, null).run()
|
||||
if (exit != 0) {
|
||||
println("...Failed")
|
||||
} else {
|
||||
println()
|
||||
}
|
||||
git("apply", "--ignore-whitespace", patch.absolutePath).executeSilently()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
89
src/main/kotlin/tasks/ApplyPaperPatches.kt
Normal file
89
src/main/kotlin/tasks/ApplyPaperPatches.kt
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Git
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class ApplyPaperPatches : ControllableOutputTask() {
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val patchDir: DirectoryProperty
|
||||
@get:InputFile
|
||||
abstract val remappedSource: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val templateGitIgnore: RegularFileProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
@get:OutputDirectory
|
||||
abstract val remapTargetDir: DirectoryProperty
|
||||
|
||||
override fun init() {
|
||||
printOutput.convention(true)
|
||||
remapTargetDir.convention(outputDir.dir("src/main/java"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val outputFile = outputDir.file
|
||||
if (outputFile.exists()) {
|
||||
outputFile.deleteRecursively()
|
||||
}
|
||||
outputFile.mkdirs()
|
||||
|
||||
val target = outputFile.name
|
||||
|
||||
if (printOutput.get()) {
|
||||
println(" Creating $target from remapped source...")
|
||||
}
|
||||
|
||||
Git(outputFile).let { git ->
|
||||
git("init").runSilently(silenceErr = true)
|
||||
|
||||
val sourceDir = remapTargetDir.file
|
||||
if (sourceDir.exists()) {
|
||||
sourceDir.deleteRecursively()
|
||||
}
|
||||
sourceDir.mkdirs()
|
||||
|
||||
fs.copy {
|
||||
from(archives.zipTree(remappedSource.file))
|
||||
into(sourceDir)
|
||||
}
|
||||
|
||||
templateGitIgnore.file.copyTo(outputFile.resolve(".gitignore"))
|
||||
|
||||
git("add", ".gitignore", ".").executeSilently()
|
||||
git("commit", "-m", "Initial", "--author=Initial <auto@mated.null>").executeSilently()
|
||||
|
||||
applyGitPatches(git, target, outputFile, patchDir.file, printOutput.get())
|
||||
}
|
||||
}
|
||||
}
|
81
src/main/kotlin/tasks/ApplySourceAt.kt
Normal file
81
src/main/kotlin/tasks/ApplySourceAt.kt
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.path
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.mercury.Mercury
|
||||
import org.cadixdev.mercury.at.AccessTransformerRewriter
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import java.io.File
|
||||
|
||||
abstract class ApplySourceAt : ZippedTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val vanillaJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val vanillaRemappedSrgJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val atFile: RegularFileProperty
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
val inputDir = rootDir.resolve("input")
|
||||
val outputDir = rootDir.resolve("output")
|
||||
|
||||
// Move everything into `input/` so we can put output into `output/`
|
||||
inputDir.mkdirs()
|
||||
rootDir.listFiles()?.forEach { file ->
|
||||
if (file != inputDir) {
|
||||
file.renameTo(inputDir.resolve(file.name))
|
||||
}
|
||||
}
|
||||
outputDir.mkdirs()
|
||||
|
||||
val at = AccessTransformFormats.FML.read(atFile.path)
|
||||
|
||||
Mercury().apply {
|
||||
classPath.addAll(listOf(
|
||||
vanillaJar.path,
|
||||
vanillaRemappedSrgJar.path
|
||||
))
|
||||
|
||||
processors.add(AccessTransformerRewriter.create(at))
|
||||
|
||||
rewrite(inputDir.toPath(), outputDir.toPath())
|
||||
}
|
||||
|
||||
// Remove input files
|
||||
rootDir.listFiles()?.forEach { file ->
|
||||
if (file != outputDir) {
|
||||
file.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
// Move output into root
|
||||
outputDir.listFiles()?.forEach { file ->
|
||||
file.renameTo(rootDir.resolve(file.name))
|
||||
}
|
||||
outputDir.delete()
|
||||
}
|
||||
}
|
48
src/main/kotlin/tasks/BaseTask.kt
Normal file
48
src/main/kotlin/tasks/BaseTask.kt
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ArchiveOperations
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class BaseTask : DefaultTask() {
|
||||
|
||||
@get:Inject
|
||||
abstract val objects: ObjectFactory
|
||||
@get:Inject
|
||||
abstract val layout: ProjectLayout
|
||||
@get:Inject
|
||||
abstract val fs: FileSystemOperations
|
||||
@get:Inject
|
||||
abstract val archives: ArchiveOperations
|
||||
|
||||
open fun init() {}
|
||||
|
||||
init {
|
||||
this.init()
|
||||
}
|
||||
}
|
51
src/main/kotlin/tasks/ControllableOutputTask.kt
Normal file
51
src/main/kotlin/tasks/ControllableOutputTask.kt
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Command
|
||||
import io.papermc.paperweight.util.UselessOutputStream
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Console
|
||||
|
||||
abstract class ControllableOutputTask : BaseTask() {
|
||||
|
||||
@get:Console
|
||||
abstract val printOutput: Property<Boolean>
|
||||
|
||||
fun Command.setupOut(showError: Boolean = true) = apply {
|
||||
if (printOutput.get()) {
|
||||
val err = if (showError) System.out else UselessOutputStream
|
||||
setup(System.out, err)
|
||||
} else {
|
||||
setup(UselessOutputStream, UselessOutputStream)
|
||||
}
|
||||
}
|
||||
|
||||
fun Command.showErrors() = apply {
|
||||
if (printOutput.get()) {
|
||||
setup(System.out, System.out)
|
||||
} else {
|
||||
setup(UselessOutputStream, System.out)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -29,27 +28,29 @@ import io.papermc.paperweight.util.cache
|
|||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
open class DecompileVanillaJar : DefaultTask() {
|
||||
abstract class DecompileVanillaJar : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val fernFlowerJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@Input
|
||||
val decompileCommand: Property<String> = project.objects.property()
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val fernFlowerJar: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val decompileCommand: Property<String>
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
@ -68,10 +69,10 @@ open class DecompileVanillaJar : DefaultTask() {
|
|||
cmd += inputJarPath
|
||||
cmd += decomp.canonicalPath
|
||||
|
||||
val logFile = project.cache.resolve(paperTaskOutput("log"))
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("log"))
|
||||
logFile.delete()
|
||||
|
||||
runJar(fernFlowerJar, workingDir = project.cache, logFile = logFile, args = *cmd.toTypedArray())
|
||||
runJar(fernFlowerJar, workingDir = layout.cache, logFile = logFile, args = *cmd.toTypedArray())
|
||||
|
||||
ensureDeleted(outputJarFile)
|
||||
decomp.resolve(inputJarFile.name).renameTo(outputJarFile)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -25,38 +24,34 @@ package io.papermc.paperweight.tasks
|
|||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import org.gradle.api.DefaultTask
|
||||
import io.papermc.paperweight.util.download
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import java.math.BigInteger
|
||||
import java.net.URL
|
||||
import java.security.MessageDigest
|
||||
|
||||
open class DownloadServerJar : DefaultTask() {
|
||||
abstract class DownloadServerJar : BaseTask() {
|
||||
|
||||
@Input
|
||||
val downloadUrl: Property<String> = project.objects.property()
|
||||
@Input
|
||||
val hash: Property<String> = project.objects.property()
|
||||
@get:Input
|
||||
abstract val downloadUrl: Property<String>
|
||||
@get:Input
|
||||
abstract val hash: Property<String>
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val file = outputJar.asFile.get()
|
||||
ensureParentExists(file)
|
||||
ensureDeleted(file)
|
||||
|
||||
file.outputStream().buffered().use { out ->
|
||||
URL(downloadUrl.get()).openStream().copyTo(out)
|
||||
}
|
||||
download(downloadUrl, outputJar)
|
||||
|
||||
val digest = MessageDigest.getInstance("MD5")
|
||||
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class Extract : DefaultTask() {
|
||||
|
||||
@Input
|
||||
val config: Property<String> = project.objects.property()
|
||||
|
||||
@OutputDirectory
|
||||
val outputDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
project.copy {
|
||||
from(project.zipTree(project.configurations[config.get()].resolve().single()))
|
||||
into(outputDir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class ExtractMcpMappings : Extract() {
|
||||
|
||||
@OutputFile
|
||||
val fieldsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
.convention(outputDir.map { it.file("fields.csv") })
|
||||
@OutputFile
|
||||
val methodsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
.convention(outputDir.map { it.file("methods.csv") })
|
||||
@OutputFile
|
||||
val paramsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
.convention(outputDir.map { it.file("params.csv") })
|
||||
}
|
||||
|
||||
open class ExtractMcpData : Extract() {
|
||||
|
||||
@OutputFile
|
||||
val configJson: RegularFileProperty = project.objects.fileProperty()
|
||||
.convention(outputDir.map { it.file("config.json") })
|
||||
}
|
|
@ -1,3 +1,25 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.file
|
||||
|
@ -9,10 +31,10 @@ import java.io.File
|
|||
* Because Spigot doesn't remap all classes, there are class and package name clashes if we don't do this in the source
|
||||
* remap step. Other than that, we don't need this jar
|
||||
*/
|
||||
open class FilterExcludes : ZippedTask() {
|
||||
abstract class FilterExcludes : ZippedTask() {
|
||||
|
||||
@InputFile
|
||||
val excludesFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val excludesFile: RegularFileProperty
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
excludesFile.file.useLines { lines ->
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,6 +23,7 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fileOrNull
|
||||
import io.papermc.paperweight.util.writeMappings
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
|
@ -40,37 +40,40 @@ import org.cadixdev.lorenz.model.TopLevelClassMapping
|
|||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
open class GenerateSpigotSrgs : DefaultTask() {
|
||||
abstract class GenerateSpigotSrgs : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
val notchToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val srgToMcp: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val classMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val memberMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val packageMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val extraSpigotSrgMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val notchToSrg: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val srgToMcp: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val classMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val memberMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val packageMappings: RegularFileProperty
|
||||
@get:Optional
|
||||
@get:InputFile
|
||||
abstract val extraSpigotSrgMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val loggerFields: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val spigotToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val spigotToMcp: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val spigotToNotch: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val srgToSpigot: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val mcpToSpigot: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val notchToSpigot: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val spigotToSrg: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val spigotToMcp: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val spigotToNotch: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val srgToSpigot: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mcpToSpigot: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val notchToSpigot: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
@ -78,6 +81,12 @@ open class GenerateSpigotSrgs : DefaultTask() {
|
|||
val memberMappingSet = MappingFormats.CSRG.createReader(memberMappings.file.toPath()).use { it.read() }
|
||||
val mergedMappingSet = MappingSetMerger.create(classMappingSet, memberMappingSet).merge()
|
||||
|
||||
for (line in loggerFields.file.readLines(Charsets.UTF_8)) {
|
||||
val (className, fieldName) = line.split(' ')
|
||||
val classMapping = mergedMappingSet.getClassMapping(className).orElse(null) ?: continue
|
||||
classMapping.getOrCreateFieldMapping(fieldName).deobfuscatedName = "LOGGER"
|
||||
}
|
||||
|
||||
// Get the new package name
|
||||
val newPackage = packageMappings.asFile.get().readLines()[0].split(Regex("\\s+"))[1]
|
||||
|
||||
|
@ -88,14 +97,16 @@ open class GenerateSpigotSrgs : DefaultTask() {
|
|||
mergedMappingSet,
|
||||
notchToSrgSet,
|
||||
MergeConfig.builder()
|
||||
.withHandler(SpigotPackageMergerHandler(newPackage))
|
||||
.withMergeHandler(SpigotPackageMergerHandler(newPackage))
|
||||
.build()
|
||||
).merge()
|
||||
|
||||
val srgToMcpSet = MappingFormats.TSRG.createReader(srgToMcp.file.toPath()).use { it.read() }
|
||||
|
||||
val spigotToSrgSet = MappingSetMerger.create(notchToSpigotSet.reverse(), notchToSrgSet).merge()
|
||||
MappingFormats.TSRG.createReader(extraSpigotSrgMappings.file.toPath()).use { it.read(spigotToSrgSet) }
|
||||
extraSpigotSrgMappings.fileOrNull?.toPath()?.let { path ->
|
||||
MappingFormats.TSRG.createReader(path).use { it.read(spigotToSrgSet) }
|
||||
}
|
||||
|
||||
val mcpToNotchSet = MappingSetMerger.create(notchToSrgSet, srgToMcpSet).merge().reverse()
|
||||
val mcpToSpigotSet = MappingSetMerger.create(mcpToNotchSet, notchToSpigotSet).merge()
|
||||
|
@ -135,7 +146,7 @@ class SpigotPackageMergerHandler(private val newPackage: String) : MappingSetMer
|
|||
): MergeResult<TopLevelClassMapping?> {
|
||||
// If both are provided, keep spigot
|
||||
return MergeResult(
|
||||
target.createTopLevelClassMapping(left.obfuscatedName, prependPackage(left.deobfuscatedName)),
|
||||
target.createTopLevelClassMapping(prependPackage(left.obfuscatedName), prependPackage(left.deobfuscatedName)),
|
||||
right
|
||||
)
|
||||
}
|
||||
|
@ -145,7 +156,7 @@ class SpigotPackageMergerHandler(private val newPackage: String) : MappingSetMer
|
|||
context: MergeContext
|
||||
): MergeResult<TopLevelClassMapping?> {
|
||||
return MergeResult(
|
||||
target.createTopLevelClassMapping(left.obfuscatedName, prependPackage(left.deobfuscatedName))
|
||||
target.createTopLevelClassMapping(prependPackage(left.obfuscatedName), prependPackage(left.deobfuscatedName))
|
||||
)
|
||||
}
|
||||
override fun addRightTopLevelClassMapping(
|
||||
|
@ -157,8 +168,10 @@ class SpigotPackageMergerHandler(private val newPackage: String) : MappingSetMer
|
|||
return if (right.deobfuscatedName.contains("/client/")) {
|
||||
MergeResult(null)
|
||||
} else {
|
||||
// This is a mapping Spigot is totally missing, but Spigot maps all classes without a package to
|
||||
// /net/minecraft regardless if there are mappings for the classes or not
|
||||
MergeResult(
|
||||
target.createTopLevelClassMapping(right.obfuscatedName, prependPackage(right.obfuscatedName)),
|
||||
target.createTopLevelClassMapping(prependPackage(right.obfuscatedName), right.obfuscatedName),
|
||||
right
|
||||
)
|
||||
}
|
||||
|
@ -195,19 +208,23 @@ class SpigotPackageMergerHandler(private val newPackage: String) : MappingSetMer
|
|||
|
||||
override fun mergeFieldMappings(
|
||||
left: FieldMapping,
|
||||
right: FieldMapping,
|
||||
strictRight: FieldMapping?,
|
||||
looseRight: FieldMapping?,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): FieldMapping? {
|
||||
): FieldMapping {
|
||||
throw IllegalStateException("Unexpectedly merged field: $left")
|
||||
}
|
||||
|
||||
override fun mergeDuplicateFieldMappings(
|
||||
left: FieldMapping,
|
||||
right: FieldMapping,
|
||||
rightContinuation: FieldMapping?,
|
||||
strictRightDuplicate: FieldMapping?,
|
||||
looseRightDuplicate: FieldMapping?,
|
||||
strictRightContinuation: FieldMapping?,
|
||||
looseRightContinuation: FieldMapping?,
|
||||
target: ClassMapping<*, *>,
|
||||
context: MergeContext
|
||||
): FieldMapping? {
|
||||
): FieldMapping {
|
||||
return target.createFieldMapping(left.obfuscatedName, left.deobfuscatedName)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -25,10 +24,10 @@ package io.papermc.paperweight.tasks
|
|||
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fileOrNull
|
||||
import io.papermc.paperweight.util.getCsvReader
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import io.papermc.paperweight.util.writeMappings
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.cadixdev.lorenz.merge.MappingSetMerger
|
||||
|
@ -37,44 +36,46 @@ import org.cadixdev.lorenz.model.InnerClassMapping
|
|||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
open class GenerateSrgs : DefaultTask() {
|
||||
abstract class GenerateSrgs : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val methodsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val fieldsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val extraNotchSrgMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val methodsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val fieldsCsv: RegularFileProperty
|
||||
@get:Optional
|
||||
@get:InputFile
|
||||
abstract val extraNotchSrgMappings: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val notchToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val notchToMcp: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val mcpToNotch: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val mcpToSrg: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val srgToNotch: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val srgToMcp: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val inSrg: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val notchToSrg: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val notchToMcp: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mcpToNotch: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mcpToSrg: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val srgToNotch: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val srgToMcp: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val config = mcpConfig(configFile)
|
||||
val inSrg = mcpFile(configFile, config.data.mappings)
|
||||
|
||||
val methods = HashMap<String, String>()
|
||||
val fields = HashMap<String, String>()
|
||||
readCsvs(methods, fields)
|
||||
|
||||
val inSet = MappingFormats.TSRG.createReader(inSrg.toPath()).use { it.read() }
|
||||
MappingFormats.TSRG.createReader(extraNotchSrgMappings.file.toPath()).use { it.read(inSet) }
|
||||
val inSet = MappingFormats.TSRG.createReader(inSrg.file.toPath()).use { it.read() }
|
||||
extraNotchSrgMappings.fileOrNull?.toPath()?.let { path ->
|
||||
MappingFormats.TSRG.createReader(path).use { it.read(inSet) }
|
||||
}
|
||||
|
||||
ensureParentExists(notchToSrg, notchToMcp, mcpToNotch, mcpToSrg, srgToNotch, srgToMcp)
|
||||
createMappings(inSet, methods, fields)
|
||||
|
@ -96,10 +97,12 @@ open class GenerateSrgs : DefaultTask() {
|
|||
|
||||
private fun createMappings(inSet: MappingSet, methods: Map<String, String>, fields: Map<String, String>) {
|
||||
val notchToSrgSet = MappingSet.create()
|
||||
|
||||
for (mapping in inSet.topLevelClassMappings) {
|
||||
val newMapping = notchToSrgSet.createTopLevelClassMapping(mapping.obfuscatedName, mapping.deobfuscatedName)
|
||||
remapMembers(mapping, newMapping)
|
||||
}
|
||||
handleKeywordMappings(notchToSrgSet)
|
||||
|
||||
// We have Notch -> SRG
|
||||
val srgToNotchSet = notchToSrgSet.reverse()
|
||||
|
@ -138,6 +141,39 @@ open class GenerateSrgs : DefaultTask() {
|
|||
)
|
||||
}
|
||||
|
||||
private fun handleKeywordMappings(mappings: MappingSet) {
|
||||
for (classMapping in mappings.topLevelClassMappings) {
|
||||
handleKeywordMappingClass(classMapping)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleKeywordMappingClass(classMapping: ClassMapping<*, *>) {
|
||||
for (innerClassMapping in classMapping.innerClassMappings) {
|
||||
handleKeywordMappingClass(innerClassMapping)
|
||||
}
|
||||
for (fieldMapping in classMapping.fieldMappings) {
|
||||
if (fieldMapping.obfuscatedName in javaKeywords) {
|
||||
val sourceName = fieldMapping.obfuscatedName + '_'
|
||||
if (classMapping.hasFieldMapping(sourceName)) {
|
||||
// If the "source name" of the mapping already exists, just skip it. I don't even know what would
|
||||
// happen in this case at decompile time to be honest
|
||||
continue
|
||||
}
|
||||
classMapping.createFieldMapping(sourceName, fieldMapping.deobfuscatedName)
|
||||
}
|
||||
}
|
||||
for (methodMapping in classMapping.methodMappings) {
|
||||
if (methodMapping.obfuscatedName in javaKeywords) {
|
||||
val sourceName = methodMapping.obfuscatedName + "_"
|
||||
val sourceSignature = MethodSignature(sourceName, methodMapping.signature.descriptor)
|
||||
if (classMapping.hasMethodMapping(sourceSignature)) {
|
||||
continue
|
||||
}
|
||||
classMapping.createMethodMapping(sourceSignature, methodMapping.deobfuscatedName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapClass(inClass: ClassMapping<*, *>, outClass: ClassMapping<*, *>, methods: Map<String, String>, fields: Map<String, String>) {
|
||||
for (fieldMapping in inClass.fieldMappings) {
|
||||
val mcpName = fields[fieldMapping.deobfuscatedName] ?: fieldMapping.deobfuscatedName
|
||||
|
@ -155,13 +191,7 @@ open class GenerateSrgs : DefaultTask() {
|
|||
}
|
||||
|
||||
private fun remapAnonymousClasses(mapping: InnerClassMapping, target: ClassMapping<*, *>) {
|
||||
val newMapping = if (mapping.obfuscatedName.toIntOrNull() != null) {
|
||||
// This is an anonymous class, keep the index
|
||||
target.createInnerClassMapping(mapping.deobfuscatedName, mapping.deobfuscatedName)
|
||||
} else {
|
||||
target.createInnerClassMapping(mapping.obfuscatedName, mapping.deobfuscatedName)
|
||||
}
|
||||
|
||||
val newMapping = target.createInnerClassMapping(mapping.obfuscatedName, mapping.deobfuscatedName)
|
||||
remapMembers(mapping, newMapping)
|
||||
}
|
||||
|
||||
|
@ -177,3 +207,56 @@ open class GenerateSrgs : DefaultTask() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val javaKeywords: HashSet<String> = hashSetOf(
|
||||
"abstract",
|
||||
"continue",
|
||||
"for",
|
||||
"new",
|
||||
"switch",
|
||||
"assert",
|
||||
"default",
|
||||
"goto",
|
||||
"package",
|
||||
"synchronized",
|
||||
"boolean",
|
||||
"do",
|
||||
"if",
|
||||
"private",
|
||||
"this",
|
||||
"break",
|
||||
"double",
|
||||
"implements",
|
||||
"protected",
|
||||
"throw",
|
||||
"byte",
|
||||
"else",
|
||||
"import",
|
||||
"public",
|
||||
"throws",
|
||||
"case",
|
||||
"enum",
|
||||
"instanceof",
|
||||
"return",
|
||||
"transient",
|
||||
"catch",
|
||||
"extends",
|
||||
"int",
|
||||
"short",
|
||||
"try",
|
||||
"char",
|
||||
"final",
|
||||
"interface",
|
||||
"static",
|
||||
"void",
|
||||
"class",
|
||||
"finally",
|
||||
"long",
|
||||
"strictfp",
|
||||
"volatile",
|
||||
"const",
|
||||
"float",
|
||||
"native",
|
||||
"super",
|
||||
"while"
|
||||
)
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import com.github.salomonbrys.kotson.array
|
||||
import com.github.salomonbrys.kotson.fromJson
|
||||
import com.github.salomonbrys.kotson.get
|
||||
import com.github.salomonbrys.kotson.string
|
||||
import com.google.gson.JsonObject
|
||||
import io.papermc.paperweight.util.Constants
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.ext
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.getWithEtag
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.toProvider
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import util.MinecraftManifest
|
||||
|
||||
open class GetRemoteJsons : DefaultTask() {
|
||||
|
||||
@Input
|
||||
val config: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val artifactOutputFile: RegularFileProperty = project.objects.run {
|
||||
fileProperty().convention(project.toProvider {
|
||||
project.cache.resolve(paperTaskOutput("mc-libraries", "txt"))
|
||||
})
|
||||
}
|
||||
|
||||
init {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val cache = project.cache
|
||||
val extension = project.ext
|
||||
|
||||
val mcManifestJson = cache.resolve(Constants.MC_MANIFEST)
|
||||
val mcVersionJson = cache.resolve(Constants.VERSION_JSON)
|
||||
ensureParentExists(mcManifestJson, mcVersionJson)
|
||||
|
||||
// McManifest.json
|
||||
val mcManifestEtag = cache.resolve("${Constants.MC_MANIFEST}.etag")
|
||||
getWithEtag(Constants.MC_MANIFEST_URL, mcManifestJson, mcManifestEtag)
|
||||
val mcManifestText = gson.fromJson<MinecraftManifest>(mcManifestJson.readText())
|
||||
|
||||
val mcVersionEtag = mcVersionJson.resolveSibling("${mcVersionJson.name}.etag")
|
||||
getWithEtag(mcManifestText.versions.first { it.id == extension.minecraftVersion.get() }.url, mcVersionJson, mcVersionEtag)
|
||||
|
||||
val jsonObject = mcVersionJson.bufferedReader().use { reader ->
|
||||
gson.fromJson<JsonObject>(reader)
|
||||
}
|
||||
|
||||
val conf = config.get()
|
||||
artifactOutputFile.file.delete()
|
||||
artifactOutputFile.file.bufferedWriter().use { writer ->
|
||||
for (library in jsonObject["libraries"].array) {
|
||||
val artifact = library["name"].string
|
||||
project.dependencies.add(conf, artifact)
|
||||
writer.appendln(artifact)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
109
src/main/kotlin/tasks/InspectVanillaJar.kt
Normal file
109
src/main/kotlin/tasks/InspectVanillaJar.kt
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.objectweb.asm.ClassReader
|
||||
import org.objectweb.asm.ClassVisitor
|
||||
import org.objectweb.asm.FieldVisitor
|
||||
import org.objectweb.asm.Opcodes
|
||||
|
||||
abstract class InspectVanillaJar : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputFile.convention(defaultOutput("txt"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val outputList = mutableListOf<LoggerField>()
|
||||
|
||||
val jarFile = inputJar.file
|
||||
archives.zipTree(jarFile).matching {
|
||||
include("/*.class")
|
||||
include("/net/minecraft/**/*.class")
|
||||
}.forEach { file ->
|
||||
if (file.isDirectory) {
|
||||
return@forEach
|
||||
}
|
||||
val classData = file.readBytes()
|
||||
|
||||
val reader = ClassReader(classData)
|
||||
reader.accept(LoggerFinder(outputList), 0)
|
||||
|
||||
}
|
||||
|
||||
outputFile.file.bufferedWriter(Charsets.UTF_8).use { writer ->
|
||||
for (loggerField in outputList) {
|
||||
writer.append(loggerField.className)
|
||||
writer.append(' ')
|
||||
writer.append(loggerField.fieldName)
|
||||
writer.newLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoggerFinder(private val fields: MutableList<LoggerField>) : ClassVisitor(Opcodes.ASM8) {
|
||||
|
||||
private var currentClass: String? = null
|
||||
|
||||
override fun visit(
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String?,
|
||||
interfaces: Array<out String>?
|
||||
) {
|
||||
this.currentClass = name
|
||||
}
|
||||
|
||||
override fun visitField(
|
||||
access: Int,
|
||||
name: String,
|
||||
descriptor: String,
|
||||
signature: String?,
|
||||
value: Any?
|
||||
): FieldVisitor? {
|
||||
val className = currentClass ?: return null
|
||||
if (descriptor != "Lorg/apache/logging/log4j/Logger;") {
|
||||
return null
|
||||
}
|
||||
fields += LoggerField(className, name)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
data class LoggerField(val className: String, val fieldName: String)
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,42 +23,38 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.cadixdev.atlas.Atlas
|
||||
import org.cadixdev.bombe.asm.jar.JarEntryRemappingTransformer
|
||||
import org.cadixdev.lorenz.asm.LorenzRemapper
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.cadixdev.at.AccessTransformSet
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
open class RemapVanillaJarSrg : DefaultTask() {
|
||||
abstract class MergeAccessTransforms : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFiles
|
||||
abstract val inputFiles: ListProperty<RegularFile>
|
||||
|
||||
@InputFile
|
||||
val mappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
override fun init() {
|
||||
outputFile.convention(defaultOutput("at"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
ensureParentExists(outputJar.file)
|
||||
ensureDeleted(outputJar.file)
|
||||
val ats = inputFiles.get()
|
||||
.map { AccessTransformFormats.FML.read(it.asFile.toPath()) }
|
||||
|
||||
val mappings = MappingFormats.TSRG.createReader(mappings.file.toPath()).use { it.read() }
|
||||
Atlas().apply {
|
||||
install { ctx ->
|
||||
JarEntryRemappingTransformer(LorenzRemapper(mappings, ctx.inheritanceProvider()))
|
||||
}
|
||||
run(inputJar.file.toPath(), outputJar.file.toPath())
|
||||
val outputAt = AccessTransformSet.create()
|
||||
for (at in ats) {
|
||||
outputAt.merge(at)
|
||||
}
|
||||
|
||||
AccessTransformFormats.FML.write(outputFile.file.toPath(), outputAt)
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -31,23 +30,23 @@ import org.gradle.api.tasks.TaskAction
|
|||
import java.io.PrintWriter
|
||||
import java.util.regex.Pattern
|
||||
|
||||
open class PatchMcpCsv : DefaultTask() {
|
||||
abstract class PatchMcpCsv : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
val fieldsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val methodsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val paramsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val changesFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val fieldsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val methodsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val paramsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val changesFile: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val paperFieldCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val paperMethodCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@OutputFile
|
||||
val paperParamCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val paperFieldCsv: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val paperMethodCsv: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val paperParamCsv: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,33 +22,35 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import org.gradle.api.DefaultTask
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class SetupMcpDependencies : DefaultTask() {
|
||||
abstract class RemapAccessTransform : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@Input
|
||||
val forgeFlowerConfig: Property<String> = project.objects.property()
|
||||
@Input
|
||||
val mcInjectorConfig: Property<String> = project.objects.property()
|
||||
@get:InputFile
|
||||
abstract val inputFile: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val mappings: RegularFileProperty
|
||||
|
||||
init {
|
||||
outputs.upToDateWhen { false }
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputFile.convention(defaultOutput("at"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val config = mcpConfig(configFile)
|
||||
val at = AccessTransformFormats.FML.read(inputFile.file.toPath())
|
||||
val mappingSet = MappingFormats.TSRG.createReader(mappings.file.toPath()).use { it.read() }
|
||||
|
||||
project.dependencies.add(forgeFlowerConfig.get(), config.functions.getValue("decompile").version)
|
||||
project.dependencies.add(mcInjectorConfig.get(), config.functions.getValue("mcinject").version)
|
||||
val resultAt = at.remap(mappingSet)
|
||||
AccessTransformFormats.FML.write(outputFile.file.toPath(), resultAt)
|
||||
}
|
||||
}
|
|
@ -1,267 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import org.cadixdev.at.AccessTransformSet
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.cadixdev.mercury.Mercury
|
||||
import org.cadixdev.mercury.RewriteContext
|
||||
import org.cadixdev.mercury.SourceProcessor
|
||||
import org.cadixdev.mercury.SourceRewriter
|
||||
import org.cadixdev.mercury.at.AccessTransformerRewriter
|
||||
import org.cadixdev.mercury.extra.AccessAnalyzerProcessor
|
||||
import org.cadixdev.mercury.extra.BridgeMethodRewriter
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper
|
||||
import org.cadixdev.mercury.util.BombeBindings
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding
|
||||
import org.eclipse.jdt.core.dom.IVariableBinding
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration
|
||||
import org.eclipse.jdt.core.dom.Modifier
|
||||
import org.eclipse.jdt.core.dom.SimpleName
|
||||
import org.eclipse.jdt.core.dom.VariableDeclaration
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import java.io.File
|
||||
|
||||
open class RemapSources : ZippedTask() {
|
||||
|
||||
@InputFile
|
||||
val vanillaJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val vanillaRemappedSpigotJar: RegularFileProperty = project.objects.fileProperty() // Required for pre-remap pass
|
||||
@InputFile
|
||||
val vanillaRemappedSrgJar: RegularFileProperty = project.objects.fileProperty() // Required for post-remap pass
|
||||
@InputFile
|
||||
val mappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@Input
|
||||
val configuration: Property<String> = project.objects.property()
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputDirectory
|
||||
val spigotServerDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
@InputDirectory
|
||||
val spigotApiDir: DirectoryProperty = project.objects.directoryProperty()
|
||||
|
||||
@OutputFile
|
||||
val generatedAt: RegularFileProperty = defaultOutput("at")
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
val config = mcpConfig(configFile)
|
||||
val constructors = mcpFile(configFile, config.data.constructors)
|
||||
|
||||
val mappings = MappingFormats.TSRG.createReader(mappings.file.toPath()).use { it.read() }
|
||||
|
||||
val srcDir = spigotServerDir.file.resolve("src/main/java")
|
||||
val pass1Dir = rootDir.resolve("pass1")
|
||||
val outDir = rootDir.resolve("out")
|
||||
|
||||
val configuration = project.configurations[configuration.get()]
|
||||
|
||||
val ats = AccessTransformSet.create()
|
||||
|
||||
// Remap any references Spigot maps to SRG
|
||||
Mercury().apply {
|
||||
classPath.addAll(listOf(
|
||||
vanillaJar.asFile.get().toPath(),
|
||||
vanillaRemappedSpigotJar.asFile.get().toPath(),
|
||||
spigotApiDir.file.resolve("src/main/java").toPath()
|
||||
))
|
||||
|
||||
for (file in configuration.resolvedConfiguration.files) {
|
||||
classPath.add(file.toPath())
|
||||
}
|
||||
|
||||
// Generate AT
|
||||
processors.add(AccessAnalyzerProcessor.create(ats, mappings))
|
||||
process(srcDir.toPath())
|
||||
|
||||
// Remap
|
||||
processors.clear()
|
||||
processors.addAll(listOf(
|
||||
MercuryRemapper.create(mappings),
|
||||
BridgeMethodRewriter.create(),
|
||||
AccessTransformerRewriter.create(ats)
|
||||
))
|
||||
|
||||
rewrite(srcDir.toPath(), pass1Dir.toPath())
|
||||
}
|
||||
|
||||
Mercury().apply {
|
||||
// Remap SRG parameters
|
||||
classPath.addAll(listOf(
|
||||
vanillaJar.asFile.get().toPath(),
|
||||
vanillaRemappedSrgJar.asFile.get().toPath(),
|
||||
spigotApiDir.file.resolve("src/main/java").toPath()
|
||||
))
|
||||
|
||||
processors.add(SrgParameterRemapper(constructors))
|
||||
rewrite(pass1Dir.toPath(), outDir.toPath())
|
||||
}
|
||||
|
||||
// Only leave remapped source
|
||||
val fileList = rootDir.listFiles() ?: throw PaperweightException("Could not list files in $rootDir")
|
||||
for (file in fileList) {
|
||||
if (file != outDir) {
|
||||
file.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
// Move out/* to base dir
|
||||
val files = outDir.listFiles() ?: throw PaperweightException("No files found in $outDir")
|
||||
for (file in files) {
|
||||
file.renameTo(rootDir.resolve(file.name))
|
||||
}
|
||||
outDir.delete()
|
||||
|
||||
// And write generated AT file
|
||||
AccessTransformFormats.FML.write(generatedAt.asFile.get().toPath(), ats)
|
||||
}
|
||||
}
|
||||
|
||||
class SrgParameterRemapper(constructors: File) : SourceRewriter {
|
||||
|
||||
private val constructorMap = hashMapOf<String, MutableList<ConstructorNode>>()
|
||||
|
||||
init {
|
||||
constructors.useLines { lines ->
|
||||
lines.forEach { line ->
|
||||
val parts = line.split(' ')
|
||||
constructorMap.compute(parts[1].replace('/', '.')) { _, v ->
|
||||
val node = ConstructorNode(parts[0].toInt(), parts[2])
|
||||
if (v == null) {
|
||||
return@compute mutableListOf(node)
|
||||
} else {
|
||||
v += node
|
||||
return@compute v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (list in constructorMap.values) {
|
||||
// Put bigger numbers first
|
||||
// Old constructor entries are still present, just with smaller numbers. So we don't want to grab an older
|
||||
// entry
|
||||
list.reverse()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFlags(): Int = SourceProcessor.FLAG_RESOLVE_BINDINGS
|
||||
|
||||
override fun rewrite(context: RewriteContext) {
|
||||
context.compilationUnit.accept(SrgParameterVisitor(context, constructorMap))
|
||||
}
|
||||
}
|
||||
|
||||
data class ConstructorNode(
|
||||
val id: Int,
|
||||
val signature: String
|
||||
)
|
||||
|
||||
class SrgParameterVisitor(
|
||||
private val context: RewriteContext,
|
||||
private val constructors: Map<String, List<ConstructorNode>>
|
||||
) : ASTVisitor() {
|
||||
|
||||
companion object {
|
||||
private val MATCHER = Regex("func_(\\d+)_.*")
|
||||
}
|
||||
|
||||
override fun visit(node: SimpleName): Boolean {
|
||||
val binding = node.resolveBinding() as? IVariableBinding ?: return false
|
||||
if (!binding.isParameter) {
|
||||
return false
|
||||
}
|
||||
|
||||
val variableDecl = context.compilationUnit.findDeclaringNode(binding.variableDeclaration) as VariableDeclaration
|
||||
|
||||
val method = binding.declaringMethod
|
||||
val methodDecl = context.compilationUnit.findDeclaringNode(method) as? MethodDeclaration ?: return false
|
||||
|
||||
handleMethod(node, methodDecl, method, variableDecl)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun handleMethod(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding, variableDecl: VariableDeclaration) {
|
||||
if (method.isConstructor) {
|
||||
handleConstructor(node, methodDecl, method, variableDecl)
|
||||
return
|
||||
}
|
||||
|
||||
val match = MATCHER.matchEntire(method.name) ?: return
|
||||
val isStatic = method.modifiers and Modifier.STATIC != 0
|
||||
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
if (!isStatic) {
|
||||
index++
|
||||
}
|
||||
|
||||
val paramName = "p_${match.groupValues[1]}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
private fun handleConstructor(node: SimpleName, methodDecl: MethodDeclaration, method: IMethodBinding, variableDecl: VariableDeclaration) {
|
||||
val constructorNodes = constructors[method.declaringClass.binaryName] ?: return
|
||||
|
||||
val constructorNode = constructorNodes.firstOrNull { constructorNode ->
|
||||
constructorNode.signature == BombeBindings.convertSignature(method).descriptor.toString()
|
||||
} ?: return
|
||||
|
||||
val id = constructorNode.id
|
||||
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
// Constructors are never static
|
||||
index++
|
||||
|
||||
val paramName = "p_i${id}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
private fun getParameterIndex(methodDecl: MethodDeclaration, decl: VariableDeclaration): Int {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val params = methodDecl.parameters() as List<VariableDeclaration>
|
||||
return params.indexOfFirst { it === decl }
|
||||
}
|
||||
}
|
135
src/main/kotlin/tasks/RemapSpigotAt.kt
Normal file
135
src/main/kotlin/tasks/RemapSpigotAt.kt
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.cadixdev.at.AccessChange
|
||||
import org.cadixdev.at.AccessTransform
|
||||
import org.cadixdev.at.AccessTransformSet
|
||||
import org.cadixdev.at.ModifierChange
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.bombe.type.MethodDescriptor
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.util.jar.JarFile
|
||||
|
||||
abstract class RemapSpigotAt : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val spigotAt: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val mapping: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputFile.convention(defaultOutput("at"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val outputAt = AccessTransformSet.create()
|
||||
|
||||
spigotAt.file.useLines { lines ->
|
||||
JarFile(inputJar.file).use { jarFile ->
|
||||
for (line in lines) {
|
||||
if (line.isBlank() || line.startsWith('#')) {
|
||||
continue
|
||||
}
|
||||
|
||||
val (access, desc) = line.split(' ')
|
||||
|
||||
if (desc.contains('(')) {
|
||||
// method
|
||||
val index = desc.indexOf('(')
|
||||
val methodDesc = desc.substring(index)
|
||||
val classAndMethodName = desc.substring(0, index)
|
||||
val slashIndex = classAndMethodName.lastIndexOf('/')
|
||||
val className = classAndMethodName.substring(0, slashIndex)
|
||||
val methodName = classAndMethodName.substring(slashIndex + 1)
|
||||
|
||||
outputAt.getOrCreateClass(className).replaceMethod(
|
||||
MethodSignature(methodName, MethodDescriptor.of(methodDesc)),
|
||||
parseAccess(access)
|
||||
)
|
||||
} else {
|
||||
// either field or class
|
||||
if (jarFile.getJarEntry("$desc.class") == null) {
|
||||
// field
|
||||
val index = desc.lastIndexOf('/')
|
||||
val className = desc.substring(0, index)
|
||||
val fieldName = desc.substring(index + 1)
|
||||
outputAt.getOrCreateClass(className).replaceField(fieldName, parseAccess(access))
|
||||
} else {
|
||||
// class
|
||||
outputAt.getOrCreateClass(desc).replace(parseAccess(access))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val mappings = MappingFormats.TSRG.createReader(mapping.file.toPath()).use { it.read() }
|
||||
val remappedAt = outputAt.remap(mappings)
|
||||
|
||||
AccessTransformFormats.FML.write(outputFile.file.toPath(), remappedAt)
|
||||
}
|
||||
|
||||
private fun parseAccess(text: String): AccessTransform {
|
||||
val index = text.indexOfAny(charArrayOf('+', '-'))
|
||||
return if (index == -1) {
|
||||
// only access
|
||||
AccessTransform.of(parseAccessChange(text))
|
||||
} else {
|
||||
val accessChange = parseAccessChange(text.substring(0, index))
|
||||
val modifierChange = parseModifierChange(text[index])
|
||||
AccessTransform.of(accessChange, modifierChange)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseAccessChange(text: String): AccessChange {
|
||||
return when (text) {
|
||||
"public" -> AccessChange.PUBLIC
|
||||
"private" -> AccessChange.PRIVATE
|
||||
"protected" -> AccessChange.PROTECTED
|
||||
"default" -> AccessChange.PACKAGE_PRIVATE
|
||||
else -> AccessChange.NONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseModifierChange(c: Char): ModifierChange {
|
||||
return when (c) {
|
||||
'+' -> ModifierChange.ADD
|
||||
'-' -> ModifierChange.REMOVE
|
||||
else -> ModifierChange.NONE
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,14 +31,14 @@ import java.io.BufferedWriter
|
|||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
open class RemapSrgSources : ZippedTask() {
|
||||
abstract class RemapSrgSources : ZippedTask() {
|
||||
|
||||
@InputFile
|
||||
val methodsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val fieldsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val paramsCsv: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val methodsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val fieldsCsv: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val paramsCsv: RegularFileProperty
|
||||
|
||||
private val methods = hashMapOf<String, String>()
|
||||
private val methodDocs = hashMapOf<String, String>()
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -28,52 +27,44 @@ import io.papermc.paperweight.util.cache
|
|||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import io.papermc.paperweight.util.wrapException
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class RemapVanillaJarSpigot : DefaultTask() {
|
||||
abstract class RemapVanillaJarSpigot : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val classMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val memberMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val packageMappings: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val accessTransformers: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val workDirName: Property<String>
|
||||
@get:InputFile
|
||||
abstract val specialSourceJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val specialSource2Jar: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val classMapCommand: Property<String>
|
||||
@get:Input
|
||||
abstract val memberMapCommand: Property<String>
|
||||
@get:Input
|
||||
abstract val finalMapCommand: Property<String>
|
||||
|
||||
@InputFile
|
||||
val classMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val memberMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val packageMappings: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val accessTransformers: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@Input
|
||||
val workDirName: Property<String> = project.objects.property()
|
||||
|
||||
@InputFile
|
||||
val specialSourceJar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@InputFile
|
||||
val specialSource2Jar: RegularFileProperty = project.objects.fileProperty()
|
||||
|
||||
@Input
|
||||
val classMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@Input
|
||||
val memberMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@Input
|
||||
val finalMapCommand: Property<String> = project.objects.property()
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
@ -92,14 +83,15 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
val packageMappingsPath = packageMappings.asFile.get().canonicalPath
|
||||
val accessTransformersPath = accessTransformers.asFile.get().canonicalPath
|
||||
|
||||
val work = layout.projectDirectory.file(workDirName.get())
|
||||
|
||||
try {
|
||||
println("Applying class mappings...")
|
||||
wrapException("Failed to apply class mappings") {
|
||||
val logFile = project.cache.resolve(paperTaskOutput("class.log"))
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("class.log"))
|
||||
logFile.delete()
|
||||
runJar(
|
||||
specialSource2Jar,
|
||||
workingDir = workDirName.get(),
|
||||
workingDir = work,
|
||||
logFile = logFile,
|
||||
args = *doReplacements(classMapCommand.get(), inputJarPath, classMappingPath, classJarPath) {
|
||||
// ignore excludes, we actually want to map every class
|
||||
|
@ -107,24 +99,22 @@ open class RemapVanillaJarSpigot : DefaultTask() {
|
|||
}
|
||||
)
|
||||
}
|
||||
println("Applying member mappings...")
|
||||
wrapException("Failed to apply member mappings") {
|
||||
val logFile = project.cache.resolve(paperTaskOutput("member.log"))
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("member.log"))
|
||||
logFile.delete()
|
||||
runJar(
|
||||
specialSource2Jar,
|
||||
workingDir = workDirName.get(),
|
||||
workingDir = work,
|
||||
logFile = logFile,
|
||||
args = *doReplacements(memberMapCommand.get(), classJarPath, memberMappingsPath, membersJarPath)
|
||||
)
|
||||
}
|
||||
println("Creating remapped jar...")
|
||||
wrapException("Failed to create remapped jar") {
|
||||
val logFile = project.cache.resolve(paperTaskOutput("final.log"))
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("final.log"))
|
||||
logFile.delete()
|
||||
runJar(
|
||||
specialSourceJar,
|
||||
workingDir = workDirName.get(),
|
||||
workingDir = work,
|
||||
logFile = logFile,
|
||||
args = *doReplacements(finalMapCommand.get(), membersJarPath, accessTransformersPath, packageMappingsPath, outputJarPath)
|
||||
)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,57 +23,67 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.McpConfig
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.decompile
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class RunForgeFlower : DefaultTask() {
|
||||
abstract class RunForgeFlower : BaseTask() {
|
||||
|
||||
@Input
|
||||
val configuration: Property<String> = project.objects.property()
|
||||
@get:InputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val executable: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val libraries: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val libraries: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val config = mcpConfig(configFile)
|
||||
val out = outputJar.file
|
||||
val target = out.resolveSibling("${out.name}.dir")
|
||||
if (target.exists()) {
|
||||
target.deleteRecursively()
|
||||
}
|
||||
target.mkdirs()
|
||||
|
||||
val forgeFlowerArgs = config.functions.getValue("decompile").args
|
||||
val jvmArgs = config.functions.getValue("decompile").jvmargs ?: listOf()
|
||||
val config = gson.fromJson<McpConfig>(configFile)
|
||||
|
||||
val argList = forgeFlowerArgs.map {
|
||||
val argList = config.functions.decompile.args.map {
|
||||
when (it) {
|
||||
"{libraries}" -> libraries.file.absolutePath
|
||||
"{input}" -> inputJar.file.absolutePath
|
||||
"{output}" -> outputJar.file.absolutePath
|
||||
"{output}" -> target.absolutePath
|
||||
else -> it
|
||||
}
|
||||
}
|
||||
|
||||
val logFile = project.cache.resolve(paperTaskOutput("log"))
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("log"))
|
||||
logFile.delete()
|
||||
|
||||
val forgeFlowerJar = project.configurations[configuration.get()].resolve().single()
|
||||
runJar(forgeFlowerJar, project.cache, logFile, jvmArgs = jvmArgs, args = *argList.toTypedArray())
|
||||
val jvmArgs = config.functions.decompile.jvmargs ?: listOf()
|
||||
|
||||
runJar(executable.file, layout.cache, logFile, jvmArgs = jvmArgs, args = *argList.toTypedArray())
|
||||
|
||||
// FernFlower is weird with how it does directory output
|
||||
target.resolve(inputJar.file.name).renameTo(out)
|
||||
target.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,60 +22,65 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.McpConfig
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.mcpConfig
|
||||
import io.papermc.paperweight.util.mcpFile
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.mcinject
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class RunMcInjector : DefaultTask() {
|
||||
abstract class RunMcInjector : BaseTask() {
|
||||
|
||||
@Input
|
||||
val configuration: Property<String> = project.objects.property()
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@InputFile
|
||||
val configFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val executable: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
@OutputFile
|
||||
val logFile: RegularFileProperty = defaultOutput("log")
|
||||
@get:InputFile
|
||||
abstract val exceptions: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val access: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val constructors: RegularFileProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
@get:Internal
|
||||
abstract val logFile: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
logFile.convention(defaultOutput("log"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val config = mcpConfig(configFile)
|
||||
val exceptions = mcpFile(configFile, config.data.exceptions)
|
||||
val access = mcpFile(configFile, config.data.access)
|
||||
val constructors = mcpFile(configFile, config.data.constructors)
|
||||
val config = gson.fromJson<McpConfig>(configFile)
|
||||
|
||||
val mcInjectorArgs = config.functions.getValue("mcinject").args
|
||||
val jvmArgs = config.functions.getValue("mcinject").jvmargs ?: listOf()
|
||||
|
||||
val argList = mcInjectorArgs.map {
|
||||
val argList = config.functions.mcinject.args.map {
|
||||
when (it) {
|
||||
"{input}" -> inputJar.file.absolutePath
|
||||
"{output}" -> outputJar.file.absolutePath
|
||||
"{log}" -> logFile.file.absolutePath
|
||||
"{exceptions}" -> exceptions.absolutePath
|
||||
"{access}" -> access.absolutePath
|
||||
"{constructors}" -> constructors.absolutePath
|
||||
"{exceptions}" -> exceptions.file.absolutePath
|
||||
"{access}" -> access.file.absolutePath
|
||||
"{constructors}" -> constructors.file.absolutePath
|
||||
else -> it
|
||||
}
|
||||
}
|
||||
|
||||
val mcInjectorJar = project.configurations[configuration.get()].resolve().single()
|
||||
val jvmArgs = config.functions.mcinject.jvmargs ?: listOf()
|
||||
|
||||
runJar(mcInjectorJar, project.cache, logFile = null, jvmArgs = jvmArgs, args = *argList.toTypedArray())
|
||||
runJar(executable, layout.cache, logFile = null, jvmArgs = jvmArgs, args = *argList.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
|
84
src/main/kotlin/tasks/RunSpecialSource.kt
Normal file
84
src/main/kotlin/tasks/RunSpecialSource.kt
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import io.papermc.paperweight.util.McpConfig
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.rename
|
||||
import io.papermc.paperweight.util.runJar
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class RunSpecialSource : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val mappings: RegularFileProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val executable: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val out = outputJar.file
|
||||
ensureParentExists(out)
|
||||
ensureDeleted(out)
|
||||
|
||||
val config = gson.fromJson<McpConfig>(configFile)
|
||||
|
||||
val argList = config.functions.rename.args.map {
|
||||
when (it) {
|
||||
"{input}" -> inputJar.file.absolutePath
|
||||
"{output}" -> outputJar.file.absolutePath
|
||||
"{mappings}" -> mappings.file.absolutePath
|
||||
else -> it
|
||||
}
|
||||
}
|
||||
|
||||
val jvmArgs = config.functions.rename.jvmargs ?: listOf()
|
||||
|
||||
val logFile = layout.cache.resolve(paperTaskOutput("log"))
|
||||
logFile.delete()
|
||||
|
||||
runJar(executable.file, layout.cache, logFile, jvmArgs = jvmArgs, args = *argList.toTypedArray())
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,22 +22,30 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import com.github.salomonbrys.kotson.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import util.BuildDataInfo
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
open class GatherBuildData : DefaultTask() {
|
||||
abstract class SetupMcLibraries : DefaultTask() {
|
||||
|
||||
@OutputFile
|
||||
val buildDataInfoFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:Input
|
||||
abstract val dependencies: ListProperty<String>
|
||||
|
||||
val buildDataInfo: Provider<BuildDataInfo> = buildDataInfoFile.map {
|
||||
it.asFile.bufferedReader().use { reader ->
|
||||
gson.fromJson(reader)
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val list = dependencies.get().sorted()
|
||||
|
||||
outputFile.file.bufferedWriter().use { writer ->
|
||||
for (line in list) {
|
||||
writer.appendln(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.property
|
||||
import org.w3c.dom.Element
|
||||
import java.io.File
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
||||
open class SetupSpigotDependencies : DefaultTask() {
|
||||
|
||||
@InputDirectory
|
||||
val spigotApi: DirectoryProperty = project.objects.directoryProperty()
|
||||
@InputDirectory
|
||||
val spigotServer: DirectoryProperty = project.objects.directoryProperty()
|
||||
|
||||
@Input
|
||||
val configurationName: Property<String> = project.objects.property()
|
||||
|
||||
init {
|
||||
// we set dependencies here, can't cache this
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val apiDeps = parsePom(spigotApi.file.resolve("pom.xml"))
|
||||
val serverDeps = parsePom(spigotServer.file.resolve("pom.xml"))
|
||||
|
||||
for (dep in apiDeps) {
|
||||
project.dependencies.add(configurationName.get(), dep)
|
||||
}
|
||||
for (dep in serverDeps) {
|
||||
project.dependencies.add(configurationName.get(), dep)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parsePom(pomFile: File): List<String> {
|
||||
val depList = arrayListOf<String>()
|
||||
|
||||
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
val doc = pomFile.inputStream().buffered().use { stream ->
|
||||
stream.buffered().use { buffered ->
|
||||
builder.parse(buffered)
|
||||
}
|
||||
}
|
||||
|
||||
doc.documentElement.normalize()
|
||||
|
||||
val list = doc.getElementsByTagName("dependencies")
|
||||
for (i in 0 until list.length) {
|
||||
val node = list.item(i) as? Element ?: continue
|
||||
|
||||
val depNode = node.getElementsByTagName("dependency")
|
||||
for (j in 0 until depNode.length) {
|
||||
val dependency = depNode.item(j) as? Element ?: continue
|
||||
val text = getDependency(dependency) ?: continue
|
||||
depList += text
|
||||
}
|
||||
}
|
||||
|
||||
return depList
|
||||
}
|
||||
|
||||
private fun getDependency(node: Element): String? {
|
||||
val scopeNode = node.getElementsByTagName("scope")
|
||||
val scope = if (scopeNode.length == 0) {
|
||||
"compile"
|
||||
} else {
|
||||
scopeNode.item(0).textContent
|
||||
}
|
||||
|
||||
if (scope != "compile") {
|
||||
return null
|
||||
}
|
||||
|
||||
val group = node.getElementsByTagName("groupId").item(0).textContent
|
||||
val artifact = node.getElementsByTagName("artifactId").item(0).textContent
|
||||
val version = node.getElementsByTagName("version").item(0).textContent
|
||||
|
||||
if (version.contains("\${")) {
|
||||
// Don't handle complicated things
|
||||
// We don't need to (for now anyways)
|
||||
return null
|
||||
}
|
||||
|
||||
return "$group:$artifact:$version"
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,32 +22,31 @@
|
|||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Classpath
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.property
|
||||
|
||||
open class WriteLibrariesFile : DefaultTask() {
|
||||
abstract class WriteLibrariesFile : BaseTask() {
|
||||
|
||||
@Input
|
||||
val config: Property<String> = project.objects.property()
|
||||
@get:Classpath
|
||||
abstract val libraries: DirectoryProperty
|
||||
|
||||
@OutputFile
|
||||
val outputFile: RegularFileProperty = defaultOutput("txt")
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
init {
|
||||
outputs.upToDateWhen { false }
|
||||
override fun init() {
|
||||
outputFile.convention(defaultOutput("txt"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val files = project.configurations[config.get()].resolve().sorted()
|
||||
val files = libraries.file.listFiles()?.sorted()
|
||||
?: throw PaperweightException("Libraries directory does not exist")
|
||||
|
||||
outputFile.file.delete()
|
||||
outputFile.file.bufferedWriter().use { writer ->
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -29,7 +28,6 @@ import io.papermc.paperweight.util.file
|
|||
import io.papermc.paperweight.util.fileOrNull
|
||||
import io.papermc.paperweight.util.unzip
|
||||
import io.papermc.paperweight.util.zip
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
|
@ -38,17 +36,21 @@ import org.gradle.api.tasks.TaskAction
|
|||
import java.io.File
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
abstract class ZippedTask : DefaultTask() {
|
||||
abstract class ZippedTask : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
@Optional
|
||||
val inputZip: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
@get:Optional
|
||||
abstract val inputZip: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputZip: RegularFileProperty = defaultOutput("zip")
|
||||
@get:OutputFile
|
||||
abstract val outputZip: RegularFileProperty
|
||||
|
||||
abstract fun run(rootDir: File)
|
||||
|
||||
override fun init() {
|
||||
outputZip.convention(defaultOutput("zip"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun exec() {
|
||||
val outputZipFile = outputZip.file
|
||||
|
|
317
src/main/kotlin/tasks/download-task.kt
Normal file
317
src/main/kotlin/tasks/download-task.kt
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.Constants
|
||||
import io.papermc.paperweight.util.MavenArtifact
|
||||
import io.papermc.paperweight.util.McpConfig
|
||||
import io.papermc.paperweight.util.decompile
|
||||
import io.papermc.paperweight.util.download
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import io.papermc.paperweight.util.mcinject
|
||||
import io.papermc.paperweight.util.rename
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.workers.WorkAction
|
||||
import org.gradle.workers.WorkParameters
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import org.w3c.dom.Element
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
||||
abstract class DownloadTask : DefaultTask() {
|
||||
|
||||
@get:Input
|
||||
abstract val url: Property<String>
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputFile: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() = download(url, outputFile)
|
||||
}
|
||||
|
||||
abstract class DownloadMcpFiles : DefaultTask() {
|
||||
|
||||
@get:Input
|
||||
abstract val mcpMinecraftVersion: Property<String>
|
||||
@get:Input
|
||||
abstract val mcpConfigVersion: Property<String>
|
||||
@get:Input
|
||||
abstract val mcpMappingsChannel: Property<String>
|
||||
@get:Input
|
||||
abstract val mcpMappingsVersion: Property<String>
|
||||
|
||||
@get:OutputFile
|
||||
abstract val configZip: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mappingsZip: RegularFileProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val repo = listOf(Constants.FORGE_MAVEN_URL)
|
||||
|
||||
MavenArtifact(
|
||||
group = "de.oceanlabs.mcp",
|
||||
artifact = "mcp_config",
|
||||
version = mcpMinecraftVersion.get() + "-" + mcpConfigVersion.get(),
|
||||
extension = "zip"
|
||||
).downloadToFile(configZip.file, repo)
|
||||
|
||||
MavenArtifact(
|
||||
group = "de.oceanlabs.mcp",
|
||||
artifact = "mcp_${mcpMappingsChannel.get()}",
|
||||
version = mcpMappingsVersion.get(),
|
||||
extension = "zip"
|
||||
).downloadToFile(mappingsZip.file, repo)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DownloadMcpTools : DefaultTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val forgeFlowerFile: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mcInjectorFile: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val specialSourceFile: RegularFileProperty
|
||||
|
||||
@get:Inject
|
||||
abstract val workerExecutor: WorkerExecutor
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val config = gson.fromJson<McpConfig>(configFile)
|
||||
|
||||
val queue = workerExecutor.noIsolation()
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.add(config.functions.decompile.repo)
|
||||
artifact.set(config.functions.decompile.version)
|
||||
target.set(forgeFlowerFile.file)
|
||||
downloadToDir.set(false)
|
||||
}
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.add(config.functions.mcinject.repo)
|
||||
artifact.set(config.functions.mcinject.version)
|
||||
target.set(mcInjectorFile.file)
|
||||
downloadToDir.set(false)
|
||||
}
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.add(config.functions.rename.repo)
|
||||
artifact.set(config.functions.rename.version)
|
||||
target.set(specialSourceFile.file)
|
||||
downloadToDir.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DownloadMcLibraries : DefaultTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val mcLibrariesFile: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val mcRepo: Property<String>
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
|
||||
@get:Inject
|
||||
abstract val workerExecutor: WorkerExecutor
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val out = outputDir.file
|
||||
out.deleteRecursively()
|
||||
|
||||
val mcRepos = listOf(mcRepo.get())
|
||||
|
||||
val queue = workerExecutor.noIsolation()
|
||||
mcLibrariesFile.file.useLines { lines ->
|
||||
lines.forEach { line ->
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.set(mcRepos)
|
||||
artifact.set(line)
|
||||
target.set(out)
|
||||
downloadToDir.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DownloadSpigotDependencies : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val apiPom: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val serverPom: RegularFileProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val apiOutputDir: DirectoryProperty
|
||||
@get:OutputDirectory
|
||||
abstract val serverOutputDir: DirectoryProperty
|
||||
|
||||
@get:Inject
|
||||
abstract val workerExecutor: WorkerExecutor
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val apiSetup = parsePom(apiPom.file)
|
||||
val serverSetup = parsePom(serverPom.file)
|
||||
|
||||
val apiOut = apiOutputDir.file
|
||||
apiOut.deleteRecursively()
|
||||
|
||||
val serverOut = serverOutputDir.file
|
||||
serverOut.deleteRecursively()
|
||||
|
||||
val queue = workerExecutor.noIsolation()
|
||||
for (art in apiSetup.artifacts) {
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.set(apiSetup.repos)
|
||||
artifact.set(art.toString())
|
||||
target.set(apiOut)
|
||||
downloadToDir.set(true)
|
||||
}
|
||||
}
|
||||
for (art in serverSetup.artifacts) {
|
||||
queue.submit(DownloadWorker::class.java) {
|
||||
repos.set(serverSetup.repos)
|
||||
artifact.set(art.toString())
|
||||
target.set(serverOut)
|
||||
downloadToDir.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun parsePom(pomFile: File): MavenSetup {
|
||||
val depList = arrayListOf<MavenArtifact>()
|
||||
val repoList = arrayListOf<String>()
|
||||
// Maven Central is implicit
|
||||
repoList += "https://repo.maven.apache.org/maven2/"
|
||||
|
||||
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
val doc = pomFile.inputStream().buffered().use { stream ->
|
||||
stream.buffered().use { buffered ->
|
||||
builder.parse(buffered)
|
||||
}
|
||||
}
|
||||
|
||||
doc.documentElement.normalize()
|
||||
|
||||
val list = doc.getElementsByTagName("dependencies")
|
||||
for (i in 0 until list.length) {
|
||||
val node = list.item(i) as? Element ?: continue
|
||||
|
||||
val depNode = node.getElementsByTagName("dependency")
|
||||
for (j in 0 until depNode.length) {
|
||||
val dependency = depNode.item(j) as? Element ?: continue
|
||||
val artifact = getDependency(dependency) ?: continue
|
||||
depList += artifact
|
||||
}
|
||||
}
|
||||
|
||||
val repos = doc.getElementsByTagName("repositories")
|
||||
for (i in 0 until repos.length) {
|
||||
val node = repos.item(i) as? Element ?: continue
|
||||
val depNode = node.getElementsByTagName("repository")
|
||||
for (j in 0 until depNode.length) {
|
||||
val repo = depNode.item(j) as? Element ?: continue
|
||||
val repoUrl = repo.getElementsByTagName("url").item(0).textContent
|
||||
repoList += repoUrl
|
||||
}
|
||||
}
|
||||
|
||||
return MavenSetup(repos = repoList, artifacts = depList)
|
||||
}
|
||||
|
||||
private fun getDependency(node: Element): MavenArtifact? {
|
||||
val scopeNode = node.getElementsByTagName("scope")
|
||||
val scope = if (scopeNode.length == 0) {
|
||||
"compile"
|
||||
} else {
|
||||
scopeNode.item(0).textContent
|
||||
}
|
||||
|
||||
if (scope != "compile") {
|
||||
return null
|
||||
}
|
||||
|
||||
val group = node.getElementsByTagName("groupId").item(0).textContent
|
||||
val artifact = node.getElementsByTagName("artifactId").item(0).textContent
|
||||
val version = node.getElementsByTagName("version").item(0).textContent
|
||||
|
||||
if (version.contains("\${")) {
|
||||
// Don't handle complicated things
|
||||
// We don't need to (for now anyways)
|
||||
return null
|
||||
}
|
||||
|
||||
return MavenArtifact(
|
||||
group = group,
|
||||
artifact = artifact,
|
||||
version = version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class MavenSetup(
|
||||
val repos: List<String>,
|
||||
val artifacts: List<MavenArtifact>
|
||||
)
|
||||
|
||||
interface DownloadParams : WorkParameters {
|
||||
val repos: ListProperty<String>
|
||||
val artifact: Property<String>
|
||||
val target: RegularFileProperty
|
||||
val downloadToDir: Property<Boolean>
|
||||
}
|
||||
abstract class DownloadWorker : WorkAction<DownloadParams> {
|
||||
@get:Inject
|
||||
abstract val layout: ProjectLayout
|
||||
|
||||
override fun execute() {
|
||||
val artifact = MavenArtifact.parse(parameters.artifact.get())
|
||||
if (parameters.downloadToDir.get()) {
|
||||
artifact.downloadToDir(parameters.target.file, parameters.repos.get())
|
||||
} else {
|
||||
artifact.downloadToFile(parameters.target.file, parameters.repos.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
127
src/main/kotlin/tasks/extract-tasks.kt
Normal file
127
src/main/kotlin/tasks/extract-tasks.kt
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.McpConfig
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.fromJson
|
||||
import io.papermc.paperweight.util.gson
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
|
||||
abstract class Extract : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputFile: RegularFileProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val outputDir: DirectoryProperty
|
||||
|
||||
@TaskAction
|
||||
open fun run() {
|
||||
val input = inputFile.file
|
||||
val output = outputDir.file
|
||||
if (output.exists()) {
|
||||
output.deleteRecursively()
|
||||
}
|
||||
output.mkdirs()
|
||||
fs.copy {
|
||||
from(archives.zipTree(input))
|
||||
into(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ExtractMcp : Extract() {
|
||||
|
||||
@get:OutputFile
|
||||
abstract val configFile: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val access: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val constructors: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val exceptions: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val mappings: RegularFileProperty
|
||||
@get:OutputDirectory
|
||||
abstract val patchDir: DirectoryProperty
|
||||
|
||||
override fun init() {
|
||||
configFile.convention(outputDir.file("config.json"))
|
||||
access.convention(outputDir.file("config/access.txt"))
|
||||
constructors.convention(outputDir.file("config/constructors.txt"))
|
||||
exceptions.convention(outputDir.file("config/exceptions.txt"))
|
||||
mappings.convention(outputDir.file("config/joined.tsrg"))
|
||||
patchDir.convention(outputDir.dir("config/patches/server"))
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
override fun run() {
|
||||
super.run()
|
||||
|
||||
val output = outputDir.file
|
||||
val config = gson.fromJson<McpConfig>(output.resolve("config.json"))
|
||||
|
||||
// We have to know what our output file paths are at configuration time, but these could change based on the
|
||||
// config.json file.
|
||||
// So as a workaround we just rename the files the config.json file points to to our expected paths. Likely
|
||||
// is a no-op.
|
||||
|
||||
output.resolve(config.data.access).renameTo(access.file.createParent())
|
||||
output.resolve(config.data.constructors).renameTo(constructors.file.createParent())
|
||||
output.resolve(config.data.exceptions).renameTo(exceptions.file.createParent())
|
||||
output.resolve(config.data.mappings).renameTo(mappings.file.createParent())
|
||||
output.resolve(config.data.patches.server).renameTo(patchDir.file.createParent())
|
||||
}
|
||||
|
||||
private fun File.createParent(): File {
|
||||
val par = this.parentFile
|
||||
if (!par.exists()) {
|
||||
par.mkdirs()
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ExtractMappings : Extract() {
|
||||
|
||||
@get:OutputFile
|
||||
abstract val fieldsCsv: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val methodsCsv: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val paramsCsv: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
fieldsCsv.convention(outputDir.file("fields.csv"))
|
||||
methodsCsv.convention(outputDir.file("methods.csv"))
|
||||
paramsCsv.convention(outputDir.file("params.csv"))
|
||||
}
|
||||
}
|
100
src/main/kotlin/tasks/jar-tasks.kt
Normal file
100
src/main/kotlin/tasks/jar-tasks.kt
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.zip
|
||||
import org.gradle.api.file.DuplicatesStrategy
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.InputFiles
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class Filter : BaseTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
@get:Input
|
||||
abstract val includes: ListProperty<String>
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val out = outputJar.file
|
||||
val target = out.resolveSibling("${out.name}.dir")
|
||||
target.mkdirs()
|
||||
|
||||
fs.copy {
|
||||
from(archives.zipTree(inputJar)) {
|
||||
for (inc in this@Filter.includes.get()) {
|
||||
include(inc)
|
||||
}
|
||||
}
|
||||
into(target)
|
||||
}
|
||||
|
||||
zip(target, outputJar)
|
||||
target.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Merge : BaseTask() {
|
||||
@get:InputFiles
|
||||
abstract val inputJars: ListProperty<RegularFile>
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val out = outputJar.file
|
||||
val target = out.resolveSibling("${out.name}.dir")
|
||||
target.mkdirs()
|
||||
|
||||
fs.copy {
|
||||
for (file in inputJars.get()) {
|
||||
from(archives.zipTree(file))
|
||||
}
|
||||
into(target)
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
zip(target, outputJar)
|
||||
target.deleteRecursively()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,28 @@
|
|||
package io.papermc.paperweight.tasks
|
||||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.patchremap
|
||||
|
||||
import io.papermc.paperweight.tasks.BaseTask
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.ensureDeleted
|
||||
import io.papermc.paperweight.util.ensureParentExists
|
||||
|
@ -14,11 +37,8 @@ import org.cadixdev.atlas.Atlas
|
|||
import org.cadixdev.bombe.jar.JarClassEntry
|
||||
import org.cadixdev.bombe.jar.JarEntryTransformer
|
||||
import org.cadixdev.bombe.type.signature.MethodSignature
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.objectweb.asm.ClassReader
|
||||
|
@ -28,19 +48,20 @@ import org.objectweb.asm.FieldVisitor
|
|||
import org.objectweb.asm.MethodVisitor
|
||||
import org.objectweb.asm.Opcodes
|
||||
|
||||
open class ApplyAccessTransform : DefaultTask() {
|
||||
abstract class ApplyAccessTransform : BaseTask() {
|
||||
|
||||
@InputFile
|
||||
val inputJar: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val inputJar: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val atFile: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:InputFile
|
||||
abstract val atFile: RegularFileProperty
|
||||
|
||||
@InputFile
|
||||
val mapping: RegularFileProperty = project.objects.fileProperty()
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
@OutputFile
|
||||
val outputJar: RegularFileProperty = defaultOutput()
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
|
@ -48,12 +69,10 @@ open class ApplyAccessTransform : DefaultTask() {
|
|||
ensureDeleted(outputJar.file)
|
||||
|
||||
val at = AccessTransformFormats.FML.read(atFile.file.toPath())
|
||||
val mappings = MappingFormats.TSRG.createReader(mapping.file.toPath()).use { it.read() }
|
||||
val remappedAt = at.remap(mappings)
|
||||
|
||||
Atlas().apply {
|
||||
install {
|
||||
AtJarEntryTransformer(remappedAt)
|
||||
AtJarEntryTransformer(at)
|
||||
}
|
||||
run(inputJar.file.toPath(), outputJar.file.toPath())
|
||||
}
|
91
src/main/kotlin/tasks/patchremap/PatchApplier.kt
Normal file
91
src/main/kotlin/tasks/patchremap/PatchApplier.kt
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.patchremap
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.util.Git
|
||||
import java.io.File
|
||||
|
||||
class PatchApplier(
|
||||
private val remappedBranch: String,
|
||||
private val unmappedBranch: String,
|
||||
targetDir: File
|
||||
) {
|
||||
|
||||
private val git = Git(targetDir)
|
||||
|
||||
private var commitMessage: String? = null
|
||||
private var commitAuthor: String? = null
|
||||
private var commitTime: String? = null
|
||||
|
||||
fun initRepo() {
|
||||
println("Initializing patch remap repo")
|
||||
git("init").executeSilently()
|
||||
git("commit", "-m", "Initial", "--author=Initial <auto@mated.null>", "--allow-empty").executeSilently()
|
||||
git("branch", remappedBranch).executeSilently()
|
||||
git("branch", unmappedBranch).executeSilently()
|
||||
git("checkout", unmappedBranch).executeSilently()
|
||||
}
|
||||
|
||||
fun checkoutRemapped() {
|
||||
println("Switching to $remappedBranch without losing changes")
|
||||
git("symbolic-ref", "HEAD", "refs/heads/$remappedBranch").executeSilently()
|
||||
}
|
||||
|
||||
fun checkoutOld() {
|
||||
println("Resetting back to $unmappedBranch branch")
|
||||
git("checkout", unmappedBranch).executeSilently()
|
||||
}
|
||||
|
||||
fun commitInitialSource() {
|
||||
git("add", ".").executeSilently()
|
||||
git("commit", "-m", "Initial Source", "--author=Initial <auto@mated.null>").executeSilently()
|
||||
}
|
||||
|
||||
fun recordCommit() {
|
||||
commitMessage = git("git", "log", "--format=%B", "-n", "1", "HEAD").getText()
|
||||
commitAuthor = git("git", "log", "--format=%an <%ae>", "-n", "1", "HEAD").getText()
|
||||
commitTime = git("git", "log", "--format=%aD", "-n", "1", "HEAD").getText()
|
||||
}
|
||||
|
||||
fun commitChanges() {
|
||||
println("Committing remapped changes to $remappedBranch")
|
||||
val message = commitMessage ?: throw PaperweightException("commitMessage not set")
|
||||
val author = commitAuthor ?: throw PaperweightException("commitAuthor not set")
|
||||
val time = commitTime ?: throw PaperweightException("commitTime not set")
|
||||
commitMessage = null
|
||||
commitAuthor = null
|
||||
commitTime = null
|
||||
|
||||
git("add", ".").executeSilently()
|
||||
git("commit", "-m", message, "--author=$author", "--date=$time").execute()
|
||||
}
|
||||
|
||||
fun applyPatch(patch: File) {
|
||||
println("Applying patch ${patch.name}")
|
||||
val result = git("am", "--3way", "--ignore-whitespace", patch.absolutePath).runOut()
|
||||
if (result != 0) {
|
||||
System.err.println("Patch failed to apply: $patch")
|
||||
}
|
||||
}
|
||||
}
|
96
src/main/kotlin/tasks/patchremap/PatchSourceRemapWorker.kt
Normal file
96
src/main/kotlin/tasks/patchremap/PatchSourceRemapWorker.kt
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.patchremap
|
||||
|
||||
import io.papermc.paperweight.tasks.sourceremap.ConstructorsData
|
||||
import io.papermc.paperweight.tasks.sourceremap.ParamNames
|
||||
import io.papermc.paperweight.tasks.sourceremap.PatchParameterRemapper
|
||||
import io.papermc.paperweight.tasks.sourceremap.SrgParameterRemapper
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.mercury.Mercury
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||
|
||||
class PatchSourceRemapWorker(
|
||||
private val mappings: MappingSet,
|
||||
private val classpath: Collection<Path>,
|
||||
private val paramNames: ParamNames,
|
||||
private val constructorsData: ConstructorsData,
|
||||
private val inputDir: Path,
|
||||
private val outputDir: Path
|
||||
) {
|
||||
|
||||
private val reverseMappings: MappingSet = mappings.reverse()
|
||||
|
||||
fun remap() {
|
||||
setup()
|
||||
|
||||
Mercury().apply {
|
||||
classPath.addAll(classpath)
|
||||
|
||||
processors.addAll(listOf(
|
||||
MercuryRemapper.create(reverseMappings),
|
||||
PatchParameterRemapper(paramNames, constructorsData)
|
||||
))
|
||||
|
||||
rewrite(inputDir, outputDir)
|
||||
}
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
fun remapBack() {
|
||||
setup()
|
||||
|
||||
Mercury().apply {
|
||||
classPath.addAll(classpath)
|
||||
|
||||
processors.addAll(listOf(
|
||||
MercuryRemapper.create(mappings),
|
||||
SrgParameterRemapper(mappings, constructorsData, paramNames)
|
||||
))
|
||||
|
||||
rewrite(inputDir, outputDir)
|
||||
}
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
private fun setup() {
|
||||
Files.walk(outputDir).use { it.forEach(Files::delete) }
|
||||
Files.createDirectories(outputDir)
|
||||
}
|
||||
|
||||
private fun cleanup() {
|
||||
Files.walk(inputDir).use { it.forEach(Files::delete) }
|
||||
Files.walk(outputDir).use {
|
||||
it.forEach { src ->
|
||||
val dest = inputDir.resolve(outputDir.relativize(src))
|
||||
Files.createDirectories(dest.parent)
|
||||
Files.copy(src, dest, REPLACE_EXISTING)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
187
src/main/kotlin/tasks/patchremap/RemapPatches.kt
Normal file
187
src/main/kotlin/tasks/patchremap/RemapPatches.kt
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.patchremap
|
||||
|
||||
import io.papermc.paperweight.tasks.BaseTask
|
||||
import io.papermc.paperweight.tasks.sourceremap.parseConstructors
|
||||
import io.papermc.paperweight.tasks.sourceremap.parseParamNames
|
||||
import io.papermc.paperweight.util.cache
|
||||
import io.papermc.paperweight.util.file
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.tasks.Classpath
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
abstract class RemapPatches : BaseTask() {
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val inputPatchDir: DirectoryProperty
|
||||
@get:InputFile
|
||||
abstract val sourceJar: RegularFileProperty
|
||||
@get:InputDirectory
|
||||
abstract val apiPatchDir: DirectoryProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val mappingsFile: RegularFileProperty
|
||||
|
||||
@get:Classpath
|
||||
abstract val classpathJars: ListProperty<RegularFile>
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val spigotApiDir: DirectoryProperty
|
||||
@get:InputDirectory
|
||||
abstract val spigotServerDir: DirectoryProperty
|
||||
@get:InputFile
|
||||
abstract val spigotDecompJar: RegularFileProperty
|
||||
|
||||
// For parameter name remapping
|
||||
@get:InputFile
|
||||
abstract val parameterNames: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val constructors: RegularFileProperty
|
||||
|
||||
@get:OutputDirectory
|
||||
abstract val outputPatchDir: DirectoryProperty
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
// Check patches
|
||||
val patches = inputPatchDir.file.listFiles() ?: return run {
|
||||
println("No input patches found")
|
||||
}
|
||||
|
||||
patches.sort()
|
||||
|
||||
// Setup param remapping
|
||||
val constructorsData = parseConstructors(constructors.file)
|
||||
val paramMap = parseParamNames(parameterNames.file)
|
||||
|
||||
val mappings = MappingFormats.TSRG.createReader(mappingsFile.file.toPath()).use { it.read() }
|
||||
|
||||
// This should pull in any libraries needed for type bindings
|
||||
val configFiles = project.project(":Paper-Server").configurations["runtimeClasspath"].resolve()
|
||||
val classpathFiles = classpathJars.get().map { it.asFile } + configFiles
|
||||
|
||||
// Remap output directory, after each output this directory will be re-named to the input directory below for
|
||||
// the next remap operation
|
||||
val tempApiDir = createWorkDir("patch-remap-api", source = spigotApiDir.file)
|
||||
val tempInputDir = createWorkDir("patch-remap-input", source = spigotServerDir.file)
|
||||
val tempOutputDir = createWorkDir("patch-remap-output")
|
||||
|
||||
val sourceInputDir = tempInputDir.resolve("src/main/java")
|
||||
sourceInputDir.deleteRecursively()
|
||||
sourceInputDir.mkdirs()
|
||||
|
||||
project.copy {
|
||||
from(project.zipTree(sourceJar.file))
|
||||
into(sourceInputDir)
|
||||
}
|
||||
|
||||
tempInputDir.resolve(".git").deleteRecursively()
|
||||
|
||||
PatchSourceRemapWorker(
|
||||
mappings,
|
||||
listOf(*classpathFiles.toTypedArray(), tempApiDir.resolve("src/main/java")).map { it.toPath() },
|
||||
paramMap,
|
||||
constructorsData,
|
||||
sourceInputDir.toPath(),
|
||||
tempOutputDir.toPath()
|
||||
).let { remapper ->
|
||||
val patchApplier = PatchApplier("remapped", "old", tempInputDir)
|
||||
// Setup patch remapping repo
|
||||
patchApplier.initRepo() // Create empty initial commit
|
||||
remapper.remap() // Remap to Spigot mappings
|
||||
|
||||
// We need to include any missing classes for the patches later on
|
||||
importMcDev(patches, tempInputDir.resolve("src/main/java"))
|
||||
patchApplier.commitInitialSource() // Initial commit of Spigot sources
|
||||
patchApplier.checkoutRemapped() // Switch to remapped branch without checking out files
|
||||
|
||||
remapper.remapBack() // Remap to new mappings
|
||||
patchApplier.commitInitialSource() // Initial commit of Spigot sources mapped to new mappings
|
||||
patchApplier.checkoutOld() // Normal checkout back to Spigot mappings branch
|
||||
|
||||
// Repo setup is done, we can begin the patch "loop" now
|
||||
// - not a loop yet cause it doesn't even work for the first patch
|
||||
remapper.remap() // Remap to to Spigot mappings TODO: verify this step produces correct results
|
||||
patchApplier.applyPatch(patches.first()) // Apply patch on Spigot mappings
|
||||
patchApplier.recordCommit() // Keep track of commit author, message, and time
|
||||
patchApplier.checkoutRemapped() // Switch to remapped branch without checkout out files
|
||||
remapper.remapBack() // Remap to new mappings
|
||||
patchApplier.commitChanges() // Commit the changes
|
||||
patchApplier.checkoutOld() // Normal checkout back to Spigot mappings branch
|
||||
}
|
||||
}
|
||||
|
||||
private fun importMcDev(patches: Array<File>, inputDir: File) {
|
||||
val importMcDev = readMcDevNames(patches).asSequence()
|
||||
.map { inputDir.resolve("net/minecraft/server/$it.java") }
|
||||
.filter { !it.exists() }
|
||||
.toSet()
|
||||
ZipFile(spigotDecompJar.file).use { zipFile ->
|
||||
for (file in importMcDev) {
|
||||
val zipEntry = zipFile.getEntry(file.relativeTo(inputDir).path) ?: continue
|
||||
zipFile.getInputStream(zipEntry).use { input ->
|
||||
file.outputStream().buffered().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readMcDevNames(patches: Array<File>): Set<String> {
|
||||
val result = hashSetOf<String>()
|
||||
|
||||
val prefix = "+++ b/src/main/java/net/minecraft/server/"
|
||||
val suffix = ".java"
|
||||
|
||||
for (patch in patches) {
|
||||
patch.useLines { lines ->
|
||||
lines
|
||||
.filter { it.startsWith(prefix) }
|
||||
.map { it.substring(prefix.length, it.length - suffix.length) }
|
||||
.forEach { result.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun createWorkDir(name: String, source: File? = null): File {
|
||||
return layout.cache.resolve("paperweight").resolve(name).apply {
|
||||
deleteRecursively()
|
||||
mkdirs()
|
||||
source?.copyRecursively(this)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.sourceremap
|
||||
|
||||
import org.cadixdev.mercury.RewriteContext
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding
|
||||
import org.eclipse.jdt.core.dom.IVariableBinding
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration
|
||||
import org.eclipse.jdt.core.dom.SimpleName
|
||||
import org.eclipse.jdt.core.dom.VariableDeclaration
|
||||
|
||||
abstract class AbstractParameterVisitor(protected val context: RewriteContext) : ASTVisitor() {
|
||||
|
||||
override fun visit(node: SimpleName): Boolean {
|
||||
val binding = node.resolveBinding() as? IVariableBinding ?: return false
|
||||
if (!binding.isParameter) {
|
||||
return false
|
||||
}
|
||||
|
||||
val variableDecl = context.compilationUnit.findDeclaringNode(binding.variableDeclaration) as VariableDeclaration
|
||||
|
||||
val method = binding.declaringMethod
|
||||
val methodDecl = context.compilationUnit.findDeclaringNode(method) as? MethodDeclaration ?: return false
|
||||
|
||||
if (method.isConstructor) {
|
||||
handleConstructor(node, methodDecl, method, variableDecl)
|
||||
} else {
|
||||
handleMethod(node, methodDecl, method, variableDecl)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
abstract fun handleMethod(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
)
|
||||
|
||||
abstract fun handleConstructor(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
)
|
||||
|
||||
fun getParameterIndex(methodDecl: MethodDeclaration, decl: VariableDeclaration): Int {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val params = methodDecl.parameters() as List<VariableDeclaration>
|
||||
return params.indexOfFirst { it === decl }
|
||||
}
|
||||
}
|
95
src/main/kotlin/tasks/sourceremap/PatchParameterRemapper.kt
Normal file
95
src/main/kotlin/tasks/sourceremap/PatchParameterRemapper.kt
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.sourceremap
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import org.cadixdev.mercury.RewriteContext
|
||||
import org.cadixdev.mercury.SourceProcessor
|
||||
import org.cadixdev.mercury.SourceRewriter
|
||||
import org.cadixdev.mercury.util.BombeBindings
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration
|
||||
import org.eclipse.jdt.core.dom.SimpleName
|
||||
import org.eclipse.jdt.core.dom.VariableDeclaration
|
||||
|
||||
class PatchParameterRemapper(
|
||||
private val paramNames: ParamNames,
|
||||
private val constructorsData: ConstructorsData
|
||||
) : SourceRewriter {
|
||||
override fun getFlags(): Int = SourceProcessor.FLAG_RESOLVE_BINDINGS
|
||||
|
||||
override fun rewrite(context: RewriteContext) {
|
||||
context.compilationUnit.accept(PatchParameterVisitor(context, paramNames, constructorsData))
|
||||
}
|
||||
}
|
||||
|
||||
class PatchParameterVisitor(
|
||||
context: RewriteContext,
|
||||
private val paramNames: ParamNames,
|
||||
private val constructorsData: ConstructorsData
|
||||
) : AbstractParameterVisitor(context) {
|
||||
|
||||
override fun handleMethod(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
) {
|
||||
val paramNames = paramNames[methodDecl.name.identifier] ?: return
|
||||
val params = methodDecl.parameters()
|
||||
|
||||
if (paramNames.size != params.size) {
|
||||
throw PaperweightException("Invalid parameter length; expected ${paramNames.size}, actual ${params.size} " +
|
||||
"for method ${methodDecl.name.identifier}")
|
||||
}
|
||||
|
||||
val index = getParameterIndex(methodDecl, variableDecl)
|
||||
val newName = paramNames[index] ?: return
|
||||
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, newName, null)
|
||||
}
|
||||
|
||||
override fun handleConstructor(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
) {
|
||||
val className = method.declaringClass.binaryName.replace('.', '/')
|
||||
val descriptor = BombeBindings.convertSignature(method).descriptor
|
||||
|
||||
val constructorNode = constructorsData.findConstructorNode(className, descriptor) ?: return
|
||||
val paramNames = paramNames["const_${constructorNode.id}"] ?: return
|
||||
val params = methodDecl.parameters()
|
||||
|
||||
if (paramNames.size != params.size) {
|
||||
throw PaperweightException("Invalid parameter length; expected ${paramNames.size}, actual ${params.size} " +
|
||||
"for constructor $className $descriptor")
|
||||
}
|
||||
|
||||
val index = getParameterIndex(methodDecl, variableDecl)
|
||||
val newName = paramNames[index]
|
||||
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, newName, null)
|
||||
}
|
||||
}
|
114
src/main/kotlin/tasks/sourceremap/RemapSources.kt
Normal file
114
src/main/kotlin/tasks/sourceremap/RemapSources.kt
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.sourceremap
|
||||
|
||||
import io.papermc.paperweight.tasks.ZippedTask
|
||||
import io.papermc.paperweight.util.defaultOutput
|
||||
import io.papermc.paperweight.util.file
|
||||
import io.papermc.paperweight.util.path
|
||||
import org.cadixdev.at.AccessTransformSet
|
||||
import org.cadixdev.at.io.AccessTransformFormats
|
||||
import org.cadixdev.lorenz.io.MappingFormats
|
||||
import org.cadixdev.mercury.Mercury
|
||||
import org.cadixdev.mercury.at.AccessTransformerRewriter
|
||||
import org.cadixdev.mercury.extra.AccessAnalyzerProcessor
|
||||
import org.cadixdev.mercury.extra.BridgeMethodRewriter
|
||||
import org.cadixdev.mercury.remapper.MercuryRemapper
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import java.io.File
|
||||
|
||||
abstract class RemapSources : ZippedTask() {
|
||||
|
||||
@get:InputFile
|
||||
abstract val vanillaJar: RegularFileProperty
|
||||
@get:InputFile
|
||||
abstract val vanillaRemappedSpigotJar: RegularFileProperty // Required for pre-remap pass
|
||||
@get:InputFile
|
||||
abstract val mappings: RegularFileProperty
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val spigotApiDeps: DirectoryProperty
|
||||
@get:InputDirectory
|
||||
abstract val spigotServerDeps: DirectoryProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val constructors: RegularFileProperty
|
||||
@get:InputDirectory
|
||||
abstract val spigotServerDir: DirectoryProperty
|
||||
@get:InputDirectory
|
||||
abstract val spigotApiDir: DirectoryProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val generatedAt: RegularFileProperty
|
||||
@get:OutputFile
|
||||
abstract val parameterNames: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
generatedAt.convention(defaultOutput("at"))
|
||||
parameterNames.convention(defaultOutput("params"))
|
||||
}
|
||||
|
||||
override fun run(rootDir: File) {
|
||||
val constructorsData = parseConstructors(constructors.file)
|
||||
|
||||
val paramNames: ParamNames = newParamNames()
|
||||
|
||||
val srcDir = spigotServerDir.file.resolve("src/main/java")
|
||||
|
||||
val mappingSet = MappingFormats.TSRG.read(mappings.path)
|
||||
val processAt = AccessTransformSet.create()
|
||||
|
||||
// Remap any references Spigot maps to SRG
|
||||
Mercury().apply {
|
||||
classPath.addAll(listOf(
|
||||
vanillaJar.path,
|
||||
vanillaRemappedSpigotJar.path,
|
||||
spigotApiDir.path.resolve("src/main/java"),
|
||||
*spigotApiDeps.get().asFileTree.files.map { it.toPath() }.toTypedArray(),
|
||||
*spigotServerDeps.get().asFileTree.files.map { it.toPath() }.toTypedArray()
|
||||
))
|
||||
|
||||
processors += AccessAnalyzerProcessor.create(processAt, mappingSet)
|
||||
|
||||
process(srcDir.toPath())
|
||||
|
||||
processors.clear()
|
||||
processors.addAll(listOf(
|
||||
MercuryRemapper.create(mappingSet),
|
||||
BridgeMethodRewriter.create(),
|
||||
AccessTransformerRewriter.create(processAt),
|
||||
SrgParameterRemapper(mappingSet, constructorsData, paramNames)
|
||||
))
|
||||
|
||||
rewrite(srcDir.toPath(), rootDir.toPath())
|
||||
}
|
||||
|
||||
AccessTransformFormats.FML.write(generatedAt.path, processAt)
|
||||
writeParamNames(paramNames, parameterNames.file)
|
||||
}
|
||||
}
|
142
src/main/kotlin/tasks/sourceremap/SrgParameterRemapper.kt
Normal file
142
src/main/kotlin/tasks/sourceremap/SrgParameterRemapper.kt
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.sourceremap
|
||||
|
||||
import org.cadixdev.bombe.type.MethodDescriptor
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.mercury.RewriteContext
|
||||
import org.cadixdev.mercury.SourceProcessor
|
||||
import org.cadixdev.mercury.SourceRewriter
|
||||
import org.cadixdev.mercury.util.BombeBindings
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration
|
||||
import org.eclipse.jdt.core.dom.Modifier
|
||||
import org.eclipse.jdt.core.dom.SimpleName
|
||||
import org.eclipse.jdt.core.dom.VariableDeclaration
|
||||
|
||||
class SrgParameterRemapper(
|
||||
private val mappings: MappingSet,
|
||||
private val constructorsData: ConstructorsData,
|
||||
private val parameterNames: ParamNames? = null
|
||||
) : SourceRewriter {
|
||||
|
||||
override fun getFlags(): Int = SourceProcessor.FLAG_RESOLVE_BINDINGS
|
||||
|
||||
override fun rewrite(context: RewriteContext) {
|
||||
context.compilationUnit.accept(SrgParameterVisitor(context, mappings, constructorsData, parameterNames))
|
||||
}
|
||||
}
|
||||
|
||||
class SrgParameterVisitor(
|
||||
context: RewriteContext,
|
||||
private val mappings: MappingSet,
|
||||
private val constructorsData: ConstructorsData,
|
||||
private val paramNames: ParamNames?
|
||||
) : AbstractParameterVisitor(context) {
|
||||
|
||||
companion object {
|
||||
private val MATCHER = Regex("func_(\\d+)_.*")
|
||||
}
|
||||
|
||||
override fun handleMethod(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
) {
|
||||
val methodName = mappings.getClassMapping(method.declaringClass.binaryName)
|
||||
.flatMap { it.getMethodMapping(BombeBindings.convertSignature(method)) }
|
||||
.map { it.deobfuscatedName }
|
||||
.orElse(null) ?: return
|
||||
|
||||
val match = MATCHER.matchEntire(methodName) ?: return
|
||||
val isStatic = method.modifiers and Modifier.STATIC != 0
|
||||
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
|
||||
recordName(methodName, method, node, index)
|
||||
|
||||
if (!isStatic) {
|
||||
index++
|
||||
}
|
||||
|
||||
val paramName = "p_${match.groupValues[1]}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
override fun handleConstructor(
|
||||
node: SimpleName,
|
||||
methodDecl: MethodDeclaration,
|
||||
method: IMethodBinding,
|
||||
variableDecl: VariableDeclaration
|
||||
) {
|
||||
val binaryName = method.declaringClass.binaryName
|
||||
val classMapping = mappings.getClassMapping(binaryName)
|
||||
val className = classMapping
|
||||
.map { it.fullDeobfuscatedName }
|
||||
.orElse(binaryName)
|
||||
|
||||
val descriptor = BombeBindings.convertSignature(method).descriptor
|
||||
val constructorNode = constructorsData.findConstructorNode(className, descriptor) ?: return
|
||||
|
||||
val id = constructorNode.id
|
||||
|
||||
var index = getParameterIndex(methodDecl, variableDecl)
|
||||
if (index == -1) {
|
||||
return
|
||||
}
|
||||
|
||||
recordName("const_$id", method, node, index)
|
||||
|
||||
// Constructors are never static
|
||||
index++
|
||||
|
||||
val paramName = "p_i${id}_${index}_"
|
||||
context.createASTRewrite().set(node, SimpleName.IDENTIFIER_PROPERTY, paramName, null)
|
||||
}
|
||||
|
||||
private fun recordName(
|
||||
methodName: String,
|
||||
method: IMethodBinding,
|
||||
node: SimpleName,
|
||||
index: Int
|
||||
) {
|
||||
paramNames?.let { map ->
|
||||
val paramCount = method.parameterTypes.size
|
||||
map.computeIfAbsent(methodName) { arrayOfNulls(paramCount) }[index] = node.identifier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ConstructorsData.findConstructorNode(className: String, desc: MethodDescriptor): ConstructorNode? {
|
||||
val constructorNodes = constructors[className] ?: return null
|
||||
|
||||
val descriptorText = desc.toString()
|
||||
return constructorNodes.firstOrNull { constructorNode ->
|
||||
constructorNode.descriptor == descriptorText
|
||||
}
|
||||
}
|
||||
|
90
src/main/kotlin/tasks/sourceremap/remap.kt
Normal file
90
src/main/kotlin/tasks/sourceremap/remap.kt
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks.sourceremap
|
||||
|
||||
import java.io.File
|
||||
|
||||
data class ConstructorsData(val constructors: Map<String, List<ConstructorNode>>)
|
||||
|
||||
data class ConstructorNode(
|
||||
val id: Int,
|
||||
val descriptor: String
|
||||
)
|
||||
|
||||
fun parseConstructors(constructors: File): ConstructorsData {
|
||||
val constructorMap = hashMapOf<String, MutableList<ConstructorNode>>()
|
||||
|
||||
constructors.useLines { lines ->
|
||||
lines.forEach { line ->
|
||||
val parts = line.split(' ')
|
||||
constructorMap.compute(parts[1]) { _, v ->
|
||||
val node = ConstructorNode(parts[0].toInt(), parts[2])
|
||||
if (v == null) {
|
||||
return@compute mutableListOf(node)
|
||||
} else {
|
||||
v += node
|
||||
return@compute v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (list in constructorMap.values) {
|
||||
// Put bigger numbers first
|
||||
// Old constructor entries are still present, just with smaller numbers. So we don't want to grab an older
|
||||
// entry
|
||||
list.reverse()
|
||||
}
|
||||
|
||||
return ConstructorsData(constructorMap)
|
||||
}
|
||||
|
||||
typealias ParamNames = MutableMap<String, Array<String?>>
|
||||
fun newParamNames(): ParamNames = mutableMapOf()
|
||||
|
||||
fun writeParamNames(names: ParamNames, file: File) {
|
||||
file.bufferedWriter().use { writer ->
|
||||
for ((desc, params) in names.entries) {
|
||||
writer.append(desc).append(' ')
|
||||
for (i in params.indices) {
|
||||
writer.append(i.toString()).append(' ').append(params[i])
|
||||
if (i != params.lastIndex) {
|
||||
writer.append(' ')
|
||||
}
|
||||
}
|
||||
writer.newLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun parseParamNames(file: File): ParamNames {
|
||||
val paramNames: MutableMap<String, Array<String?>> = mutableMapOf()
|
||||
file.useLines { lines ->
|
||||
for (line in lines) {
|
||||
val parts = line.split(' ')
|
||||
val params = parts.asSequence().drop(1).chunked(2).associate { it[0].toInt() to it[1] }
|
||||
paramNames[parts.first()] = Array(params.size) { params.getValue(it) }
|
||||
}
|
||||
}
|
||||
return paramNames
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -21,7 +20,7 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
package util
|
||||
package io.papermc.paperweight.util
|
||||
|
||||
data class BuildDataInfo(
|
||||
val minecraftVersion: String,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -28,14 +27,6 @@ import org.gradle.api.Task
|
|||
object Constants {
|
||||
const val EXTENSION = "paperweight"
|
||||
|
||||
const val MCP_MAPPINGS_CONFIG = "mcpConfig"
|
||||
|
||||
const val MCP_DATA_CONFIG = "mcpData"
|
||||
const val SPIGOT_DEP_CONFIG = "spigotDeps"
|
||||
const val MINECRAFT_DEP_CONFIG = "minecraft"
|
||||
const val FORGE_FLOWER_CONFIG = "forgeFlower"
|
||||
const val MCINJECT_CONFIG = "mcinject"
|
||||
|
||||
const val FORGE_MAVEN_URL = "https://files.minecraftforge.net/maven"
|
||||
const val MC_LIBRARY_URL = "https://libraries.minecraft.net/"
|
||||
const val MC_MANIFEST_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json"
|
||||
|
@ -43,9 +34,19 @@ object Constants {
|
|||
const val CACHE_PATH = "caches"
|
||||
private const val PAPER_PATH = "paperweight"
|
||||
|
||||
private const val JARS_PATH = "$PAPER_PATH/jars"
|
||||
const val MINECRAFT_JARS_PATH = "$JARS_PATH/minecraft"
|
||||
const val MCP_TOOLS_PATH = "$JARS_PATH/tools"
|
||||
const val MCP_ZIPS_PATH = "$JARS_PATH/mcp"
|
||||
private const val SPIGOT_JARS_PATH = "$JARS_PATH/spigot"
|
||||
const val SPIGOT_API_JARS_PATH = "$SPIGOT_JARS_PATH/api"
|
||||
const val SPIGOT_SERVER_JARS_PATH = "$SPIGOT_JARS_PATH/server"
|
||||
|
||||
const val MCP_DATA_DIR = "mcp/data"
|
||||
const val MCP_MAPPINGS_DIR = "mcp/mappings"
|
||||
const val SRG_DIR = "$MCP_MAPPINGS_DIR/srgs"
|
||||
private const val SRG_DIR = "$MCP_MAPPINGS_DIR/srgs"
|
||||
|
||||
const val MCP_CONFIG_JSON = "$MCP_DATA_DIR/config.json"
|
||||
|
||||
const val PAPER_FIELDS_CSV = "$MCP_MAPPINGS_DIR/paper_fields.csv"
|
||||
const val PAPER_METHODS_CSV = "$MCP_MAPPINGS_DIR/paper_methods.csv"
|
||||
|
@ -69,10 +70,10 @@ object Constants {
|
|||
|
||||
const val MC_MANIFEST = "jsons/McManifest.json"
|
||||
const val VERSION_JSON = "jsons/McVersion.json"
|
||||
const val MC_LIBRARIES = "jsons/McLibraries.txt"
|
||||
|
||||
const val TASK_CACHE = "$PAPER_PATH/taskCache"
|
||||
private const val TASK_CACHE = "$PAPER_PATH/taskCache"
|
||||
|
||||
fun Task.paperTaskOutput() = paperTaskOutput("jar")
|
||||
fun Task.paperTaskOutput(ext: String) = paperTaskOutput(name, ext)
|
||||
fun Task.paperTaskOutput(name: String, ext: String) = "$TASK_CACHE/$name.$ext"
|
||||
fun paperTaskOutput(name: String, ext: String) = "$TASK_CACHE/$name.$ext"
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,23 +23,66 @@
|
|||
package io.papermc.paperweight.util
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import java.io.File
|
||||
|
||||
data class ArtifactDescriptor(
|
||||
val group: String,
|
||||
val artifact: String,
|
||||
val version: String,
|
||||
val classifier: String?,
|
||||
val extension: String
|
||||
class MavenArtifact(
|
||||
private val group: String,
|
||||
private val artifact: String,
|
||||
private val version: String,
|
||||
private val classifier: String? = null,
|
||||
private val extension: String? = null
|
||||
) {
|
||||
|
||||
private val classifierText: String
|
||||
get() = if (classifier != null) "-$classifier" else ""
|
||||
|
||||
private val ext: String
|
||||
get() = extension ?: "jar"
|
||||
|
||||
private val path: String
|
||||
get() = "${group.replace('.', '/')}/$artifact/$version/$file"
|
||||
val file: String
|
||||
get() = "$artifact-$version$classifierText.$ext"
|
||||
|
||||
fun downloadToFile(targetFile: File, repos: List<String>) {
|
||||
targetFile.parentFile.mkdirs()
|
||||
|
||||
var thrown: Exception? = null
|
||||
for (repo in repos) {
|
||||
try {
|
||||
download(addSlash(repo) + path, targetFile)
|
||||
return
|
||||
} catch (e: Exception) {
|
||||
if (thrown != null) {
|
||||
thrown.addSuppressed(e)
|
||||
} else {
|
||||
thrown = e
|
||||
}
|
||||
}
|
||||
}
|
||||
thrown?.let { throw PaperweightException("Failed to download artifact: $this. Checked repos: $repos", it) }
|
||||
}
|
||||
|
||||
fun downloadToDir(targetDir: File, repos: List<String>): File {
|
||||
val out = targetDir.resolve(file)
|
||||
downloadToFile(targetDir.resolve(file), repos)
|
||||
return out
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val path = group.replace('.', '/')
|
||||
val classifierText = classifier?.let { "-$it" } ?: ""
|
||||
val file = "$artifact-$version$classifierText.$extension"
|
||||
return "$path/$artifact/$version/$file"
|
||||
return if (classifier == null) {
|
||||
"$group:$artifact:$version"
|
||||
} else {
|
||||
"$group:$artifact:$version:$classifier"
|
||||
}
|
||||
}
|
||||
|
||||
private fun addSlash(url: String): String {
|
||||
return if (url.endsWith('/')) url else "$url/"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun parse(text: String): ArtifactDescriptor {
|
||||
fun parse(text: String): MavenArtifact {
|
||||
val (group, groupIndex) = text.nextSubstring(0, charArrayOf(':'))
|
||||
val (artifact, artifactIndex) = text.nextSubstring(groupIndex, charArrayOf(':'))
|
||||
val (version, versionIndex) = text.nextSubstring(artifactIndex, charArrayOf(':', '@'), goToEnd = true)
|
||||
|
@ -51,7 +93,7 @@ data class ArtifactDescriptor(
|
|||
artifact ?: throw PaperweightException("Invalid Maven artifact descriptor (no artifactId found): $text")
|
||||
version ?: throw PaperweightException("Invalid Maven artifact descriptor (no version found): $text")
|
||||
|
||||
return ArtifactDescriptor(group, artifact, version, classifier, extension ?: "jar")
|
||||
return MavenArtifact(group, artifact, version, classifier, extension)
|
||||
}
|
||||
|
||||
private fun String.nextSubstring(startIndex: Int, stops: CharArray, goToEnd: Boolean = false): Pair<String?, Int> {
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,6 +22,14 @@
|
|||
|
||||
package io.papermc.paperweight.util
|
||||
|
||||
typealias FunctionMap = Map<String, McpJvmCommand>
|
||||
val FunctionMap.decompile: McpJvmCommand
|
||||
get() = getValue("decompile")
|
||||
val FunctionMap.mcinject: McpJvmCommand
|
||||
get() = getValue("mcinject")
|
||||
val FunctionMap.rename: McpJvmCommand
|
||||
get() = getValue("rename")
|
||||
|
||||
data class McpConfig(
|
||||
val spec: Int,
|
||||
val version: String,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -21,7 +20,7 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
package util
|
||||
package io.papermc.paperweight.util
|
||||
|
||||
data class MinecraftManifest(
|
||||
internal val latest: Map<String, *>,
|
||||
|
|
140
src/main/kotlin/util/download.kt
Normal file
140
src/main/kotlin/util/download.kt
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.util
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import org.apache.http.HttpHost
|
||||
import org.apache.http.HttpStatus
|
||||
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.utils.DateUtils
|
||||
import org.apache.http.impl.client.HttpClientBuilder
|
||||
import org.gradle.api.provider.Provider
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
fun download(source: Any, target: Any) {
|
||||
val url = source.convertToUrl()
|
||||
val file = target.convertToFile()
|
||||
download(url, file)
|
||||
}
|
||||
|
||||
private fun download(source: URL, target: File) {
|
||||
target.parentFile.mkdirs()
|
||||
|
||||
val etagFile = target.resolveSibling(target.name + ".etag")
|
||||
val etag = if (etagFile.exists()) etagFile.readText() else null
|
||||
|
||||
val host = HttpHost(source.host, source.port, source.protocol)
|
||||
val httpClient = HttpClientBuilder.create().run {
|
||||
setRetryHandler { _, count, _ -> count < 3 }
|
||||
useSystemProperties()
|
||||
build()
|
||||
}
|
||||
|
||||
val time = if (target.exists()) target.lastModified() else 0
|
||||
|
||||
httpClient.use { client ->
|
||||
val httpGet = HttpGet(source.file)
|
||||
// Super high timeout, reduce chances of weird things going wrong
|
||||
val timeouts = TimeUnit.MINUTES.toMillis(5).toInt()
|
||||
|
||||
httpGet.config = RequestConfig.custom()
|
||||
.setConnectTimeout(timeouts)
|
||||
.setConnectionRequestTimeout(timeouts)
|
||||
.setSocketTimeout(timeouts)
|
||||
.setCookieSpec(CookieSpecs.STANDARD)
|
||||
.build()
|
||||
|
||||
if (time > 0) {
|
||||
httpGet.setHeader("If-Modified-Since", DateUtils.formatDate(Date(time)))
|
||||
}
|
||||
if (etag != null) {
|
||||
httpGet.setHeader("If-None-Match", etag)
|
||||
}
|
||||
|
||||
client.execute(host, httpGet).use { response ->
|
||||
val code = response.statusLine.statusCode
|
||||
if ((code < 200 || code > 299) && code != HttpStatus.SC_NOT_MODIFIED) {
|
||||
val reason = response.statusLine.reasonPhrase
|
||||
throw PaperweightException("Download failed, HTTP code: $code; URL: $source; Reason: $reason")
|
||||
}
|
||||
|
||||
val lastModified = handleResponse(response, time, target)
|
||||
saveEtag(response, lastModified, target, etagFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleResponse(response: CloseableHttpResponse, time: Long, target: File): Long {
|
||||
val lastModified = with(response.getLastHeader("Last-Modified")) {
|
||||
if (this == null) {
|
||||
return@with 0
|
||||
}
|
||||
if (value.isNullOrBlank()) {
|
||||
return@with 0
|
||||
}
|
||||
val date = DateUtils.parseDate(value) ?: return@with 0
|
||||
return@with date.time
|
||||
}
|
||||
if (response.statusLine.statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
||||
if (lastModified != 0L && time >= lastModified) {
|
||||
return lastModified
|
||||
}
|
||||
}
|
||||
|
||||
val entity = response.entity ?: return lastModified
|
||||
entity.content.use { input ->
|
||||
target.outputStream().buffered().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
|
||||
return lastModified
|
||||
}
|
||||
|
||||
private fun saveEtag(response: CloseableHttpResponse, lastModified: Long, target: File, etagFile: File) {
|
||||
if (lastModified > 0) {
|
||||
target.setLastModified(lastModified)
|
||||
}
|
||||
|
||||
val header = response.getFirstHeader("ETag") ?: return
|
||||
val etag = header.value
|
||||
|
||||
etagFile.writeText(etag)
|
||||
}
|
||||
|
||||
private fun Any.convertToUrl(): URL {
|
||||
return when (this) {
|
||||
is URL -> this
|
||||
is URI -> this.toURL()
|
||||
is String -> URI.create(this).toURL()
|
||||
is Provider<*> -> this.get().convertToUrl()
|
||||
else -> throw PaperweightException("Unknown URL type: ${this.javaClass.name}")
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project. It uses
|
||||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.util
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import java.io.File
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"
|
||||
|
||||
fun getWithEtag(urlText: String, cache: File, etagFile: File) {
|
||||
if (cache.exists() && cache.lastModified() + TimeUnit.MINUTES.toMillis(1) >= System.currentTimeMillis()) {
|
||||
return
|
||||
}
|
||||
|
||||
val etag = if (etagFile.exists()) {
|
||||
etagFile.readText()
|
||||
} else {
|
||||
etagFile.parentFile.mkdirs()
|
||||
""
|
||||
}
|
||||
|
||||
var thrown: Throwable? = null
|
||||
|
||||
try {
|
||||
val url = URL(urlText)
|
||||
|
||||
val con = url.openConnection() as HttpURLConnection
|
||||
con.instanceFollowRedirects = true
|
||||
con.setRequestProperty("User-Agent", USER_AGENT)
|
||||
con.ifModifiedSince = cache.lastModified()
|
||||
|
||||
if (etag.isNotEmpty()) {
|
||||
con.setRequestProperty("If-None-Match", etag)
|
||||
}
|
||||
|
||||
try {
|
||||
con.connect()
|
||||
|
||||
when (con.responseCode) {
|
||||
304 -> {
|
||||
cache.setLastModified(System.currentTimeMillis())
|
||||
return
|
||||
}
|
||||
200 -> {
|
||||
val data = con.inputStream.use { stream ->
|
||||
stream.readBytes()
|
||||
}
|
||||
|
||||
cache.writeBytes(data)
|
||||
|
||||
val newEtag = con.getHeaderField("ETag")
|
||||
if (newEtag.isNullOrEmpty()) {
|
||||
if (!etagFile.createNewFile()) {
|
||||
etagFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
} else {
|
||||
etagFile.writeText(newEtag)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
else -> throw RuntimeException("Etag download for $urlText failed with code ${con.responseCode}")
|
||||
}
|
||||
} finally {
|
||||
con.disconnect()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (thrown == null) {
|
||||
thrown = e
|
||||
} else {
|
||||
thrown.addSuppressed(e)
|
||||
}
|
||||
}
|
||||
|
||||
val errorString = "Unable to download from $urlText with etag"
|
||||
val ex = if (thrown != null) {
|
||||
PaperweightException(errorString, thrown)
|
||||
} else {
|
||||
PaperweightException(errorString)
|
||||
}
|
||||
throw ex
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,12 +36,6 @@ class Git(private var repo: File) {
|
|||
}
|
||||
}
|
||||
|
||||
val status
|
||||
get() = this("status", "-z").getText()
|
||||
|
||||
val ref
|
||||
get() = this("rev-parse", "HEAD").getText().replace('\n', ' ').replace(Regex("\\s+"), "")
|
||||
|
||||
operator fun invoke(vararg args: String, disableGpg: Boolean = true): Command {
|
||||
val cmd = if (disableGpg) {
|
||||
arrayOf("git", "-c", "commit.gpgsign=false", *args)
|
||||
|
@ -57,18 +50,38 @@ class Git(private var repo: File) {
|
|||
}
|
||||
}
|
||||
|
||||
class Command(internal val process: Process, private val command: String) {
|
||||
class Command(private val process: Process, private val command: String) {
|
||||
|
||||
var outStream: OutputStream? = null
|
||||
private var outStream: OutputStream = UselessOutputStream
|
||||
private var errStream: OutputStream = UselessOutputStream
|
||||
|
||||
fun run(): Int = try {
|
||||
outStream?.let { out ->
|
||||
process.inputStream.copyTo(out)
|
||||
fun run(): Int {
|
||||
try {
|
||||
val input = process.inputStream
|
||||
val error = process.errorStream
|
||||
val buffer = ByteArray(1000)
|
||||
|
||||
while (process.isAlive) {
|
||||
// Read both stdout and stderr on the same thread
|
||||
// This is important for how Gradle outputs the logs
|
||||
if (input.available() > 0) {
|
||||
val count = input.read(buffer)
|
||||
outStream.write(buffer, 0, count)
|
||||
}
|
||||
process.waitFor()
|
||||
if (error.available() > 0) {
|
||||
val count = error.read(buffer)
|
||||
errStream.write(buffer, 0, count)
|
||||
}
|
||||
Thread.sleep(1)
|
||||
}
|
||||
// Catch any other output we may have missed
|
||||
outStream.write(input.readBytes())
|
||||
errStream.write(error.readBytes())
|
||||
return process.waitFor()
|
||||
} catch (e: Exception) {
|
||||
throw PaperweightException("Failed to call git command: $command", e)
|
||||
}
|
||||
}
|
||||
|
||||
fun runSilently(silenceOut: Boolean = true, silenceErr: Boolean = false): Int {
|
||||
silence(silenceOut, silenceErr)
|
||||
|
@ -76,7 +89,7 @@ class Command(internal val process: Process, private val command: String) {
|
|||
}
|
||||
|
||||
fun runOut(): Int {
|
||||
setup(System.out, System.out)
|
||||
setup(System.out, System.err)
|
||||
return run()
|
||||
}
|
||||
|
||||
|
@ -93,8 +106,8 @@ class Command(internal val process: Process, private val command: String) {
|
|||
}
|
||||
|
||||
private fun silence(silenceOut: Boolean, silenceErr: Boolean) {
|
||||
val out = if (silenceOut) UselessOutputStream else System.out
|
||||
val err = if (silenceErr) UselessOutputStream else System.err
|
||||
val out = if (silenceOut) null else System.out
|
||||
val err = if (silenceErr) null else System.err
|
||||
setup(out, err)
|
||||
}
|
||||
|
||||
|
@ -104,16 +117,15 @@ class Command(internal val process: Process, private val command: String) {
|
|||
}
|
||||
|
||||
fun setup(out: OutputStream? = null, err: OutputStream? = null): Command {
|
||||
outStream = out
|
||||
if (err != null) {
|
||||
redirect(process.errorStream, err)
|
||||
}
|
||||
outStream = out ?: UselessOutputStream
|
||||
errStream = err ?: UselessOutputStream
|
||||
return this
|
||||
}
|
||||
|
||||
fun getText(): String {
|
||||
val out = ByteArrayOutputStream()
|
||||
setup(out, System.err)
|
||||
execute()
|
||||
return String(out.toByteArray(), Charsets.UTF_8)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,19 +23,12 @@
|
|||
package io.papermc.paperweight.util
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.internal.jvm.Jvm
|
||||
import java.io.OutputStream
|
||||
|
||||
fun Task.runJar(
|
||||
jar: Any,
|
||||
workingDir: Any,
|
||||
logFile: Any?,
|
||||
jvmArgs: List<String> = listOf(),
|
||||
vararg args: String
|
||||
) {
|
||||
val jarFile = project.file(jar)
|
||||
val dir = project.file(workingDir)
|
||||
fun runJar(jar: Any, workingDir: Any, logFile: Any?, jvmArgs: List<String> = listOf(), vararg args: String) {
|
||||
val jarFile = jar.convertToFile()
|
||||
val dir = workingDir.convertToFile()
|
||||
|
||||
val process = ProcessBuilder(
|
||||
Jvm.current().javaExecutable.canonicalPath, *jvmArgs.toTypedArray(),
|
||||
|
@ -47,20 +39,15 @@ fun Task.runJar(
|
|||
val output = when {
|
||||
logFile is OutputStream -> logFile
|
||||
logFile != null -> {
|
||||
val log = project.file(logFile)
|
||||
val log = logFile.convertToFile()
|
||||
log.outputStream().buffered()
|
||||
}
|
||||
else -> null
|
||||
else -> UselessOutputStream
|
||||
}
|
||||
|
||||
output.use {
|
||||
output?.let {
|
||||
redirect(process.inputStream, it)
|
||||
redirect(process.errorStream, it)
|
||||
} ?: run {
|
||||
redirect(process.inputStream, UselessOutputStream)
|
||||
redirect(process.errorStream, UselessOutputStream)
|
||||
}
|
||||
|
||||
val e = process.waitFor()
|
||||
if (e != 0) {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -29,28 +28,36 @@ import com.github.salomonbrys.kotson.fromJson
|
|||
import com.google.gson.Gson
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import io.papermc.paperweight.ext.PaperweightExtension
|
||||
import io.papermc.paperweight.tasks.BaseTask
|
||||
import io.papermc.paperweight.util.Constants.paperTaskOutput
|
||||
import org.cadixdev.lorenz.MappingSet
|
||||
import org.cadixdev.lorenz.io.TextMappingFormat
|
||||
import org.gradle.api.NamedDomainObjectProvider
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.ProjectLayout
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.TaskContainer
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.nio.file.Path
|
||||
import java.util.Optional
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
val gson: Gson = Gson()
|
||||
|
||||
inline val Project.ext: PaperweightExtension
|
||||
inline fun <reified T> Gson.fromJson(file: Any): T =
|
||||
file.convertToFile().bufferedReader().use { fromJson(it) }
|
||||
|
||||
val Project.ext: PaperweightExtension
|
||||
get() = extensions.getByName(Constants.EXTENSION) as PaperweightExtension
|
||||
inline val Project.cache: File
|
||||
get() = file(".gradle").resolve(Constants.CACHE_PATH)
|
||||
val ProjectLayout.cache: File
|
||||
get() = projectDirectory.file(".gradle/${Constants.CACHE_PATH}").asFile
|
||||
|
||||
fun writeMappings(format: TextMappingFormat, vararg mappings: Pair<MappingSet, File>) {
|
||||
for ((set, file) in mappings) {
|
||||
|
@ -58,8 +65,8 @@ fun writeMappings(format: TextMappingFormat, vararg mappings: Pair<MappingSet, F
|
|||
}
|
||||
}
|
||||
|
||||
fun redirect(input: InputStream, out: OutputStream) {
|
||||
Thread {
|
||||
fun redirect(input: InputStream, out: OutputStream): Thread {
|
||||
return Thread {
|
||||
try {
|
||||
input.copyTo(out)
|
||||
} catch (e: Exception) {
|
||||
|
@ -93,63 +100,81 @@ fun getCsvReader(file: File) = CSVReader(
|
|||
false
|
||||
)
|
||||
|
||||
fun Task.ensureParentExists(vararg files: Any) {
|
||||
fun Any.convertToFile(): File {
|
||||
return when (this) {
|
||||
is File -> this
|
||||
is Path -> this.toFile()
|
||||
is RegularFile -> this.asFile
|
||||
is Provider<*> -> this.get().convertToFile()
|
||||
else -> throw PaperweightException("Unknown type representing a file: ${this.javaClass.name}")
|
||||
}
|
||||
}
|
||||
|
||||
fun ensureParentExists(vararg files: Any) {
|
||||
for (file in files) {
|
||||
val parent = project.file(file).parentFile
|
||||
val parent = file.convertToFile().parentFile
|
||||
if (!parent.exists() && !parent.mkdirs()) {
|
||||
throw PaperweightException("Failed to create directory $parent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Task.ensureDeleted(vararg files: Any) {
|
||||
fun ensureDeleted(vararg files: Any) {
|
||||
for (file in files) {
|
||||
val f = project.file(file)
|
||||
val f = file.convertToFile()
|
||||
if (f.exists() && !f.deleteRecursively()) {
|
||||
throw PaperweightException("Failed to delete file $f")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun Project.toProvider(crossinline func: () -> File): Provider<RegularFile> {
|
||||
return layout.file(provider { func() })
|
||||
fun BaseTask.defaultOutput(name: String, ext: String): RegularFileProperty {
|
||||
return objects.fileProperty().convention {
|
||||
layout.cache.resolve(paperTaskOutput(name, ext))
|
||||
}
|
||||
|
||||
fun Task.defaultOutput(name: String, ext: String): RegularFileProperty {
|
||||
return project.objects.fileProperty().convention(project.toProvider {
|
||||
project.cache.resolve(paperTaskOutput(name, ext))
|
||||
})
|
||||
}
|
||||
fun Task.defaultOutput(ext: String): RegularFileProperty {
|
||||
fun BaseTask.defaultOutput(ext: String): RegularFileProperty {
|
||||
return defaultOutput(name, ext)
|
||||
}
|
||||
fun Task.defaultOutput(): RegularFileProperty {
|
||||
fun BaseTask.defaultOutput(): RegularFileProperty {
|
||||
return defaultOutput("jar")
|
||||
}
|
||||
|
||||
val <T> Optional<T>.orNull: T?
|
||||
get() = orElse(null)
|
||||
|
||||
val RegularFileProperty.file
|
||||
val RegularFileProperty.file: File
|
||||
get() = get().asFile
|
||||
val RegularFileProperty.fileOrNull
|
||||
val RegularFileProperty.fileOrNull: File?
|
||||
get() = orNull?.asFile
|
||||
val DirectoryProperty.file
|
||||
val RegularFileProperty.path: Path
|
||||
get() = file.toPath()
|
||||
val DirectoryProperty.file: File
|
||||
get() = get().asFile
|
||||
val DirectoryProperty.fileOrNull
|
||||
get() = orNull?.asFile
|
||||
val DirectoryProperty.path: Path
|
||||
get() = file.toPath()
|
||||
|
||||
inline fun <reified T> Project.contents(contentFile: Any, crossinline convert: (String) -> T): Provider<T> {
|
||||
return providers.fileContents(layout.projectDirectory.file(contentFile.convertToFile().absolutePath))
|
||||
.asText
|
||||
.forUseAtConfigurationTime()
|
||||
.map { convert(it) }
|
||||
}
|
||||
|
||||
private var parsedConfig: McpConfig? = null
|
||||
fun mcpConfig(file: Provider<RegularFile>): McpConfig {
|
||||
if (parsedConfig != null) {
|
||||
return parsedConfig as McpConfig
|
||||
// We have to create our own delegate because the ones Gradle provides don't work in plugin dev environments
|
||||
inline fun <reified T : Task> TaskContainer.registering(noinline configure: T.() -> Unit): TaskDelegateProvider<T> {
|
||||
return TaskDelegateProvider(this, T::class, configure)
|
||||
}
|
||||
parsedConfig = file.get().asFile.bufferedReader().use { reader ->
|
||||
gson.fromJson(reader)
|
||||
class TaskDelegateProvider<T : Task>(
|
||||
private val container: TaskContainer,
|
||||
private val type: KClass<T>,
|
||||
private val configure: T.() -> Unit
|
||||
) {
|
||||
operator fun provideDelegate(thisRef: Any?, property: KProperty<*>): TaskDelegate<T> {
|
||||
val provider = container.register(property.name, type.java, configure)
|
||||
return TaskDelegate(provider)
|
||||
}
|
||||
return parsedConfig as McpConfig
|
||||
}
|
||||
fun mcpFile(configFile: RegularFileProperty, path: String): File {
|
||||
return configFile.file.resolveSibling(path)
|
||||
class TaskDelegate<T : Task>(private val provider: TaskProvider<T>) {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): TaskProvider<T> = provider
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* some code and systems originally from ForgeGradle.
|
||||
*
|
||||
* Copyright (C) 2020 Kyle Wood
|
||||
* Copyright (C) 2018 Forge Development LLC
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -24,7 +23,7 @@
|
|||
package io.papermc.paperweight.util
|
||||
|
||||
import io.papermc.paperweight.PaperweightException
|
||||
import org.gradle.api.Task
|
||||
import io.papermc.paperweight.tasks.BaseTask
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.FileSystems
|
||||
|
@ -35,26 +34,26 @@ import java.nio.file.SimpleFileVisitor
|
|||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
fun Task.unzip(zip: Any, target: Any? = null): File {
|
||||
val input = project.file(zip)
|
||||
val outputDir = target?.let { project.file(it) }
|
||||
fun BaseTask.unzip(zip: Any, target: Any? = null): File {
|
||||
val input = zip.convertToFile()
|
||||
val outputDir = target?.convertToFile()
|
||||
?: input.resolveSibling("${input.name}-" + ThreadLocalRandom.current().nextInt())
|
||||
|
||||
project.copy {
|
||||
from(project.zipTree(zip))
|
||||
fs.copy {
|
||||
from(archives.zipTree(zip))
|
||||
into(outputDir)
|
||||
}
|
||||
|
||||
return outputDir
|
||||
}
|
||||
|
||||
fun Task.zip(inputDir: Any, zip: Any) {
|
||||
val outputZipFile = project.file(zip)
|
||||
fun zip(inputDir: Any, zip: Any) {
|
||||
val outputZipFile = zip.convertToFile()
|
||||
if (outputZipFile.exists() && !outputZipFile.delete()) {
|
||||
throw PaperweightException("Could not delete $outputZipFile")
|
||||
}
|
||||
|
||||
val dirPath = project.file(inputDir).toPath()
|
||||
val dirPath = inputDir.convertToFile().toPath()
|
||||
|
||||
val outUri = URI.create("jar:${outputZipFile.toURI()}")
|
||||
FileSystems.newFileSystem(outUri, mapOf("create" to "true")).use { fs ->
|
||||
|
|
Loading…
Reference in a new issue