diff --git a/build.gradle b/build.gradle index 8afc6be..67c96bd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,24 +1,18 @@ buildscript { repositories { + jcenter() maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' } - mavenCentral() - maven { - name = "Jitpack" - url 'https://jitpack.io/' - } } dependencies { - classpath "net.fabricmc:fabric-loom:0.12-SNAPSHOT" + classpath "net.fabricmc:fabric-loom:0.2.6-SNAPSHOT" } } -plugins { - id 'fabric-loom' version '0.12-SNAPSHOT' - id 'maven-publish' -} +apply plugin: net.fabricmc.loom.LoomGradlePlugin +apply plugin: 'maven-publish' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -29,18 +23,30 @@ group = project.maven_group repositories { mavenCentral() + maven { + name "Modmuss50 Repository" + url 'https://maven.fabricmc.net/' + } maven { url 'https://jitpack.io' } } dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modCompile "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modCompile "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + modCompile "com.github.modmuss50:Fabric-ASM:${project.fabric_asm_version}" + include "com.github.modmuss50:Fabric-ASM:${project.fabric_asm_version}" - modImplementation "com.github.Chocohead:Fabric-ASM:${project.fabric_asm_version}" - include "com.github.Chocohead:Fabric-ASM:${project.fabric_asm_version}" + //Used to handle the zip processing + compile "org.zeroturnaround:zt-zip:${project.zt_zip_version}" + include "org.zeroturnaround:zt-zip:${project.zt_zip_version}" + + //Required for zt-zip, kinda annoying + include "org.slf4j:slf4j-simple:${project.slf4j_version}" + include "org.slf4j:slf4j-api:${project.slf4j_version}" } task unzip(type: Copy) { @@ -58,9 +64,14 @@ task unzip(type: Copy) { processResources { inputs.property "version", project.version - filesMatching("fabric.mod.json") { + from(sourceSets.main.resources.srcDirs) { + include "fabric.mod.json" expand "version": project.version } + + from(sourceSets.main.resources.srcDirs) { + exclude "fabric.mod.json" + } } // ensure that the encoding is set to UTF-8, no matter what the system default is diff --git a/gradle.properties b/gradle.properties index 477c506..ef4fc9c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,12 +2,14 @@ org.gradle.jvmargs=-Xmx1G minecraft_version=1.14.4 -yarn_mappings=1.14.4+build.18 -loader_version=0.14.8 +yarn_mappings=1.14.4+build.15 +loader_version=0.7.0+build.171 -fabric_version=0.28.5+1.14 -fabric_asm_version=v2.3 +fabric_version=0.4.2+build.246-1.14 +fabric_asm_version=b97939c03a +zt_zip_version=1.13 +slf4j_version=1.7.29 -mod_version = 0.8.0 +mod_version = 0.7.1 maven_group = me.modmuss50 archives_base_name = optifabric diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180..94336fc 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41dfb87..f4d7b2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cbede15..cccdd3d 100644 --- a/gradlew +++ b/gradlew @@ -1,129 +1,78 @@ -#!/bin/sh - -# -# Copyright � 2015-2021 the original 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. -# +#!/usr/bin/env sh ############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions �$var�, �${var}�, �${var:-default}�, �${var+SET}�, -# �${var#prefix}�, �${var%suffix}�, and �$( cmd )�; -# * compound commands having a testable exit status, especially �case�; -# * various built-in commands including �command�, �set�, and �ulimit�. -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# +## +## Gradle start up script for UN*X +## ############################################################################## # Attempt to set APP_HOME - # Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac +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 - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} +APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum +MAX_FD="maximum" warn () { echo "$*" -} >&2 +} die () { echo echo "$*" echo exit 1 -} >&2 +} # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java + JAVACMD="$JAVA_HOME/jre/sh/java" else - JAVACMD=$JAVA_HOME/bin/java + JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -132,7 +81,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD=java + 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 @@ -140,95 +89,84 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi fi -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) +# 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"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) + 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 - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg + 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 + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# 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 -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" \ No newline at end of file +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 477c896..f955316 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,19 +1,3 @@ -@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 @@ -29,18 +13,15 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" +set DEFAULT_JVM_OPTS= @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +35,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto execute +if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,14 +45,28 @@ 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 %* +"%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 @@ -86,4 +81,4 @@ exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega \ No newline at end of file +:omega diff --git a/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixin.java b/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixin.java deleted file mode 100644 index 7695d42..0000000 --- a/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.modmuss50.optifabric.compat; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.CLASS; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Retention(CLASS) -@Target(TYPE) -public @interface InterceptingMixin { - String value(); -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixinPlugin.java b/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixinPlugin.java deleted file mode 100644 index f39acdd..0000000 --- a/src/main/java/me/modmuss50/optifabric/compat/InterceptingMixinPlugin.java +++ /dev/null @@ -1,128 +0,0 @@ -package me.modmuss50.optifabric.compat; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.AnnotationNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; - -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import org.spongepowered.asm.mixin.injection.Surrogate; -import org.spongepowered.asm.mixin.transformer.ClassInfo.Method; -import org.spongepowered.asm.util.Annotations; - -import me.modmuss50.optifabric.util.MixinFinder; -import me.modmuss50.optifabric.util.MixinFinder.Mixin; - -public class InterceptingMixinPlugin implements IMixinConfigPlugin { - - @Override - public void onLoad(String mixinPackage) { - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return true; - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - } - - @Override - public List getMixins() { - return Collections.emptyList(); - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - ClassNode thisMixin = Mixin.create(mixinInfo).getClassNode(); - - AnnotationNode interception = Annotations.getInvisible(thisMixin, InterceptingMixin.class); - if (interception == null) return; //Nothing to do for this particular Mixin - - Mixin interceptionMixin = findMixin(targetClassName, Annotations.getValue(interception)); - on: for (MethodNode method : thisMixin.methods) { - AnnotationNode surrogateNode = Annotations.getInvisible(method, PlacatingSurrogate.class); - - if (surrogateNode != null) { - for (Method realMethod : interceptionMixin.getMethods()) { - if (realMethod.getOriginalName().equals(method.name)) { - method.name = realMethod.getName(); //Mangle name to whatever Mixin is using for the real injection - method.invisibleAnnotations.remove(surrogateNode); - Annotations.setVisible(method, Surrogate.class); - - targetClass.methods.add(method); - continue on; - } - } - - throw new IllegalStateException("Cannot find original Mixin method for surrogate " + method.name + method.desc + " in " + interceptionMixin); - } - } - } - - private static Mixin findMixin(String targetClass, String mixinTarget) { - for (Mixin mixin : MixinFinder.getMixinsFor(targetClass)) { - if (mixinTarget.equals(mixin.getName())) { - return mixin; - } - } - - throw new IllegalArgumentException("Can't find Mixin class " + mixinTarget + " targetting " + targetClass); - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - ClassNode thisMixin = Mixin.create(mixinInfo).getClassNode(); - - AnnotationNode interception = Annotations.getInvisible(thisMixin, InterceptingMixin.class); - if (interception == null) return; //Nothing to do for this particular Mixin - - Mixin interceptionMixin = findMixin(targetClassName, Annotations.getValue(interception)); - Map shims = thisMixin.methods.stream().filter(method -> Annotations.getInvisible(method, Shim.class) != null).collect(Collectors.toMap(method -> method.name.concat(method.desc), method -> { - Method realMethod = interceptionMixin.getMethod(method.name, method.desc); - - if (realMethod == null) { - throw new IllegalStateException("Cannot find shim method " + method.name + method.desc + " in " + interceptionMixin); - } - - assert method.name.equals(realMethod.getOriginalName()); - return realMethod.getName(); - })); - if (shims.isEmpty()) return; //Nothing to do - - targetClassName = targetClassName.replace('.', '/'); - for (Iterator it = targetClass.methods.iterator(); it.hasNext();) { - MethodNode method = it.next(); - - if (shims.containsKey(method.name.concat(method.desc)) || Annotations.getInvisible(method, PlacatingSurrogate.class) != null) { - it.remove(); //Don't want to keep the shim methods - } else { - for (AbstractInsnNode insn : method.instructions) { - if (insn.getType() == AbstractInsnNode.METHOD_INSN) { - MethodInsnNode methodInsn = (MethodInsnNode) insn; - - String replacedName = shims.get(methodInsn.name.concat(methodInsn.desc)); - if (replacedName != null && targetClassName.equals(methodInsn.owner)) { - methodInsn.name = replacedName; - } - } - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/compat/PlacatingSurrogate.java b/src/main/java/me/modmuss50/optifabric/compat/PlacatingSurrogate.java deleted file mode 100644 index 203afb1..0000000 --- a/src/main/java/me/modmuss50/optifabric/compat/PlacatingSurrogate.java +++ /dev/null @@ -1,12 +0,0 @@ -package me.modmuss50.optifabric.compat; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.CLASS; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Retention(CLASS) -@Target(METHOD) -public @interface PlacatingSurrogate { -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/compat/Shim.java b/src/main/java/me/modmuss50/optifabric/compat/Shim.java deleted file mode 100644 index e1c7dc1..0000000 --- a/src/main/java/me/modmuss50/optifabric/compat/Shim.java +++ /dev/null @@ -1,12 +0,0 @@ -package me.modmuss50.optifabric.compat; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.CLASS; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Retention(CLASS) -@Target(METHOD) -public @interface Shim { -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/compat/fabricitemapi/mixin/MobEntityMixin.java b/src/main/java/me/modmuss50/optifabric/compat/fabricitemapi/mixin/MobEntityMixin.java deleted file mode 100644 index cca3111..0000000 --- a/src/main/java/me/modmuss50/optifabric/compat/fabricitemapi/mixin/MobEntityMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.modmuss50.optifabric.compat.fabricitemapi.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.item.ItemStack; - -import me.modmuss50.optifabric.compat.InterceptingMixin; -import me.modmuss50.optifabric.compat.PlacatingSurrogate; - -@Mixin(MobEntity.class) -@InterceptingMixin("net/fabricmc/fabric/mixin/item/MobEntityMixin") -abstract class MobEntityMixin { - @PlacatingSurrogate - private void onGetPreferredEquipmentSlot(ItemStack stack, CallbackInfoReturnable info) { - throw new AssertionError("Unexpectedly reached code path"); - } -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/mixin/MixinDefaultResourcePack.java b/src/main/java/me/modmuss50/optifabric/mixin/MixinDefaultResourcePack.java deleted file mode 100644 index 4ef154e..0000000 --- a/src/main/java/me/modmuss50/optifabric/mixin/MixinDefaultResourcePack.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.modmuss50.optifabric.mixin; - -import java.io.IOException; -import java.io.InputStream; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.resource.DefaultResourcePack; -import net.minecraft.resource.ResourceType; -import net.minecraft.util.Identifier; - -import me.modmuss50.optifabric.mod.OptifineResources; - -@Mixin(value = DefaultResourcePack.class, priority = 400) -abstract class MixinDefaultResourcePack { - - private static String getPath(ResourceType type, Identifier id) { - return "/assets/" + id.getNamespace() + "/" + id.getPath(); - } - - @Inject(method = "findInputStream", at = @At("HEAD"), cancellable = true) - protected void onFindInputStream(ResourceType type, Identifier id, CallbackInfoReturnable callback) { - String path = getPath(type, id); - - try { - InputStream stream = OptifineResources.INSTANCE.getResource(path); - if (stream != null) callback.setReturnValue(stream); - } catch (IOException e) { - //Optifine does this if it goes wrong so we will too - e.printStackTrace(); - } - } - - @Inject(method = "contains", at = @At("HEAD"), cancellable = true) - public void doesContain(ResourceType type, Identifier id, CallbackInfoReturnable callback) { - String path = getPath(type, id); - - if (OptifineResources.INSTANCE.hasResource(path)) callback.setReturnValue(true); - } -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/mixin/MixinTitleScreen.java b/src/main/java/me/modmuss50/optifabric/mixin/MixinTitleScreen.java index d7e0b83..40cb64c 100644 --- a/src/main/java/me/modmuss50/optifabric/mixin/MixinTitleScreen.java +++ b/src/main/java/me/modmuss50/optifabric/mixin/MixinTitleScreen.java @@ -7,7 +7,7 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.text.Text; -import net.minecraft.util.Util; +import net.minecraft.util.SystemUtil; import net.minecraft.util.math.MathHelper; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -38,7 +38,7 @@ private void init(CallbackInfo info) { @Inject(method = "render", at = @At("RETURN")) private void render(int int_1, int int_2, float float_1, CallbackInfo info) { if (!OptifabricError.hasError()) { - float fadeTime = this.doBackgroundFade ? (float) (Util.getMeasuringTimeMs() - this.backgroundFadeStart) / 1000.0F : 1.0F; + float fadeTime = this.doBackgroundFade ? (float) (SystemUtil.getMeasuringTimeMs() - this.backgroundFadeStart) / 1000.0F : 1.0F; float fadeColor = this.doBackgroundFade ? MathHelper.clamp(fadeTime - 1.0F, 0.0F, 1.0F) : 1.0F; int int_6 = MathHelper.ceil(fadeColor * 255.0F) << 24; diff --git a/src/main/java/me/modmuss50/optifabric/mod/Optifabric.java b/src/main/java/me/modmuss50/optifabric/mod/Optifabric.java index 7789940..c37bc01 100644 --- a/src/main/java/me/modmuss50/optifabric/mod/Optifabric.java +++ b/src/main/java/me/modmuss50/optifabric/mod/Optifabric.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.screen.ConfirmScreen; import net.minecraft.text.LiteralText; import net.minecraft.util.Formatting; -import net.minecraft.util.Util; +import net.minecraft.util.SystemUtil; public class Optifabric implements ModInitializer { @@ -13,7 +13,7 @@ public static void checkForErrors() { if (OptifabricError.hasError()) { ConfirmScreen confirmScreen = new ConfirmScreen(t -> { if (t) { - Util.getOperatingSystem().open(OptifabricError.getErrorURL()); + SystemUtil.getOperatingSystem().open(OptifabricError.getErrorURL()); } else { MinecraftClient.getInstance().scheduleStop(); } diff --git a/src/main/java/me/modmuss50/optifabric/mod/OptifabricSetup.java b/src/main/java/me/modmuss50/optifabric/mod/OptifabricSetup.java index a0b9ac4..443e265 100644 --- a/src/main/java/me/modmuss50/optifabric/mod/OptifabricSetup.java +++ b/src/main/java/me/modmuss50/optifabric/mod/OptifabricSetup.java @@ -4,11 +4,10 @@ import me.modmuss50.optifabric.patcher.ClassCache; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; -import net.fabricmc.loader.api.VersionParsingException; import net.fabricmc.loader.api.metadata.ModMetadata; import net.fabricmc.loader.util.version.SemanticVersionImpl; import net.fabricmc.loader.util.version.SemanticVersionPredicateParser; - +import net.fabricmc.loader.util.version.VersionParsingException; import org.apache.commons.lang3.tuple.Pair; import org.spongepowered.asm.mixin.Mixins; @@ -18,7 +17,6 @@ @SuppressWarnings("unused") public class OptifabricSetup implements Runnable { - public static File optifineRuntimeJar = null; //This is called early on to allow us to get the transformers in beofore minecraft starts @Override @@ -34,8 +32,6 @@ public void run() { OptifineInjector injector = new OptifineInjector(runtime.getRight()); injector.setup(); - - optifineRuntimeJar = runtime.getLeft(); } catch (Throwable e) { if(!OptifabricError.hasError()){ OptifineVersion.jarType = OptifineVersion.JarType.INCOMPATIBE; @@ -49,15 +45,6 @@ public void run() { Mixins.addConfiguration("optifabric.indigofix.mixins.json"); } - try { - if (FabricLoader.getInstance().isModLoaded("fabric-item-api-v1") && isVersionValid("fabric-item-api-v1", ">=1.1.0")) { - Mixins.addConfiguration("optifabric.compat.fabric-item-api.mixins.json"); - } - } catch (VersionParsingException e) { - //Let's just gamble on the version not being valid so also not being a problem - e.printStackTrace(); - } - Mixins.addConfiguration("optifabric.optifine.mixins.json"); } diff --git a/src/main/java/me/modmuss50/optifabric/mod/OptifineInjector.java b/src/main/java/me/modmuss50/optifabric/mod/OptifineInjector.java index ad469ba..4ffb54e 100644 --- a/src/main/java/me/modmuss50/optifabric/mod/OptifineInjector.java +++ b/src/main/java/me/modmuss50/optifabric/mod/OptifineInjector.java @@ -1,7 +1,7 @@ package me.modmuss50.optifabric.mod; import com.chocohead.mm.api.ClassTinkerers; -import me.modmuss50.optifabric.util.ASMUtils; +import me.modmuss50.optifabric.patcher.ASMUtils; import me.modmuss50.optifabric.patcher.ChunkRendererFix; import me.modmuss50.optifabric.patcher.ClassCache; import net.fabricmc.loader.api.FabricLoader; @@ -38,7 +38,7 @@ public void setup() throws IOException { chunkRenderer = FabricLoader.getInstance().getMappingResolver().mapClassName("intermediary", "net.minecraft.class_851").replaceAll("\\.", "/"); particleManager = FabricLoader.getInstance().getMappingResolver().mapClassName("intermediary", "net.minecraft.class_702").replaceAll("\\.", "/"); - classCache.getClasses().forEach(s -> ClassTinkerers.addReplacement(s.replaceAll("/", ".").substring(0, s.length() - 6), transformer)); + classCache.getClasses().forEach(s -> ClassTinkerers.addTransformation(s.replaceAll("/", ".").substring(0, s.length() - 6), transformer)); } //I have no idea why and how this works, if you know better please let me know diff --git a/src/main/java/me/modmuss50/optifabric/mod/OptifineResources.java b/src/main/java/me/modmuss50/optifabric/mod/OptifineResources.java deleted file mode 100644 index fb13878..0000000 --- a/src/main/java/me/modmuss50/optifabric/mod/OptifineResources.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.modmuss50.optifabric.mod; - -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -import org.apache.commons.lang3.StringUtils; - -public enum OptifineResources { - INSTANCE; - - private OptifineResources() { - try { - zip = new ZipFile(OptifabricSetup.optifineRuntimeJar); - } catch (ZipException e) { - //Would've thought the classloader would have caught this sooner but whatever - throw new RuntimeException("Error opening Optifine jar, probably corrupt?", e); - } catch (IOException e) { - throw new UncheckedIOException("Error opening Optifine jar", e); - } - } - - private ZipEntry getEntry(String path) { - return StringUtils.isNotBlank(path) ? zip.getEntry(path.charAt(0) == '/' ? path.substring(1) : path) : null; - } - - public boolean hasResource(String path) { - return getEntry(path) != null; - } - - public InputStream getResource(String path) throws IOException { - ZipEntry entry = getEntry(path); - return entry != null ? zip.getInputStream(entry) : null; - } - - private final ZipFile zip; -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/mod/OptifineSetup.java b/src/main/java/me/modmuss50/optifabric/mod/OptifineSetup.java index 5eabf1c..2f4a061 100644 --- a/src/main/java/me/modmuss50/optifabric/mod/OptifineSetup.java +++ b/src/main/java/me/modmuss50/optifabric/mod/OptifineSetup.java @@ -3,36 +3,49 @@ import me.modmuss50.optifabric.patcher.ClassCache; import me.modmuss50.optifabric.patcher.LambadaRebuiler; import me.modmuss50.optifabric.patcher.PatchSplitter; -import me.modmuss50.optifabric.util.RemapUtils; -import me.modmuss50.optifabric.util.ZipUtils; +import me.modmuss50.optifabric.patcher.RemapUtils; import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.ModContainer; +import net.fabricmc.loader.launch.common.FabricLauncher; import net.fabricmc.loader.launch.common.FabricLauncherBase; +import net.fabricmc.loader.launch.common.MappingConfiguration; +import net.fabricmc.loader.launch.knot.Knot; +import net.fabricmc.loader.util.UrlConversionException; +import net.fabricmc.loader.util.UrlUtil; +import net.fabricmc.loader.util.mappings.TinyRemapperMappingsHelper; +import net.fabricmc.mapping.reader.v2.TinyMetadata; import net.fabricmc.mapping.tree.ClassDef; -import net.fabricmc.mapping.tree.FieldDef; -import net.fabricmc.mapping.tree.MethodDef; import net.fabricmc.mapping.tree.TinyTree; import net.fabricmc.tinyremapper.IMappingProvider; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.tuple.Pair; +import org.zeroturnaround.zip.ZipUtil; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; public class OptifineSetup { - private File workingDir = new File(String.valueOf(FabricLoader.getInstance().getGameDir()), ".optifine"); + + private File workingDir = new File(FabricLoader.getInstance().getGameDirectory(), ".optifine"); private File versionDir; + private MappingConfiguration mappingConfiguration = new MappingConfiguration(); + + private FabricLauncher fabricLauncher = FabricLauncherBase.getLauncher(); + public Pair getRuntime() throws Throwable { if (!workingDir.exists()) { @@ -78,24 +91,34 @@ public Pair getRuntime() throws Throwable { //A jar without srgs File jarOfTheFree = new File(versionDir, "/Optifine-jarofthefree.jar"); + List srgs = new ArrayList<>(); System.out.println("De-Volderfiying jar"); //Find all the SRG named classes and remove them - ZipUtils.transform(optifineModJar, (zip, zipEntry) -> { + ZipUtil.iterate(optifineModJar, (in, zipEntry) -> { String name = zipEntry.getName(); if(name.startsWith("com/mojang/blaze3d/platform/")){ if(name.contains("$")){ String[] split = name.replace(".class", "").split("\\$"); if(split.length >= 2){ if(split[1].length() > 2){ - return false; + srgs.add(name); } } } } - return !(name.startsWith("srg/") || name.startsWith("net/minecraft/")); - }, jarOfTheFree); + + if(name.startsWith("srg/") || name.startsWith("net/minecraft/")){ + srgs.add(name); + } + }); + + if(jarOfTheFree.exists()){ + jarOfTheFree.delete(); + } + + ZipUtil.removeEntries(optifineModJar, srgs.toArray(new String[0]), jarOfTheFree); System.out.println("Building lambada fix mappings"); LambadaRebuiler rebuiler = new LambadaRebuiler(jarOfTheFree, getMinecraftJar().toFile()); @@ -131,7 +154,7 @@ public Pair getRuntime() throws Throwable { if(optifineClasses.exists()){ FileUtils.deleteDirectory(optifineClasses); } - ZipUtils.extract(remappedJar, optifineClasses); + ZipUtil.unpack(remappedJar, optifineClasses); } return Pair.of(remappedJar, classCache); @@ -149,10 +172,8 @@ private void remapOptifine(Path input, File remappedJar) throws Exception { //Optifine currently has two fields that match the same name as Yarn mappings, we'll rename Optifine's to something else IMappingProvider createMappings(String from, String to) { - TinyTree normalMappings = FabricLauncherBase.getLauncher().getMappingConfiguration().getMappings(); - //In dev - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { + if (fabricLauncher.isDevelopment()) { try { File fullMappings = extractMappings(); return (out) -> { @@ -168,114 +189,89 @@ IMappingProvider createMappings(String from, String to) { } //In prod - return (out) -> { - for (ClassDef classDef : normalMappings.getClasses()) { - String className = classDef.getName(from); - out.acceptClass(className, classDef.getName(to)); + TinyTree mappingsNew = new TinyTree() { + private final TinyTree mappings = mappingConfiguration.getMappings(); - for (FieldDef field : classDef.getFields()) { - out.acceptField(new IMappingProvider.Member(className, field.getName(from), field.getDescriptor(from)), field.getName(to)); - } + @Override + public TinyMetadata getMetadata() { + return mappings.getMetadata(); + } - for (MethodDef method : classDef.getMethods()) { - out.acceptMethod(new IMappingProvider.Member(className, method.getName(from), method.getDescriptor(from)), method.getName(to)); - } + @Override + public Map getDefaultNamespaceClassMap() { + return mappings.getDefaultNamespaceClassMap(); + } + + @Override + public Collection getClasses() { + return mappings.getClasses(); } }; + return TinyRemapperMappingsHelper.create(mappingsNew, from, to); } //Gets the minecraft librarys - private static List getLibs() { - Path[] libs = FabricLauncherBase.getLauncher().getLoadTimeDependencies().stream().map(url -> { + List getLibs() { + return fabricLauncher.getLoadTimeDependencies().stream().map(url -> { try { - return Paths.get(url.toURI()); - } catch (URISyntaxException e) { - throw new RuntimeException("Failed to convert " + url + " to path", e); - } - }).filter(Files::exists).toArray(Path[]::new); - - out: if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - Path launchJar = getLaunchMinecraftJar(); - - for (int i = 0, end = libs.length; i < end; i++) { - Path lib = libs[i]; - - if (launchJar.equals(lib)) { - libs[i] = getMinecraftJar(); - break out; - } + return UrlUtil.asPath(url); + } catch (UrlConversionException e) { + throw new RuntimeException(e); } - - //Can't find the launch jar apparently, remapping will go wrong if it is left in - throw new IllegalStateException("Unable to find Minecraft jar (at " + launchJar + ") in classpath: " + Arrays.toString(libs)); - } - - return new ArrayList<>(Arrays.asList(libs)); + }).filter(Files::exists).collect(Collectors.toList()); } //Gets the offical minecraft jar - private static Path getMinecraftJar() { - String givenJar = System.getProperty("optifabric.mc-jar"); - if (givenJar != null) { - File givenJarFile = new File(givenJar); - - if (givenJarFile.exists()) { - return givenJarFile.toPath(); - } else { - System.err.println("Supplied Minecraft jar at " + givenJar + " doesn't exist, falling back"); + Path getMinecraftJar() throws FileNotFoundException { + Optional entrypointResult = findFirstClass(Knot.class.getClassLoader(), Collections.singletonList("net.minecraft.client.main.Main")); + if (!entrypointResult.isPresent()) { + throw new RuntimeException("Failed to find minecraft jar"); + } + if (!Files.exists(entrypointResult.get())) { + throw new RuntimeException("Failed to locate minecraft jar"); + } + if (fabricLauncher.isDevelopment()) { + Path path = entrypointResult.get().getParent(); + Path minecraftJar = path.resolve(String.format("minecraft-%s-client.jar", OptifineVersion.minecraftVersion)); //Lets hope you are using loom in dev + if (!Files.exists(minecraftJar)) { + throw new FileNotFoundException("Could not find minecraft jar!"); } + return minecraftJar; } + return entrypointResult.get(); + } - Path minecraftJar = getLaunchMinecraftJar(); - - if (FabricLoader.getInstance().isDevelopmentEnvironment()) { - Path officialNames = minecraftJar.resolveSibling(String.format("minecraft-%s-client.jar", OptifineVersion.minecraftVersion)); - - if (Files.notExists(officialNames)) { - Path parent = minecraftJar.getParent().resolveSibling(String.format("minecraft-%s-client.jar", OptifineVersion.minecraftVersion)); - - if (Files.notExists(parent)) { - Path alternativeParent = parent.resolveSibling("minecraft-client.jar"); - - if (Files.notExists(alternativeParent)) { - throw new AssertionError("Unable to find Minecraft dev jar! Tried " + officialNames + ", " + parent + " and " + alternativeParent - + "\nPlease supply it explicitly with -Doptifabric.mc-jar"); - } - - parent = alternativeParent; - } + //Stolen from fabric loader + static Optional findFirstClass(ClassLoader loader, List classNames) { + List entrypointFilenames = classNames.stream().map((ep) -> ep.replace('.', '/') + ".class").collect(Collectors.toList()); - officialNames = parent; + for (int i = 0; i < entrypointFilenames.size(); i++) { + String className = classNames.get(i); + String classFilename = entrypointFilenames.get(i); + Optional classSourcePath = getSource(loader, classFilename); + if (classSourcePath.isPresent()) { + return Optional.of(classSourcePath.get()); } - - minecraftJar = officialNames; } - return minecraftJar; + return Optional.empty(); } - private static Path getLaunchMinecraftJar() { - try { - return (Path) FabricLoader.getInstance().getObjectShare().get("fabric-loader:inputGameJar"); - } catch (NoClassDefFoundError | NoSuchMethodError old) { - ModContainer mod = FabricLoader.getInstance().getModContainer("minecraft").orElseThrow(() -> new IllegalStateException("No Minecraft?")); - URI uri = mod.getRootPath().toUri(); - assert "jar".equals(uri.getScheme()); - - String path = uri.getSchemeSpecificPart(); - int split = path.lastIndexOf("!/"); - - if (path.substring(0, split).indexOf(' ') > 0 && path.startsWith("file:///")) {//This is meant to be a URI... - Path out = Paths.get(path.substring(8, split)); - if (Files.exists(out)) return out; - } - + static Optional getSource(ClassLoader loader, String filename) { + URL url; + if ((url = loader.getResource(filename)) != null) { try { - return Paths.get(new URI(path.substring(0, split))); - } catch (URISyntaxException e) { - throw new RuntimeException("Failed to find Minecraft jar from " + uri + " (calculated " + path.substring(0, split) + ')', e); + URL urlSource = UrlUtil.getSource(filename, url); + Path classSourceFile = UrlUtil.asPath(urlSource); + + return Optional.of(classSourceFile); + } catch (UrlConversionException e) { + // TODO: Point to a logger + e.printStackTrace(); } } + + return Optional.empty(); } //Extracts the devtime mappings out of yarn into a file diff --git a/src/main/java/me/modmuss50/optifabric/mod/OptifineVersion.java b/src/main/java/me/modmuss50/optifabric/mod/OptifineVersion.java index d2a74b1..0902100 100644 --- a/src/main/java/me/modmuss50/optifabric/mod/OptifineVersion.java +++ b/src/main/java/me/modmuss50/optifabric/mod/OptifineVersion.java @@ -2,11 +2,12 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import me.modmuss50.optifabric.util.ASMUtils; -import me.modmuss50.optifabric.util.ZipUtils; +import me.modmuss50.optifabric.patcher.ASMUtils; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.main.Main; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; +import org.zeroturnaround.zip.ZipUtil; import java.io.*; import java.util.jar.JarEntry; @@ -98,12 +99,9 @@ private static JarType getJarType(File file) throws IOException { } Holder isInstaller = new Holder<>(false); - ZipUtils.iterateContents(file, (zip, zipEntry) -> { + ZipUtil.iterate(file, (in, zipEntry) -> { if (zipEntry.getName().startsWith("patch/")) { isInstaller.setValue(true); - return false; - } else { - return true; } }); diff --git a/src/main/java/me/modmuss50/optifabric/util/ASMUtils.java b/src/main/java/me/modmuss50/optifabric/patcher/ASMUtils.java similarity index 96% rename from src/main/java/me/modmuss50/optifabric/util/ASMUtils.java rename to src/main/java/me/modmuss50/optifabric/patcher/ASMUtils.java index 6236a99..d0e4cfd 100644 --- a/src/main/java/me/modmuss50/optifabric/util/ASMUtils.java +++ b/src/main/java/me/modmuss50/optifabric/patcher/ASMUtils.java @@ -1,4 +1,4 @@ -package me.modmuss50.optifabric.util; +package me.modmuss50.optifabric.patcher; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.Validate; diff --git a/src/main/java/me/modmuss50/optifabric/patcher/LambadaRebuiler.java b/src/main/java/me/modmuss50/optifabric/patcher/LambadaRebuiler.java index cdb19c4..686dfb1 100644 --- a/src/main/java/me/modmuss50/optifabric/patcher/LambadaRebuiler.java +++ b/src/main/java/me/modmuss50/optifabric/patcher/LambadaRebuiler.java @@ -1,6 +1,5 @@ package me.modmuss50.optifabric.patcher; -import me.modmuss50.optifabric.util.ASMUtils; import net.fabricmc.tinyremapper.IMappingProvider; import net.fabricmc.tinyremapper.MemberInstance; import org.objectweb.asm.tree.ClassNode; diff --git a/src/main/java/me/modmuss50/optifabric/patcher/PatchSplitter.java b/src/main/java/me/modmuss50/optifabric/patcher/PatchSplitter.java index d308e3b..fec1aff 100644 --- a/src/main/java/me/modmuss50/optifabric/patcher/PatchSplitter.java +++ b/src/main/java/me/modmuss50/optifabric/patcher/PatchSplitter.java @@ -2,12 +2,14 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; - -import me.modmuss50.optifabric.util.ZipUtils; +import org.zeroturnaround.zip.ZipUtil; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; //Pulls out the patched classes and saves into a classCache, and also creates an optifine jar without these classes public class PatchSplitter { @@ -19,28 +21,31 @@ public static ClassCache generateClassCache(File inputFile, File classCacheOutpu classesDir.mkdir(); } ClassCache classCache = new ClassCache(inputHash); - ZipUtils.transformInPlace(inputFile, (jarFile, entry) -> { - if ((entry.getName().startsWith("net/minecraft/") || entry.getName().startsWith("com/mojang/")) && entry.getName().endsWith(".class")) { - try(InputStream inputStream = jarFile.getInputStream(entry)){ - String name = entry.getName(); - byte[] bytes = IOUtils.toByteArray(inputStream); - classCache.addClass(name, bytes); - if(extractClasses){ - File classFile = new File(classesDir, entry.getName()); - FileUtils.writeByteArrayToFile(classFile, bytes); + try (JarFile jarFile = new JarFile(inputFile)) { + Enumeration entrys = jarFile.entries(); + while (entrys.hasMoreElements()) { + JarEntry entry = entrys.nextElement(); + if ((entry.getName().startsWith("net/minecraft/") || entry.getName().startsWith("com/mojang/")) && entry.getName().endsWith(".class")) { + try(InputStream inputStream = jarFile.getInputStream(entry)){ + String name = entry.getName(); + byte[] bytes = IOUtils.toByteArray(inputStream); + classCache.addClass(name, bytes); + if(extractClasses){ + File classFile = new File(classesDir, entry.getName()); + FileUtils.writeByteArrayToFile(classFile, bytes); + } } } - - //Remove all the classes that are going to be patched in, we dont want theses on the classpath - return false; - } else { - return true; } - }); + } + + + //Remove all the classes that are going to be patched in, we dont want theses on the classpath + ZipUtil.removeEntries(inputFile, classCache.getClasses().stream().toArray(String[]::new)); System.out.println("Found " + classCache.getClasses().size() + " patched classes"); classCache.save(classCacheOutput); return classCache; } -} \ No newline at end of file +} diff --git a/src/main/java/me/modmuss50/optifabric/util/RemapUtils.java b/src/main/java/me/modmuss50/optifabric/patcher/RemapUtils.java similarity index 97% rename from src/main/java/me/modmuss50/optifabric/util/RemapUtils.java rename to src/main/java/me/modmuss50/optifabric/patcher/RemapUtils.java index 6831f6d..e710cd1 100644 --- a/src/main/java/me/modmuss50/optifabric/util/RemapUtils.java +++ b/src/main/java/me/modmuss50/optifabric/patcher/RemapUtils.java @@ -1,4 +1,4 @@ -package me.modmuss50.optifabric.util; +package me.modmuss50.optifabric.patcher; import net.fabricmc.tinyremapper.IMappingProvider; import net.fabricmc.tinyremapper.OutputConsumerPath; diff --git a/src/main/java/me/modmuss50/optifabric/util/MixinFinder.java b/src/main/java/me/modmuss50/optifabric/util/MixinFinder.java deleted file mode 100644 index 258ac2b..0000000 --- a/src/main/java/me/modmuss50/optifabric/util/MixinFinder.java +++ /dev/null @@ -1,136 +0,0 @@ -package me.modmuss50.optifabric.util; - -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import com.google.common.collect.Lists; - -import org.apache.commons.lang3.reflect.FieldUtils; -import org.apache.commons.lang3.reflect.MethodUtils; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.tree.ClassNode; - -import org.spongepowered.asm.mixin.MixinEnvironment; -import org.spongepowered.asm.mixin.extensibility.IMixinConfig; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; -import org.spongepowered.asm.mixin.transformer.ClassInfo; - -public class MixinFinder { - public static class MixinInfo { - private final IMixinConfig config; - private final Method getMixins; - - MixinInfo(IMixinConfig config) { - this.config = config; - getMixins = MethodUtils.getMatchingMethod(config.getClass(), "getMixinsFor", String.class); - getMixins.setAccessible(true); - } - - public boolean hasMixinFor(String target) { - return config.getTargets().contains(target); - } - - @SuppressWarnings("unchecked") - public List getMixinsFor(String target) { - if (hasMixinFor(target)) { - try { - return (List) getMixins.invoke(config, target); - } catch (ReflectiveOperationException e) { - throw new RuntimeException("Error getting " + target + " mixins from " + config, e); - } - } else { - return Collections.emptyList(); - } - } - - @Override - public String toString() { - return config.getName(); - } - } - - @SuppressWarnings("unchecked") //It is but so is reflection in general - private static List goFish() throws ReflectiveOperationException { - Object transformer = MixinEnvironment.getCurrentEnvironment().getActiveTransformer(); - if (transformer == null) throw new IllegalStateException("No active transformer?"); - - Object processor = FieldUtils.readDeclaredField(transformer, "processor", true); - assert processor != null; //Shouldn't manage to get it null - - Object configs = FieldUtils.readDeclaredField(processor, "configs", true); - assert configs != null; //Shouldn't manage to be null either - - return (List) configs; - } - - private static final List MIXINS; - static { - try { - MIXINS = Lists.transform(goFish(), MixinInfo::new); - } catch (ReflectiveOperationException e) { - throw new RuntimeException("Error fishing for mixins", e); - } - } - - public static class Mixin implements Comparable { - private final IMixinInfo mixin; - private final ClassInfo info; - private ClassNode node; - - public static Mixin create(IMixinInfo mixin) { - return new Mixin(mixin); - } - - Mixin(IMixinInfo mixin) { - this.mixin = mixin; - try { - info = (ClassInfo) FieldUtils.readDeclaredField(mixin, "info", true); - } catch (ReflectiveOperationException e) { - throw new RuntimeException("Error getting class info from " + mixin, e); - } - } - - public String getName() { - return mixin.getClassRef(); - } - - public ClassNode getClassNode() { - if (node == null) { - node = mixin.getClassNode(ClassReader.SKIP_CODE); - } - - return node; - } - - public Set getMethods() { - return info.getMethods(); - } - - public boolean hasMethod(String name, String descriptor) { - return getMethod(name, descriptor) != null; - } - - public ClassInfo.Method getMethod(String name, String descriptor) { - return info.findMethod(name, descriptor, ClassInfo.INCLUDE_ALL | ClassInfo.INCLUDE_INITIALISERS); - } - - @Override - @SuppressWarnings("unchecked") //The underlying type is comparable even if the interface isn't - public int compareTo(Mixin other) { - return ((Comparable) mixin).compareTo(other.mixin); - } - - @Override - public String toString() { - return getName(); - } - } - - public static List getMixinsFor(String target) { - return MIXINS.stream().filter(info -> info.hasMixinFor(target)).flatMap(info -> info.getMixinsFor(target).stream()).map(Mixin::new).sorted().collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/src/main/java/me/modmuss50/optifabric/util/ZipUtils.java b/src/main/java/me/modmuss50/optifabric/util/ZipUtils.java deleted file mode 100644 index 9e43aab..0000000 --- a/src/main/java/me/modmuss50/optifabric/util/ZipUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -package me.modmuss50.optifabric.util; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; - -public class ZipUtils { - public interface ZipTranformer { - boolean keep(ZipFile zip, ZipEntry entry) throws IOException; - } - - /** - * Visit the contents of the given zip file as per {@link ZipFile#entries()} - * - * @param zip The zip file to visit the contents of - * @param visitor A visitor to receive the contents, returning {@code false} will immediately end visiting - */ - public static void iterateContents(File zip, ZipTranformer visitor) { - try (ZipFile origin = new ZipFile(zip)) { - for (Enumeration it = origin.entries(); it.hasMoreElements();) { - if (!visitor.keep(origin, it.nextElement())) { - break; - } - } - } catch (IOException e) { - throw new UncheckedIOException("Error iterating " + zip, e); - } - } - - /** - * Extract the given zip file into the given root directory - * - * @param zip The zip file to be extracted fully - * @param to The directory to extract the zip into - */ - public static void extract(File zip, File to) { - iterateContents(zip, (zipFile, entry) -> { - String name = entry.getName(); - File extract = new File(to, name); - - if (name.indexOf("..") >= 0 && !extract.getCanonicalPath().startsWith(to.getCanonicalPath())) { - throw new SecurityException("The file \"" + name + "\" (in " + zip + ") tried to leave the output directory: " + to); - } - - if (entry.isDirectory()) { - FileUtils.forceMkdir(extract); - } else { - FileUtils.forceMkdir(extract.getParentFile()); - FileUtils.copyInputStreamToFile(zipFile.getInputStream(entry), extract); - } - - return true; - }); - } - - /** - * Filter the given zip based on the given filter - * - * @param zip The zip file to filter the contents of - * @param filter A filter of the contents, returning {@code false} will remove the given entry - */ - public static void transformInPlace(File zip, ZipTranformer filter) { - File tempZip = null; - try { - tempZip = File.createTempFile("optifabric", ".zip"); - - transform(zip, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE, filter, tempZip); - - FileUtils.moveFile(tempZip, zip); - } catch (IOException e) { - throw new UncheckedIOException("Error modifying " + zip, e); - } finally { - FileUtils.deleteQuietly(tempZip); - } - } - - /** - * Filter the given zip based on the given filter to produce a new zip - * - * @param zipOrigin The zip file to filter the contents of - * @param filter A filter of the contents, returning {@code false} will remove the given entry - * @param zipDestination The location of the filtered zip file - */ - public static void transform(File zipOrigin, ZipTranformer filter, File zipDestination) { - try { - transform(zipOrigin, ZipFile.OPEN_READ, filter, zipDestination); - } catch (IOException e) { - throw new UncheckedIOException("Error transforming " + zipOrigin, e); - } - } - - private static void transform(File zipOrigin, int originFlags, ZipTranformer filter, File zipDestination) throws IOException { - try (ZipFile origin = new ZipFile(zipOrigin, originFlags); ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipDestination)))) { - for (Enumeration it = origin.entries(); it.hasMoreElements();) { - ZipEntry entry = it.nextElement(); - - if (filter.keep(origin, entry)) { - out.putNextEntry(new ZipEntry(entry)); - IOUtils.copy(origin.getInputStream(entry), out); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f2eea1d..e3a51c4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -31,6 +31,6 @@ ] }, "depends": { - "fabricloader": ">=0.12.0" + "fabricloader": ">=0.4.0" } } diff --git a/src/main/resources/optifabric.compat.fabric-item-api.mixins.json b/src/main/resources/optifabric.compat.fabric-item-api.mixins.json deleted file mode 100644 index 0fb44ae..0000000 --- a/src/main/resources/optifabric.compat.fabric-item-api.mixins.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "required": true, - "package": "me.modmuss50.optifabric.compat.fabricitemapi.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - "MobEntityMixin" - ], - "plugin": "me.modmuss50.optifabric.compat.InterceptingMixinPlugin", - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/src/main/resources/optifabric.mixins.json b/src/main/resources/optifabric.mixins.json index cd3fa95..4303508 100644 --- a/src/main/resources/optifabric.mixins.json +++ b/src/main/resources/optifabric.mixins.json @@ -3,8 +3,7 @@ "package": "me.modmuss50.optifabric.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ - "MixinTitleScreen", - "MixinDefaultResourcePack" + "MixinTitleScreen" ], "injectors": { "defaultRequire": 1