.refmap.json.
151 | # example: mixins.foo.json,mixins.bar.json
152 | mixinConfigs = mixins.gasstation_mixinbooter.json,mixins.gasstation_mixingasm.json,mixins.gasstation.json
153 |
154 | #endregion mixins
155 |
156 | # Coremod and access transformers
157 | #region core
158 |
159 | # Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/
160 | # Example value: mymodid_at.cfg
161 | accessTransformersFile =
162 |
163 | # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
164 | # This parameter is for legacy compatibility only
165 | # Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
166 | coreModClass = core.GasStationCore
167 |
168 | #endregion core
169 |
170 | # Dependency deobfuscation settings (advanced)
171 | #region ddeobf
172 |
173 | # These 3 entries specify the location where the SRG mappings should be fetched from. Only set these if you know
174 | # what you're doing. The defaults inside the buildscript should just work without any extra configuration.
175 | remoteMappings =
176 | mappingsChannel =
177 | mappingsVersion =
178 |
179 | #endregion ddeobf
180 |
181 | # Miscellaneous settings
182 | #region misc
183 |
184 | # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
185 | # that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
186 | containsMixinsAndOrCoreModOnly = false
187 |
188 | # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
189 | # responsibility check the licence and request permission for distribution, if required.
190 | usesShadowedDependencies = true
191 |
192 | # If enabled, class stubbing will be enabled. In this mode, all classes with a package named "stubpackage" in their
193 | # path will be removed, and all classes that refer to said classes will be modified so that the "stubpackage" will map
194 | # to the root package instead. This is useful for referring to compile-time inaccessible classes, such as classes in the
195 | # default package
196 | remapStubs = false
197 |
198 | # Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
199 | # projects. New projects should not use this parameter.
200 | customArchiveBaseName = 00gasstation
201 |
202 | #endregion misc
203 |
204 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FalsePattern/GasStation/38bf2d78c394b78d4391fddb26bc09b5307013be/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/repositories.gradle:
--------------------------------------------------------------------------------
1 | // Add any additional repositories for your dependencies here
2 |
3 | repositories {
4 | maven {
5 | name = "mavenpattern"
6 | url = "https://mvn.falsepattern.com/releases"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/GasStation.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation;
2 |
3 | import cpw.mods.fml.common.Mod;
4 |
5 | @Mod(modid = Tags.MODID,
6 | version = Tags.VERSION,
7 | name = Tags.MODNAME,
8 | acceptableRemoteVersions = "*")
9 | public class GasStation {
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/IEarlyMixinLoader.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Early mixins are defined as mixins that affects vanilla or forge classes.
7 | * Or technically, classes that can be queried via the current state of {@link net.minecraft.launchwrapper.LaunchClassLoader}
8 | *
9 | * If you want to add mixins that affect mods, use {@link ILateMixinLoader}
10 | *
11 | * Implement this in your {@link cpw.mods.fml.relauncher.IFMLLoadingPlugin}.
12 | * Return all early mixin configs you want MixinBooter to queue and send to Mixin library.
13 | */
14 | public interface IEarlyMixinLoader {
15 |
16 | /**
17 | * @return mixin configurations to be queued and sent to Mixin library.
18 | */
19 | List getMixinConfigs();
20 |
21 | /**
22 | * Runs when a mixin config is successfully queued and sent to Mixin library.
23 | *
24 | * @param mixinConfig mixin config name, queried via {@link IEarlyMixinLoader#getMixinConfigs()}.
25 | * @return true if the mixinConfig should be queued, false if it should not.
26 | */
27 | default boolean shouldMixinConfigQueue(String mixinConfig) {
28 | return true;
29 | }
30 |
31 | /**
32 | * Runs when a mixin config is successfully queued and sent to Mixin library.
33 | *
34 | * @param mixinConfig mixin config name, queried via {@link IEarlyMixinLoader#getMixinConfigs()}.
35 | */
36 | default void onMixinConfigQueued(String mixinConfig) {
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/ILateMixinLoader.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Late mixins are defined as mixins that affects mod classes.
7 | * Or technically, classes that can be queried via the current state of
8 | * {@link net.minecraft.launchwrapper.LaunchClassLoader}
9 | *
10 | * Majority if not all vanilla and forge classes would have been loaded here.
11 | * If you want to add mixins that affect vanilla or forge, use and consult {@link IEarlyMixinLoader}
12 | *
13 | * Implement this in any arbitrary class. Said class will be constructed when mixins are ready to be queued.
14 | * Return all late mixin configs you want MixinBooter to queue and send to Mixin library.
15 | */
16 | public interface ILateMixinLoader {
17 |
18 | /**
19 | * @return mixin configurations to be queued and sent to Mixin library.
20 | */
21 | List getMixinConfigs();
22 |
23 | /**
24 | * Runs when a mixin config is successfully queued and sent to Mixin library.
25 | *
26 | * @param mixinConfig mixin config name, queried via {@link ILateMixinLoader#getMixinConfigs()}.
27 | * @return true if the mixinConfig should be queued, false if it should not.
28 | */
29 | default boolean shouldMixinConfigQueue(String mixinConfig) {
30 | return true;
31 | }
32 |
33 | /**
34 | * Runs when a mixin config is successfully queued and sent to Mixin library.
35 | *
36 | * @param mixinConfig mixin config name, queried via {@link ILateMixinLoader#getMixinConfigs()}.
37 | */
38 | default void onMixinConfigQueued(String mixinConfig) {
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/MinecraftURLClassPath.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 TimeConqueror
3 | *
4 | * 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:
5 | *
6 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 | *
8 | * 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.
9 | */
10 | package com.falsepattern.gasstation;
11 |
12 | import com.google.common.io.Files;
13 | import sun.misc.URLClassPath;
14 |
15 | import net.minecraft.launchwrapper.Launch;
16 | import net.minecraft.launchwrapper.LaunchClassLoader;
17 |
18 | import java.io.File;
19 | import java.io.IOException;
20 | import java.lang.reflect.Field;
21 | import java.net.URL;
22 | import java.nio.file.Path;
23 |
24 | public class MinecraftURLClassPath {
25 | /**
26 | * Utility to manipulate the minecraft URL ClassPath
27 | */
28 | private static final Path MOD_DIRECTORY_PATH = new File(Launch.minecraftHome, "mods/").toPath();
29 | private static final URLClassPath ucp;
30 |
31 | static {
32 | try {
33 | Field ucpField = LaunchClassLoader.class.getSuperclass().getDeclaredField("ucp");
34 | ucpField.setAccessible(true);
35 |
36 | ucp = (URLClassPath)ucpField.get(Launch.classLoader);
37 | } catch (NoSuchFieldException | IllegalAccessException e) {
38 | throw new RuntimeException(e.getMessage());
39 | }
40 | }
41 |
42 | /**
43 | * Get a jar within the minecraft mods directory
44 | */
45 | @SuppressWarnings("All")
46 | public static File getJarInModPath(final String jarname) {
47 | try {
48 | return java.nio.file.Files.walk(MOD_DIRECTORY_PATH)
49 | .filter( p -> {
50 | final String filename = p.toString();
51 | final String extension = Files.getFileExtension(filename);
52 |
53 | return Files.getNameWithoutExtension(filename).contains(jarname) && ("jar".equals(extension) || "litemod".equals(extension));
54 | })
55 | .map(Path::toFile)
56 | .findFirst()
57 | .orElse(null);
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | return null;
61 | }
62 | }
63 |
64 | /**
65 | * Returns true if the given mod is found within the class path; generally useful for identifying if a mod has been loaded
66 | * while running in dev due to a compile dependency
67 | */
68 | @SuppressWarnings("All")
69 | public static boolean findJarInClassPath(final String jarname) {
70 | for(URL url : ucp.getURLs()) {
71 | final String filename = url.getFile();
72 | final String extension = Files.getFileExtension(filename);
73 |
74 | if(Files.getNameWithoutExtension(filename).contains(jarname) && ("jar".equals(extension) || "litemod".equals(extension))) {
75 | return true;
76 | }
77 | }
78 | return false;
79 | }
80 |
81 | /**
82 | * Adds a Jar to the Minecraft URL ClassPath
83 | * - Needed when using mixins on classes outside of Minecraft or other coremods
84 | */
85 | public static void addJar(File pathToJar) throws Exception {
86 | ucp.addURL(pathToJar.toURI().toURL());
87 | }
88 |
89 | private MinecraftURLClassPath() {
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/Tags.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation;
2 |
3 | // Use this class for Strings only. Do not import any classes here. It will lead to issues with Mixins if in use!
4 |
5 | public class Tags {
6 |
7 | // GRADLETOKEN_* will be replaced by your configuration values at build time
8 | public static final String MODID = "GRADLETOKEN_MODID";
9 | public static final String MODNAME = "GRADLETOKEN_MODNAME";
10 | public static final String VERSION = "GRADLETOKEN_VERSION";
11 | public static final String GROUPNAME = "GRADLETOKEN_GROUPNAME";
12 | }
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/core/GasStationCore.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.core;
2 |
3 | import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
4 | import net.minecraft.launchwrapper.Launch;
5 |
6 | import com.falsepattern.gasstation.Tags;
7 | import com.llamalad7.mixinextras.MixinExtrasBootstrap;
8 | import com.falsepattern.gasstation.IEarlyMixinLoader;
9 | import org.apache.logging.log4j.LogManager;
10 | import org.apache.logging.log4j.Logger;
11 | import org.spongepowered.asm.launch.MixinBootstrap;
12 | import org.spongepowered.asm.mixin.Mixins;
13 | import sun.misc.URLClassPath;
14 |
15 | import java.lang.reflect.Field;
16 | import java.net.URL;
17 | import java.net.URLClassLoader;
18 | import java.util.Arrays;
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | @IFMLLoadingPlugin.MCVersion("1.7.10")
24 | @IFMLLoadingPlugin.SortingIndex(Integer.MIN_VALUE + 5)
25 | @IFMLLoadingPlugin.Name(GasStationCore.PLUGIN_NAME)
26 | @IFMLLoadingPlugin.TransformerExclusions("com.falsepattern.gasstation.core")
27 | public class GasStationCore implements IFMLLoadingPlugin {
28 | public static final String PLUGIN_NAME = Tags.MODNAME + " Core Plugin";
29 | public static final Logger LOGGER = LogManager.getLogger(PLUGIN_NAME);
30 |
31 | static {
32 | LOGGER.info("Initializing " + Tags.MODNAME + "Core");
33 | fixMixinClasspathOrder();
34 | MixinBootstrap.init();
35 | MixinExtrasBootstrap.init();
36 | }
37 |
38 | private static void fixMixinClasspathOrder() {
39 | // Borrowed from VanillaFix -- Move jar up in the classloader's URLs to make sure that the latest version of Mixin is used
40 | URL url = GasStationCore.class.getProtectionDomain().getCodeSource().getLocation();
41 | givePriorityInClasspath(url, Launch.classLoader);
42 | givePriorityInClasspath(url, (URLClassLoader) ClassLoader.getSystemClassLoader());
43 | }
44 |
45 | private static void givePriorityInClasspath(URL url, URLClassLoader classLoader) {
46 | try {
47 | Field ucpField = URLClassLoader.class.getDeclaredField("ucp");
48 | ucpField.setAccessible(true);
49 |
50 | List urls = new ArrayList<>(Arrays.asList(classLoader.getURLs()));
51 | urls.remove(url);
52 | urls.add(0, url);
53 | URLClassPath ucp = new URLClassPath(urls.toArray(new URL[0]));
54 |
55 | ucpField.set(classLoader, ucp);
56 | } catch (ReflectiveOperationException e) {
57 | throw new AssertionError(e);
58 | }
59 | }
60 |
61 |
62 | @Override
63 | public String[] getASMTransformerClass() {
64 | return new String[0];
65 | }
66 |
67 | @Override
68 | public String getModContainerClass() {
69 | return null;
70 | }
71 |
72 | @Override
73 | public String getSetupClass() {
74 | return null;
75 | }
76 |
77 | @Override
78 | public void injectData(Map data) {
79 | Object coremodList = data.get("coremodList");
80 | if (coremodList instanceof List) {
81 | // noinspection rawtypes
82 | for (Object coremod : (List)coremodList) {
83 | try {
84 | Field field = coremod.getClass().getField("coreModInstance");
85 | field.setAccessible(true);
86 | Object theMod = field.get(coremod);
87 | if (theMod instanceof IEarlyMixinLoader) {
88 | IEarlyMixinLoader loader = (IEarlyMixinLoader)theMod;
89 | for (String mixinConfig : loader.getMixinConfigs()) {
90 | if (loader.shouldMixinConfigQueue(mixinConfig)) {
91 | LOGGER.info("Adding {} mixin configuration.", mixinConfig);
92 | Mixins.addConfiguration(mixinConfig);
93 | loader.onMixinConfigQueued(mixinConfig);
94 | }
95 | }
96 | }
97 | } catch (Exception e) {
98 | LOGGER.error("Unexpected error", e);
99 | }
100 | }
101 | }
102 | }
103 |
104 | @Override
105 | public String getAccessTransformerClass() {
106 | return null;
107 | }
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/mixins/DevMixinPlugin.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.mixins;
2 |
3 | import com.falsepattern.gasstation.core.GasStationCore;
4 | import org.spongepowered.asm.lib.tree.ClassNode;
5 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
6 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
7 |
8 | import net.minecraft.launchwrapper.Launch;
9 |
10 | import java.io.IOException;
11 | import java.util.Arrays;
12 | import java.util.Collections;
13 | import java.util.List;
14 | import java.util.Set;
15 |
16 | public class DevMixinPlugin implements IMixinConfigPlugin {
17 | @Override
18 | public void onLoad(String mixinPackage) {
19 |
20 | }
21 |
22 | @Override
23 | public String getRefMapperConfig() {
24 | return null;
25 | }
26 |
27 | @Override
28 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
29 | return true;
30 | }
31 |
32 | @Override
33 | public void acceptTargets(Set myTargets, Set otherTargets) {
34 |
35 | }
36 |
37 | @Override
38 | public List getMixins() {
39 | boolean isDev = false;
40 | try {
41 | if (Launch.classLoader.getClassBytes("net.minecraft.world.World") != null)
42 | isDev = true;
43 | } catch (IOException ignored) {}
44 | if (isDev) {
45 | GasStationCore.LOGGER.info("Development environment detected! Loading dev hotfixes...");
46 | return Arrays.asList("dev.LoaderMixin", "dev.ModDiscovererMixin");
47 | } else {
48 | GasStationCore.LOGGER.info("Development environment NOT detected! Skipping dev hotfixes...");
49 | return Collections.emptyList();
50 | }
51 | }
52 |
53 | @Override
54 | public void preApply(String s, ClassNode classNode, String s1, IMixinInfo iMixinInfo) {
55 |
56 | }
57 |
58 | @Override
59 | public void postApply(String s, ClassNode classNode, String s1, IMixinInfo iMixinInfo) {
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/mixins/IModDiscovererMixin.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.mixins;
2 |
3 | import cpw.mods.fml.common.discovery.ModCandidate;
4 |
5 | import java.util.List;
6 |
7 | public interface IModDiscovererMixin {
8 | List getCandidates();
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/mixins/mixin/LoadControllerMixin.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.mixins.mixin;
2 |
3 | import cpw.mods.fml.common.*;
4 | import cpw.mods.fml.common.discovery.ASMDataTable;
5 |
6 | import com.falsepattern.gasstation.core.GasStationCore;
7 | import net.minecraft.launchwrapper.Launch;
8 | import org.spongepowered.asm.mixin.Mixin;
9 | import org.spongepowered.asm.mixin.MixinEnvironment;
10 | import org.spongepowered.asm.mixin.Mixins;
11 | import org.spongepowered.asm.mixin.Shadow;
12 | import org.spongepowered.asm.mixin.injection.At;
13 | import org.spongepowered.asm.mixin.injection.Inject;
14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15 | import org.spongepowered.asm.mixin.transformer.Proxy;
16 | import com.falsepattern.gasstation.ILateMixinLoader;
17 |
18 | import java.lang.reflect.Field;
19 | import java.lang.reflect.Method;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | @Mixin(value = LoadController.class, remap = false)
24 | public abstract class LoadControllerMixin {
25 |
26 | @Shadow
27 | private Loader loader;
28 |
29 | @Inject(method = "distributeStateMessage(Lcpw/mods/fml/common/LoaderState;[Ljava/lang/Object;)V",
30 | at = @At("HEAD"))
31 | private void beforeConstructing(LoaderState state, Object[] eventData, CallbackInfo ci) throws Throwable {
32 | // This state is where Forge adds mod files to ModClassLoader
33 | if (state != LoaderState.CONSTRUCTING) {
34 | return;
35 | }
36 |
37 | ModClassLoader modClassLoader = (ModClassLoader)eventData[0];
38 | ASMDataTable asmDataTable = (ASMDataTable)eventData[1];
39 |
40 | GasStationCore.LOGGER.info("Instantiating all ILateMixinLoader implemented classes...");
41 | List asmDatas = new ArrayList<>(asmDataTable.getAll(ILateMixinLoader.class.getName().replace('.', '/')));
42 | asmDatas.addAll(asmDataTable.getAll(io.github.tox1cozz.mixinbooterlegacy.ILateMixinLoader.class.getName().replace('.', '/')));
43 | for (ASMDataTable.ASMData asmData : asmDatas) {
44 | modClassLoader.addFile(asmData.getCandidate().getModContainer()); // Add to path before `newInstance`
45 | Class> clazz = Class.forName(asmData.getClassName().replace('/', '.'));
46 | GasStationCore.LOGGER.info("Instantiating {} for its mixins.", clazz);
47 | ILateMixinLoader loader = (ILateMixinLoader)clazz.newInstance();
48 | for (String mixinConfig : loader.getMixinConfigs()) {
49 | if (loader.shouldMixinConfigQueue(mixinConfig)) {
50 | GasStationCore.LOGGER.info("Adding {} mixin configuration.", mixinConfig);
51 | Mixins.addConfiguration(mixinConfig);
52 | loader.onMixinConfigQueued(mixinConfig);
53 | }
54 | }
55 | }
56 |
57 | for (ModContainer container : loader.getActiveModList()) {
58 | modClassLoader.addFile(container.getSource());
59 | }
60 |
61 | Field transformerField = Proxy.class.getDeclaredField("transformer");
62 | transformerField.setAccessible(true);
63 | @SuppressWarnings("OptionalGetWithoutIsPresent")
64 | Object transformer = transformerField.get(Launch.classLoader.getTransformers().stream().filter(Proxy.class::isInstance).findFirst().get());
65 |
66 | Class> mixinTransformerClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinTransformer");
67 |
68 | Field processorField = mixinTransformerClass.getDeclaredField("processor");
69 | processorField.setAccessible(true);
70 | Object processor = processorField.get(transformer);
71 |
72 | Class> mixinProcessorClass = Class.forName("org.spongepowered.asm.mixin.transformer.MixinProcessor");
73 |
74 | Method selectConfigsMethod = mixinProcessorClass.getDeclaredMethod("selectConfigs", MixinEnvironment.class);
75 | selectConfigsMethod.setAccessible(true);
76 |
77 | MixinEnvironment env = MixinEnvironment.getCurrentEnvironment();
78 | selectConfigsMethod.invoke(processor, env);
79 |
80 | try {
81 | Method prepareConfigsMethod = mixinProcessorClass.getDeclaredMethod("prepareConfigs", MixinEnvironment.class);
82 | prepareConfigsMethod.setAccessible(true);
83 | prepareConfigsMethod.invoke(processor, env);
84 | } catch (NoSuchMethodException e) { // 0.8.3+
85 | Class> extensionsClass = Class.forName("org.spongepowered.asm.mixin.transformer.ext.Extensions");
86 | @SuppressWarnings("JavaReflectionMemberAccess")
87 | Method prepareConfigsMethod = mixinProcessorClass.getDeclaredMethod("prepareConfigs", MixinEnvironment.class, extensionsClass);
88 | prepareConfigsMethod.setAccessible(true);
89 |
90 | Field extensionsField = mixinProcessorClass.getDeclaredField("extensions");
91 | extensionsField.setAccessible(true);
92 | Object extensions = extensionsField.get(processor);
93 |
94 | //noinspection JavaReflectionInvocation
95 | prepareConfigsMethod.invoke(processor, env, extensions);
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/mixins/mixin/dev/LoaderMixin.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.mixins.mixin.dev;
2 |
3 | import com.falsepattern.gasstation.mixins.IModDiscovererMixin;
4 | import org.spongepowered.asm.mixin.Mixin;
5 | import org.spongepowered.asm.mixin.injection.At;
6 | import org.spongepowered.asm.mixin.injection.Redirect;
7 |
8 | import cpw.mods.fml.common.Loader;
9 | import cpw.mods.fml.common.ModContainer;
10 | import cpw.mods.fml.common.discovery.ModCandidate;
11 | import cpw.mods.fml.common.discovery.ModDiscoverer;
12 |
13 | import java.io.File;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | @Mixin(value = Loader.class,
18 | remap = false)
19 | public abstract class LoaderMixin {
20 | @Redirect(method = "identifyMods",
21 | at = @At(value = "INVOKE",
22 | target = "Lcpw/mods/fml/common/discovery/ModDiscoverer;identifyMods()Ljava/util/List;"),
23 | require = 1)
24 | private List removeDuplicateFiles(ModDiscoverer instance) {
25 | List candidates = ((IModDiscovererMixin)instance).getCandidates();
26 | List uniques = new ArrayList<>();
27 | List dupes = new ArrayList<>();
28 | for(ModCandidate candidate: candidates) {
29 | File file = candidate.getModContainer().getAbsoluteFile().toPath().normalize().toFile();
30 | boolean isUnique = true;
31 | for (ModCandidate uniqueCandidate: uniques) {
32 | File uniqueFile = uniqueCandidate.getModContainer().getAbsoluteFile().toPath().normalize().toFile();
33 | if (file.equals(uniqueFile)) {
34 | isUnique = false;
35 | break;
36 | }
37 | }
38 | if (isUnique) {
39 | uniques.add(candidate);
40 | } else {
41 | dupes.add(candidate);
42 | }
43 | }
44 | candidates.removeAll(dupes);
45 | return instance.identifyMods();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/falsepattern/gasstation/mixins/mixin/dev/ModDiscovererMixin.java:
--------------------------------------------------------------------------------
1 | package com.falsepattern.gasstation.mixins.mixin.dev;
2 |
3 | import com.falsepattern.gasstation.mixins.IModDiscovererMixin;
4 | import org.spongepowered.asm.mixin.Mixin;
5 | import org.spongepowered.asm.mixin.Shadow;
6 | import org.spongepowered.asm.mixin.injection.At;
7 | import org.spongepowered.asm.mixin.injection.Inject;
8 | import org.spongepowered.asm.mixin.injection.Redirect;
9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
10 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
11 |
12 | import cpw.mods.fml.common.FMLLog;
13 | import cpw.mods.fml.common.ModClassLoader;
14 | import cpw.mods.fml.common.discovery.ContainerType;
15 | import cpw.mods.fml.common.discovery.ModCandidate;
16 | import cpw.mods.fml.common.discovery.ModDiscoverer;
17 |
18 | import java.io.File;
19 | import java.util.List;
20 |
21 | @Mixin(value = ModDiscoverer.class,
22 | remap = false)
23 | public abstract class ModDiscovererMixin implements IModDiscovererMixin {
24 | @Shadow private List candidates;
25 |
26 | @Override
27 | public List getCandidates() {
28 | return candidates;
29 | }
30 |
31 | @Inject(method = "findClasspathMods",
32 | at = @At(value = "INVOKE",
33 | target = "Lcpw/mods/fml/common/FMLLog;finer(Ljava/lang/String;[Ljava/lang/Object;)V"),
34 | locals = LocalCapture.CAPTURE_FAILHARD,
35 | require = 1)
36 | private void smartCheck(ModClassLoader modClassLoader, CallbackInfo ci, List knownLibraries, File[] minecraftSources, int i) {
37 | FMLLog.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
38 | candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, i == 0, true));
39 | }
40 |
41 | @Redirect(method = "findClasspathMods",
42 | at = @At(value = "INVOKE",
43 | target = "Lcpw/mods/fml/common/FMLLog;finer(Ljava/lang/String;[Ljava/lang/Object;)V"),
44 | require = 1)
45 | private void noLog(String format, Object[] data) {
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/io/github/tox1cozz/mixinbooterlegacy/IEarlyMixinLoader.java:
--------------------------------------------------------------------------------
1 | package io.github.tox1cozz.mixinbooterlegacy;
2 |
3 | /**
4 | * This is here for mixin-booter-legacy backwards compat
5 | */
6 | @SuppressWarnings("unused")
7 | public interface IEarlyMixinLoader extends com.falsepattern.gasstation.IEarlyMixinLoader {
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/io/github/tox1cozz/mixinbooterlegacy/ILateMixinLoader.java:
--------------------------------------------------------------------------------
1 | package io.github.tox1cozz.mixinbooterlegacy;
2 |
3 | /**
4 | * This is here for mixin-booter-legacy backwards compat
5 | */
6 | @SuppressWarnings("unused")
7 | public interface ILateMixinLoader extends com.falsepattern.gasstation.ILateMixinLoader {
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/io/github/tox1cozz/mixinbooterlegacy/MixinBooterLegacyPlugin.java:
--------------------------------------------------------------------------------
1 | package io.github.tox1cozz.mixinbooterlegacy;
2 |
3 | import org.apache.logging.log4j.LogManager;
4 | import org.apache.logging.log4j.Logger;
5 |
6 | import cpw.mods.fml.common.Mod;
7 |
8 | /**
9 | * This is here for mixin-booter-legacy backwards compat
10 | */
11 | @SuppressWarnings("unused")
12 | public class MixinBooterLegacyPlugin {
13 | public static final Logger LOGGER = LogManager.getLogger("MixinBooter");
14 |
15 | @Mod(modid = "mixinbooterlegacy",
16 | version = "1.1.2",
17 | name = "MixinBooterLegacy",
18 | acceptableRemoteVersions = "*")
19 | public static class Container {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/DefaultConfigHelper.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.net.URI;
6 | import java.net.URL;
7 | import java.nio.file.FileSystems;
8 | import java.nio.file.Files;
9 | import java.nio.file.Path;
10 | import java.nio.file.Paths;
11 | import java.nio.file.StandardCopyOption;
12 |
13 | import org.apache.logging.log4j.LogManager;
14 | import org.apache.logging.log4j.Logger;
15 |
16 | import net.minecraft.launchwrapper.Launch;
17 |
18 | public class DefaultConfigHelper {
19 |
20 | private final String MODID;
21 | private final Logger LOGGER;
22 |
23 | public DefaultConfigHelper(String modid) {
24 | this.MODID = modid;
25 | this.LOGGER = LogManager.getLogger(MODID);
26 | }
27 |
28 | public Path getDefaultConfigFilePath(Path relPath) throws IOException {
29 | String resourceRelPath = Paths.get("assets/" + MODID + "/default_config/").resolve(relPath).toString().replace('\\', '/');
30 | URL resourceURL = new Object() { }.getClass().getEnclosingClass().getClassLoader().getResource(resourceRelPath);
31 |
32 | switch(resourceURL.getProtocol()) {
33 | case "jar":
34 | String urlString = resourceURL.getPath();
35 | int lastExclamation = urlString.lastIndexOf('!');
36 | String newURLString = urlString.substring(0, lastExclamation);
37 | return FileSystems.newFileSystem(new File(URI.create(newURLString)).toPath(), null).getPath(resourceRelPath);
38 | case "file":
39 | return new File(URI.create(resourceURL.toString())).toPath();
40 | default:
41 | return null;
42 | }
43 | }
44 |
45 | private void copyDefaultConfigFile(Path src, Path dest) throws IOException {
46 | Files.createDirectories(getParentSafe(dest));
47 | LOGGER.debug("Copying " + src + " -> " + dest);
48 | Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
49 | }
50 |
51 | public boolean createDefaultConfigFileIfMissing(File destFile, boolean overwrite) {
52 | Path destConfigFolderPath = Paths.get(new File(Launch.minecraftHome, "config").getPath());
53 | Path destFilePath = Paths.get(destFile.getPath());
54 |
55 | Path destRelPath = destConfigFolderPath.relativize(destFilePath);
56 |
57 | if (destFilePath.startsWith(destConfigFolderPath)) {
58 | try {
59 | Path srcConfigPath = getDefaultConfigFilePath(destRelPath).toAbsolutePath();
60 | if(Files.isRegularFile(srcConfigPath)) {
61 | if(!destFile.exists() || overwrite) {
62 | copyDefaultConfigFile(srcConfigPath, destFile.toPath());
63 | }
64 | } else if(Files.isDirectory(srcConfigPath)) {
65 | Files.createDirectories(Paths.get(destFile.getPath()));
66 | // create contents of directory as well
67 | for(Path srcChildPath : Files.walk(srcConfigPath).toArray(Path[]::new)) {
68 | Path destPath = destFile.toPath().resolve(srcConfigPath.relativize(srcChildPath).toString());
69 | if(!srcChildPath.equals(srcConfigPath) && srcChildPath.startsWith(srcConfigPath)) {
70 | if(!createDefaultConfigFileIfMissing(destPath.toFile(), overwrite)) {
71 | return false;
72 | }
73 | }
74 | }
75 | }
76 | } catch (IOException e) {
77 | LOGGER.error("Failed to create default config file for " + destRelPath.toString() + ": " + e.getMessage());
78 | return false;
79 | }
80 | } else {
81 | LOGGER.debug("Invalid argument for creating default config file: " + destRelPath.toString()
82 | + " (file is not in the config directory)");
83 | return false;
84 | }
85 | return true;
86 | }
87 |
88 | public Path getParentSafe(Path p) {
89 | if(p == null || p.getParent() == null) {
90 | return Paths.get("");
91 | } else {
92 | return p.getParent();
93 | }
94 | }
95 | }
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/MixinConfigPlugin.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.Set;
6 | import org.spongepowered.asm.lib.tree.ClassNode;
7 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
8 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
9 |
10 | public class MixinConfigPlugin implements IMixinConfigPlugin {
11 | @Override
12 | public void onLoad(String mixinPackage) {
13 | Mixingasm.run();
14 | }
15 |
16 | @Override
17 | public String getRefMapperConfig() {
18 | return null;
19 | }
20 |
21 | @Override
22 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
23 | return true;
24 | }
25 |
26 | @Override
27 | public void acceptTargets(Set myTargets, Set otherTargets) {
28 |
29 | }
30 |
31 | @Override
32 | public List getMixins() {
33 | return Arrays.asList();
34 | }
35 |
36 | @Override
37 | public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
38 |
39 | }
40 |
41 | @Override
42 | public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
43 |
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/Mixingasm.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm;
2 |
3 | import java.io.File;
4 | import java.io.FileReader;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.List;
8 | import java.util.regex.Pattern;
9 | import java.util.stream.Collectors;
10 | import java.util.stream.Stream;
11 |
12 | import org.apache.commons.io.IOUtils;
13 | import org.apache.logging.log4j.LogManager;
14 | import org.apache.logging.log4j.Logger;
15 | import org.spongepowered.asm.mixin.MixinEnvironment;
16 |
17 | import makamys.mixingasm.api.IMixinSafeTransformer;
18 | import makamys.mixingasm.api.TransformerInclusions;
19 | import net.minecraft.launchwrapper.IClassTransformer;
20 | import net.minecraft.launchwrapper.Launch;
21 |
22 | public class Mixingasm {
23 |
24 | public static final String MODID = "mixingasm";
25 | public static final Logger LOGGER = LogManager.getLogger(MODID);
26 |
27 | public static void run() {
28 | List badTransformers = getBadTransformers();
29 | LOGGER.debug("Excluding transformers: " + badTransformers);
30 | for(String badTransformer : badTransformers) {
31 | MixinEnvironment.getCurrentEnvironment().addTransformerExclusion(badTransformer);
32 | }
33 | }
34 |
35 | private static boolean isValidClassPattern(String pattern) {
36 | return !pattern.startsWith(":");
37 | }
38 |
39 | private static List getBadTransformers() {
40 | List dynamicTransformerInclusionPatterns = TransformerInclusions.getTransformerInclusionList();
41 | LOGGER.debug("Dynamic transformer inclusion pattern list: " + dynamicTransformerInclusionPatterns);
42 |
43 | List badTransformers = new ArrayList<>();
44 |
45 | List transformerInclusionPatterns = Stream.of(
46 | readConfig("transformer_inclusion_list_default.txt").stream(),
47 | readConfig("transformer_inclusion_list.txt").stream(),
48 | dynamicTransformerInclusionPatterns.stream())
49 | .flatMap(i -> i)
50 | .filter(Mixingasm::isValidClassPattern)
51 | .collect(Collectors.toList());
52 |
53 | List transformerExclusionPatterns =
54 | readConfig("transformer_exclusion_list.txt").stream()
55 | .filter(Mixingasm::isValidClassPattern)
56 | .collect(Collectors.toList());
57 |
58 | for(IClassTransformer trans : Launch.classLoader.getTransformers()) {
59 | String name = trans.getClass().getCanonicalName();
60 | boolean included = false;
61 | if((included = (transformerInclusionPatterns.stream().anyMatch(p -> patternMatches(name, p)) || trans instanceof IMixinSafeTransformer))
62 | && transformerExclusionPatterns.stream().noneMatch(p -> patternMatches(name, p))) {
63 | LOGGER.debug(" Trusting transformer " + name);
64 | } else {
65 | LOGGER.debug(" Not trusting transformer " + name + (included ? " (because it was excluded via the config)" : ""));
66 | badTransformers.add(name);
67 | }
68 | }
69 | return badTransformers;
70 | }
71 |
72 | private static boolean patternMatches(String str, String patternStr) {
73 | Pattern pattern = Pattern.compile(patternStr.replace(".", "\\.").replace("*", ".*"));
74 | return pattern.matcher(str).matches();
75 | }
76 |
77 | private static List readConfig(String name){
78 | DefaultConfigHelper helper = new DefaultConfigHelper(MODID);
79 | File listFile = new File(Launch.minecraftHome, "config/" + MODID + "/" + name);
80 |
81 | listFile.getParentFile().mkdirs();
82 |
83 | List lines = listFile.exists() ? readConfigLines(listFile) : null;
84 | boolean overwrite = lines != null && lines.contains(":replaceableFile");
85 |
86 | if(lines == null || overwrite) {
87 | helper.createDefaultConfigFileIfMissing(listFile, overwrite);
88 | lines = readConfigLines(listFile);
89 | }
90 |
91 | return lines;
92 | }
93 |
94 | private static List readConfigLines(File file){
95 | try (FileReader fr = new FileReader(file)){
96 | return IOUtils.readLines(fr).stream()
97 | .map(l -> l.contains("#") ? l.substring(0, l.indexOf('#')) : l)
98 | .map(l -> l.trim())
99 | .filter(l -> !l.isEmpty())
100 | .collect(Collectors.toList());
101 | } catch(Exception e) {
102 | System.out.println("Failed to read " + file);
103 | e.printStackTrace();
104 | }
105 | return Arrays.asList();
106 | }
107 |
108 | }
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/api/IMixinSafeTransformer.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm.api;
2 |
3 | /** Implement this interface to signal that your transformer is "Mixin-safe", i.e. it does not cause issues when run by Mixin's preprocessor. This will be used as a hint that it shouldn't get excluded from the mixin preprocessor's transformer list by Mixingasm. */
4 |
5 | public interface IMixinSafeTransformer {
6 |
7 | }
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/api/TransformerInclusions.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm.api;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import net.minecraft.launchwrapper.Launch;
7 |
8 | public class TransformerInclusions {
9 |
10 | private static final String INCLUSION_LIST_BLACKBOARD_KEY = "mixingasm.transformerInclusionList";
11 |
12 | /** Returns Mixingasm's dynamic transformer inclusion list. Add transformer name patterns to this list if you want to spare them from being added to
13 | * the mixin environment's transformer exclusion list, for example if you need to mix into a version of a class that has been transformed by them.
14 | *
15 | * Note: this needs to be called before the DEFAULT phase.
16 | */
17 | public static List getTransformerInclusionList(){
18 | List list = (List)Launch.blackboard.get(INCLUSION_LIST_BLACKBOARD_KEY);
19 | if(list == null) {
20 | Launch.blackboard.put(INCLUSION_LIST_BLACKBOARD_KEY, list = new ArrayList());
21 | }
22 | return list;
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/src/main/java/makamys/mixingasm/forge/MixingasmMod.java:
--------------------------------------------------------------------------------
1 | package makamys.mixingasm.forge;
2 |
3 | import cpw.mods.fml.common.Mod;
4 | import makamys.mixingasm.Mixingasm;
5 |
6 | @Mod(modid = Mixingasm.MODID, version = "0.2.2")
7 | public class MixingasmMod {
8 | }
--------------------------------------------------------------------------------
/src/main/java/ru/timeconqueror/spongemixins/MinecraftURLClassPath.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 TimeConqueror
3 | *
4 | * 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:
5 | *
6 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 | *
8 | * 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.
9 | */
10 | package ru.timeconqueror.spongemixins;
11 |
12 | import java.io.File;
13 |
14 | /**
15 | * This is here for SpongeMixins backwards compat
16 | */
17 | @SuppressWarnings("unused")
18 | public final class MinecraftURLClassPath {
19 | public static File getJarInModPath(final String jarname) {
20 | return com.falsepattern.gasstation.MinecraftURLClassPath.getJarInModPath(jarname);
21 | }
22 |
23 | public static boolean findJarInClassPath(final String jarname) {
24 | return com.falsepattern.gasstation.MinecraftURLClassPath.findJarInClassPath(jarname);
25 | }
26 |
27 | public static void addJar(File pathToJar) throws Exception {
28 | com.falsepattern.gasstation.MinecraftURLClassPath.addJar(pathToJar);
29 | }
30 |
31 | private MinecraftURLClassPath() {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/ru/timeconqueror/spongemixins/SpongeMixins.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 TimeConqueror
3 | *
4 | * 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:
5 | *
6 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 | *
8 | * 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.
9 | */
10 | package ru.timeconqueror.spongemixins;
11 |
12 | import cpw.mods.fml.common.Mod;
13 | import org.apache.logging.log4j.LogManager;
14 | import org.apache.logging.log4j.Logger;
15 |
16 | /**
17 | * This is here for SpongeMixins backwards compat
18 | */
19 | @SuppressWarnings("unused")
20 | @Mod(modid = SpongeMixins.MODID, version = "1.5.0", name = SpongeMixins.NAME, acceptableRemoteVersions = "*")
21 | public class SpongeMixins {
22 | public static final String NAME = "SpongeMixins Loader";
23 | public static final String MODID = "spongemixins";
24 | public static final Logger LOGGER = LogManager.getLogger(NAME);
25 | }
--------------------------------------------------------------------------------
/src/main/java/ru/timeconqueror/spongemixins/core/SpongeMixinsCore.java:
--------------------------------------------------------------------------------
1 | package ru.timeconqueror.spongemixins.core;
2 |
3 | import org.apache.logging.log4j.LogManager;
4 | import org.apache.logging.log4j.Logger;
5 |
6 | /**
7 | * This is here for SpongeMixins backwards compat
8 | */
9 | public class SpongeMixinsCore {
10 | public static final String PLUGIN_NAME = "SpongeMixin Core Plugin";
11 | public static final Logger LOGGER = LogManager.getLogger(PLUGIN_NAME);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/resources/CREDITS:
--------------------------------------------------------------------------------
1 | Embedded code licenses:
2 |
3 | SpongePowered Mixins is licensed under MIT, and is compatible with LGPLv3.
4 | Full license notice here: https://github.com/SpongePowered/Mixin/blob/master/LICENSE.txt
5 |
6 | MixinExtras is licensed under MIT, and is compatible with LGPLv3.
7 | Full license notice here: https://github.com/LlamaLad7/MixinExtras/blob/master/LICENSE
8 |
9 | MixinBooterLegacy is licensed under LGPLv2.1+, and is compatible with LGPLv3.
10 | Full license notice here: https://github.com/tox1cozZ/mixin-booter-legacy/blob/master/LICENSE
11 |
12 | SpongeMixins is licensed under MIT, and is compatible with LGPLv3.
13 | Full license notice here: https://github.com/TimeConqueror/SpongeMixins/blob/master/LICENSE
14 |
15 | Mixingasm is licensed under Unlicense, and is compatible with LGPLv3.
16 | https://github.com/makamys/Mixingasm/blob/master/UNLICENSE
--------------------------------------------------------------------------------
/src/main/resources/LICENSE:
--------------------------------------------------------------------------------
1 | GasStation
2 |
3 | Copyright (C) 2022 FalsePattern
4 | All Rights Reserved
5 |
6 | The above copyright notice, this permission notice and the word "SNEED"
7 | shall be included in all copies or substantial portions of the Software.
8 |
9 | This program is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 3 of the License, or
12 | (at your option) any later version.
13 |
14 | This program is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with this program. If not, see .
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService:
--------------------------------------------------------------------------------
1 | org.spongepowered.asm.launch.MixinTransformationService
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService:
--------------------------------------------------------------------------------
1 | org.spongepowered.asm.launch.MixinLaunchPlugin
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/javax.annotation.processing.Processor:
--------------------------------------------------------------------------------
1 | org.spongepowered.tools.obfuscation.MixinObfuscationProcessorInjection
2 | org.spongepowered.tools.obfuscation.MixinObfuscationProcessorTargets
3 | com.llamalad7.mixinextras.MixinExtrasAP
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.spongepowered.asm.service.IGlobalPropertyService:
--------------------------------------------------------------------------------
1 | org.spongepowered.asm.service.mojang.Blackboard
2 | org.spongepowered.asm.service.modlauncher.Blackboard
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinService:
--------------------------------------------------------------------------------
1 | org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper
2 | org.spongepowered.asm.service.modlauncher.MixinServiceModLauncher
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.spongepowered.asm.service.IMixinServiceBootstrap:
--------------------------------------------------------------------------------
1 | org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapperBootstrap
2 | org.spongepowered.asm.service.modlauncher.MixinServiceModLauncherBootstrap
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.spongepowered.tools.obfuscation.service.IObfuscationService:
--------------------------------------------------------------------------------
1 | org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP
2 | org.spongepowered.tools.obfuscation.fg3.ObfuscationServiceFG3
--------------------------------------------------------------------------------
/src/main/resources/assets/mixingasm/default_config/mixingasm/transformer_exclusion_list.txt:
--------------------------------------------------------------------------------
1 | # Classes listed in this file will be considered "untrusted" by Mixingasm and
2 | # added to the mixin environment's transformer exclusion list.
3 | # See transformer_inclusion_list_default.txt for more info.
4 |
5 |
6 | # --- Untrusted transformers ---
--------------------------------------------------------------------------------
/src/main/resources/assets/mixingasm/default_config/mixingasm/transformer_inclusion_list.txt:
--------------------------------------------------------------------------------
1 | # Classes listed in this file will be considered "trusted" by Mixingasm and
2 | # may be spared from the mixin environment's transformer exclusion list.
3 | # See transformer_inclusion_list_default.txt for more info.
4 |
5 |
6 | # --- Additional trusted transformers ---
--------------------------------------------------------------------------------
/src/main/resources/assets/mixingasm/default_config/mixingasm/transformer_inclusion_list_default.txt:
--------------------------------------------------------------------------------
1 | :replaceableFile # This file will get OVERWRITTEN at launch, nullifying any changes made to it, unless you delete this line. It is recommended to edit transformer_inclusion_list.txt and transformer_exclusion_list.txt instead, though.
2 |
3 | # Mixingasm adds all transformers it doesn't "trust" to be Mixin-safe to the
4 | # mixin environment's transformer exclusion list, avoiding running them an
5 | # additional time when processing mixins at startup.
6 |
7 | # This fixes issues that can arise from non-Mixin-aware transformers being run
8 | # in that way. For example, some transformers break when run more than once.
9 |
10 | # A transformer is considered "trusted" if one of these are true...
11 | # * It's matched by a pattern in this file
12 | # * It's matched by a pattern in transformer_inclusion_list.txt
13 | # * It was added to Mixingasm's dynamic inclusion list by a mod using the API at startup
14 | # * The transformer implements IMixinSafeTransformer
15 | # AND the transformer is not matched by a pattern in transformer_exclusion_list.txt
16 |
17 | # '*' can be used as a wildcard character.
18 |
19 |
20 | # --- Trusted transformers ---
21 |
22 | cpw.mods.fml.common.asm.*
23 | net.minecraftforge.*
24 | codechicken.core.asm.*
25 | codechicken.lib.asm.*
26 | org.spongepowered.asm.*
--------------------------------------------------------------------------------
/src/main/resources/gasstation_parity.txt:
--------------------------------------------------------------------------------
1 | This file is here for tracking feature parity with upstream projects we pulled in code from.
2 |
3 | MBL: 3997fe943aab26bc916bb745f229b12651d769d3
4 | SM: c372c9010f9854dc80415a8fd1ff414fd0822f00
5 | MGASM: 0295a8243255e0dd63d8a995d61c0295f14834db
--------------------------------------------------------------------------------
/src/main/resources/mcmod.info:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "modid": "${modId}",
4 | "name": "${modName}",
5 | "description": "Just another mixin library with some extras",
6 | "version": "${modVersion}",
7 | "mcversion": "${minecraftVersion}",
8 | "url": "https://github.com/FalsePattern/GasStation",
9 | "updateUrl": "",
10 | "authorList": [
11 | "FalsePattern"
12 | ],
13 | "credits": "",
14 | "logoFile": "",
15 | "screenshots": [],
16 | "dependencies": []
17 | },
18 | {
19 | "modid": "mixinbooterlegacy",
20 | "name": "MixinBooterLegacy",
21 | "description": "GasStation's MixinBooterLegacy stub for mods that depend on it",
22 | "version": "1.1.2",
23 | "mcversion": "${minecraftVersion}",
24 | "url": "https://github.com/tox1cozZ/mixin-booter-legacy",
25 | "updateUrl": "",
26 | "authorList": [
27 | "Rongmario",
28 | "tox1cozZ"
29 | ],
30 | "credits": "Thanks Rongmario for a MixinBooter on Minecraft 1.12.2.",
31 | "logoFile": "",
32 | "screenshots": [],
33 | "parent": "${modId}",
34 | "dependencies": []
35 | },
36 | {
37 | "modid": "spongemixins",
38 | "name": "SpongeMixins",
39 | "description": "GasStation's SpongeMixins stub for mods that depend on it",
40 | "version": "1.5.0",
41 | "mcversion": "${minecraftVersion}",
42 | "url": "",
43 | "updateUrl": "",
44 | "authorList": [
45 | "Time_Conqueror"
46 | ],
47 | "credits": "SpongePowered Team",
48 | "logoFile": "",
49 | "screenshots": [],
50 | "parent": "${modId}",
51 | "dependencies": []
52 | },
53 | {
54 | "modid": "mixingasm",
55 | "name": "Mixingasm",
56 | "description": "Improves compatibility between mixin mods and ASM mods",
57 | "version": "0.2.2",
58 | "mcversion": "${minecraftVersion}",
59 | "url": "",
60 | "updateUrl": "",
61 | "authorList": ["makamys"],
62 | "logoFile": "",
63 | "screenshots": [],
64 | "parent": "${modId}",
65 | "dependencies": []
66 | }
67 | ]
68 |
--------------------------------------------------------------------------------
/src/main/resources/mixins.gasstation.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "minVersion": "0.8.3",
4 | "package": "com.falsepattern.gasstation.mixins.mixin",
5 | "refmap": "mixins.gasstation.refmap.json",
6 | "target": "@env(PREINIT)",
7 | "compatibilityLevel": "JAVA_8",
8 | "mixins": [
9 |
10 | ],
11 | "plugin": "com.falsepattern.gasstation.mixins.DevMixinPlugin"
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/main/resources/mixins.gasstation_mixinbooter.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "minVersion": "0.8.3",
4 | "package": "com.falsepattern.gasstation.mixins.mixin",
5 | "refmap": "mixins.gasstation.refmap.json",
6 | "target": "@env(PREINIT)",
7 | "compatibilityLevel": "JAVA_8",
8 | "mixins": ["LoadControllerMixin"]
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/src/main/resources/mixins.gasstation_mixingasm.json:
--------------------------------------------------------------------------------
1 | {
2 | "required": true,
3 | "minVersion": "0.6",
4 | "package": "com.falsepattern.gasstation.mixins.mixin",
5 | "compatibilityLevel": "JAVA_8",
6 | "mixins": [
7 |
8 | ],
9 | "plugin": "makamys.mixingasm.MixinConfigPlugin"
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/resources/pack.mcmeta:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------