recreate repo
commit
7efa7780fe
|
@ -0,0 +1,15 @@
|
||||||
|
/.idea
|
||||||
|
|
||||||
|
/work
|
||||||
|
/tools
|
||||||
|
/build
|
||||||
|
/.gradle
|
||||||
|
*.log
|
||||||
|
*.reject
|
||||||
|
/run/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
/out
|
||||||
|
/classes/
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 ChorusMC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,5 @@
|
||||||
|
# ChorusGradle
|
||||||
|
Gradle plugin for Chorus
|
||||||
|
|
||||||
|
run : bash gradlew setupChorus genIdeaRuns
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'groovy'
|
||||||
|
apply plugin: 'maven'
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
apply plugin: 'idea'
|
||||||
|
|
||||||
|
group = 'chorusmc.gradle'
|
||||||
|
version = '0.0.1'
|
||||||
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
|
|
||||||
|
if (System.getenv().BUILD_NUMBER) {
|
||||||
|
version = version + "." + "${System.getenv().BUILD_NUMBER}"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
flatDir {
|
||||||
|
dirs 'libs'
|
||||||
|
}
|
||||||
|
ivy {
|
||||||
|
name "Enigma-Temporary"
|
||||||
|
artifactPattern "http://modmuss50.me:8080/job/Enigma-Asie/lastSuccessfulBuild/artifact/build/libs/[module]-[revision]-[classifier].[ext]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
deployerJars
|
||||||
|
shade
|
||||||
|
compile.extendsFrom shade
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile gradleApi()
|
||||||
|
shade 'org.zeroturnaround:zt-zip:1.9'
|
||||||
|
compile 'org.slf4j:slf4j-api:1.7.21'
|
||||||
|
compile 'org.slf4j:slf4j-simple:1.7.21'
|
||||||
|
shade 'com.google.code.gson:gson:2.6.2'
|
||||||
|
shade 'com.googlecode.java-diff-utils:diffutils:1.3.0'
|
||||||
|
shade 'com.cloudbees:diff4j:1.2'
|
||||||
|
shade 'commons-io:commons-io:1.4'
|
||||||
|
shade 'com.google.guava:guava-jdk5:17.0'
|
||||||
|
shade 'org.ow2.asm:asm-debug-all:5.0.3'
|
||||||
|
shade 'com.google.guava:guava:19.0'
|
||||||
|
shade name: "enigma", version: "0.11.0.6", classifier: "all"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.compileClasspath += configurations.shade;
|
||||||
|
main.runtimeClasspath += configurations.shade;
|
||||||
|
test.compileClasspath += configurations.shade;
|
||||||
|
test.runtimeClasspath += configurations.shade;
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
configurations.shade.each { dep ->
|
||||||
|
from(project.zipTree(dep)) {
|
||||||
|
exclude 'META-INF', 'META-INF/**'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO maven uploading
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
#Wed Jun 22 18:29:49 CEST 2016
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
|
|
@ -0,0 +1,164 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
|
@ -0,0 +1,90 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@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 DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_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=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
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%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -0,0 +1,2 @@
|
||||||
|
rootProject.name = 'ChorusGradle'
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
package chorusmc.gradle;
|
||||||
|
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.gradle.api.Plugin;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.Task;
|
||||||
|
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
|
||||||
|
import org.gradle.api.plugins.JavaPlugin;
|
||||||
|
import org.gradle.api.plugins.JavaPluginConvention;
|
||||||
|
import org.gradle.api.tasks.SourceSet;
|
||||||
|
import org.gradle.api.tasks.javadoc.Javadoc;
|
||||||
|
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
|
||||||
|
import org.gradle.plugins.ide.idea.model.IdeaModel;
|
||||||
|
|
||||||
|
public class AbstractPlugin implements Plugin<Project> {
|
||||||
|
protected Project project;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(Project target) {
|
||||||
|
this.project = target;
|
||||||
|
|
||||||
|
// Apply default plugins
|
||||||
|
project.apply(ImmutableMap.of("plugin", "java"));
|
||||||
|
project.apply(ImmutableMap.of("plugin", "eclipse"));
|
||||||
|
project.apply(ImmutableMap.of("plugin", "idea"));
|
||||||
|
|
||||||
|
project.getExtensions().create("minecraft", ChorusGradleExtension.class);
|
||||||
|
|
||||||
|
// Force add Mojang repository
|
||||||
|
addMavenRepo(target, "Mojang", "https://libraries.minecraft.net/");
|
||||||
|
|
||||||
|
// Minecraft libraries configuration
|
||||||
|
project.getConfigurations().maybeCreate(Constants.CONFIG_MC_DEPENDENCIES);
|
||||||
|
project.getConfigurations().maybeCreate(Constants.CONFIG_MC_DEPENDENCIES_CLIENT);
|
||||||
|
project.getConfigurations().maybeCreate(Constants.CONFIG_NATIVES);
|
||||||
|
|
||||||
|
// Common libraries extends from client libraries, CONFIG_MC_DEPENDENCIES will contains all MC dependencies
|
||||||
|
project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).extendsFrom(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES_CLIENT));
|
||||||
|
|
||||||
|
configureIDEs();
|
||||||
|
configureCompile();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permit to create a Task instance of the type in the project
|
||||||
|
*
|
||||||
|
* @param name The name of the task
|
||||||
|
* @param type The type of the task that will be used to create an instance
|
||||||
|
* @return The created task object for the project
|
||||||
|
*/
|
||||||
|
public <T extends Task> T makeTask(String name, Class<T> type) {
|
||||||
|
return makeTask(project, name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permit to create a Task instance of the type in a project
|
||||||
|
*
|
||||||
|
* @param target The target project
|
||||||
|
* @param name The name of the task
|
||||||
|
* @param type The type of the task that will be used to create an instance
|
||||||
|
* @return The created task object for the specified project
|
||||||
|
*/
|
||||||
|
public static <T extends Task> T makeTask(Project target, String name, Class<T> type) {
|
||||||
|
return target.getTasks().create(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permit to add a Maven repository to a target project
|
||||||
|
*
|
||||||
|
* @param target The garget project
|
||||||
|
* @param name The name of the repository
|
||||||
|
* @param url The URL of the repository
|
||||||
|
* @return An object containing the name and the URL of the repository that can be modified later
|
||||||
|
*/
|
||||||
|
public MavenArtifactRepository addMavenRepo(Project target, final String name, final String url) {
|
||||||
|
return target.getRepositories().maven(repo -> {
|
||||||
|
repo.setName(name);
|
||||||
|
repo.setUrl(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Minecraft dependencies to IDE dependencies
|
||||||
|
*/
|
||||||
|
protected void configureIDEs() {
|
||||||
|
// IDEA
|
||||||
|
IdeaModel ideaModule = (IdeaModel) project.getExtensions().getByName("idea");
|
||||||
|
|
||||||
|
ideaModule.getModule().getExcludeDirs().addAll(project.files(".gradle", "build", ".idea", "out").getFiles());
|
||||||
|
ideaModule.getModule().setDownloadJavadoc(true);
|
||||||
|
ideaModule.getModule().setDownloadSources(true);
|
||||||
|
ideaModule.getModule().setInheritOutputDirs(true);
|
||||||
|
ideaModule.getModule().getScopes().get("COMPILE").get("plus").add(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES));
|
||||||
|
|
||||||
|
// ECLIPSE
|
||||||
|
EclipseModel eclipseModule = (EclipseModel) project.getExtensions().getByName("eclipse");
|
||||||
|
eclipseModule.getClasspath().getPlusConfigurations().add(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Minecraft dependencies to compile time
|
||||||
|
*/
|
||||||
|
protected void configureCompile() {
|
||||||
|
JavaPluginConvention javaModule = (JavaPluginConvention) project.getConvention().getPlugins().get("java");
|
||||||
|
|
||||||
|
SourceSet main = javaModule.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||||
|
SourceSet test = javaModule.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME);
|
||||||
|
|
||||||
|
main.setCompileClasspath(main.getCompileClasspath().plus(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES)));
|
||||||
|
test.setCompileClasspath(test.getCompileClasspath().plus(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES)));
|
||||||
|
main.setRuntimeClasspath(main.getCompileClasspath().plus(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES)));
|
||||||
|
test.setCompileClasspath(test.getCompileClasspath().plus(project.getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES)));
|
||||||
|
|
||||||
|
Javadoc javadoc = (Javadoc) project.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME);
|
||||||
|
javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package chorusmc.gradle;
|
||||||
|
|
||||||
|
public class ChorusGradleExtension {
|
||||||
|
public String version;
|
||||||
|
public String runDir = "run";
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package chorusmc.gradle;
|
||||||
|
|
||||||
|
import chorusmc.gradle.task.*;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
|
public class ChorusGradlePlugin extends AbstractPlugin {
|
||||||
|
@Override
|
||||||
|
public void apply(Project target) {
|
||||||
|
super.apply(target);
|
||||||
|
|
||||||
|
makeTask("download", DownloadTask.class);
|
||||||
|
makeTask("mapJars", MapJarsTask.class).dependsOn("download");
|
||||||
|
makeTask("setupChorus", DefaultTask.class).dependsOn("mapJars");
|
||||||
|
|
||||||
|
makeTask("extractNatives", ExtractNativesTask.class).dependsOn("download");
|
||||||
|
makeTask("genIdeaRuns", GenIdeaProjectTask.class).dependsOn("cleanIdea").dependsOn("idea").dependsOn("extractNatives");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package chorusmc.gradle.task;
|
||||||
|
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.tasks.Input;
|
||||||
|
import org.gradle.api.tasks.OutputFile;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import chorusmc.gradle.util.progress.ProgressLogger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic Download class compatible with ProgressLogger
|
||||||
|
*/
|
||||||
|
public class DownloadNewTask extends DefaultTask {
|
||||||
|
|
||||||
|
@Input
|
||||||
|
private Object output;
|
||||||
|
|
||||||
|
@OutputFile
|
||||||
|
private String url;
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void download() throws IOException {
|
||||||
|
File outputFile = getProject().file(getOutput());
|
||||||
|
outputFile.getParentFile().mkdirs();
|
||||||
|
outputFile.createNewFile();
|
||||||
|
|
||||||
|
getLogger().info("Downloading " + getURL());
|
||||||
|
|
||||||
|
URL url = new URL(getURL());
|
||||||
|
HttpURLConnection connect = (HttpURLConnection) url.openConnection();
|
||||||
|
connect.setRequestProperty("User-Agent", Constants.USER_AGENT);
|
||||||
|
connect.setInstanceFollowRedirects(true);
|
||||||
|
|
||||||
|
ProgressLogger progressLogger = ProgressLogger.getProgressFactory(getProject(), getClass().getName());
|
||||||
|
progressLogger.setDescription("Downloading " + getURL());
|
||||||
|
ReadableByteChannel inChannel = new DownloadChannel(Channels.newChannel(connect.getInputStream()), getContentLength(url), progressLogger);
|
||||||
|
FileChannel outChannel = new FileOutputStream(outputFile).getChannel();
|
||||||
|
outChannel.transferFrom(inChannel, 0, Long.MAX_VALUE);
|
||||||
|
outChannel.close();
|
||||||
|
inChannel.close();
|
||||||
|
progressLogger.completed();
|
||||||
|
getLogger().info("Download complete");
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getContentLength(URL url) {
|
||||||
|
HttpURLConnection connection;
|
||||||
|
int contentLength = -1;
|
||||||
|
try {
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
contentLength = connection.getContentLength();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getOutput() {
|
||||||
|
return getProject().file(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutput(Object output) {
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getURL() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setURL(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadChannel implements ReadableByteChannel {
|
||||||
|
ProgressLogger logger;
|
||||||
|
String formattedSize;
|
||||||
|
ReadableByteChannel rbc;
|
||||||
|
long totalBytes;
|
||||||
|
|
||||||
|
DownloadChannel(ReadableByteChannel rbc, long expectedSize, ProgressLogger logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.formattedSize = toHumanReadableLength(expectedSize);
|
||||||
|
this.rbc = rbc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
rbc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOpen() {
|
||||||
|
return rbc.isOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(ByteBuffer buffer) throws IOException {
|
||||||
|
int processedBytes;
|
||||||
|
if ((processedBytes = rbc.read(buffer)) > 0) {
|
||||||
|
totalBytes += processedBytes;
|
||||||
|
logger.progress(toHumanReadableLength(totalBytes) + "/" + formattedSize + " downloaded");
|
||||||
|
}
|
||||||
|
return processedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toHumanReadableLength(long bytes) {
|
||||||
|
if (bytes < 1024) {
|
||||||
|
return bytes + " B";
|
||||||
|
} else if (bytes < 1024 * 1024) {
|
||||||
|
return (bytes / 1024) + " KB";
|
||||||
|
} else if (bytes < 1024 * 1024 * 1024) {
|
||||||
|
return String.format("%.2f MB", bytes / (1024.0 * 1024.0));
|
||||||
|
} else {
|
||||||
|
return String.format("%.2f GB", bytes / (1024.0 * 1024.0 * 1024.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package chorusmc.gradle.task;
|
||||||
|
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
import chorusmc.gradle.util.Version;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.artifacts.dsl.DependencyHandler;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import chorusmc.gradle.ChorusGradleExtension;
|
||||||
|
import chorusmc.gradle.util.Checksum;
|
||||||
|
import chorusmc.gradle.util.ManifestVersion;
|
||||||
|
import chorusmc.gradle.util.assets.AssetIndex;
|
||||||
|
import chorusmc.gradle.util.assets.AssetObject;
|
||||||
|
import chorusmc.gradle.util.progress.ProgressLogger;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class DownloadTask extends DefaultTask {
|
||||||
|
@TaskAction
|
||||||
|
public void download() {
|
||||||
|
try {
|
||||||
|
ChorusGradleExtension extension = this.getProject().getExtensions().getByType(ChorusGradleExtension.class);
|
||||||
|
|
||||||
|
if (!Constants.MINECRAFT_JSON.get(extension).exists()) {
|
||||||
|
this.getLogger().lifecycle(":downloading minecraft json");
|
||||||
|
FileUtils.copyURLToFile(new URL("https://launchermeta.mojang.com/mc/game/version_manifest.json"), Constants.VERSION_MANIFEST);
|
||||||
|
ManifestVersion mcManifest = new GsonBuilder().create().fromJson(FileUtils.readFileToString(Constants.VERSION_MANIFEST), ManifestVersion.class);
|
||||||
|
|
||||||
|
Optional<ManifestVersion.Versions> optionalVersion = mcManifest.versions.stream().filter(versions -> versions.id.equalsIgnoreCase(extension.version)).findFirst();
|
||||||
|
if (optionalVersion.isPresent()) {
|
||||||
|
FileUtils.copyURLToFile(new URL(optionalVersion.get().url), Constants.MINECRAFT_JSON.get(extension));
|
||||||
|
} else {
|
||||||
|
this.getLogger().info(":failed downloading minecraft json");
|
||||||
|
throw new RuntimeException("Failed downloading Minecraft json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Version version = gson.fromJson(new FileReader(Constants.MINECRAFT_JSON.get(extension)), Version.class);
|
||||||
|
|
||||||
|
if (!Constants.MINECRAFT_CLIENT_JAR.get(extension).exists() || !Checksum.equals(Constants.MINECRAFT_CLIENT_JAR.get(extension), version.downloads.get("client").sha1)) {
|
||||||
|
this.getLogger().lifecycle(":downloading client");
|
||||||
|
FileUtils.copyURLToFile(new URL(version.downloads.get("client").url), Constants.MINECRAFT_CLIENT_JAR.get(extension));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Constants.MAPPINGS_ZIP.exists()) {
|
||||||
|
Constants.MAPPINGS_ZIP.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getLogger().lifecycle(":downloading mappings");
|
||||||
|
FileUtils.copyURLToFile(new URL("https://github.com/ChorusMC/pomf/archive/master.zip"), Constants.MAPPINGS_ZIP);
|
||||||
|
|
||||||
|
DependencyHandler dependencyHandler = getProject().getDependencies();
|
||||||
|
|
||||||
|
if (getProject().getConfigurations().getByName(Constants.CONFIG_MC_DEPENDENCIES).getState() == Configuration.State.UNRESOLVED) {
|
||||||
|
for (Version.Library library : version.libraries) {
|
||||||
|
if (library.allowed() && library.getFile() != null) {
|
||||||
|
// By default, they are all available on all sides
|
||||||
|
String configName = Constants.CONFIG_MC_DEPENDENCIES;
|
||||||
|
if (library.name.contains("java3d") || library.name.contains("paulscode") || library.name.contains("lwjgl") || library.name.contains("twitch") || library.name.contains("jinput")) {
|
||||||
|
configName = Constants.CONFIG_MC_DEPENDENCIES_CLIENT;
|
||||||
|
}
|
||||||
|
dependencyHandler.add(configName, library.getArtifactName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getProject().getConfigurations().getByName(Constants.CONFIG_NATIVES).getState() == Configuration.State.UNRESOLVED) {
|
||||||
|
version.libraries.stream().filter(lib -> lib.natives != null).forEach(lib -> dependencyHandler.add(Constants.CONFIG_NATIVES, lib.getArtifactName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force add LaunchWrapper
|
||||||
|
dependencyHandler.add(Constants.CONFIG_MC_DEPENDENCIES, "net.minecraft:launchwrapper:1.11");
|
||||||
|
|
||||||
|
Version.AssetIndex assetIndex = version.assetIndex;
|
||||||
|
|
||||||
|
File assets = new File(Constants.CACHE_FILES, "assets");
|
||||||
|
if (!assets.exists()) {
|
||||||
|
assets.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
File assetsInfo = new File(assets, "indexes" + File.separator + assetIndex.id + ".json");
|
||||||
|
if (!assetsInfo.exists() || !Checksum.equals(assetsInfo, assetIndex.sha1)) {
|
||||||
|
this.getLogger().lifecycle(":downloading asset index");
|
||||||
|
FileUtils.copyURLToFile(new URL(assetIndex.url), assetsInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressLogger progressLogger = ProgressLogger.getProgressFactory(getProject(), getClass().getName());
|
||||||
|
progressLogger.start("Downloading assets...", "assets");
|
||||||
|
AssetIndex index = new Gson().fromJson(new FileReader(assetsInfo), AssetIndex.class);
|
||||||
|
Map<String, AssetObject> parent = index.getFileMap();
|
||||||
|
final int totalSize = parent.size();
|
||||||
|
int position = 0;
|
||||||
|
this.getLogger().lifecycle(":downloading assets...");
|
||||||
|
for (Map.Entry<String, AssetObject> entry : parent.entrySet()) {
|
||||||
|
AssetObject object = entry.getValue();
|
||||||
|
String sha1 = object.getHash();
|
||||||
|
File file = new File(assets, "objects" + File.separator + sha1.substring(0, 2) + File.separator + sha1);
|
||||||
|
if (!file.exists() || !Checksum.equals(file, sha1)) {
|
||||||
|
this.getLogger().debug(":downloading asset " + entry.getKey());
|
||||||
|
FileUtils.copyURLToFile(new URL(Constants.RESOURCES_BASE + sha1.substring(0, 2) + "/" + sha1), file);
|
||||||
|
}
|
||||||
|
String assetName = entry.getKey();
|
||||||
|
int end = assetName.lastIndexOf("/") + 1;
|
||||||
|
if (end > 0) {
|
||||||
|
assetName = assetName.substring(end, assetName.length());
|
||||||
|
}
|
||||||
|
progressLogger.progress(assetName + " - " + position + "/" + totalSize + " (" + (int) ((position / (double) totalSize) * 100) + "%) assets downloaded");
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
progressLogger.completed();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package chorusmc.gradle.task;
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
public class ExtractNativesTask extends DefaultTask {
|
||||||
|
@TaskAction
|
||||||
|
public void extractNatives() throws FileNotFoundException {
|
||||||
|
if (!Constants.MINECRAFT_NATIVES.exists()) {
|
||||||
|
for (File source : getProject().getConfigurations().getByName(Constants.CONFIG_NATIVES)) {
|
||||||
|
ZipUtil.unpack(source, Constants.MINECRAFT_NATIVES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
package chorusmc.gradle.task;
|
||||||
|
|
||||||
|
import chorusmc.gradle.ChorusGradleExtension;
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
import chorusmc.gradle.util.IdeaRunConfig;
|
||||||
|
import chorusmc.gradle.util.Version;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.OutputKeys;
|
||||||
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class GenIdeaProjectTask extends DefaultTask {
|
||||||
|
@TaskAction
|
||||||
|
public void genIdeaRuns() throws IOException, ParserConfigurationException, SAXException, TransformerException {
|
||||||
|
ChorusGradleExtension extension = this.getProject().getExtensions().getByType(ChorusGradleExtension.class);
|
||||||
|
|
||||||
|
File file = new File(getProject().getName() + ".iml");
|
||||||
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
Document doc = docBuilder.parse(file);
|
||||||
|
|
||||||
|
Node component = null;
|
||||||
|
NodeList module = doc.getElementsByTagName("module").item(0).getChildNodes();
|
||||||
|
for (int i = 0; i < module.getLength(); i++) {
|
||||||
|
if (module.item(i).getNodeName().equals("component")) {
|
||||||
|
component = module.item(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component == null) {
|
||||||
|
this.getLogger().lifecycle(":failed to generate intellij run configurations");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node content = null;
|
||||||
|
NodeList moduleList = component.getChildNodes();
|
||||||
|
|
||||||
|
for (int i = 0; i < moduleList.getLength(); i++) {
|
||||||
|
if (moduleList.item(i).getNodeName().equals("content")) {
|
||||||
|
content = moduleList.item(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content == null) {
|
||||||
|
this.getLogger().lifecycle(":failed to generate intellij run configurations");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Element sourceFolder = doc.createElement("sourceFolder");
|
||||||
|
sourceFolder.setAttribute("url", "file://$MODULE_DIR$/minecraft/src/main/java");
|
||||||
|
sourceFolder.setAttribute("isTestSource", "false");
|
||||||
|
content.appendChild(sourceFolder);
|
||||||
|
|
||||||
|
sourceFolder = doc.createElement("sourceFolder");
|
||||||
|
sourceFolder.setAttribute("url", "file://$MODULE_DIR$/minecraft/src/main/resources");
|
||||||
|
sourceFolder.setAttribute("type", "java-resource");
|
||||||
|
content.appendChild(sourceFolder);
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
Version version = gson.fromJson(new FileReader(Constants.MINECRAFT_JSON.get(extension)), Version.class);
|
||||||
|
|
||||||
|
for (Version.Library library : version.libraries) {
|
||||||
|
if (library.allowed() && library.getFile() != null && library.getFile().exists()) {
|
||||||
|
Element node = doc.createElement("orderEntry");
|
||||||
|
node.setAttribute("type", "module-library");
|
||||||
|
Element libraryElement = doc.createElement("library");
|
||||||
|
Element classes = doc.createElement("CLASSES");
|
||||||
|
Element javadoc = doc.createElement("JAVADOC");
|
||||||
|
Element sources = doc.createElement("SOURCES");
|
||||||
|
Element root = doc.createElement("root");
|
||||||
|
root.setAttribute("url", "jar://" + library.getFile().getAbsolutePath() + "!/");
|
||||||
|
classes.appendChild(root);
|
||||||
|
libraryElement.appendChild(classes);
|
||||||
|
libraryElement.appendChild(javadoc);
|
||||||
|
libraryElement.appendChild(sources);
|
||||||
|
node.appendChild(libraryElement);
|
||||||
|
component.appendChild(node);
|
||||||
|
} else if (!library.allowed()) {
|
||||||
|
this.getLogger().info(":" + library.getFile().getName() + " is not allowed on this os");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Element node = doc.createElement("orderEntry");
|
||||||
|
node.setAttribute("type", "module-library");
|
||||||
|
Element libraryElement = doc.createElement("library");
|
||||||
|
Element classes = doc.createElement("CLASSES");
|
||||||
|
Element javadoc = doc.createElement("JAVADOC");
|
||||||
|
Element sources = doc.createElement("SOURCES");
|
||||||
|
Element root = doc.createElement("root");
|
||||||
|
root.setAttribute("url", "jar://" + Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension).getAbsolutePath() + "!/");
|
||||||
|
classes.appendChild(root);
|
||||||
|
libraryElement.appendChild(classes);
|
||||||
|
libraryElement.appendChild(javadoc);
|
||||||
|
libraryElement.appendChild(sources);
|
||||||
|
node.appendChild(libraryElement);
|
||||||
|
component.appendChild(node);
|
||||||
|
|
||||||
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
|
Transformer transformer = transformerFactory.newTransformer();
|
||||||
|
DOMSource source = new DOMSource(doc);
|
||||||
|
StreamResult result = new StreamResult(file);
|
||||||
|
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
|
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||||
|
transformer.transform(source, result);
|
||||||
|
|
||||||
|
file = new File(getProject().getName() + ".iws");
|
||||||
|
docFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
doc = docBuilder.parse(file);
|
||||||
|
|
||||||
|
NodeList list = doc.getElementsByTagName("component");
|
||||||
|
Element runManager = null;
|
||||||
|
for (int i = 0; i < list.getLength(); i++) {
|
||||||
|
Element element = (Element) list.item(i);
|
||||||
|
if (element.getAttribute("name").equals("RunManager")) {
|
||||||
|
runManager = element;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runManager == null) {
|
||||||
|
this.getLogger().lifecycle(":failed to generate intellij run configurations");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IdeaRunConfig ideaClient = new IdeaRunConfig();
|
||||||
|
ideaClient.mainClass = "chorusmc.base.ClientStart";
|
||||||
|
ideaClient.projectName = getProject().getName();
|
||||||
|
ideaClient.configName = "Minecraft Client";
|
||||||
|
ideaClient.runDir = "file://$PROJECT_DIR$/" + extension.runDir;
|
||||||
|
ideaClient.arguments = "--assetIndex " + version.assetIndex.id + " --assetsDir " + new File(Constants.CACHE_FILES, "assets").getAbsolutePath();
|
||||||
|
|
||||||
|
runManager.appendChild(ideaClient.genRuns(runManager));
|
||||||
|
|
||||||
|
transformerFactory = TransformerFactory.newInstance();
|
||||||
|
transformer = transformerFactory.newTransformer();
|
||||||
|
source = new DOMSource(doc);
|
||||||
|
result = new StreamResult(file);
|
||||||
|
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
|
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||||
|
transformer.transform(source, result);
|
||||||
|
|
||||||
|
File runDir = new File(Constants.WORKING_DIRECTORY, extension.runDir);
|
||||||
|
if (!runDir.exists()) {
|
||||||
|
runDir.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package chorusmc.gradle.task;
|
||||||
|
|
||||||
|
import cuchaz.enigma.Deobfuscator;
|
||||||
|
import cuchaz.enigma.mapping.MappingsEnigmaReader;
|
||||||
|
import cuchaz.enigma.throwables.MappingParseException;
|
||||||
|
import groovy.lang.Closure;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.gradle.process.ExecResult;
|
||||||
|
import org.gradle.process.JavaExecSpec;
|
||||||
|
import chorusmc.gradle.ChorusGradleExtension;
|
||||||
|
import chorusmc.gradle.util.Constants;
|
||||||
|
import org.zeroturnaround.zip.ZipUtil;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
|
public class MapJarsTask extends DefaultTask {
|
||||||
|
|
||||||
|
Deobfuscator deobfuscator;
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void mapJars() throws IOException, MappingParseException {
|
||||||
|
ChorusGradleExtension extension = this.getProject().getExtensions().getByType(ChorusGradleExtension.class);
|
||||||
|
if(Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension).exists()){
|
||||||
|
Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension).delete();
|
||||||
|
}
|
||||||
|
this.getLogger().lifecycle(":unpacking mappings");
|
||||||
|
if(Constants.MAPPINGS_DIR.exists()){
|
||||||
|
FileUtils.deleteDirectory(Constants.MAPPINGS_DIR);
|
||||||
|
}
|
||||||
|
ZipUtil.unpack(Constants.MAPPINGS_ZIP, Constants.MAPPINGS_DIR);
|
||||||
|
|
||||||
|
this.getLogger().lifecycle(":remapping jar");
|
||||||
|
deobfuscator = new Deobfuscator(new JarFile(Constants.MINECRAFT_CLIENT_JAR.get(extension)));
|
||||||
|
this.deobfuscator.setMappings(new MappingsEnigmaReader().read(new File(Constants.MAPPINGS_DIR, "pomf-master" + File.separator + "mappings")));
|
||||||
|
this.deobfuscator.writeJar(Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension), new ProgressListener());
|
||||||
|
|
||||||
|
File tempAssests = new File(Constants.CACHE_FILES, "tempAssets");
|
||||||
|
|
||||||
|
ZipUtil.unpack(Constants.MINECRAFT_CLIENT_JAR.get(extension), tempAssests, name -> {
|
||||||
|
if (name.startsWith("assets") || name.startsWith("log4j2.xml")) {
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ZipUtil.unpack(Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension), tempAssests);
|
||||||
|
|
||||||
|
ZipUtil.pack(tempAssests, Constants.MINECRAFT_CLIENT_MAPPED_JAR.get(extension));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ProgressListener implements Deobfuscator.ProgressListener {
|
||||||
|
@Override
|
||||||
|
public void init(int i, String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgress(int i, String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
import com.google.common.hash.HashCode;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class Checksum {
|
||||||
|
public static boolean equals(File file, String checksum) {
|
||||||
|
if (file == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
HashCode hash = Files.hash(file, Hashing.sha1());
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (Byte hashBytes : hash.asBytes()) {
|
||||||
|
builder.append(Integer.toString((hashBytes & 0xFF) + 0x100, 16).substring(1));
|
||||||
|
}
|
||||||
|
return builder.toString().equals(checksum);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
import chorusmc.gradle.util.delayed.IDelayed;
|
||||||
|
import chorusmc.gradle.util.delayed.DelayedFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
public static final File WORKING_DIRECTORY = new File(".");
|
||||||
|
public static final File CACHE_FILES = new File(WORKING_DIRECTORY, ".gradle/minecraft");
|
||||||
|
|
||||||
|
public static final IDelayed<File> MINECRAFT_CLIENT_JAR = new DelayedFile(extension -> new File(CACHE_FILES, extension.version + "-client.jar"));
|
||||||
|
public static final IDelayed<File> MINECRAFT_CLIENT_MAPPED_JAR = new DelayedFile(extension -> new File(CACHE_FILES, extension.version + "-client-mapped.jar"));
|
||||||
|
|
||||||
|
public static final File MAPPINGS_ZIP = new File(CACHE_FILES, "mappings.zip");
|
||||||
|
public static final File MAPPINGS_DIR = new File(CACHE_FILES, "mappings");
|
||||||
|
|
||||||
|
public static final File MINECRAFT_LIBS = new File(CACHE_FILES, "libs");
|
||||||
|
public static final File MINECRAFT_NATIVES = new File(CACHE_FILES, "natives");
|
||||||
|
public static final IDelayed<File> MINECRAFT_JSON = new DelayedFile(extension -> new File(CACHE_FILES, extension.version + "-info.json"));
|
||||||
|
|
||||||
|
public static final File MINECRAFT_ROOT = new File(WORKING_DIRECTORY, "minecraft");
|
||||||
|
public static final IDelayed<File> MAPPING_SRG = new DelayedFile(extension -> new File(WORKING_DIRECTORY, "mappings.srg"));
|
||||||
|
|
||||||
|
public static final File VERSION_MANIFEST = new File(CACHE_FILES, "version_manifest.json");
|
||||||
|
|
||||||
|
public static final String LIBRARIES_BASE = "https://libraries.minecraft.net/";
|
||||||
|
public static final String RESOURCES_BASE = "http://resources.download.minecraft.net/";
|
||||||
|
|
||||||
|
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11";
|
||||||
|
|
||||||
|
public static final String CONFIG_NATIVES = "MC_NATIVES";
|
||||||
|
public static final String CONFIG_MC_DEPENDENCIES = "MC_DEPENDENCIES";
|
||||||
|
public static final String CONFIG_MC_DEPENDENCIES_CLIENT = "MC_DEPENDENCIES_CLIENT";
|
||||||
|
public static final String SYSTEM_ARCH = System.getProperty("os.arch").equals("64") ? "64" : "32";
|
||||||
|
|
||||||
|
public static List<String> getClassPath() {
|
||||||
|
URL[] urls = ((URLClassLoader) Constants.class.getClassLoader()).getURLs();
|
||||||
|
ArrayList<String> list = new ArrayList<>();
|
||||||
|
for (URL url : urls) {
|
||||||
|
list.add(url.getPath());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IdeaRunConfig {
|
||||||
|
public String configName;
|
||||||
|
public String projectName;
|
||||||
|
public String mainClass;
|
||||||
|
public String runDir;
|
||||||
|
public String arguments;
|
||||||
|
|
||||||
|
public Element genRuns(Element doc) throws IOException, ParserConfigurationException, TransformerException {
|
||||||
|
Element root = this.addXml(doc, "component", ImmutableMap.of("name", "ProjectRunConfigurationManager"));
|
||||||
|
root = addXml(root, "configuration", ImmutableMap.of("default", "false", "name", configName, "type", "Application", "factoryName", "Application"));
|
||||||
|
|
||||||
|
this.addXml(root, "module", ImmutableMap.of("name", projectName));
|
||||||
|
this.addXml(root, "option", ImmutableMap.of("name", "MAIN_CLASS_NAME", "value", mainClass));
|
||||||
|
this.addXml(root, "option", ImmutableMap.of("name", "WORKING_DIRECTORY", "value", runDir));
|
||||||
|
|
||||||
|
if (!Strings.isNullOrEmpty(arguments)) {
|
||||||
|
this.addXml(root, "option", ImmutableMap.of("name", "PROGRAM_PARAMETERS", "value", arguments));
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Element addXml(Node parent, String name, Map<String, String> values) {
|
||||||
|
Document doc = parent.getOwnerDocument();
|
||||||
|
if (doc == null) {
|
||||||
|
doc = (Document) parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
Element e = doc.createElement(name);
|
||||||
|
for (Map.Entry<String, String> entry : values.entrySet()) {
|
||||||
|
e.setAttribute(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
parent.appendChild(e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ManifestVersion {
|
||||||
|
public List<Versions> versions = new ArrayList<>();
|
||||||
|
|
||||||
|
public static class Versions {
|
||||||
|
public String id, url;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
public class OperatingSystem {
|
||||||
|
public static String getOS() {
|
||||||
|
String osName = System.getProperty("os.name").toLowerCase();
|
||||||
|
if (osName.contains("win")) {
|
||||||
|
return "windows";
|
||||||
|
} else if (osName.contains("mac")) {
|
||||||
|
return "osx";
|
||||||
|
} else {
|
||||||
|
return "linux";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getArch() {
|
||||||
|
if (is64Bit()) {
|
||||||
|
return "64";
|
||||||
|
} else {
|
||||||
|
return "32";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is64Bit() {
|
||||||
|
return System.getProperty("sun.arch.data.model").contains("64");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
package chorusmc.gradle.util;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Version {
|
||||||
|
public List<Library> libraries;
|
||||||
|
public Map<String, Downloads> downloads;
|
||||||
|
public AssetIndex assetIndex;
|
||||||
|
|
||||||
|
public class Downloads {
|
||||||
|
public String url;
|
||||||
|
public String sha1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AssetIndex {
|
||||||
|
public String id;
|
||||||
|
public String sha1;
|
||||||
|
public String url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Library {
|
||||||
|
public String name;
|
||||||
|
public JsonObject natives;
|
||||||
|
public JsonObject downloads;
|
||||||
|
private Artifact artifact;
|
||||||
|
public Rule[] rules;
|
||||||
|
|
||||||
|
public String getURL() {
|
||||||
|
String path;
|
||||||
|
String[] parts = this.name.split(":", 3);
|
||||||
|
path = parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + parts[1] + "-" + parts[2] + getClassifier() + ".jar";
|
||||||
|
return Constants.LIBRARIES_BASE + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
String[] parts = this.name.split(":", 3);
|
||||||
|
return new File(Constants.MINECRAFT_LIBS, parts[0].replace(".", File.separator) + File.separator + parts[1] + File.separator + parts[2] + File.separator + parts[1] + "-" + parts[2] + getClassifier() + ".jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSha1() {
|
||||||
|
if (this.downloads == null) {
|
||||||
|
return "";
|
||||||
|
} else if (this.downloads.getAsJsonObject("artifact") == null) {
|
||||||
|
return "";
|
||||||
|
} else if (this.downloads.getAsJsonObject("artifact").get("sha1") == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return this.downloads.getAsJsonObject("artifact").get("sha1").getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassifier() {
|
||||||
|
if (natives == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return "-" + natives.get(OperatingSystem.getOS().replace("${arch}", OperatingSystem.getArch())).getAsString().replace("\"", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean allowed() {
|
||||||
|
if (this.rules == null || this.rules.length <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = false;
|
||||||
|
for (Rule rule : this.rules) {
|
||||||
|
if (rule.os != null && rule.os.name != null) {
|
||||||
|
if (rule.os.name.equalsIgnoreCase(OperatingSystem.getOS())) {
|
||||||
|
return rule.action.equalsIgnoreCase("allow");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
success = rule.action.equalsIgnoreCase("allow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArtifactName() {
|
||||||
|
if (artifact == null) {
|
||||||
|
artifact = new Artifact(name);
|
||||||
|
}
|
||||||
|
return artifact.getArtifact(natives == null ? artifact.getClassifier() : natives.get(OperatingSystem.getOS()).getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Artifact {
|
||||||
|
private final String domain, name, version, classifier, ext;
|
||||||
|
|
||||||
|
public Artifact(String name) {
|
||||||
|
String[] splitedArtifact = name.split(":");
|
||||||
|
int idx = splitedArtifact[splitedArtifact.length - 1].indexOf('@');
|
||||||
|
if (idx != -1) {
|
||||||
|
ext = splitedArtifact[splitedArtifact.length - 1].substring(idx + 1);
|
||||||
|
splitedArtifact[splitedArtifact.length - 1] = splitedArtifact[splitedArtifact.length - 1].substring(0, idx);
|
||||||
|
} else {
|
||||||
|
ext = "jar";
|
||||||
|
}
|
||||||
|
this.domain = splitedArtifact[0];
|
||||||
|
this.name = splitedArtifact[1];
|
||||||
|
this.version = splitedArtifact[2];
|
||||||
|
this.classifier = splitedArtifact.length > 3 ? splitedArtifact[3] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArtifact(String classifier) {
|
||||||
|
String ret = domain + ":" + name + ":" + version;
|
||||||
|
if (classifier != null && classifier.indexOf('$') > -1) {
|
||||||
|
classifier = classifier.replace("${arch}", Constants.SYSTEM_ARCH);
|
||||||
|
}
|
||||||
|
if (classifier != null) {
|
||||||
|
ret += ":" + classifier;
|
||||||
|
}
|
||||||
|
if (!"jar".equals(ext)) {
|
||||||
|
ret += "@" + ext;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassifier() {
|
||||||
|
return classifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Rule {
|
||||||
|
public String action;
|
||||||
|
public OS os;
|
||||||
|
|
||||||
|
private class OS {
|
||||||
|
String name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package chorusmc.gradle.util.assets;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class AssetIndex {
|
||||||
|
private final Map<String, AssetObject> objects;
|
||||||
|
private boolean virtual;
|
||||||
|
|
||||||
|
public AssetIndex() {
|
||||||
|
this.objects = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, AssetObject> getFileMap() {
|
||||||
|
return this.objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<AssetObject> getUniqueObjects() {
|
||||||
|
return new HashSet<>(this.objects.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVirtual() {
|
||||||
|
return this.virtual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package chorusmc.gradle.util.assets;
|
||||||
|
|
||||||
|
public class AssetObject {
|
||||||
|
private String hash;
|
||||||
|
private long size;
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return this.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
} else if ((o == null) || (getClass() != o.getClass())) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
AssetObject that = (AssetObject) o;
|
||||||
|
return this.size == that.size && this.hash.equals(that.hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = this.hash.hashCode();
|
||||||
|
result = 31 * result + (int) (this.size ^ this.size >>> 32);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package chorusmc.gradle.util.delayed;
|
||||||
|
|
||||||
|
import chorusmc.gradle.ChorusGradleExtension;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class DelayedFile implements IDelayed<File> {
|
||||||
|
private File file;
|
||||||
|
private Function<ChorusGradleExtension, File> function;
|
||||||
|
|
||||||
|
public DelayedFile(Function<ChorusGradleExtension, File> function) {
|
||||||
|
this.function = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File get(ChorusGradleExtension extension) {
|
||||||
|
if (this.file == null) {
|
||||||
|
this.file = this.function.apply(extension);
|
||||||
|
}
|
||||||
|
return this.file;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package chorusmc.gradle.util.delayed;
|
||||||
|
|
||||||
|
import chorusmc.gradle.ChorusGradleExtension;
|
||||||
|
|
||||||
|
public interface IDelayed<T> {
|
||||||
|
T get(ChorusGradleExtension extension);
|
||||||
|
}
|
|
@ -0,0 +1,206 @@
|
||||||
|
package chorusmc.gradle.util.progress;
|
||||||
|
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper to ProgressLogger internal API
|
||||||
|
*/
|
||||||
|
public class ProgressLogger {
|
||||||
|
private final Object logger;
|
||||||
|
private final Method getDescription, setDescription, getShortDescription, setShortDescription, getLoggingHeader, setLoggingHeader, start, started, startedArg, progress, completed, completedArg;
|
||||||
|
|
||||||
|
private ProgressLogger(Object logger) {
|
||||||
|
this.logger = logger;
|
||||||
|
this.getDescription = getMethod("getDescription");
|
||||||
|
this.setDescription = getMethod("setDescription", String.class);
|
||||||
|
this.getShortDescription = getMethod("getShortDescription");
|
||||||
|
this.setShortDescription = getMethod("setShortDescription", String.class);
|
||||||
|
this.getLoggingHeader = getMethod("getLoggingHeader");
|
||||||
|
this.setLoggingHeader = getMethod("setLoggingHeader", String.class);
|
||||||
|
this.start = getMethod("start", String.class, String.class);
|
||||||
|
this.started = getMethod("started");
|
||||||
|
this.startedArg = getMethod("started", String.class);
|
||||||
|
this.progress = getMethod("progress", String.class);
|
||||||
|
this.completed = getMethod("completed");
|
||||||
|
this.completedArg = getMethod("completed", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> getFactoryClass() {
|
||||||
|
Class<?> progressLoggerFactoryClass = null;
|
||||||
|
try {
|
||||||
|
//Gradle 2.14 and higher
|
||||||
|
progressLoggerFactoryClass = Class.forName("org.gradle.internal.logging.progress.ProgressLoggerFactory");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
//prior to Gradle 2.14
|
||||||
|
try {
|
||||||
|
progressLoggerFactoryClass = Class.forName("org.gradle.logging.ProgressLoggerFactory");
|
||||||
|
} catch (ClassNotFoundException e1) {
|
||||||
|
// Unsupported Gradle version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return progressLoggerFactoryClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Method getMethod(String methodName, Class<?>... args) {
|
||||||
|
if (logger != null) {
|
||||||
|
try {
|
||||||
|
return logger.getClass().getMethod(methodName, args);
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object invoke(Method method, Object... args) {
|
||||||
|
if (logger != null) {
|
||||||
|
try {
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(logger, args);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Progress logger from the Gradle internal API
|
||||||
|
*
|
||||||
|
* @param project The project
|
||||||
|
* @param category The logger category
|
||||||
|
* @return In any case a progress logger
|
||||||
|
*/
|
||||||
|
public static ProgressLogger getProgressFactory(Project project, String category) {
|
||||||
|
try {
|
||||||
|
Method getServices = project.getClass().getMethod("getServices");
|
||||||
|
Object serviceFactory = getServices.invoke(project);
|
||||||
|
Method get = serviceFactory.getClass().getMethod("get", Class.class);
|
||||||
|
Object progressLoggerFactory = get.invoke(serviceFactory, getFactoryClass());
|
||||||
|
Method newOperation = progressLoggerFactory.getClass().getMethod("newOperation", String.class);
|
||||||
|
return new ProgressLogger(newOperation.invoke(progressLoggerFactory, category));
|
||||||
|
} catch (Exception e) {
|
||||||
|
project.getLogger().error("Unable to get progress logger. Download progress will not be displayed.");
|
||||||
|
return new ProgressLogger(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the description of the operation.
|
||||||
|
*
|
||||||
|
* @return the description, must not be empty.
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return (String) invoke(getDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Sets the description of the operation. This should be a full, stand-alone description of the operation.
|
||||||
|
* <p>
|
||||||
|
* <p>This must be called before {@link #started()}.
|
||||||
|
*
|
||||||
|
* @param description The description.
|
||||||
|
*/
|
||||||
|
public ProgressLogger setDescription(String description) {
|
||||||
|
invoke(setDescription, description);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the short description of the operation. This is used in place of the full description when display space is limited.
|
||||||
|
*
|
||||||
|
* @return The short description, must not be empty.
|
||||||
|
*/
|
||||||
|
public String getShortDescription() {
|
||||||
|
return (String) invoke(getShortDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Sets the short description of the operation. This is used in place of the full description when display space is limited.
|
||||||
|
* <p>
|
||||||
|
* <p>This must be called before {@link #started()}
|
||||||
|
*
|
||||||
|
* @param description The short description.
|
||||||
|
*/
|
||||||
|
public ProgressLogger setShortDescription(String description) {
|
||||||
|
invoke(setShortDescription, description);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Returns the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually
|
||||||
|
* also logged at the end of the operation, along with the final status message. Defaults to null.
|
||||||
|
* <p>
|
||||||
|
* <p>If not specified, no logging header is logged.
|
||||||
|
*
|
||||||
|
* @return The logging header, possibly empty.
|
||||||
|
*/
|
||||||
|
public String getLoggingHeader() {
|
||||||
|
return (String) invoke(getLoggingHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Sets the logging header for the operation. This is logged before any other log messages for this operation are logged. It is usually
|
||||||
|
* also logged at the end of the operation, along with the final status message. Defaults to null.
|
||||||
|
*
|
||||||
|
* @param header The header. May be empty or null.
|
||||||
|
*/
|
||||||
|
public ProgressLogger setLoggingHeader(String header) {
|
||||||
|
invoke(setLoggingHeader, header);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method that sets descriptions and logs started() event.
|
||||||
|
*
|
||||||
|
* @return this logger instance
|
||||||
|
*/
|
||||||
|
public ProgressLogger start(String description, String shortDescription) {
|
||||||
|
invoke(start, description, shortDescription);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the start of the operation, with no initial status.
|
||||||
|
*/
|
||||||
|
public void started() {
|
||||||
|
invoke(started);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the start of the operation, with the given status.
|
||||||
|
*
|
||||||
|
* @param status The initial status message. Can be null or empty.
|
||||||
|
*/
|
||||||
|
public void started(String status) {
|
||||||
|
invoke(started, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs some progress, indicated by a new status.
|
||||||
|
*
|
||||||
|
* @param status The new status message. Can be null or empty.
|
||||||
|
*/
|
||||||
|
public void progress(String status) {
|
||||||
|
invoke(progress, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the completion of the operation, with no final status
|
||||||
|
*/
|
||||||
|
public void completed() {
|
||||||
|
invoke(completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the completion of the operation, with a final status. This is generally logged along with the description.
|
||||||
|
*
|
||||||
|
* @param status The final status message. Can be null or empty.
|
||||||
|
*/
|
||||||
|
public void completed(String status) {
|
||||||
|
invoke(completed, status);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
implementation-class=chorusmc.gradle.ChorusGradlePlugin
|
Loading…
Reference in New Issue