mirror of
https://github.com/FliegendeWurst/AsyncLighting.git
synced 2024-11-24 15:24:56 +00:00
Initial commit
This commit is contained in:
commit
fb28900032
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.gradle
|
||||||
|
build
|
||||||
|
run
|
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
2
.idea/AsyncLighting.iml
Normal file
2
.idea/AsyncLighting.iml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4" />
|
6
.idea/compiler.xml
Normal file
6
.idea/compiler.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="1.8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# AsyncLighting
|
||||||
|
|
||||||
|
This mod moves Minecraft's light engine processing to another thread.
|
||||||
|
It also fixes most issues with the Forge option "alwaysSetupTerrainOffThread" by simply moving all rendering off the main thread. It is recommended to enable this Forge option to avoid rendering issues.
|
||||||
|
Also included is a fix for opening screenshots using the chat link (vanilla behaviour: freezing the game until image viewer is closed).
|
||||||
|
Forge version this mod was tested to work with: 31.1.27. Version 31.1.87 is currently incompatible.
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
|
||||||
|
Block light in single player worlds is not rendered until the light source receives a block update.
|
||||||
|
Multiplayer worlds do not have this issue.
|
90
build.gradle
Normal file
90
build.gradle
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
maven { url = 'https://files.minecraftforge.net/maven' }
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apply plugin: 'net.minecraftforge.gradle'
|
||||||
|
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||||
|
apply plugin: 'eclipse'
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
|
||||||
|
ext.configFile = file('build.properties')
|
||||||
|
ext.config = parseConfig(configFile)
|
||||||
|
|
||||||
|
version = config.version
|
||||||
|
group = "fliegendewurst.${config.mod_id}"
|
||||||
|
archivesBaseName = config.mod_name
|
||||||
|
|
||||||
|
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
mappings channel: "${config.mapping_channel}", version: "${config.mapping_version}"
|
||||||
|
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||||
|
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||||
|
|
||||||
|
runs {
|
||||||
|
client {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
|
||||||
|
property 'forge.logging.markers', ''
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "net.minecraftforge:forge:${config.mc_version}-${config.forge_version}"
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
archiveName = "${baseName}-${config.mc_version}-${version}.${extension}"
|
||||||
|
|
||||||
|
manifest {
|
||||||
|
attributes([
|
||||||
|
"Specification-Title": "${config.mod_id}",
|
||||||
|
"Specification-Vendor": 'FliegendeWurst',
|
||||||
|
"Specification-Version": '1',
|
||||||
|
"Implementation-Title": "${config.mod_id}",
|
||||||
|
"Implementation-Version": "${version}",
|
||||||
|
"Implementation-Vendor" :'FliegendeWurst',
|
||||||
|
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example configuration to allow publishing using the maven-publish task
|
||||||
|
// This is the preferred method to reobfuscate your jar file
|
||||||
|
jar.finalizedBy('reobfJar')
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
mavenJava(MavenPublication) {
|
||||||
|
artifact jar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url "file:///${project.projectDir}/mcmodsrepo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def parseConfig(File config) {
|
||||||
|
config.withReader {
|
||||||
|
def prop = new Properties()
|
||||||
|
prop.load(it)
|
||||||
|
return (new ConfigSlurper().parse(prop))
|
||||||
|
}
|
||||||
|
}
|
7
build.properties
Normal file
7
build.properties
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
mod_name=AsyncLighting
|
||||||
|
forge_version=31.1.27
|
||||||
|
mapping_version=20200225-1.15.1
|
||||||
|
mapping_channel=snapshot
|
||||||
|
mod_id=asynclighting
|
||||||
|
version=1.0
|
||||||
|
mc_version=1.15.2
|
4
gradle.properties
Normal file
4
gradle.properties
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||||
|
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||||
|
org.gradle.jvmargs=-Xmx3G
|
||||||
|
org.gradle.daemon=false
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
|
172
gradlew
vendored
Executable file
172
gradlew
vendored
Executable file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
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"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@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=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
359
src/main/java/fliegendewurst/asynclighting/AsyncLighting.java
Normal file
359
src/main/java/fliegendewurst/asynclighting/AsyncLighting.java
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
package fliegendewurst.asynclighting;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
import net.minecraft.util.math.SectionPos;
|
||||||
|
import net.minecraft.world.LightType;
|
||||||
|
import net.minecraft.world.chunk.NibbleArray;
|
||||||
|
import net.minecraft.world.lighting.WorldLightManager;
|
||||||
|
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.TickEvent;
|
||||||
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.BlockingDeque;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Mod("asynclighting")
|
||||||
|
public class AsyncLighting {
|
||||||
|
public static final String MODID = "asynclighting";
|
||||||
|
public static final Logger LOGGER = LogManager.getLogger(MODID);
|
||||||
|
|
||||||
|
public static Minecraft mc;
|
||||||
|
|
||||||
|
private static final BlockingDeque<Runnable> LIGHT_QUEUE = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
|
private static boolean tickingLight = false;
|
||||||
|
|
||||||
|
public AsyncLighting() {
|
||||||
|
AsyncLighting.mc = Minecraft.getInstance();
|
||||||
|
|
||||||
|
new Thread(AsyncLighting::processLightTicks, "Light thread").start();
|
||||||
|
|
||||||
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void drawDebugText(RenderGameOverlayEvent.Text event) {
|
||||||
|
if (!Minecraft.getInstance().gameSettings.showDebugInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!SECTION_LIGHT_UPDATES.isEmpty() || !BLOCK_LIGHT_UPDATES.isEmpty()) {
|
||||||
|
event.getLeft().add("");
|
||||||
|
}
|
||||||
|
if (!SECTION_LIGHT_UPDATES.isEmpty())
|
||||||
|
event.getLeft().add(String.format("%s section updates pending", SECTION_LIGHT_UPDATES.size()));
|
||||||
|
if (!BLOCK_LIGHT_UPDATES.isEmpty())
|
||||||
|
event.getLeft().add(String.format("%s block updates pending", BLOCK_LIGHT_UPDATES.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
|
public void worldUnload(WorldEvent.Unload event) {
|
||||||
|
BLOCK_LIGHT_UPDATES.clear();
|
||||||
|
SECTION_LIGHT_UPDATES.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onRenderStart(TickEvent.RenderTickEvent event) {
|
||||||
|
if (event.phase == TickEvent.Phase.END && !tickingLight) {
|
||||||
|
// apply block light updates (queue for rendering)
|
||||||
|
Iterator<BlockPos> iter = BLOCK_LIGHT_UPDATES.iterator();
|
||||||
|
if (iter.hasNext()) {
|
||||||
|
BlockPos pos = iter.next();
|
||||||
|
if (mc.worldRenderer == null) {
|
||||||
|
BLOCK_LIGHT_UPDATES.clear();
|
||||||
|
SECTION_LIGHT_UPDATES.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mc.worldRenderer.markBlockRangeForRenderUpdate(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
BLOCK_LIGHT_UPDATES.remove(pos);
|
||||||
|
}
|
||||||
|
Iterator<SectionPos> iter2 = SECTION_LIGHT_UPDATES.iterator();
|
||||||
|
if (iter2.hasNext()) {
|
||||||
|
SectionPos pos = iter2.next();
|
||||||
|
if (mc.worldRenderer == null) {
|
||||||
|
BLOCK_LIGHT_UPDATES.clear();
|
||||||
|
SECTION_LIGHT_UPDATES.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//LOGGER.debug("rendering section {} {} {}", pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
mc.worldRenderer.markForRerender(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
//mc.worldRenderer.markSurroundingsForRerender(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
SECTION_LIGHT_UPDATES.remove(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean uploadMore() {
|
||||||
|
if (mc.player != null) {
|
||||||
|
// lowest possible motion (standing still) is: 0.006146560239257815
|
||||||
|
return mc.player.getMotion().lengthSquared() < 0.0073;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tickLightManager(WorldLightManager lightManager, int toUpdateCount, boolean updateSkyLight, boolean updateBlockLight) {
|
||||||
|
//LOGGER.debug("ticking light {} {} {} {}", lightManager, toUpdateCount, updateSkyLight, updateBlockLight);
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new LightTick(lightManager, toUpdateCount, updateSkyLight, updateBlockLight));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light ticking interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void enableLightSources(WorldLightManager lightManager, ChunkPos pos, boolean b) {
|
||||||
|
//LOGGER.debug("enabling light {} {}", pos, b);
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new LightEnable(lightManager, pos, b));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light enabling interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateSectionStatus(WorldLightManager lightManager, SectionPos pos, boolean b) {
|
||||||
|
//LOGGER.debug("updating section {} {}", pos, b);
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new LightUpdate(lightManager, pos, b));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light section update interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setData(WorldLightManager lightManager, LightType type, SectionPos pos, @Nullable NibbleArray b) {
|
||||||
|
//LOGGER.debug("setting data {} {}", type, pos);
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new SetData(lightManager, type, pos, b));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light data interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void checkBlock(WorldLightManager lightManager, BlockPos pos) {
|
||||||
|
//LOGGER.debug("checking block {}", pos);
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new CheckBlock(lightManager, pos));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light check block interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only called in the ServerWorldLightManager
|
||||||
|
public static void blockEmission(WorldLightManager lightManager, BlockPos pos, int i) {
|
||||||
|
try {
|
||||||
|
LIGHT_QUEUE.putLast(new BlockEmission(lightManager, pos, i));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("block emission increase interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Set<BlockPos> BLOCK_LIGHT_UPDATES = Sets.newConcurrentHashSet();
|
||||||
|
private static final Set<SectionPos> SECTION_LIGHT_UPDATES = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
|
private static void processLightTicks() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Runnable tick = LIGHT_QUEUE.takeFirst();
|
||||||
|
/* queue will never fill up (since thread never waits on render to finish)
|
||||||
|
if (LIGHT_QUEUE.remainingCapacity() < 100) {
|
||||||
|
LOGGER.warn("light tick queue almost full: {} slots remaining", LIGHT_QUEUE.remainingCapacity());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
//Set<BlockPos> updated = new HashSet<>();
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
int counter = 0;
|
||||||
|
if (mc.world == null) {
|
||||||
|
// world exited
|
||||||
|
LIGHT_QUEUE.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while (tick != null) {
|
||||||
|
tickingLight = true;
|
||||||
|
tick.run();
|
||||||
|
counter++;
|
||||||
|
if (tick instanceof CheckBlock) {
|
||||||
|
BlockPos pos = ((CheckBlock) tick).pos;
|
||||||
|
//updated.add(pos);
|
||||||
|
BLOCK_LIGHT_UPDATES.add(pos);
|
||||||
|
} else if (tick instanceof LightUpdate) {
|
||||||
|
SECTION_LIGHT_UPDATES.add(((LightUpdate) tick).pos);
|
||||||
|
} else if (tick instanceof SetData) {
|
||||||
|
SECTION_LIGHT_UPDATES.add(((SetData) tick).pos);
|
||||||
|
}
|
||||||
|
tick = LIGHT_QUEUE.pollFirst(1, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
for (BlockPos pos : updated) {
|
||||||
|
mc.worldRenderer.markBlockRangeForRenderUpdate(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
//mc.worldRenderer.notifyBlockUpdate(mc.world, pos, mc.world.getBlockState(pos), mc.world.getBlockState(pos), 8 | 1);
|
||||||
|
//mc.worldRenderer.markSurroundingsForRerender(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
tickingLight = false;
|
||||||
|
long time = System.currentTimeMillis() - start;
|
||||||
|
if (time > 100) {
|
||||||
|
LOGGER.warn("processing {} light updates: {} ms", counter, time);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("light ticking thread interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
private static void processBlockUpdates() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
while (rendering) {
|
||||||
|
// do not update lights in current frame
|
||||||
|
Thread.sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.warn("block light update thread interrupted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static class LightTick implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
int toUpdateCount;
|
||||||
|
boolean updateSkyLight;
|
||||||
|
boolean updateBlockLight;
|
||||||
|
|
||||||
|
LightTick(WorldLightManager lightManager, int toUpdateCount, boolean updateSkyLight, boolean updateBlockLight) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.toUpdateCount = toUpdateCount;
|
||||||
|
this.updateSkyLight = updateSkyLight;
|
||||||
|
this.updateBlockLight = updateBlockLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
lightManager.tick(toUpdateCount, updateSkyLight, updateBlockLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LightEnable implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
ChunkPos pos;
|
||||||
|
boolean b;
|
||||||
|
|
||||||
|
LightEnable(WorldLightManager lightManager, ChunkPos pos, boolean b) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.pos = pos;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (lightManager.blockLight != null) {
|
||||||
|
lightManager.blockLight.func_215620_a(pos, b);
|
||||||
|
}
|
||||||
|
if (lightManager.skyLight != null) {
|
||||||
|
lightManager.skyLight.func_215620_a(pos, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LightUpdate implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
SectionPos pos;
|
||||||
|
boolean b;
|
||||||
|
|
||||||
|
LightUpdate(WorldLightManager lightManager, SectionPos pos, boolean b) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.pos = pos;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (lightManager.blockLight != null) {
|
||||||
|
lightManager.blockLight.updateSectionStatus(pos, b);
|
||||||
|
}
|
||||||
|
if (lightManager.skyLight != null) {
|
||||||
|
lightManager.skyLight.updateSectionStatus(pos, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SetData implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
LightType block;
|
||||||
|
SectionPos pos;
|
||||||
|
@Nullable
|
||||||
|
NibbleArray b;
|
||||||
|
|
||||||
|
SetData(WorldLightManager lightManager, LightType type, SectionPos pos, @Nullable NibbleArray b) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.block = type;
|
||||||
|
this.pos = pos;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (block == LightType.BLOCK) {
|
||||||
|
if (lightManager.blockLight != null) {
|
||||||
|
lightManager.blockLight.setData(pos.asLong(), b);
|
||||||
|
}
|
||||||
|
} else if (lightManager.skyLight != null) {
|
||||||
|
lightManager.skyLight.setData(pos.asLong(), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CheckBlock implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
BlockPos pos;
|
||||||
|
|
||||||
|
CheckBlock(WorldLightManager lightManager, BlockPos pos) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (lightManager.blockLight != null) {
|
||||||
|
lightManager.blockLight.checkLight(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lightManager.skyLight != null) {
|
||||||
|
lightManager.skyLight.checkLight(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BlockEmission implements Runnable {
|
||||||
|
WorldLightManager lightManager;
|
||||||
|
BlockPos pos;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BlockEmission(WorldLightManager lightManager, BlockPos pos, int i) {
|
||||||
|
this.lightManager = lightManager;
|
||||||
|
this.pos = pos;
|
||||||
|
this.i = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (lightManager.blockLight != null) {
|
||||||
|
lightManager.blockLight.func_215623_a(pos, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
src/main/resources/META-INF/accesstransformer.cfg
Normal file
3
src/main/resources/META-INF/accesstransformer.cfg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
public net.minecraft.world.lighting.WorldLightManager field_215576_a # blockLight
|
||||||
|
public net.minecraft.world.lighting.WorldLightManager field_215577_b # skyLight
|
||||||
|
public net.minecraft.world.lighting.LightEngine func_215621_a(JLnet/minecraft/world/chunk/NibbleArray;)V # setData
|
3
src/main/resources/META-INF/coremods.json
Normal file
3
src/main/resources/META-INF/coremods.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"AsyncLighting Transformer": "asynclighting-transformer.js"
|
||||||
|
}
|
28
src/main/resources/META-INF/mods.toml
Normal file
28
src/main/resources/META-INF/mods.toml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
modLoader="javafml"
|
||||||
|
loaderVersion="[31,)"
|
||||||
|
issueTrackerURL="https://github.com/FliegendeWurst/AsyncLighting/issues"
|
||||||
|
|
||||||
|
[[mods]]
|
||||||
|
modId="asynclighting"
|
||||||
|
displayName="AsyncLighting"
|
||||||
|
version="0.1"
|
||||||
|
#updateJSONURL=""
|
||||||
|
displayURL="https://github.com/FliegendeWurst/AsyncLighting/"
|
||||||
|
#logoFile=""
|
||||||
|
authors="FliegendeWurst"
|
||||||
|
description='''
|
||||||
|
Asynchronous light processing, rendering and more.
|
||||||
|
'''
|
||||||
|
|
||||||
|
[[dependencies.asynclighting]]
|
||||||
|
modId="forge"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="[31,)" #mandatory
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
||||||
|
[[dependencies.asynclighting]]
|
||||||
|
modId="minecraft"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="[1.15.2]"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
813
src/main/resources/asynclighting-transformer.js
Normal file
813
src/main/resources/asynclighting-transformer.js
Normal file
@ -0,0 +1,813 @@
|
|||||||
|
/**
|
||||||
|
* This function is called by Forge before any minecraft classes are loaded to
|
||||||
|
* setup the coremod.
|
||||||
|
*
|
||||||
|
* @return {object} All the transformers of this coremod.
|
||||||
|
*/
|
||||||
|
function initializeCoreMod() {
|
||||||
|
/*Class/Interface*/ Opcodes = Java.type("org.objectweb.asm.Opcodes");
|
||||||
|
/*Class*/ ASMAPI = Java.type("net.minecraftforge.coremod.api.ASMAPI");;
|
||||||
|
|
||||||
|
/*Class*/ InsnList = Java.type("org.objectweb.asm.tree.InsnList");
|
||||||
|
/*Class*/ LabelNode = Java.type("org.objectweb.asm.tree.LabelNode");
|
||||||
|
|
||||||
|
/*Class*/ FieldNode = Java.type("org.objectweb.asm.tree.FieldNode");
|
||||||
|
/*Class*/ MethodNode = Java.type("org.objectweb.asm.tree.MethodNode");
|
||||||
|
|
||||||
|
/*Class*/ AbstractInsnNode = Java.type("org.objectweb.asm.tree.AbstractInsnNode");
|
||||||
|
/*Class*/ InsnNode = Java.type("org.objectweb.asm.tree.InsnNode");
|
||||||
|
/*Class*/ VarInsnNode = Java.type("org.objectweb.asm.tree.VarInsnNode");
|
||||||
|
/*Class*/ LdcInsnNode = Java.type("org.objectweb.asm.tree.LdcInsnNode");
|
||||||
|
/*Class*/ FieldInsnNode = Java.type("org.objectweb.asm.tree.FieldInsnNode");
|
||||||
|
/*Class*/ MethodInsnNode = Java.type("org.objectweb.asm.tree.MethodInsnNode");
|
||||||
|
/*Class*/ JumpInsnNode = Java.type("org.objectweb.asm.tree.JumpInsnNode");
|
||||||
|
/*Class*/ TypeInsnNode = Java.type("org.objectweb.asm.tree.TypeInsnNode");
|
||||||
|
|
||||||
|
ACC_PUBLIC = Opcodes.ACC_PUBLIC;
|
||||||
|
|
||||||
|
INVOKESTATIC = Opcodes.INVOKESTATIC;
|
||||||
|
INVOKEVIRTUAL = Opcodes.INVOKEVIRTUAL;
|
||||||
|
|
||||||
|
ALOAD = Opcodes.ALOAD;
|
||||||
|
ILOAD = Opcodes.ILOAD;
|
||||||
|
FLOAD = Opcodes.FLOAD;
|
||||||
|
DLOAD = Opcodes.DLOAD;
|
||||||
|
|
||||||
|
ASTORE = Opcodes.ASTORE;
|
||||||
|
ISTORE = Opcodes.ISTORE;
|
||||||
|
|
||||||
|
RETURN = Opcodes.RETURN;
|
||||||
|
ARETURN = Opcodes.ARETURN;
|
||||||
|
IRETURN = Opcodes.IRETURN;
|
||||||
|
DRETURN = Opcodes.DRETURN;
|
||||||
|
|
||||||
|
NEW = Opcodes.NEW;
|
||||||
|
|
||||||
|
MONITORENTER = Opcodes.MONITORENTER;
|
||||||
|
MONITOREXIT = Opcodes.MONITOREXIT;
|
||||||
|
|
||||||
|
ACONST_NULL = Opcodes.ACONST_NULL;
|
||||||
|
ICONST_0 = Opcodes.ICONST_0;
|
||||||
|
|
||||||
|
IFEQ = Opcodes.IFEQ;
|
||||||
|
IFNE = Opcodes.IFNE;
|
||||||
|
IF_ACMPEQ = Opcodes.IF_ACMPEQ;
|
||||||
|
IFNULL = Opcodes.IFNULL;
|
||||||
|
|
||||||
|
GETFIELD = Opcodes.GETFIELD;
|
||||||
|
GETSTATIC = Opcodes.GETSTATIC;
|
||||||
|
|
||||||
|
GOTO = Opcodes.GOTO;
|
||||||
|
FRAME = Opcodes.FRAME;
|
||||||
|
|
||||||
|
LABEL = AbstractInsnNode.LABEL;
|
||||||
|
METHOD_INSN = AbstractInsnNode.METHOD_INSN;
|
||||||
|
VAR_INSN = AbstractInsnNode.VAR_INSN;
|
||||||
|
|
||||||
|
return {
|
||||||
|
"WorldRenderer modify updateCameraAndRender": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.renderer.WorldRenderer",
|
||||||
|
"methodName": "func_228426_a_", // updateCameraAndRender func_228426_a_
|
||||||
|
"methodDesc": "(Lcom/mojang/blaze3d/matrix/MatrixStack;FJZLnet/minecraft/client/renderer/ActiveRenderInfo;Lnet/minecraft/client/renderer/GameRenderer;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/renderer/Matrix4f;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "tickLightManager", "(Lnet/minecraft/world/lighting/WorldLightManager;IZZ)V");
|
||||||
|
// 40 to 47 need to go (method call has to be wrapped)
|
||||||
|
for (var i = 0; i < 48; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
toInject.add(callback);
|
||||||
|
for (var i = 50; i < method.instructions.size(); i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WorldLightManager#enableLightSources": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.lighting.WorldLightManager",
|
||||||
|
"methodName": "func_215571_a", // enableLightSources func_215571_a
|
||||||
|
"methodDesc": "(Lnet/minecraft/util/math/ChunkPos;Z)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "enableLightSources", "(Lnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/util/math/ChunkPos;Z)V");
|
||||||
|
// load parameters
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
for (var i = 9; i <= 10; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
toInject.add(callback);
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WorldLightManager#updateSectionStatus": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.lighting.WorldLightManager",
|
||||||
|
"methodName": "func_215566_a", // updateSectionStatus func_215566_a
|
||||||
|
"methodDesc": "(Lnet/minecraft/util/math/SectionPos;Z)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "updateSectionStatus", "(Lnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/util/math/SectionPos;Z)V");
|
||||||
|
// load parameters
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
for (var i = 9; i <= 10; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
toInject.add(callback);
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WorldLightManager#setData": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.lighting.WorldLightManager",
|
||||||
|
"methodName": "func_215574_a", // setData func_215574_a
|
||||||
|
"methodDesc": "(Lnet/minecraft/world/LightType;Lnet/minecraft/util/math/SectionPos;Lnet/minecraft/world/chunk/NibbleArray;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "setData", "(Lnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/world/LightType;Lnet/minecraft/util/math/SectionPos;Lnet/minecraft/world/chunk/NibbleArray;)V");
|
||||||
|
// load parameters
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 1));
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 2));
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 3));
|
||||||
|
toInject.add(callback);
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"less unnecessary rendering": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.network.play.ClientPlayNetHandler",
|
||||||
|
// setLightData func_217284_a (IILnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/world/LightType;IILjava/util/Iterator;)V
|
||||||
|
"methodName": "func_217284_a",
|
||||||
|
"methodDesc": "(IILnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/world/LightType;IILjava/util/Iterator;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
for (var i = 0; i <= 81; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
// ignore markForRerender
|
||||||
|
for (var i = 90; i < method.instructions.size(); i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"less unnecessary rendering #2": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.network.play.ClientPlayNetHandler",
|
||||||
|
// processChunkUnload func_184326_a (Lnet/minecraft/network/play/server/SUnloadChunkPacket;)V
|
||||||
|
"methodName": "func_184326_a",
|
||||||
|
"methodDesc": "(Lnet/minecraft/network/play/server/SUnloadChunkPacket;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
for (var i = 0; i <= 42; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
// ignore markForRerender
|
||||||
|
for (var i = 51; i < method.instructions.size(); i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"less unnecessary rendering #3": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.network.play.ClientPlayNetHandler",
|
||||||
|
// handleChunkData func_147263_a (Lnet/minecraft/network/play/server/SChunkDataPacket;)V
|
||||||
|
"methodName": "func_147263_a",
|
||||||
|
"methodDesc": "(Lnet/minecraft/network/play/server/SChunkDataPacket;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
for (var i = 0; i <= 56; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
// ignore markForRerender
|
||||||
|
for (var i = 65; i < method.instructions.size(); i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
"network debugging": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.network.NetworkManager",
|
||||||
|
// exceptionCaught (Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Throwable;)V exceptionCaught
|
||||||
|
"methodName": "exceptionCaught",
|
||||||
|
"methodDesc": "(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Throwable;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 2));
|
||||||
|
toInject.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V"));
|
||||||
|
method.instructions.insert(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
"WorldLightManager#checkBlock": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.lighting.WorldLightManager",
|
||||||
|
"methodName": "func_215568_a", // checkBlock func_215568_a (Lnet/minecraft/util/math/BlockPos;)V
|
||||||
|
"methodDesc": "(Lnet/minecraft/util/math/BlockPos;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "checkBlock", "(Lnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/util/math/BlockPos;)V");
|
||||||
|
// load parameters
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 1));
|
||||||
|
toInject.add(callback);
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"queue call to onBlockEmissionIncrease": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.lighting.WorldLightManager",
|
||||||
|
// func_215573_a (Lnet/minecraft/util/math/BlockPos;I)V onBlockEmissionIncrease
|
||||||
|
"methodName": "func_215573_a",
|
||||||
|
"methodDesc": "(Lnet/minecraft/util/math/BlockPos;I)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
var callback = new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "blockEmission", "(Lnet/minecraft/world/lighting/WorldLightManager;Lnet/minecraft/util/math/BlockPos;I)V");
|
||||||
|
// load parameters
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 0));
|
||||||
|
toInject.add(new VarInsnNode(ALOAD, 1));
|
||||||
|
toInject.add(new VarInsnNode(ILOAD, 2));
|
||||||
|
toInject.add(callback);
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"World: off-thread rendering": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.world.World",
|
||||||
|
// markAndNotifyBlock(BlockPos pos, @Nullable Chunk chunk, BlockState blockstate, BlockState newState, int flags)
|
||||||
|
"methodName": "markAndNotifyBlock",
|
||||||
|
"methodDesc": "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/BlockState;Lnet/minecraft/block/BlockState;I)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
toInject.add(new VarInsnNode(ILOAD, 5));
|
||||||
|
toInject.add(new LdcInsnNode(~8));
|
||||||
|
toInject.add(new InsnNode(Opcodes.IAND));
|
||||||
|
toInject.add(new VarInsnNode(ISTORE, 5));
|
||||||
|
method.instructions.insert(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Chunk: never immediately render": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$ChunkRender",
|
||||||
|
// boolean needsImmediateUpdate()
|
||||||
|
"methodName": "func_188281_o",
|
||||||
|
"methodDesc": "()Z"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
toInject.add(new LdcInsnNode(false));
|
||||||
|
toInject.add(new InsnNode(IRETURN));
|
||||||
|
method.instructions.clear();
|
||||||
|
method.instructions.insert(toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ChunkRenderDispatcher: upload chunks slowly": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher",
|
||||||
|
// boolean runChunkUploads()
|
||||||
|
"methodName": "func_228908_d_",
|
||||||
|
"methodDesc": "()Z"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
toInject.add(new MethodInsnNode(INVOKESTATIC, "fliegendewurst/asynclighting/AsyncLighting", "uploadMore", "()Z"));
|
||||||
|
toInject.add(new JumpInsnNode(IFNE, method.instructions.get(18)));
|
||||||
|
toInject.add(new VarInsnNode(ILOAD, 1));
|
||||||
|
toInject.add(new InsnNode(IRETURN));
|
||||||
|
method.instructions.insert(method.instructions.get(17), toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Open screenshots without blocking on viewer exit": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.util.Util$OS",
|
||||||
|
// void openURL(java.net.URL)
|
||||||
|
"methodName": "func_195639_a",
|
||||||
|
"methodDesc": "(Ljava/net/URL;)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
var toInject = new InsnList();
|
||||||
|
toInject.add(new InsnNode(RETURN));
|
||||||
|
method.instructions.insert(method.instructions.get(5), toInject);
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
"SectionLightStorage synchronization": {
|
||||||
|
"target": {
|
||||||
|
"type": "CLASS",
|
||||||
|
"name": "net.minecraft.world.lighting.SectionLightStorage"
|
||||||
|
//"methodName": "func_215522_a", // updateSections func_215522_a
|
||||||
|
//"methodDesc": "(Lnet/minecraft/world/lighting/LightEngine;ZZ)V"
|
||||||
|
},
|
||||||
|
"transformer": function (clazz) {
|
||||||
|
//method.instructions.insert(new InsnNode(MONITORENTER));
|
||||||
|
//method.instructions.insert(new VarInsnNode(ALOAD, 0));
|
||||||
|
//method.instructions.add(new InsnNode(MONITOREXIT));
|
||||||
|
for (var i = 1; i < clazz.methods.size(); i++) {
|
||||||
|
var method = clazz.methods.get(i);
|
||||||
|
//if (method.name === "getLightOrDefault") {
|
||||||
|
if ((method.access & Opcodes.ACC_ABSTRACT) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.access |= Opcodes.ACC_SYNCHRONIZED;
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BlockLightStorage synchronization": {
|
||||||
|
"target": {
|
||||||
|
"type": "CLASS",
|
||||||
|
"name": "net.minecraft.world.lighting.BlockLightStorage"
|
||||||
|
},
|
||||||
|
"transformer": function (clazz) {
|
||||||
|
for (var i = 1; i < clazz.methods.size(); i++) {
|
||||||
|
var method = clazz.methods.get(i);
|
||||||
|
if ((method.access & Opcodes.ACC_ABSTRACT) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.access |= Opcodes.ACC_SYNCHRONIZED;
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SkyLightStorage synchronization": {
|
||||||
|
"target": {
|
||||||
|
"type": "CLASS",
|
||||||
|
"name": "net.minecraft.world.lighting.SkyLightStorage"
|
||||||
|
},
|
||||||
|
"transformer": function (clazz) {
|
||||||
|
for (var i = 1; i < clazz.methods.size(); i++) {
|
||||||
|
var method = clazz.methods.get(i);
|
||||||
|
if ((method.access & Opcodes.ACC_ABSTRACT) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.access |= Opcodes.ACC_SYNCHRONIZED;
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SectionDistanceGraph synchronization": {
|
||||||
|
"target": {
|
||||||
|
"type": "CLASS",
|
||||||
|
"name": "net.minecraft.util.SectionDistanceGraph"
|
||||||
|
},
|
||||||
|
"transformer": function (clazz) {
|
||||||
|
for (var i = 1; i < clazz.methods.size(); i++) {
|
||||||
|
var method = clazz.methods.get(i);
|
||||||
|
if ((method.access & Opcodes.ACC_ABSTRACT) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.access |= Opcodes.ACC_SYNCHRONIZED;
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"LevelBasedGraph synchronization": {
|
||||||
|
"target": {
|
||||||
|
"type": "CLASS",
|
||||||
|
"name": "net.minecraft.world.lighting.LevelBasedGraph"
|
||||||
|
},
|
||||||
|
"transformer": function (clazz) {
|
||||||
|
for (var i = 1; i < clazz.methods.size(); i++) {
|
||||||
|
var method = clazz.methods.get(i);
|
||||||
|
if ((method.access & Opcodes.ACC_ABSTRACT) !== 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
method.access |= Opcodes.ACC_SYNCHRONIZED;
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
"WorldRenderer modify updateChunks": {
|
||||||
|
"target": {
|
||||||
|
"type": "METHOD",
|
||||||
|
"class": "net.minecraft.client.renderer.WorldRenderer",
|
||||||
|
"methodName": "func_174967_a", // updateChunks func_174967_a
|
||||||
|
"methodDesc": "(J)V"
|
||||||
|
},
|
||||||
|
"transformer": function (method) {
|
||||||
|
return method;
|
||||||
|
printInstructions(method.instructions);
|
||||||
|
print(method.instructions.size());
|
||||||
|
var toInject = new InsnList();
|
||||||
|
for (var i = 0; i <= 97; i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
//toInject.add(new InsnNode(RETURN));
|
||||||
|
toInject.add(new LdcInsnNode(0));
|
||||||
|
toInject.add(new LdcInsnNode(1));
|
||||||
|
for (var i = 100; i < method.instructions.size(); i++) {
|
||||||
|
toInject.add(method.instructions.get(i));
|
||||||
|
}
|
||||||
|
print("done, clearing");
|
||||||
|
method.instructions.clear();
|
||||||
|
print("adding");
|
||||||
|
method.instructions.add(toInject);
|
||||||
|
//print("printing " + method.instructions.size());
|
||||||
|
//printInstructions(method.instructions);
|
||||||
|
print("done!");
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util function to print a list of instructions for debugging
|
||||||
|
*
|
||||||
|
* @param {InsnList} instructions The list of instructions to print
|
||||||
|
*/
|
||||||
|
function printInstructions(instructions) {
|
||||||
|
var arrayLength = instructions.size();
|
||||||
|
var labelNames = {
|
||||||
|
length: 0
|
||||||
|
};
|
||||||
|
for (var i = 0; i < arrayLength; ++i) {
|
||||||
|
var text = getInstructionText(instructions.get(i), labelNames);
|
||||||
|
if (text.length > 0) // Some instructions are ignored
|
||||||
|
print(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util function to get the text for an instruction
|
||||||
|
*
|
||||||
|
* @param {AbstractInsnNode} instruction The instruction to generate text for
|
||||||
|
* @param {Map<int, string>} labelNames The names of the labels in the format Map<LabelHashCode, LabelName>
|
||||||
|
*/
|
||||||
|
function getInstructionText(instruction, labelNames) {
|
||||||
|
var out = "";
|
||||||
|
if (instruction == null) {
|
||||||
|
return "null!";
|
||||||
|
}
|
||||||
|
if (instruction.getType() != 8) // LABEL
|
||||||
|
out += " "; // Nice formatting
|
||||||
|
if (instruction.getOpcode() > 0) // Labels, Frames and LineNumbers don't have opcodes
|
||||||
|
out += OPCODES[instruction.getOpcode()] + " ";
|
||||||
|
switch (instruction.getType()) {
|
||||||
|
default:
|
||||||
|
case 0: // INSN
|
||||||
|
break;
|
||||||
|
case 1: // INT_INSN
|
||||||
|
out += instruction.operand;
|
||||||
|
break;
|
||||||
|
case 2: // VAR_INSN
|
||||||
|
out += instruction.var;
|
||||||
|
break;
|
||||||
|
case 3: // TYPE_INSN
|
||||||
|
out += instruction.desc;
|
||||||
|
break;
|
||||||
|
case 4: // FIELD_INSN
|
||||||
|
out += instruction.owner + "." + instruction.name + " " + instruction.desc;
|
||||||
|
break;
|
||||||
|
case 5: // METHOD_INSN
|
||||||
|
out += instruction.owner + "." + instruction.name + " " + instruction.desc + " (" + instruction.itf + ")";
|
||||||
|
break;
|
||||||
|
case 6: // INVOKE_DYNAMIC_INSN
|
||||||
|
out += instruction.name + " " + instruction.desc;
|
||||||
|
break;
|
||||||
|
case 7: // JUMP_INSN
|
||||||
|
out += getLabelName(instruction.label, labelNames);
|
||||||
|
break;
|
||||||
|
case 8: // LABEL
|
||||||
|
out += getLabelName(instruction.getLabel(), labelNames);
|
||||||
|
break;
|
||||||
|
case 9: // LDC_INSN
|
||||||
|
out += instruction.cst;
|
||||||
|
break;
|
||||||
|
case 10: // IINC_INSN
|
||||||
|
out += instruction.var + " " + instruction.incr;
|
||||||
|
break;
|
||||||
|
case 11: // TABLESWITCH_INSN
|
||||||
|
out += instruction.min + " " + instruction.max;
|
||||||
|
out += "\n";
|
||||||
|
for (var i = 0; i < instruction.labels.length; ++i) {
|
||||||
|
out += " " + (instruction.min + i) + ": ";
|
||||||
|
out += getLabelName(instruction.labels[i], labelNames);
|
||||||
|
out += "\n";
|
||||||
|
}
|
||||||
|
out += " " + "default: " + getLabelName(instruction.dflt, labelNames);
|
||||||
|
break;
|
||||||
|
case 12: // LOOKUPSWITCH_INSN
|
||||||
|
for (var i = 0; i < instruction.labels.length; ++i) {
|
||||||
|
out += " " + instruction.keys[i] + ": ";
|
||||||
|
out += getLabelName(instruction.labels[i], labelNames);
|
||||||
|
out += "\n";
|
||||||
|
}
|
||||||
|
out += " " + "default: " + getLabelName(instruction.dflt, labelNames);
|
||||||
|
break;
|
||||||
|
case 13: // MULTIANEWARRAY_INSN
|
||||||
|
out += instruction.desc + " " + instruction.dims;
|
||||||
|
break;
|
||||||
|
case 14: // FRAME
|
||||||
|
out += "FRAME";
|
||||||
|
// Frames don't work because Nashhorn calls AbstractInsnNode#getType()
|
||||||
|
// instead of accessing FrameNode#type for the code "instruction.type"
|
||||||
|
// so there is no way to get the frame type of the FrameNode
|
||||||
|
break;
|
||||||
|
case 15: // LINENUMBER
|
||||||
|
out += "LINENUMBER ";
|
||||||
|
out += instruction.line + " " + getLabelName(instruction.start.getLabel(), labelNames);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util function to get the name for a LabelNode "instruction"
|
||||||
|
*
|
||||||
|
* @param {LabelNode} label The label to generate a name for
|
||||||
|
* @param {Map<int, string>} labelNames The names of other labels in the format Map<LabelHashCode, LabelName>
|
||||||
|
*/
|
||||||
|
function getLabelName(label, labelNames) {
|
||||||
|
var labelHashCode = label.hashCode();
|
||||||
|
var labelName = labelNames[labelHashCode];
|
||||||
|
if (labelName == undefined) {
|
||||||
|
labelName = "L" + labelNames.length;
|
||||||
|
labelNames[labelHashCode] = labelName;
|
||||||
|
++labelNames.length;
|
||||||
|
}
|
||||||
|
return labelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The names of the Java Virtual Machine opcodes. */
|
||||||
|
OPCODES = [
|
||||||
|
"NOP", // 0 (0x0)
|
||||||
|
"ACONST_NULL", // 1 (0x1)
|
||||||
|
"ICONST_M1", // 2 (0x2)
|
||||||
|
"ICONST_0", // 3 (0x3)
|
||||||
|
"ICONST_1", // 4 (0x4)
|
||||||
|
"ICONST_2", // 5 (0x5)
|
||||||
|
"ICONST_3", // 6 (0x6)
|
||||||
|
"ICONST_4", // 7 (0x7)
|
||||||
|
"ICONST_5", // 8 (0x8)
|
||||||
|
"LCONST_0", // 9 (0x9)
|
||||||
|
"LCONST_1", // 10 (0xa)
|
||||||
|
"FCONST_0", // 11 (0xb)
|
||||||
|
"FCONST_1", // 12 (0xc)
|
||||||
|
"FCONST_2", // 13 (0xd)
|
||||||
|
"DCONST_0", // 14 (0xe)
|
||||||
|
"DCONST_1", // 15 (0xf)
|
||||||
|
"BIPUSH", // 16 (0x10)
|
||||||
|
"SIPUSH", // 17 (0x11)
|
||||||
|
"LDC", // 18 (0x12)
|
||||||
|
"LDC_W", // 19 (0x13)
|
||||||
|
"LDC2_W", // 20 (0x14)
|
||||||
|
"ILOAD", // 21 (0x15)
|
||||||
|
"LLOAD", // 22 (0x16)
|
||||||
|
"FLOAD", // 23 (0x17)
|
||||||
|
"DLOAD", // 24 (0x18)
|
||||||
|
"ALOAD", // 25 (0x19)
|
||||||
|
"ILOAD_0", // 26 (0x1a)
|
||||||
|
"ILOAD_1", // 27 (0x1b)
|
||||||
|
"ILOAD_2", // 28 (0x1c)
|
||||||
|
"ILOAD_3", // 29 (0x1d)
|
||||||
|
"LLOAD_0", // 30 (0x1e)
|
||||||
|
"LLOAD_1", // 31 (0x1f)
|
||||||
|
"LLOAD_2", // 32 (0x20)
|
||||||
|
"LLOAD_3", // 33 (0x21)
|
||||||
|
"FLOAD_0", // 34 (0x22)
|
||||||
|
"FLOAD_1", // 35 (0x23)
|
||||||
|
"FLOAD_2", // 36 (0x24)
|
||||||
|
"FLOAD_3", // 37 (0x25)
|
||||||
|
"DLOAD_0", // 38 (0x26)
|
||||||
|
"DLOAD_1", // 39 (0x27)
|
||||||
|
"DLOAD_2", // 40 (0x28)
|
||||||
|
"DLOAD_3", // 41 (0x29)
|
||||||
|
"ALOAD_0", // 42 (0x2a)
|
||||||
|
"ALOAD_1", // 43 (0x2b)
|
||||||
|
"ALOAD_2", // 44 (0x2c)
|
||||||
|
"ALOAD_3", // 45 (0x2d)
|
||||||
|
"IALOAD", // 46 (0x2e)
|
||||||
|
"LALOAD", // 47 (0x2f)
|
||||||
|
"FALOAD", // 48 (0x30)
|
||||||
|
"DALOAD", // 49 (0x31)
|
||||||
|
"AALOAD", // 50 (0x32)
|
||||||
|
"BALOAD", // 51 (0x33)
|
||||||
|
"CALOAD", // 52 (0x34)
|
||||||
|
"SALOAD", // 53 (0x35)
|
||||||
|
"ISTORE", // 54 (0x36)
|
||||||
|
"LSTORE", // 55 (0x37)
|
||||||
|
"FSTORE", // 56 (0x38)
|
||||||
|
"DSTORE", // 57 (0x39)
|
||||||
|
"ASTORE", // 58 (0x3a)
|
||||||
|
"ISTORE_0", // 59 (0x3b)
|
||||||
|
"ISTORE_1", // 60 (0x3c)
|
||||||
|
"ISTORE_2", // 61 (0x3d)
|
||||||
|
"ISTORE_3", // 62 (0x3e)
|
||||||
|
"LSTORE_0", // 63 (0x3f)
|
||||||
|
"LSTORE_1", // 64 (0x40)
|
||||||
|
"LSTORE_2", // 65 (0x41)
|
||||||
|
"LSTORE_3", // 66 (0x42)
|
||||||
|
"FSTORE_0", // 67 (0x43)
|
||||||
|
"FSTORE_1", // 68 (0x44)
|
||||||
|
"FSTORE_2", // 69 (0x45)
|
||||||
|
"FSTORE_3", // 70 (0x46)
|
||||||
|
"DSTORE_0", // 71 (0x47)
|
||||||
|
"DSTORE_1", // 72 (0x48)
|
||||||
|
"DSTORE_2", // 73 (0x49)
|
||||||
|
"DSTORE_3", // 74 (0x4a)
|
||||||
|
"ASTORE_0", // 75 (0x4b)
|
||||||
|
"ASTORE_1", // 76 (0x4c)
|
||||||
|
"ASTORE_2", // 77 (0x4d)
|
||||||
|
"ASTORE_3", // 78 (0x4e)
|
||||||
|
"IASTORE", // 79 (0x4f)
|
||||||
|
"LASTORE", // 80 (0x50)
|
||||||
|
"FASTORE", // 81 (0x51)
|
||||||
|
"DASTORE", // 82 (0x52)
|
||||||
|
"AASTORE", // 83 (0x53)
|
||||||
|
"BASTORE", // 84 (0x54)
|
||||||
|
"CASTORE", // 85 (0x55)
|
||||||
|
"SASTORE", // 86 (0x56)
|
||||||
|
"POP", // 87 (0x57)
|
||||||
|
"POP2", // 88 (0x58)
|
||||||
|
"DUP", // 89 (0x59)
|
||||||
|
"DUP_X1", // 90 (0x5a)
|
||||||
|
"DUP_X2", // 91 (0x5b)
|
||||||
|
"DUP2", // 92 (0x5c)
|
||||||
|
"DUP2_X1", // 93 (0x5d)
|
||||||
|
"DUP2_X2", // 94 (0x5e)
|
||||||
|
"SWAP", // 95 (0x5f)
|
||||||
|
"IADD", // 96 (0x60)
|
||||||
|
"LADD", // 97 (0x61)
|
||||||
|
"FADD", // 98 (0x62)
|
||||||
|
"DADD", // 99 (0x63)
|
||||||
|
"ISUB", // 100 (0x64)
|
||||||
|
"LSUB", // 101 (0x65)
|
||||||
|
"FSUB", // 102 (0x66)
|
||||||
|
"DSUB", // 103 (0x67)
|
||||||
|
"IMUL", // 104 (0x68)
|
||||||
|
"LMUL", // 105 (0x69)
|
||||||
|
"FMUL", // 106 (0x6a)
|
||||||
|
"DMUL", // 107 (0x6b)
|
||||||
|
"IDIV", // 108 (0x6c)
|
||||||
|
"LDIV", // 109 (0x6d)
|
||||||
|
"FDIV", // 110 (0x6e)
|
||||||
|
"DDIV", // 111 (0x6f)
|
||||||
|
"IREM", // 112 (0x70)
|
||||||
|
"LREM", // 113 (0x71)
|
||||||
|
"FREM", // 114 (0x72)
|
||||||
|
"DREM", // 115 (0x73)
|
||||||
|
"INEG", // 116 (0x74)
|
||||||
|
"LNEG", // 117 (0x75)
|
||||||
|
"FNEG", // 118 (0x76)
|
||||||
|
"DNEG", // 119 (0x77)
|
||||||
|
"ISHL", // 120 (0x78)
|
||||||
|
"LSHL", // 121 (0x79)
|
||||||
|
"ISHR", // 122 (0x7a)
|
||||||
|
"LSHR", // 123 (0x7b)
|
||||||
|
"IUSHR", // 124 (0x7c)
|
||||||
|
"LUSHR", // 125 (0x7d)
|
||||||
|
"IAND", // 126 (0x7e)
|
||||||
|
"LAND", // 127 (0x7f)
|
||||||
|
"IOR", // 128 (0x80)
|
||||||
|
"LOR", // 129 (0x81)
|
||||||
|
"IXOR", // 130 (0x82)
|
||||||
|
"LXOR", // 131 (0x83)
|
||||||
|
"IINC", // 132 (0x84)
|
||||||
|
"I2L", // 133 (0x85)
|
||||||
|
"I2F", // 134 (0x86)
|
||||||
|
"I2D", // 135 (0x87)
|
||||||
|
"L2I", // 136 (0x88)
|
||||||
|
"L2F", // 137 (0x89)
|
||||||
|
"L2D", // 138 (0x8a)
|
||||||
|
"F2I", // 139 (0x8b)
|
||||||
|
"F2L", // 140 (0x8c)
|
||||||
|
"F2D", // 141 (0x8d)
|
||||||
|
"D2I", // 142 (0x8e)
|
||||||
|
"D2L", // 143 (0x8f)
|
||||||
|
"D2F", // 144 (0x90)
|
||||||
|
"I2B", // 145 (0x91)
|
||||||
|
"I2C", // 146 (0x92)
|
||||||
|
"I2S", // 147 (0x93)
|
||||||
|
"LCMP", // 148 (0x94)
|
||||||
|
"FCMPL", // 149 (0x95)
|
||||||
|
"FCMPG", // 150 (0x96)
|
||||||
|
"DCMPL", // 151 (0x97)
|
||||||
|
"DCMPG", // 152 (0x98)
|
||||||
|
"IFEQ", // 153 (0x99)
|
||||||
|
"IFNE", // 154 (0x9a)
|
||||||
|
"IFLT", // 155 (0x9b)
|
||||||
|
"IFGE", // 156 (0x9c)
|
||||||
|
"IFGT", // 157 (0x9d)
|
||||||
|
"IFLE", // 158 (0x9e)
|
||||||
|
"IF_ICMPEQ", // 159 (0x9f)
|
||||||
|
"IF_ICMPNE", // 160 (0xa0)
|
||||||
|
"IF_ICMPLT", // 161 (0xa1)
|
||||||
|
"IF_ICMPGE", // 162 (0xa2)
|
||||||
|
"IF_ICMPGT", // 163 (0xa3)
|
||||||
|
"IF_ICMPLE", // 164 (0xa4)
|
||||||
|
"IF_ACMPEQ", // 165 (0xa5)
|
||||||
|
"IF_ACMPNE", // 166 (0xa6)
|
||||||
|
"GOTO", // 167 (0xa7)
|
||||||
|
"JSR", // 168 (0xa8)
|
||||||
|
"RET", // 169 (0xa9)
|
||||||
|
"TABLESWITCH", // 170 (0xaa)
|
||||||
|
"LOOKUPSWITCH", // 171 (0xab)
|
||||||
|
"IRETURN", // 172 (0xac)
|
||||||
|
"LRETURN", // 173 (0xad)
|
||||||
|
"FRETURN", // 174 (0xae)
|
||||||
|
"DRETURN", // 175 (0xaf)
|
||||||
|
"ARETURN", // 176 (0xb0)
|
||||||
|
"RETURN", // 177 (0xb1)
|
||||||
|
"GETSTATIC", // 178 (0xb2)
|
||||||
|
"PUTSTATIC", // 179 (0xb3)
|
||||||
|
"GETFIELD", // 180 (0xb4)
|
||||||
|
"PUTFIELD", // 181 (0xb5)
|
||||||
|
"INVOKEVIRTUAL", // 182 (0xb6)
|
||||||
|
"INVOKESPECIAL", // 183 (0xb7)
|
||||||
|
"INVOKESTATIC", // 184 (0xb8)
|
||||||
|
"INVOKEINTERFACE", // 185 (0xb9)
|
||||||
|
"INVOKEDYNAMIC", // 186 (0xba)
|
||||||
|
"NEW", // 187 (0xbb)
|
||||||
|
"NEWARRAY", // 188 (0xbc)
|
||||||
|
"ANEWARRAY", // 189 (0xbd)
|
||||||
|
"ARRAYLENGTH", // 190 (0xbe)
|
||||||
|
"ATHROW", // 191 (0xbf)
|
||||||
|
"CHECKCAST", // 192 (0xc0)
|
||||||
|
"INSTANCEOF", // 193 (0xc1)
|
||||||
|
"MONITORENTER", // 194 (0xc2)
|
||||||
|
"MONITOREXIT", // 195 (0xc3)
|
||||||
|
"WIDE", // 196 (0xc4)
|
||||||
|
"MULTIANEWARRAY", // 197 (0xc5)
|
||||||
|
"IFNULL", // 198 (0xc6)
|
||||||
|
"IFNONNULL" // 199 (0xc7)
|
||||||
|
];
|
6
src/main/resources/pack.mcmeta
Normal file
6
src/main/resources/pack.mcmeta
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": "asynclighting resources",
|
||||||
|
"pack_format": 5
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user