├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src ├── debug ├── java │ └── org │ │ └── dimdev │ │ └── testmod │ │ ├── CPacketTest.java │ │ ├── ChangeDimensionCommand.java │ │ ├── ExplosionCommand.java │ │ ├── ItemPacketTester.java │ │ ├── TestMessage.java │ │ ├── TestMod.java │ │ └── WhiteFluid.java └── resources │ ├── assets │ └── testmod │ │ ├── blockstates │ │ ├── translucent_white_block.json │ │ ├── white_block.json │ │ └── white_fluid.json │ │ ├── lang │ │ └── en_us.json │ │ ├── models │ │ ├── block │ │ │ ├── translucent_white_block.json │ │ │ ├── white_block.json │ │ │ └── white_fluid.json │ │ └── item │ │ │ ├── translucent_white_block.json │ │ │ └── white_block.json │ │ └── textures │ │ └── block │ │ ├── translucent_white_block.png │ │ ├── white_block.png │ │ ├── white_fluid_flow.png │ │ └── white_fluid_still.png │ ├── data │ └── minecraft │ │ └── tags │ │ └── fluids │ │ └── water.json │ ├── pack.mcmeta │ └── riftmod.json └── main ├── java └── org │ └── dimdev │ ├── accesstransform │ ├── AccessLevel.java │ ├── AccessTransformationSet.java │ ├── AccessTransformer.java │ └── ElementReference.java │ ├── rift │ ├── Rift.java │ ├── injectedmethods │ │ ├── RiftCPacketCustomPayload.java │ │ └── RiftFluid.java │ ├── listener │ │ ├── ArgumentTypeAdder.java │ │ ├── BiomeAdder.java │ │ ├── BlockAdder.java │ │ ├── BootstrapListener.java │ │ ├── BurnTimeProvider.java │ │ ├── ChunkEventListener.java │ │ ├── ChunkGeneratorReplacer.java │ │ ├── CommandAdder.java │ │ ├── CustomPayloadHandler.java │ │ ├── DataPackFinderAdder.java │ │ ├── DimensionTypeAdder.java │ │ ├── DispenserBehaviorAdder.java │ │ ├── EnchantmentAdder.java │ │ ├── EntityTypeAdder.java │ │ ├── FluidAdder.java │ │ ├── ItemAdder.java │ │ ├── MessageAdder.java │ │ ├── MinecraftStartListener.java │ │ ├── MobEffectAdder.java │ │ ├── PacketAdder.java │ │ ├── ParticleTypeAdder.java │ │ ├── RecipeAdder.java │ │ ├── RecipeSerializerAdder.java │ │ ├── ResourcePackFinderAdder.java │ │ ├── ServerTickable.java │ │ ├── SoundAdder.java │ │ ├── StructureAdder.java │ │ ├── TileEntityTypeAdder.java │ │ ├── ToolEfficiencyProvider.java │ │ ├── WorldChanger.java │ │ └── client │ │ │ ├── AmbientMusicTypeProvider.java │ │ │ ├── ClientTickable.java │ │ │ ├── EntityRendererAdder.java │ │ │ ├── GameGuiAdder.java │ │ │ ├── KeyBindingAdder.java │ │ │ ├── KeybindHandler.java │ │ │ ├── OverlayRenderer.java │ │ │ ├── TextureAdder.java │ │ │ └── TileEntityRendererAdder.java │ ├── mixin │ │ ├── core │ │ │ ├── MixinMinecraftServer.java │ │ │ ├── MixinVanillaPack.java │ │ │ └── client │ │ │ │ ├── MixinBlockFluidRenderer.java │ │ │ │ ├── MixinClientBrandRetriever.java │ │ │ │ ├── MixinLavaFluid.java │ │ │ │ ├── MixinLayerArmorBase.java │ │ │ │ └── MixinWaterFluid.java │ │ └── hook │ │ │ ├── MixinAnvilSaveHandler.java │ │ │ ├── MixinArgumentTypes.java │ │ │ ├── MixinBiome.java │ │ │ ├── MixinBlock.java │ │ │ ├── MixinBootstrap.java │ │ │ ├── MixinCPacketCustomPayload.java │ │ │ ├── MixinChunk.java │ │ │ ├── MixinCommands.java │ │ │ ├── MixinDimensionType.java │ │ │ ├── MixinEnchantment.java │ │ │ ├── MixinEntityType.java │ │ │ ├── MixinEnumConnectionState.java │ │ │ ├── MixinFeature.java │ │ │ ├── MixinFluid.java │ │ │ ├── MixinFurnace.java │ │ │ ├── MixinItem.java │ │ │ ├── MixinItemTool.java │ │ │ ├── MixinMinecraftServer.java │ │ │ ├── MixinNetHandlerPlayServer.java │ │ │ ├── MixinOverworldBiomeProvider.java │ │ │ ├── MixinParticleType.java │ │ │ ├── MixinPotion.java │ │ │ ├── MixinRecipeManager.java │ │ │ ├── MixinRecipeSerializers.java │ │ │ ├── MixinSoundEvent.java │ │ │ ├── MixinStructureIO.java │ │ │ ├── MixinTileEntityType.java │ │ │ ├── MixinWorldServer.java │ │ │ └── client │ │ │ ├── MixinEntityPlayerSP.java │ │ │ ├── MixinGameSettings.java │ │ │ ├── MixinGuiIngame.java │ │ │ ├── MixinIntegratedServer.java │ │ │ ├── MixinMinecraft.java │ │ │ ├── MixinModelBakery.java │ │ │ ├── MixinNetHandlerPlayClient.java │ │ │ ├── MixinRenderManager.java │ │ │ └── MixinTileEntityRendererDispatcher.java │ ├── network │ │ ├── ClientMessageContext.java │ │ ├── Message.java │ │ ├── MessageContext.java │ │ ├── MessageRegistrator.java │ │ └── ServerMessageContext.java │ ├── resources │ │ ├── ModPack.java │ │ ├── ModPackFinder.java │ │ └── ResourceManager.java │ └── util │ │ ├── ArmorMaterialImpl.java │ │ ├── ItemTierImpl.java │ │ ├── NBTSerializable.java │ │ └── NBTSerializer.java │ ├── riftloader │ ├── DuplicateModException.java │ ├── Main.java │ ├── ModInfo.java │ ├── OptifineLoader.java │ ├── RiftAccessTransformer.java │ ├── RiftLoader.java │ ├── Side.java │ ├── launch │ │ ├── RiftLoaderClientTweaker.java │ │ ├── RiftLoaderServerTweaker.java │ │ └── RiftLoaderTweaker.java │ └── listener │ │ ├── InitializationListener.java │ │ └── Instantiator.java │ └── utils │ ├── InstanceListMap.java │ ├── InstanceMap.java │ └── ReflectionUtils.java └── resources ├── access_transformations.at ├── mixins.rift.core.json ├── mixins.rift.hooks.json ├── profile.json └── riftmod.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | eclipse 3 | bin 4 | *.launch 5 | .settings 6 | .metadata 7 | .classpath 8 | .project 9 | 10 | # idea 11 | out 12 | classes 13 | *.ipr 14 | *.iws 15 | *.iml 16 | .idea 17 | 18 | # gradle 19 | build 20 | .gradle 21 | 22 | #Netbeans 23 | .nb-gradle 24 | .nb-gradle-properties 25 | 26 | # other 27 | run 28 | .DS_Store 29 | Thumbs.db 30 | .gradletasknamecache -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: oraclejdk8 3 | 4 | if: tag IS blank 5 | git: 6 | depth: 5 7 | 8 | install: ./gradlew setupCIWorkspace 9 | script: ./gradlew clean build 10 | after_success: ./gradlew publish 11 | 12 | before_cache: find $HOME/.gradle/ -name '*.lock' -print -exec rm -f {} \; 13 | cache: 14 | directories: 15 | - $HOME/.gradle/caches/ 16 | - $HOME/.gradle/wrapper/ 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dimensional Development 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | maven { url 'https://www.dimdev.org/maven/' } 5 | maven { url 'http://repo.spongepowered.org/maven' } 6 | maven { url 'https://plugins.gradle.org/m2/' } 7 | } 8 | dependencies { 9 | classpath 'org.dimdev:ForgeGradle:2.3-SNAPSHOT' 10 | classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT' 11 | classpath 'gradle.plugin.com.github.breadmoirai:github-release:2.0.1' 12 | } 13 | } 14 | 15 | apply plugin: 'net.minecraftforge.gradle.tweaker-client' 16 | apply plugin: 'java' 17 | apply plugin: 'org.spongepowered.mixin' 18 | apply plugin: 'maven-publish' 19 | apply plugin: 'com.github.breadmoirai.github-release' 20 | 21 | def travisBuildNumber = System.getenv('TRAVIS_BUILD_NUMBER') 22 | def versionSuffix = travisBuildNumber != null ? travisBuildNumber : 'SNAPSHOT' 23 | 24 | group 'org.dimdev' 25 | version '1.0.4-' + versionSuffix 26 | archivesBaseName = 'Rift' 27 | 28 | sourceCompatibility = 1.8 29 | targetCompatibility = 1.8 30 | 31 | repositories { 32 | mavenCentral() 33 | maven { url 'https://libraries.minecraft.net/' } 34 | maven { url 'https://www.dimdev.org/maven/' } 35 | maven { url = 'https://repo.spongepowered.org/maven/' } 36 | } 37 | 38 | dependencies { 39 | implementation('org.dimdev:mixin:0.7.11-SNAPSHOT') { transitive = false } 40 | implementation('net.minecraft:launchwrapper:1.12') { transitive = false } 41 | implementation 'org.ow2.asm:asm:6.2' 42 | implementation 'org.ow2.asm:asm-commons:6.2' 43 | } 44 | 45 | minecraft { 46 | version = '1.13' 47 | mappings = 'snapshot_20180908' 48 | runDir = 'run' 49 | tweakClass = 'org.dimdev.riftloader.launch.RiftLoaderClientTweaker' 50 | makeObfSourceJar = false 51 | 52 | replace "@VERSION@", project.version 53 | replaceIn "org/dimdev/riftloader/Main.java" 54 | } 55 | 56 | mixin { 57 | defaultObfuscationEnv notch 58 | add sourceSets.main, 'mixins.rift.refmap.json' 59 | } 60 | 61 | sourceSets { 62 | main 63 | debug { 64 | compileClasspath += main.compileClasspath 65 | } 66 | } 67 | 68 | processResources { 69 | filesMatching('profile.json') { 70 | expand 'version': project.version 71 | } 72 | 73 | // Re-run this task when these change 74 | inputs.property "version", project.version 75 | inputs.property "mcversion", project.minecraft.version 76 | } 77 | 78 | jar { 79 | finalizedBy reobfJar 80 | manifest.attributes( 81 | 'Main-Class': 'org.dimdev.riftloader.Main' 82 | ) 83 | } 84 | 85 | task devJar(type: Jar, dependsOn: classes) { 86 | classifier 'dev' 87 | from sourceSets.main.output 88 | } 89 | 90 | task sourcesJar(type: Jar, dependsOn: classes) { 91 | classifier 'sources' 92 | from sourceSets.main.allSource 93 | } 94 | 95 | artifacts { 96 | archives jar 97 | archives devJar 98 | archives sourcesJar 99 | } 100 | 101 | publishing { 102 | repositories { 103 | maven { url "$buildDir/repo/" } 104 | maven { 105 | url 'sftp://www.dimdev.org:22/data/www/html/maven/' 106 | credentials { 107 | username 'www' 108 | password System.getenv('dimdev_maven_password') 109 | } 110 | } 111 | } 112 | 113 | publications { 114 | mavenJava(MavenPublication) { 115 | artifactId = 'rift' 116 | 117 | from components.java 118 | artifact devJar 119 | artifact sourcesJar 120 | } 121 | } 122 | } 123 | 124 | tasks.publish.dependsOn(tasks.githubRelease) 125 | githubRelease { 126 | token = System.getenv('dimdev_repo_token') 127 | owner = 'DimensionalDevelopment' 128 | repo = 'Rift' 129 | targetCommitish = 'master' 130 | prerelease = true 131 | releaseAssets = jar.destinationDir.listFiles() 132 | } 133 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DimensionalDevelopment/Rift/dfc75ff7254cbbea81535c02ddc5252e384ac806/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip 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 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/CPacketTest.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import net.minecraft.network.Packet; 4 | import net.minecraft.network.PacketBuffer; 5 | import net.minecraft.network.play.INetHandlerPlayServer; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | public class CPacketTest implements Packet { 10 | private static final Logger log = LogManager.getLogger(); 11 | private int data; 12 | 13 | public CPacketTest() {} 14 | 15 | public CPacketTest(int data) { 16 | this.data = data; 17 | } 18 | 19 | @Override 20 | public void readPacketData(PacketBuffer buf) { 21 | data = buf.readVarInt(); 22 | } 23 | 24 | @Override 25 | public void writePacketData(PacketBuffer buf) { 26 | buf.writeVarInt(data); 27 | } 28 | 29 | @Override 30 | public void processPacket(INetHandlerPlayServer handler) { 31 | log.info("Server received test packet: " + data); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/ChangeDimensionCommand.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.arguments.ArgumentType; 5 | import com.mojang.brigadier.arguments.IntegerArgumentType; 6 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 7 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 8 | import net.minecraft.command.CommandSource; 9 | import net.minecraft.entity.Entity; 10 | 11 | public class ChangeDimensionCommand { 12 | public static void register(CommandDispatcher dispatcher) { 13 | LiteralArgumentBuilder builder = literalArgument("changedimension") 14 | .then(requiredArgument("dimension", IntegerArgumentType.integer(0)) 15 | .executes(context -> { 16 | Entity entity = context.getSource().getEntity(); 17 | entity.changeDimension(context.getArgument("dimension", Integer.class)); 18 | return 0; 19 | })); 20 | dispatcher.register(builder); 21 | } 22 | 23 | private static LiteralArgumentBuilder literalArgument(String name) { 24 | return LiteralArgumentBuilder.literal(name); 25 | } 26 | 27 | private static RequiredArgumentBuilder requiredArgument(String name, ArgumentType type) { 28 | return RequiredArgumentBuilder.argument(name, type); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/ExplosionCommand.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import com.mojang.brigadier.arguments.ArgumentType; 5 | import com.mojang.brigadier.arguments.BoolArgumentType; 6 | import com.mojang.brigadier.arguments.IntegerArgumentType; 7 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 8 | import com.mojang.brigadier.builder.RequiredArgumentBuilder; 9 | import net.minecraft.command.CommandSource; 10 | import net.minecraft.entity.Entity; 11 | 12 | public class ExplosionCommand { 13 | public static void register(CommandDispatcher dispatcher) { 14 | LiteralArgumentBuilder builder = literalArgument("explosion") 15 | .executes(context -> { 16 | Entity entity = context.getSource().getEntity(); 17 | entity.world.newExplosion(null, entity.posX, entity.posY, entity.posZ, 1, true, true); 18 | return 0; 19 | }) 20 | .then(requiredArgument("strength", IntegerArgumentType.integer(0)) 21 | .executes(context -> { 22 | Entity entity = context.getSource().getEntity(); 23 | entity.world.newExplosion(null, entity.posX, entity.posY, entity.posZ, context.getArgument("strength", Integer.class), true, true); 24 | return 0; 25 | }) 26 | .then(requiredArgument("causesFire", BoolArgumentType.bool()) 27 | .executes(context -> { 28 | Entity entity = context.getSource().getEntity(); 29 | entity.world.newExplosion(null, entity.posX, entity.posY, entity.posZ, context.getArgument("strength", Integer.class), context.getArgument("causesFire", Boolean.class), true); 30 | return 0; 31 | }))); 32 | dispatcher.register(builder); 33 | } 34 | 35 | private static LiteralArgumentBuilder literalArgument(String name) { 36 | return LiteralArgumentBuilder.literal(name); 37 | } 38 | 39 | private static RequiredArgumentBuilder requiredArgument(String name, ArgumentType type) { 40 | return RequiredArgumentBuilder.argument(name, type); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/ItemPacketTester.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.item.Item; 5 | import net.minecraft.item.ItemUseContext; 6 | import net.minecraft.util.EnumActionResult; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | public class ItemPacketTester extends Item { 11 | private static final Logger log = LogManager.getLogger(); 12 | 13 | public ItemPacketTester(Builder builder) { 14 | super(builder); 15 | } 16 | 17 | @Override 18 | public EnumActionResult onItemUse(ItemUseContext context) { 19 | if (context.getWorld().isRemote) { 20 | return EnumActionResult.SUCCESS; 21 | } 22 | 23 | int data = (int) (Math.random() * 1000); 24 | log.info("Sending test packet and message to server: " + data); 25 | Minecraft.getMinecraft().getConnection().sendPacket(new CPacketTest(data)); 26 | 27 | new TestMessage(data).sendToServer(); 28 | 29 | return EnumActionResult.SUCCESS; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/TestMessage.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import net.minecraft.network.PacketBuffer; 4 | import org.dimdev.rift.network.ClientMessageContext; 5 | import org.dimdev.rift.network.Message; 6 | import org.dimdev.rift.network.ServerMessageContext; 7 | 8 | public class TestMessage extends Message { 9 | public int data; 10 | 11 | public TestMessage() {} 12 | 13 | public TestMessage(int data) { 14 | this.data = data; 15 | } 16 | 17 | @Override 18 | public void write(PacketBuffer buffer) { 19 | buffer.writeVarInt(data); 20 | } 21 | 22 | @Override 23 | public void read(PacketBuffer buffer) { 24 | data = buffer.readVarInt(); 25 | } 26 | 27 | @Override 28 | public void process(ClientMessageContext context) { 29 | System.out.println("Received message on client: " + data); 30 | 31 | if (Math.random() < 0.5) { 32 | context.reply(new TestMessage(data + 1)); 33 | } 34 | } 35 | 36 | @Override 37 | public void process(ServerMessageContext context) { 38 | System.out.println("Received message on server: " + data); 39 | 40 | if (Math.random() < 0.5) { 41 | context.reply(new TestMessage(data + 1)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/TestMod.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.BlockFlowingFluid; 6 | import net.minecraft.block.BlockStainedGlass; 7 | import net.minecraft.block.material.Material; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.audio.MusicTicker; 10 | import net.minecraft.command.CommandSource; 11 | import net.minecraft.fluid.FlowingFluid; 12 | import net.minecraft.fluid.Fluid; 13 | import net.minecraft.item.EnumDyeColor; 14 | import net.minecraft.item.Item; 15 | import net.minecraft.item.ItemGroup; 16 | import net.minecraft.network.EnumPacketDirection; 17 | import net.minecraft.util.ResourceLocation; 18 | import net.minecraft.util.registry.RegistryNamespaced; 19 | import net.minecraft.world.dimension.DimensionType; 20 | import net.minecraft.world.dimension.EndDimension; 21 | import org.apache.logging.log4j.LogManager; 22 | import org.apache.logging.log4j.Logger; 23 | import org.dimdev.rift.listener.*; 24 | import org.dimdev.rift.listener.client.AmbientMusicTypeProvider; 25 | import org.dimdev.rift.listener.client.ClientTickable; 26 | import org.dimdev.rift.listener.client.TextureAdder; 27 | import org.dimdev.rift.network.Message; 28 | 29 | import java.util.Collection; 30 | import java.util.Collections; 31 | import java.util.Set; 32 | 33 | import static net.minecraft.init.SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP; 34 | 35 | public class TestMod implements BlockAdder, ItemAdder, FluidAdder, TextureAdder, PacketAdder, CommandAdder, ClientTickable, /*AmbientMusicTypeProvider,*/ DimensionTypeAdder, MessageAdder { 36 | private static final Logger LOGGER = LogManager.getLogger(); 37 | public static final Block WHITE_BLOCK = new Block(Block.Builder.create(Material.ROCK)); 38 | public static final Block TRANSLUCENT_WHITE_BLOCK = new BlockStainedGlass(EnumDyeColor.WHITE, Block.Builder.create(Material.GLASS)); 39 | public static final FlowingFluid WHITE_FLUID = new WhiteFluid.Source(); 40 | public static final FlowingFluid FLOWING_WHITE_FLUID = new WhiteFluid.Flowing(); 41 | public static final BlockFlowingFluid BLOCK_WHITE_FLUID = new BlockFlowingFluid(WHITE_FLUID, Block.Builder.create(Material.WATER).doesNotBlockMovement().hardnessAndResistance(100F, 100F).variableOpacity()); 42 | public static final Item PACKET_TESTER = new ItemPacketTester(new Item.Builder()); 43 | public static final MusicTicker.MusicType TEST_MUSIC = AmbientMusicTypeProvider.newMusicType("test", ENTITY_EXPERIENCE_ORB_PICKUP, 0, 0); 44 | private int clientTickCount = 0; 45 | 46 | @Override 47 | public void registerBlocks() { 48 | Block.register(new ResourceLocation("testmod", "white_block"), WHITE_BLOCK); 49 | Block.register(new ResourceLocation("testmod", "translucent_white_block"), TRANSLUCENT_WHITE_BLOCK); 50 | Block.register(new ResourceLocation("testmod", "white_fluid"), BLOCK_WHITE_FLUID); 51 | } 52 | 53 | @Override 54 | public void registerItems() { 55 | Item.registerItemBlock(WHITE_BLOCK, ItemGroup.BUILDING_BLOCKS); 56 | Item.registerItemBlock(TRANSLUCENT_WHITE_BLOCK, ItemGroup.BUILDING_BLOCKS); 57 | Item.registerItem(new ResourceLocation("testmod", "packet_tester"), PACKET_TESTER); 58 | } 59 | 60 | @Override 61 | public void registerFluids() { 62 | Fluid.register(new ResourceLocation("testmod", "white_fluid"), WHITE_FLUID); 63 | Fluid.register(new ResourceLocation("testmod", "flowing_white_fluid"), FLOWING_WHITE_FLUID); 64 | } 65 | 66 | @Override 67 | public Collection getBuiltinTextures() { 68 | return Collections.singletonList(new ResourceLocation("testmod", "block/white_fluid_flow")); 69 | } 70 | 71 | @Override 72 | public void registerHandshakingPackets(PacketRegistrationReceiver receiver) {} 73 | 74 | @Override 75 | public void registerPlayPackets(PacketRegistrationReceiver receiver) { 76 | receiver.registerPacket(EnumPacketDirection.SERVERBOUND, CPacketTest.class); 77 | } 78 | 79 | @Override 80 | public void registerStatusPackets(PacketRegistrationReceiver receiver) {} 81 | 82 | @Override 83 | public void registerLoginPackets(PacketRegistrationReceiver receiver) {} 84 | 85 | @Override 86 | public void registerCommands(CommandDispatcher dispatcher) { 87 | ExplosionCommand.register(dispatcher); 88 | ChangeDimensionCommand.register(dispatcher); 89 | } 90 | 91 | @Override 92 | public void clientTick() { 93 | if (clientTickCount++ == 100) { 94 | LOGGER.info("100 ticks have passed"); 95 | } 96 | } 97 | 98 | // @Override 99 | public MusicTicker.MusicType getAmbientMusicType(Minecraft client) { 100 | return TEST_MUSIC; 101 | } 102 | 103 | @Override 104 | public Set getDimensionTypes() { 105 | return Collections.singleton(DimensionTypeAdder.newDimensionType(555, "test_dimension", "_test", EndDimension::new)); 106 | } 107 | 108 | @Override 109 | public void registerMessages(RegistryNamespaced> registry) { 110 | registry.putObject(new ResourceLocation("testmod", "test_message"), TestMessage.class); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/debug/java/org/dimdev/testmod/WhiteFluid.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.testmod; 2 | 3 | import net.minecraft.block.BlockFlowingFluid; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 7 | import net.minecraft.fluid.FlowingFluid; 8 | import net.minecraft.fluid.Fluid; 9 | import net.minecraft.fluid.IFluidState; 10 | import net.minecraft.init.Items; 11 | import net.minecraft.init.Particles; 12 | import net.minecraft.item.Item; 13 | import net.minecraft.particles.IParticleData; 14 | import net.minecraft.state.StateContainer; 15 | import net.minecraft.util.BlockRenderLayer; 16 | import net.minecraft.util.EnumFacing; 17 | import net.minecraft.util.ResourceLocation; 18 | import net.minecraft.util.math.BlockPos; 19 | import net.minecraft.util.math.MathHelper; 20 | import net.minecraft.world.IWorld; 21 | import net.minecraft.world.IWorldReader; 22 | import net.minecraft.world.IWorldReaderBase; 23 | import net.minecraft.world.World; 24 | import org.dimdev.rift.injectedmethods.RiftFluid; 25 | 26 | import javax.annotation.Nullable; 27 | import java.util.Random; 28 | 29 | public abstract class WhiteFluid extends FlowingFluid implements RiftFluid { 30 | public WhiteFluid() {} 31 | 32 | @Override 33 | public Fluid getFlowingFluid() { 34 | return TestMod.FLOWING_WHITE_FLUID; 35 | } 36 | 37 | @Override 38 | public Fluid getStillFluid() { 39 | return TestMod.WHITE_FLUID; 40 | } 41 | 42 | @Override 43 | public BlockRenderLayer getRenderLayer() { 44 | return BlockRenderLayer.SOLID; 45 | } 46 | 47 | @Override 48 | public Item getFilledBucket() { 49 | return Items.WATER_BUCKET; 50 | } 51 | 52 | @Override 53 | public void randomDisplayTick(World world, BlockPos pos, IFluidState state, Random random) {} 54 | 55 | @Override @Nullable 56 | public IParticleData getDripParticleData() { 57 | return Particles.DRIPPING_WATER; 58 | } 59 | 60 | @Override 61 | protected boolean canSourcesMultiply() { 62 | return true; 63 | } 64 | 65 | @Override 66 | protected void beforeReplacingBlock(IWorld world, BlockPos pos, IBlockState state) { 67 | state.dropBlockAsItem(world.getWorld(), pos, 0); 68 | } 69 | 70 | @Override 71 | public int getSlopeFindDistance(IWorldReaderBase worldIn) { 72 | return 4; 73 | } 74 | 75 | @Override 76 | public IBlockState getBlockState(IFluidState state) { 77 | return TestMod.BLOCK_WHITE_FLUID.getDefaultState().withProperty(BlockFlowingFluid.LEVEL, getLevelFromState(state)); 78 | } 79 | 80 | @Override 81 | public boolean isSameAs(Fluid fluid) { 82 | return fluid == TestMod.WHITE_FLUID || fluid == TestMod.FLOWING_WHITE_FLUID; 83 | } 84 | 85 | @Override 86 | public int getLevelDecreasePerBlock(IWorldReaderBase world) { 87 | return 1; 88 | } 89 | 90 | @Override 91 | public int getTickRate(IWorldReaderBase world) { 92 | return 5; 93 | } 94 | 95 | @Override 96 | public boolean canOtherFlowInto(IFluidState state, Fluid fluid, EnumFacing direction) { 97 | return false; 98 | } 99 | 100 | @Override 101 | protected float getExplosionResistance() { 102 | return 100.0F; 103 | } 104 | 105 | @Override 106 | public TextureAtlasSprite getStillTexture() { 107 | return Minecraft.getMinecraft().getModelManager().getBlockModelShapes().getModelForState(TestMod.BLOCK_WHITE_FLUID.getDefaultState()).getParticleTexture(); 108 | } 109 | 110 | @Override 111 | public TextureAtlasSprite getFlowingTexture() { 112 | return Minecraft.getMinecraft().getTextureMapBlocks().getSprite(new ResourceLocation("testmod", "block/white_fluid_flow")); 113 | } 114 | 115 | @Override 116 | public int getColorMultiplier(IWorldReader world, BlockPos pos) { 117 | int brightness = (int) MathHelper.clamp(255 * ((pos.getY() - 50) / 20.0), 0, 255); 118 | return (brightness << 16) + (brightness << 8) + brightness; 119 | } 120 | 121 | public static class Flowing extends WhiteFluid { 122 | public Flowing() {} 123 | 124 | @Override 125 | protected void buildStateContainer(StateContainer.Builder builder) { 126 | super.buildStateContainer(builder); 127 | builder.add(LEVEL_1_TO_8); 128 | } 129 | 130 | @Override 131 | public int getLevel(IFluidState getLevel) { 132 | return getLevel.getValue(LEVEL_1_TO_8); 133 | } 134 | 135 | @Override 136 | public boolean isSource(IFluidState state) { 137 | return false; 138 | } 139 | } 140 | 141 | public static class Source extends WhiteFluid { 142 | public Source() {} 143 | 144 | @Override 145 | public int getLevel(IFluidState getLevel) { 146 | return 8; 147 | } 148 | 149 | @Override 150 | public boolean isSource(IFluidState state) { 151 | return true; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/blockstates/translucent_white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "testmod:block/translucent_white_block" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/blockstates/white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "testmod:block/white_block" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/blockstates/white_fluid.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { "model": "testmod:block/white_fluid" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "block.testmod.white_block": "White Block", 3 | "block.testmod.translucent_white_block": "Translucent White Block", 4 | "item.testmod.white_block": "White Block", 5 | "item.testmod.translucent_white_block": "Translucent White Block" 6 | } 7 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/models/block/translucent_white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "testmod:block/translucent_white_block" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/models/block/white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "testmod:block/white_block" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/models/block/white_fluid.json: -------------------------------------------------------------------------------- 1 | { 2 | "textures": { 3 | "particle": "testmod:block/white_fluid_still" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/models/item/translucent_white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "testmod:block/translucent_white_block" 3 | } 4 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/models/item/white_block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "testmod:block/white_block" 3 | } 4 | -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/textures/block/translucent_white_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DimensionalDevelopment/Rift/dfc75ff7254cbbea81535c02ddc5252e384ac806/src/debug/resources/assets/testmod/textures/block/translucent_white_block.png -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/textures/block/white_block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DimensionalDevelopment/Rift/dfc75ff7254cbbea81535c02ddc5252e384ac806/src/debug/resources/assets/testmod/textures/block/white_block.png -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/textures/block/white_fluid_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DimensionalDevelopment/Rift/dfc75ff7254cbbea81535c02ddc5252e384ac806/src/debug/resources/assets/testmod/textures/block/white_fluid_flow.png -------------------------------------------------------------------------------- /src/debug/resources/assets/testmod/textures/block/white_fluid_still.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DimensionalDevelopment/Rift/dfc75ff7254cbbea81535c02ddc5252e384ac806/src/debug/resources/assets/testmod/textures/block/white_fluid_still.png -------------------------------------------------------------------------------- /src/debug/resources/data/minecraft/tags/fluids/water.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "testmod:white_fluid", 5 | "testmod:flowing_white_fluid" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /src/debug/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 4, 4 | "description": "Test Mod" 5 | } 6 | } -------------------------------------------------------------------------------- /src/debug/resources/riftmod.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "testmod", 3 | "name": "TestMod", 4 | "authors": [ 5 | "Runemoro" 6 | ], 7 | "listeners": [ 8 | "org.dimdev.testmod.TestMod" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/accesstransform/AccessLevel.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.accesstransform; 2 | 3 | import java.util.Locale; 4 | 5 | public class AccessLevel { 6 | public enum Visibility { 7 | PRIVATE, 8 | DEFAULT, 9 | PROTECTED, 10 | PUBLIC 11 | } 12 | 13 | public final Visibility visibility; 14 | public final boolean isFinal; 15 | 16 | public AccessLevel(Visibility visibility, boolean isFinal) { 17 | this.visibility = visibility; 18 | this.isFinal = isFinal; 19 | } 20 | 21 | public static AccessLevel union(AccessLevel first, AccessLevel second) { 22 | if (first == null) { 23 | return second; 24 | } else if (second == null) { 25 | return first; 26 | } 27 | 28 | Visibility visibility = first.visibility.ordinal() < second.visibility.ordinal() ? second.visibility : first.visibility; 29 | boolean isFinal = first.isFinal && second.isFinal; 30 | 31 | return new AccessLevel(visibility, isFinal); 32 | } 33 | 34 | public static AccessLevel fromString(String string) { 35 | string = string.toUpperCase(Locale.ROOT); 36 | boolean isFinal = true; 37 | if (string.endsWith("-F")) { 38 | isFinal = false; 39 | string = string.substring(0, string.length() - 2); 40 | } 41 | 42 | return new AccessLevel(Visibility.valueOf(string), isFinal); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/accesstransform/AccessTransformationSet.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.accesstransform; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | public class AccessTransformationSet { 9 | private final Map transformations = new HashMap<>(); 10 | private final Set affectedClasses = new HashSet<>(); 11 | 12 | public void addMimimumAccessLevel(ElementReference elementReference, AccessLevel accessLevel) { 13 | transformations.put(elementReference, AccessLevel.union(transformations.get(elementReference), accessLevel)); 14 | affectedClasses.add(elementReference.kind == ElementReference.Kind.CLASS ? elementReference.name : elementReference.owner); 15 | } 16 | 17 | public void addMinimumAccessLevel(String string) { 18 | string = string.trim(); 19 | if(string.isEmpty() || string.startsWith("#")) return; 20 | int indexOfFirstSpace = string.indexOf(' '); 21 | String accessLevel = string.substring(0, indexOfFirstSpace); 22 | String elementReference = string.substring(indexOfFirstSpace + 1); 23 | 24 | addMimimumAccessLevel(ElementReference.fromString(elementReference), AccessLevel.fromString(accessLevel)); 25 | } 26 | 27 | public AccessLevel getMinimumAccessLevel(ElementReference elementReference) { 28 | return transformations.get(elementReference); 29 | } 30 | 31 | public boolean isClassAffected(String name) { 32 | return affectedClasses.contains(name); 33 | } 34 | 35 | public boolean isEmpty() { 36 | return transformations.size() == 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/accesstransform/AccessTransformer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.accesstransform; 2 | 3 | 4 | import org.objectweb.asm.ClassReader; 5 | import org.objectweb.asm.ClassWriter; 6 | import org.objectweb.asm.Opcodes; 7 | import org.objectweb.asm.tree.ClassNode; 8 | import org.objectweb.asm.tree.FieldNode; 9 | import org.objectweb.asm.tree.MethodNode; 10 | 11 | public class AccessTransformer { 12 | private final AccessTransformationSet transformations; 13 | 14 | public AccessTransformer(AccessTransformationSet transformations) { 15 | this.transformations = transformations; 16 | } 17 | 18 | public byte[] transformClass(String name, byte[] bytes) { 19 | if (bytes == null || !transformations.isClassAffected(name)) { 20 | return bytes; 21 | } 22 | 23 | ClassNode clazz = new ClassNode(); 24 | ClassReader reader = new ClassReader(bytes); 25 | reader.accept(clazz, 0); 26 | 27 | // Transform class access level 28 | clazz.access = getNewAccessLevel(new ElementReference(ElementReference.Kind.CLASS, null, name, null), clazz.access); 29 | 30 | for (FieldNode field : clazz.fields) { 31 | field.access = getNewAccessLevel(new ElementReference(ElementReference.Kind.FIELD, name, field.name, field.desc), field.access); 32 | } 33 | 34 | for (MethodNode method : clazz.methods) { 35 | method.access = getNewAccessLevel(new ElementReference(ElementReference.Kind.METHOD, name, method.name, method.desc), method.access); 36 | } 37 | 38 | ClassWriter writer = new ClassWriter(0); 39 | clazz.accept(writer); 40 | return writer.toByteArray(); 41 | } 42 | 43 | private int getNewAccessLevel(ElementReference elementReference, int access) { 44 | AccessLevel minimumAccessLevel = transformations.getMinimumAccessLevel(elementReference); 45 | if (minimumAccessLevel == null) { 46 | return access; 47 | } 48 | 49 | AccessLevel.Visibility visibility; 50 | if ((access & Opcodes.ACC_PUBLIC) != 0) { 51 | visibility = AccessLevel.Visibility.PUBLIC; 52 | access &= ~Opcodes.ACC_PUBLIC; 53 | } else if ((access & Opcodes.ACC_PROTECTED) != 0) { 54 | visibility = AccessLevel.Visibility.PROTECTED; 55 | access &= ~Opcodes.ACC_PROTECTED; 56 | } else if ((access & Opcodes.ACC_PRIVATE) != 0) { 57 | visibility = AccessLevel.Visibility.PRIVATE; 58 | access &= ~Opcodes.ACC_PRIVATE; 59 | } else { 60 | visibility = AccessLevel.Visibility.DEFAULT; 61 | } 62 | boolean isFinal = (access & Opcodes.ACC_FINAL) != 0; 63 | 64 | AccessLevel newAccessLevel = AccessLevel.union(minimumAccessLevel, new AccessLevel(visibility, isFinal)); 65 | if (newAccessLevel == null) { 66 | return access; 67 | } 68 | 69 | if (isFinal && !newAccessLevel.isFinal) { 70 | access &= ~Opcodes.ACC_FINAL; 71 | } 72 | 73 | switch (newAccessLevel.visibility) { 74 | case PUBLIC: { 75 | return access | Opcodes.ACC_PUBLIC; 76 | } 77 | 78 | case PROTECTED: { 79 | return access | Opcodes.ACC_PROTECTED; 80 | } 81 | 82 | case DEFAULT: { 83 | return access; 84 | } 85 | 86 | case PRIVATE: { 87 | return access | Opcodes.ACC_PRIVATE; 88 | } 89 | 90 | default: { 91 | throw new RuntimeException("Unknown visibility level '" + newAccessLevel.visibility + "'"); 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/accesstransform/ElementReference.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.accesstransform; 2 | 3 | import java.util.Objects; 4 | 5 | public class ElementReference { 6 | public enum Kind { 7 | CLASS, 8 | METHOD, 9 | FIELD 10 | } 11 | 12 | public final Kind kind; 13 | public final String owner; 14 | public final String name; 15 | public final String desc; 16 | 17 | public ElementReference(Kind kind, String owner, String name, String desc) { 18 | this.kind = kind; 19 | this.owner = owner; 20 | this.name = name; 21 | this.desc = desc; 22 | } 23 | 24 | public static ElementReference fromString(String string) { 25 | String[] split = string.split(" "); 26 | 27 | switch (split[0]) { 28 | case "class": { 29 | return new ElementReference(Kind.CLASS, null, split[1], null); 30 | } 31 | 32 | case "method": { 33 | return new ElementReference(Kind.METHOD, split[1], split[2], split[3]); 34 | } 35 | 36 | case "field": { 37 | return new ElementReference(Kind.FIELD, split[1], split[2], split[3]); 38 | } 39 | 40 | default: { 41 | throw new RuntimeException("Unknown element type '" + split[0] + "'"); 42 | } 43 | } 44 | } 45 | 46 | @Override 47 | public boolean equals(Object obj) { 48 | return obj != null && 49 | obj.getClass() == ElementReference.class && 50 | ((ElementReference) obj).kind == kind && 51 | Objects.equals(((ElementReference) obj).owner, owner) && 52 | Objects.equals(((ElementReference) obj).name, name) && 53 | Objects.equals(((ElementReference) obj).desc, desc); 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | return Objects.hash(kind, owner, name, desc); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/Rift.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import org.dimdev.riftloader.listener.InitializationListener; 6 | import org.spongepowered.asm.launch.MixinBootstrap; 7 | import org.spongepowered.asm.mixin.Mixins; 8 | 9 | public class Rift implements InitializationListener { 10 | private static final Logger LOGGER = LogManager.getLogger(); 11 | @Override 12 | public void onInitialization() { 13 | LOGGER.info("Loading Rift!"); 14 | 15 | MixinBootstrap.init(); 16 | Mixins.addConfiguration("mixins.rift.core.json"); 17 | Mixins.addConfiguration("mixins.rift.hooks.json"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/injectedmethods/RiftCPacketCustomPayload.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.injectedmethods; 2 | 3 | import net.minecraft.network.PacketBuffer; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | public interface RiftCPacketCustomPayload { 7 | ResourceLocation getChannelName(); 8 | PacketBuffer getData(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/injectedmethods/RiftFluid.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.injectedmethods; 2 | 3 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraft.world.IWorldReader; 6 | 7 | public interface RiftFluid { 8 | TextureAtlasSprite getStillTexture(); 9 | TextureAtlasSprite getFlowingTexture(); 10 | int getColorMultiplier(IWorldReader world, BlockPos pos); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ArgumentTypeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.command.arguments.IArgumentSerializer; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | public interface ArgumentTypeAdder { 7 | /** 8 | * Use {@link net.minecraft.command.arguments.ArgumentTypes#register(ResourceLocation, Class, IArgumentSerializer)} 9 | * to register argument types. 10 | */ 11 | void addArgumentTypes(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/BiomeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.biome.Biome; 4 | 5 | import java.util.Collection; 6 | 7 | public interface BiomeAdder { 8 | void registerBiomes(); 9 | Collection getOverworldBiomes(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/BlockAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface BlockAdder { 4 | void registerBlocks(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/BootstrapListener.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface BootstrapListener { 4 | void afterVanillaBootstrap(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/BurnTimeProvider.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.item.Item; 4 | import java.util.Map; 5 | 6 | public interface BurnTimeProvider { 7 | void registerBurnTimes(Map burnTimeMap); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ChunkEventListener.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.chunk.Chunk; 4 | 5 | public interface ChunkEventListener { 6 | void onChunkLoad(Chunk chunk); 7 | void onChunkUnload(Chunk chunk); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ChunkGeneratorReplacer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.WorldServer; 4 | import net.minecraft.world.WorldType; 5 | import net.minecraft.world.gen.ChunkGeneratorType; 6 | import net.minecraft.world.gen.IChunkGenSettings; 7 | import net.minecraft.world.gen.IChunkGenerator; 8 | import net.minecraft.world.gen.IChunkGeneratorFactory; 9 | 10 | import javax.annotation.Nullable; 11 | import java.util.function.Supplier; 12 | 13 | /** 14 | * used to substitute custom {@link IChunkGenerator}s for vanilla ones
15 | * NOTE:
16 | * custom {@link WorldType}s are registered by just instantiating them
17 | * custom {@link ChunkGeneratorType}s are registered via {@link ChunkGeneratorType#registerChunkGeneratorType(String, IChunkGeneratorFactory, ChunkGeneratorType.Settings, boolean)}
18 | * custom {@link ChunkGeneratorType.Settings} are registered via {@link ChunkGeneratorType.Settings#registerChunkGeneratorSettings(String, Supplier)} 19 | */ 20 | public interface ChunkGeneratorReplacer { 21 | 22 | /** 23 | * create an {@link IChunkGenerator} for your world type 24 | * @param worldType the world type that is currently set 25 | * @return a custom chunk generator or {@code null} to fall back to vanilla chunk generator selection 26 | */ 27 | @Nullable 28 | IChunkGenerator createChunkGenerator(WorldServer world, WorldType worldType, int dimensionID); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/CommandAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import com.mojang.brigadier.CommandDispatcher; 4 | import net.minecraft.command.CommandSource; 5 | 6 | public interface CommandAdder { 7 | void registerCommands(CommandDispatcher dispatcher); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/CustomPayloadHandler.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.network.PacketBuffer; 4 | import net.minecraft.util.ResourceLocation; 5 | 6 | /** 7 | * @deprecated Use {@link MessageAdder} instead. 8 | */ 9 | @Deprecated 10 | @SuppressWarnings("DeprecatedIsStillUsed") 11 | public interface CustomPayloadHandler { 12 | boolean clientHandlesChannel(ResourceLocation channelName); 13 | void clientHandleCustomPayload(ResourceLocation channelName, PacketBuffer bufferData); 14 | 15 | boolean serverHandlesChannel(ResourceLocation channelName); 16 | void serverHandleCustomPayload(ResourceLocation channelName, PacketBuffer bufferData); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/DataPackFinderAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.resources.IPackFinder; 4 | 5 | import java.util.List; 6 | 7 | public interface DataPackFinderAdder { 8 | List getDataPackFinders(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/DimensionTypeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.dimension.Dimension; 4 | import net.minecraft.world.dimension.DimensionType; 5 | import org.dimdev.utils.ReflectionUtils; 6 | 7 | import java.util.Set; 8 | import java.util.function.Supplier; 9 | 10 | public interface DimensionTypeAdder { 11 | static DimensionType newDimensionType(int id, String name, String suffix, Supplier dimensionSupplier) { 12 | return ReflectionUtils.makeEnumInstance(DimensionType.class, name.toUpperCase(), -1, id, name, suffix, dimensionSupplier); 13 | } 14 | 15 | Set getDimensionTypes(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/DispenserBehaviorAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface DispenserBehaviorAdder { 4 | void registerDispenserBehaviors(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/EnchantmentAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface EnchantmentAdder { 4 | void registerEnchantments(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/EntityTypeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface EntityTypeAdder { 4 | void registerEntityTypes(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/FluidAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface FluidAdder { 4 | void registerFluids(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ItemAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface ItemAdder { 4 | void registerItems(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/MessageAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | import net.minecraft.util.registry.RegistryNamespaced; 5 | import org.dimdev.rift.network.Message; 6 | 7 | public interface MessageAdder { 8 | void registerMessages(RegistryNamespaced> registry); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/MinecraftStartListener.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface MinecraftStartListener { 4 | void onMinecraftStart(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/MobEffectAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface MobEffectAdder { 4 | void registerMobEffects(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/PacketAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.network.EnumConnectionState; 4 | import net.minecraft.network.EnumPacketDirection; 5 | import net.minecraft.network.Packet; 6 | 7 | public interface PacketAdder { 8 | interface PacketRegistrationReceiver { 9 | EnumConnectionState registerPacket(EnumPacketDirection direction, Class> packetClass); 10 | } 11 | 12 | void registerHandshakingPackets(PacketRegistrationReceiver receiver); 13 | void registerPlayPackets(PacketRegistrationReceiver receiver); 14 | void registerStatusPackets(PacketRegistrationReceiver receiver); 15 | void registerLoginPackets(PacketRegistrationReceiver receiver); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ParticleTypeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface ParticleTypeAdder { 4 | void registerParticles(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/RecipeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.item.crafting.IRecipe; 4 | import net.minecraft.resources.IResourceManager; 5 | import net.minecraft.util.ResourceLocation; 6 | 7 | import java.util.Map; 8 | 9 | public interface RecipeAdder { 10 | void addRecipes(Map target, IResourceManager resourceManager); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/RecipeSerializerAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.item.crafting.IRecipeSerializer; 4 | 5 | public interface RecipeSerializerAdder { 6 | /** 7 | * Use {@link net.minecraft.item.crafting.RecipeSerializers#register(IRecipeSerializer)} 8 | * to register new recipe serializers. 9 | */ 10 | void addRecipeSerializers(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ResourcePackFinderAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.resources.IPackFinder; 4 | 5 | import java.util.List; 6 | 7 | public interface ResourcePackFinderAdder { 8 | List getResourcePackFinders(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ServerTickable.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.server.MinecraftServer; 4 | 5 | public interface ServerTickable { 6 | void serverTick(MinecraftServer server); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/SoundAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface SoundAdder { 4 | void registerSounds(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/StructureAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.gen.feature.structure.Structure; 4 | 5 | import java.util.Map; 6 | 7 | public interface StructureAdder { 8 | /** Register structure and structure and peice names in {@link net.minecraft.world.gen.feature.structure.StructureIO}.*/ 9 | void registerStructureNames(); 10 | 11 | /** Add structures to a map between lowercase structure names and structures. See {@link net.minecraft.world.gen.feature.Feature}*/ 12 | void addStructuresToMap(Map> map); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/TileEntityTypeAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | public interface TileEntityTypeAdder { 4 | void registerTileEntityTypes(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/ToolEfficiencyProvider.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.item.ItemTool; 5 | 6 | import java.util.Set; 7 | 8 | public interface ToolEfficiencyProvider { 9 | void addEffectiveBlocks(ItemTool tool, Set target); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/WorldChanger.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener; 2 | 3 | import net.minecraft.world.biome.Biome; 4 | 5 | public interface WorldChanger { 6 | void modifyBiome(int biomeId, String biomeName, Biome biome); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/AmbientMusicTypeProvider.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.util.SoundEvent; 5 | import org.dimdev.utils.ReflectionUtils; 6 | 7 | import static net.minecraft.client.audio.MusicTicker.MusicType; 8 | 9 | public interface AmbientMusicTypeProvider { 10 | static MusicType newMusicType(String name, SoundEvent sound, int minDelay, int maxDelay) { 11 | return ReflectionUtils.makeEnumInstance(MusicType.class, name, -1, sound, minDelay, maxDelay); 12 | } 13 | 14 | MusicType getAmbientMusicType(Minecraft client); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/ClientTickable.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | public interface ClientTickable { 4 | void clientTick(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/EntityRendererAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.client.renderer.entity.Render; 4 | import net.minecraft.client.renderer.entity.RenderManager; 5 | import net.minecraft.entity.Entity; 6 | 7 | import java.util.Map; 8 | 9 | public interface EntityRendererAdder { 10 | void addEntityRenderers(Map, Render> entityRenderMap, RenderManager renderManager); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/GameGuiAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.client.entity.EntityPlayerSP; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.world.IInteractionObject; 6 | 7 | public interface GameGuiAdder { 8 | void displayGui(EntityPlayerSP player, String id, IInteractionObject interactionObject); 9 | void displayContainerGui(EntityPlayerSP player, String id, IInventory inventory); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/KeyBindingAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.client.settings.KeyBinding; 4 | 5 | import java.util.Collection; 6 | 7 | public interface KeyBindingAdder { 8 | Collection getKeyBindings(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/KeybindHandler.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | public interface KeybindHandler { 4 | void processKeybinds(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/OverlayRenderer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | public interface OverlayRenderer { 4 | void renderOverlay(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/TextureAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | 5 | import java.util.Collection; 6 | 7 | public interface TextureAdder { 8 | Collection getBuiltinTextures(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/listener/client/TileEntityRendererAdder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.listener.client; 2 | 3 | import net.minecraft.client.renderer.tileentity.TileEntityRenderer; 4 | import net.minecraft.tileentity.TileEntity; 5 | 6 | import java.util.Map; 7 | 8 | public interface TileEntityRendererAdder { 9 | void addTileEntityRenderers(Map, TileEntityRenderer> renderers); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/MixinMinecraftServer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core; 2 | 3 | import net.minecraft.command.CommandSource; 4 | import net.minecraft.server.MinecraftServer; 5 | import net.minecraft.util.math.Vec2f; 6 | import net.minecraft.util.math.Vec3d; 7 | import net.minecraft.util.text.TextComponentString; 8 | import net.minecraft.world.WorldServer; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Overwrite; 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.CallbackInfoReturnable; 15 | 16 | @Mixin(MinecraftServer.class) 17 | public class MixinMinecraftServer { 18 | @Shadow 19 | public WorldServer[] worlds; 20 | 21 | @Overwrite 22 | public String getServerModName() { 23 | return "rift"; 24 | } 25 | 26 | @Inject( 27 | method = "getCommandSource", 28 | at = @At(value = "NEW"), 29 | cancellable = true 30 | ) 31 | private void beforeNew(CallbackInfoReturnable ci) { 32 | if(worlds == null) { // World has not been loaded yet, this might happen when the datapack is loaded for the first time 33 | ci.setReturnValue(new CommandSource((MinecraftServer) (Object) this, Vec3d.ZERO, Vec2f.ZERO, null, 4, "Server", 34 | new TextComponentString("Server"), (MinecraftServer) (Object) this, null)); 35 | ci.cancel(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/MixinVanillaPack.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core; 2 | 3 | import net.minecraft.resources.ResourcePackType; 4 | import net.minecraft.resources.VanillaPack; 5 | import net.minecraft.util.ResourceLocation; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Overwrite; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | 10 | import javax.annotation.Nullable; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.net.URL; 14 | import java.nio.file.Files; 15 | import java.nio.file.Path; 16 | 17 | @Mixin(VanillaPack.class) 18 | public class MixinVanillaPack { 19 | @Shadow public static Path field_199754_a; 20 | 21 | /** 22 | * @reason Give priority to resources in the Minecraft jar to avoid them 23 | * from being overwritten by mods. 24 | */ 25 | @Overwrite 26 | @Nullable 27 | protected InputStream func_195782_c(ResourcePackType type, ResourceLocation location) { 28 | String pathString = type.getDirectoryName() + "/" + location.getNamespace() + "/" + location.getPath(); 29 | 30 | if (field_199754_a != null) { 31 | Path path = field_199754_a.resolve(pathString); 32 | if (Files.exists(path)) { 33 | try { 34 | return Files.newInputStream(path); 35 | } catch (IOException ignored) {} 36 | } 37 | } 38 | 39 | try { 40 | URL rootMarker = VanillaPack.class.getResource("/" + type.getDirectoryName() + "/.mcassetsroot"); 41 | String root = rootMarker.toString().substring(0, rootMarker.toString().length() - ".mcassetsroot".length()); 42 | String path = location.getNamespace() + "/" + location.getPath(); 43 | return new URL(root + path).openStream(); 44 | } catch (IOException ignored) {} 45 | 46 | // Realms and Optifine just add resources to the classpath. If no resources were 47 | // found in the Minecraft jar, fall back to looking on the classpath. Duplicates 48 | // will be handled by the classpath order. 49 | return VanillaPack.class.getResourceAsStream("/" + type.getDirectoryName() + "/" + location.getNamespace() + "/" + location.getPath()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/client/MixinBlockFluidRenderer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core.client; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.BlockStainedGlass; 5 | import net.minecraft.client.renderer.BlockFluidRenderer; 6 | import net.minecraft.client.renderer.BufferBuilder; 7 | import net.minecraft.client.renderer.texture.MissingTextureSprite; 8 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 9 | import net.minecraft.fluid.Fluid; 10 | import net.minecraft.fluid.IFluidState; 11 | import net.minecraft.init.Blocks; 12 | import net.minecraft.tags.FluidTags; 13 | import net.minecraft.util.EnumFacing; 14 | import net.minecraft.util.math.BlockPos; 15 | import net.minecraft.util.math.MathHelper; 16 | import net.minecraft.util.math.Vec3d; 17 | import net.minecraft.world.IBlockReader; 18 | import net.minecraft.world.IWorldReader; 19 | import net.minecraft.world.IWorldReaderBase; 20 | import org.dimdev.rift.injectedmethods.RiftFluid; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.Overwrite; 23 | import org.spongepowered.asm.mixin.Shadow; 24 | 25 | @Mixin(BlockFluidRenderer.class) 26 | public abstract class MixinBlockFluidRenderer { 27 | @Shadow private static boolean isAdjacentFluidSameAs(IBlockReader world, BlockPos pos, EnumFacing side, IFluidState state) { return false; } 28 | @Shadow private static boolean func_209556_a(IBlockReader p_209556_0_, BlockPos p_209556_1_, EnumFacing p_209556_2_, float p_209556_3_) { return false; } 29 | @Shadow protected abstract float func_204504_a(IWorldReaderBase p_204504_1_, BlockPos p_204504_2_, Fluid p_204504_3_); 30 | @Shadow protected abstract int func_204835_a(IWorldReader p_204835_1_, BlockPos p_204835_2_); 31 | @Shadow private TextureAtlasSprite atlasSpriteWaterOverlay; 32 | 33 | @Overwrite 34 | public boolean render(IWorldReader world, BlockPos pos, BufferBuilder buffer, IFluidState state) { 35 | boolean isLava = state.isTagged(FluidTags.LAVA); 36 | 37 | // Get textures and color multiplier 38 | TextureAtlasSprite stillTexture = MissingTextureSprite.getSprite(); 39 | TextureAtlasSprite flowingTexture = MissingTextureSprite.getSprite(); 40 | int colorMultiplier = 0xFFFFFF; 41 | if (state.getFluid() instanceof RiftFluid) { 42 | RiftFluid fluid = (RiftFluid) state.getFluid(); 43 | stillTexture = fluid.getStillTexture(); 44 | flowingTexture = fluid.getFlowingTexture(); 45 | colorMultiplier = fluid.getColorMultiplier(world, pos); 46 | } 47 | 48 | float redMultiplier = (colorMultiplier >> 16 & 255) / 255F; 49 | float greenMultiplier = (colorMultiplier >> 8 & 255) / 255F; 50 | float blueMultiplier = (colorMultiplier & 255) / 255F; 51 | 52 | boolean renderTop = !isAdjacentFluidSameAs(world, pos, EnumFacing.UP, state); 53 | boolean renderBottom = !isAdjacentFluidSameAs(world, pos, EnumFacing.DOWN, state) && !func_209556_a(world, pos, EnumFacing.DOWN, 0.8888889F); 54 | boolean renderNorth = !isAdjacentFluidSameAs(world, pos, EnumFacing.NORTH, state); 55 | boolean renderSouth = !isAdjacentFluidSameAs(world, pos, EnumFacing.SOUTH, state); 56 | boolean renderWest = !isAdjacentFluidSameAs(world, pos, EnumFacing.WEST, state); 57 | boolean renderEast = !isAdjacentFluidSameAs(world, pos, EnumFacing.EAST, state); 58 | 59 | if (!renderTop && !renderBottom && !renderEast && !renderWest && !renderNorth && !renderSouth) { 60 | return false; 61 | } 62 | 63 | boolean rendered = false; 64 | 65 | float var17 = func_204504_a(world, pos, state.getFluid()); 66 | float var18 = func_204504_a(world, pos.south(), state.getFluid()); 67 | float var19 = func_204504_a(world, pos.east().south(), state.getFluid()); 68 | float var20 = func_204504_a(world, pos.east(), state.getFluid()); 69 | 70 | double x = pos.getX(); 71 | double y = pos.getY(); 72 | double z = pos.getZ(); 73 | 74 | float minU; 75 | float maxU; 76 | float minV; 77 | float maxV; 78 | float var34; 79 | 80 | if (renderTop && !func_209556_a(world, pos, EnumFacing.UP, Math.min(Math.min(var17, var18), Math.min(var19, var20)))) { 81 | rendered = true; 82 | var17 -= 0.001F; 83 | var18 -= 0.001F; 84 | var19 -= 0.001F; 85 | var20 -= 0.001F; 86 | Vec3d var25 = state.getFlow(world, pos); 87 | float var28; 88 | float var30; 89 | float var32; 90 | TextureAtlasSprite texture; 91 | float var37; 92 | 93 | if (var25.x == 0 && var25.z == 0) { 94 | texture = stillTexture; 95 | minU = texture.getInterpolatedU(0); 96 | var28 = texture.getInterpolatedV(0); 97 | maxU = minU; 98 | var30 = texture.getInterpolatedV(16); 99 | minV = texture.getInterpolatedU(16); 100 | var32 = var30; 101 | maxV = minV; 102 | var34 = var28; 103 | } else { 104 | texture = flowingTexture; 105 | float var35 = (float) MathHelper.atan2(var25.z, var25.x) - 1.5707964F; 106 | float var36 = MathHelper.sin(var35) * 0.25F; 107 | var37 = MathHelper.cos(var35) * 0.25F; 108 | minU = texture.getInterpolatedU(8 + (-var37 - var36) * 16); 109 | var28 = texture.getInterpolatedV(8 + (-var37 + var36) * 16); 110 | maxU = texture.getInterpolatedU(8 + (-var37 + var36) * 16); 111 | var30 = texture.getInterpolatedV(8 + (var37 + var36) * 16); 112 | minV = texture.getInterpolatedU(8 + (var37 + var36) * 16); 113 | var32 = texture.getInterpolatedV(8 + (var37 - var36) * 16); 114 | maxV = texture.getInterpolatedU(8 + (var37 - var36) * 16); 115 | var34 = texture.getInterpolatedV(8 + (-var37 - var36) * 16); 116 | } 117 | 118 | int blockLight = func_204835_a(world, pos); 119 | int skyLight = blockLight >> 16; 120 | 121 | buffer.pos(x, y + var17, z).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(minU, var28).lightmap(skyLight, blockLight).endVertex(); 122 | buffer.pos(x, y + var18, z + 1).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(maxU, var30).lightmap(skyLight, blockLight).endVertex(); 123 | buffer.pos(x + 1, y + var19, z + 1).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(minV, var32).lightmap(skyLight, blockLight).endVertex(); 124 | buffer.pos(x + 1, y + var20, z).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(maxV, var34).lightmap(skyLight, blockLight).endVertex(); 125 | if (state.shouldRenderSides(world, pos.up())) { 126 | buffer.pos(x, y + var17, z).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(minU, var28).lightmap(skyLight, blockLight).endVertex(); 127 | buffer.pos(x + 1, y + var20, z).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(maxV, var34).lightmap(skyLight, blockLight).endVertex(); 128 | buffer.pos(x + 1, y + var19, z + 1).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(minV, var32).lightmap(skyLight, blockLight).endVertex(); 129 | buffer.pos(x, y + var18, z + 1).color(redMultiplier, greenMultiplier, blueMultiplier, 1).tex(maxU, var30).lightmap(skyLight, blockLight).endVertex(); 130 | } 131 | } 132 | 133 | if (renderBottom) { 134 | minU = stillTexture.getMinU(); 135 | maxU = stillTexture.getMaxU(); 136 | minV = stillTexture.getMinV(); 137 | maxV = stillTexture.getMaxV(); 138 | 139 | int blockLight = func_204835_a(world, pos.down()); 140 | int skyLight = blockLight >> 16; 141 | 142 | float darkerRedMultiplier = 0.5F * redMultiplier; 143 | float darkerGreenMultiplier = 0.5F * greenMultiplier; 144 | float darkerBlueMultiplier = 0.5F * blueMultiplier; 145 | 146 | buffer.pos(x, y, z + 1).color(darkerRedMultiplier, darkerGreenMultiplier, darkerBlueMultiplier, 1).tex(minU, maxV).lightmap(skyLight, blockLight).endVertex(); 147 | buffer.pos(x, y, z).color(darkerRedMultiplier, darkerGreenMultiplier, darkerBlueMultiplier, 1).tex(minU, minV).lightmap(skyLight, blockLight).endVertex(); 148 | buffer.pos(x + 1, y, z).color(darkerRedMultiplier, darkerGreenMultiplier, darkerBlueMultiplier, 1).tex(maxU, minV).lightmap(skyLight, blockLight).endVertex(); 149 | buffer.pos(x + 1, y, z + 1).color(darkerRedMultiplier, darkerGreenMultiplier, darkerBlueMultiplier, 1).tex(maxU, maxV).lightmap(skyLight, blockLight).endVertex(); 150 | 151 | rendered = true; 152 | } 153 | 154 | for (int direction = 0; direction < 4; ++direction) { 155 | double x1; 156 | double z1; 157 | double x2; 158 | double z2; 159 | EnumFacing side; 160 | boolean render; 161 | if (direction == 0) { 162 | maxU = var17; 163 | minV = var20; 164 | x1 = x; 165 | x2 = x + 1; 166 | z1 = z + 0.001; 167 | z2 = z + 0.001; 168 | side = EnumFacing.NORTH; 169 | render = renderNorth; 170 | } else if (direction == 1) { 171 | maxU = var19; 172 | minV = var18; 173 | x1 = x + 1; 174 | x2 = x; 175 | z1 = z + 1 - 0.001; 176 | z2 = z + 1 - 0.001; 177 | side = EnumFacing.SOUTH; 178 | render = renderSouth; 179 | } else if (direction == 2) { 180 | maxU = var18; 181 | minV = var17; 182 | x1 = x + 0.001; 183 | x2 = x + 0.001; 184 | z1 = z + 1; 185 | z2 = z; 186 | side = EnumFacing.WEST; 187 | render = renderWest; 188 | } else { 189 | maxU = var20; 190 | minV = var19; 191 | x1 = x + 1 - 0.001; 192 | x2 = x + 1 - 0.001; 193 | z1 = z; 194 | z2 = z + 1; 195 | side = EnumFacing.EAST; 196 | render = renderEast; 197 | } 198 | 199 | if (render && !func_209556_a(world, pos, side, Math.max(maxU, minV))) { 200 | rendered = true; 201 | BlockPos var55 = pos.offset(side); 202 | TextureAtlasSprite texture = flowingTexture; 203 | if (!isLava) { 204 | Block var57 = world.getBlockState(var55).getBlock(); 205 | if (var57 == Blocks.GLASS || var57 instanceof BlockStainedGlass) { 206 | texture = atlasSpriteWaterOverlay; 207 | } 208 | } 209 | 210 | float var58 = texture.getInterpolatedU(0); 211 | float var59 = texture.getInterpolatedU(8); 212 | float var60 = texture.getInterpolatedV((1 - maxU) * 16 * 0.5); 213 | float var61 = texture.getInterpolatedV((1 - minV) * 16 * 0.5); 214 | float var62 = texture.getInterpolatedV(8); 215 | int var63 = func_204835_a(world, var55); 216 | int var64 = var63 >> 16; 217 | float colorDarkness = direction < 2 ? 0.8F : 0.6F; 218 | float var67 = colorDarkness * redMultiplier; 219 | float var68 = colorDarkness * greenMultiplier; 220 | float var69 = colorDarkness * blueMultiplier; 221 | buffer.pos(x1, y + maxU, z1).color(var67, var68, var69, 1).tex(var58, var60).lightmap(var64, var63).endVertex(); 222 | buffer.pos(x2, y + minV, z2).color(var67, var68, var69, 1).tex(var59, var61).lightmap(var64, var63).endVertex(); 223 | buffer.pos(x2, y, z2).color(var67, var68, var69, 1).tex(var59, var62).lightmap(var64, var63).endVertex(); 224 | buffer.pos(x1, y, z1).color(var67, var68, var69, 1).tex(var58, var62).lightmap(var64, var63).endVertex(); 225 | if (texture != atlasSpriteWaterOverlay) { 226 | buffer.pos(x1, y, z1).color(var67, var68, var69, 1).tex(var58, var62).lightmap(var64, var63).endVertex(); 227 | buffer.pos(x2, y, z2).color(var67, var68, var69, 1).tex(var59, var62).lightmap(var64, var63).endVertex(); 228 | buffer.pos(x2, y + minV, z2).color(var67, var68, var69, 1).tex(var59, var61).lightmap(var64, var63).endVertex(); 229 | buffer.pos(x1, y + maxU, z1).color(var67, var68, var69, 1).tex(var58, var60).lightmap(var64, var63).endVertex(); 230 | } 231 | } 232 | } 233 | 234 | return rendered; 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/client/MixinClientBrandRetriever.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core.client; 2 | 3 | import net.minecraft.client.ClientBrandRetriever; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.Overwrite; 6 | 7 | @Mixin(ClientBrandRetriever.class) 8 | public class MixinClientBrandRetriever { 9 | @Overwrite 10 | public static String getClientModName() { 11 | return "rift"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/client/MixinLavaFluid.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.renderer.block.model.ModelBakery; 5 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 6 | import net.minecraft.fluid.LavaFluid; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.world.IWorldReader; 10 | import org.dimdev.rift.injectedmethods.RiftFluid; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | 13 | @Mixin(LavaFluid.class) 14 | public class MixinLavaFluid implements RiftFluid { 15 | @Override 16 | public TextureAtlasSprite getStillTexture() { 17 | return Minecraft.getInstance().getModelManager().getBlockModelShapes().getModel(Blocks.LAVA.getDefaultState()).getParticleTexture(); 18 | } 19 | 20 | @Override 21 | public TextureAtlasSprite getFlowingTexture() { 22 | return Minecraft.getInstance().getTextureMap().getSprite(ModelBakery.LOCATION_LAVA_FLOW); 23 | } 24 | 25 | @Override 26 | public int getColorMultiplier(IWorldReader world, BlockPos pos) { 27 | return 0xFFFFFF; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/client/MixinLayerArmorBase.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core.client; 2 | 3 | import net.minecraft.client.renderer.entity.layers.LayerArmorBase; 4 | import net.minecraft.client.renderer.entity.model.ModelBase; 5 | import net.minecraft.util.ResourceLocation; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | 10 | @Mixin(LayerArmorBase.class) 11 | public class MixinLayerArmorBase { 12 | @Redirect( 13 | method = "getArmorResource(Lnet/minecraft/item/ItemArmor;ZLjava/lang/String;)Lnet/minecraft/util/ResourceLocation;", 14 | at = @At( 15 | value = "INVOKE", 16 | target = "Ljava/lang/String;format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;" 17 | ) 18 | ) 19 | private String getArmorTexture(String format, Object... args) { 20 | String name = (String) args[0]; 21 | int layer = (int) args[1]; 22 | String typeSuffix = (String) args[2]; 23 | ResourceLocation location = new ResourceLocation(name); 24 | return String.format("%s:textures/models/armor/%s_layer_%d%s.png", location.getNamespace(), location.getPath(), layer, typeSuffix); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/core/client/MixinWaterFluid.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.core.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.renderer.block.model.ModelBakery; 5 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 6 | import net.minecraft.fluid.WaterFluid; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.world.IWorldReader; 10 | import net.minecraft.world.biome.BiomeColorHelper; 11 | import org.dimdev.rift.injectedmethods.RiftFluid; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | 14 | @Mixin(WaterFluid.class) 15 | public class MixinWaterFluid implements RiftFluid { 16 | @Override 17 | public TextureAtlasSprite getStillTexture() { 18 | return Minecraft.getInstance().getModelManager().getBlockModelShapes().getModel(Blocks.WATER.getDefaultState()).getParticleTexture(); 19 | } 20 | 21 | @Override 22 | public TextureAtlasSprite getFlowingTexture() { 23 | return Minecraft.getInstance().getTextureMap().getSprite(ModelBakery.LOCATION_WATER_FLOW); 24 | } 25 | 26 | @Override 27 | public int getColorMultiplier(IWorldReader world, BlockPos pos) { 28 | return BiomeColorHelper.getWaterColor(world, pos); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinAnvilSaveHandler.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import com.mojang.datafixers.DataFixer; 4 | import net.minecraft.server.MinecraftServer; 5 | import net.minecraft.world.chunk.storage.AnvilChunkLoader; 6 | import net.minecraft.world.chunk.storage.AnvilSaveHandler; 7 | import net.minecraft.world.chunk.storage.IChunkLoader; 8 | import net.minecraft.world.dimension.Dimension; 9 | import net.minecraft.world.storage.SaveHandler; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Overwrite; 12 | 13 | import javax.annotation.Nullable; 14 | import java.io.File; 15 | 16 | @Mixin(AnvilSaveHandler.class) 17 | public class MixinAnvilSaveHandler extends SaveHandler { 18 | public MixinAnvilSaveHandler(File p_i49566_1_, String p_i49566_2_, @Nullable MinecraftServer p_i49566_3_, DataFixer p_i49566_4_) { 19 | super(p_i49566_1_, p_i49566_2_, p_i49566_3_, p_i49566_4_); 20 | } 21 | 22 | @Overwrite 23 | @Override 24 | public IChunkLoader getChunkLoader(Dimension dimension) { 25 | File worldDirectory = getWorldDirectory(); 26 | int dimensionId = dimension.getType().getId(); 27 | if (dimensionId == 0) { 28 | return new AnvilChunkLoader(worldDirectory, dataFixer); 29 | } else { 30 | File dimensionFolder = new File(worldDirectory, "DIM" + dimensionId); 31 | dimensionFolder.mkdirs(); 32 | return new AnvilChunkLoader(dimensionFolder, dataFixer); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinArgumentTypes.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.command.arguments.ArgumentTypes; 4 | import org.dimdev.rift.listener.ArgumentTypeAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(ArgumentTypes.class) 12 | public class MixinArgumentTypes { 13 | @Inject(method = "registerArgumentTypes", at = @At("RETURN")) 14 | private static void onRegisterArgumentTypes(CallbackInfo ci) { 15 | for (ArgumentTypeAdder argumentTypeAdder : RiftLoader.instance.getListeners(ArgumentTypeAdder.class)) { 16 | argumentTypeAdder.addArgumentTypes(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinBiome.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.biome.Biome; 4 | import org.dimdev.rift.listener.BiomeAdder; 5 | import org.dimdev.rift.listener.WorldChanger; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(Biome.class) 13 | public abstract class MixinBiome { 14 | @Inject(method = "registerBiomes", at = @At(value = "INVOKE", target = "Ljava/util/Collections;addAll(Ljava/util/Collection;[Ljava/lang/Object;)Z")) 15 | private static void onRegisterBiomes(CallbackInfo ci) { 16 | for (BiomeAdder biomeAdder : RiftLoader.instance.getListeners(BiomeAdder.class)) { 17 | biomeAdder.registerBiomes(); 18 | } 19 | } 20 | 21 | @Inject(method = "registerBiome", at = @At(value = "RETURN")) 22 | private static void onRegisterBiome(int biomeId, String biomeName, Biome biome, CallbackInfo ci) { 23 | for (WorldChanger worldChanger : RiftLoader.instance.getListeners(WorldChanger.class)) { 24 | worldChanger.modifyBiome(biomeId, biomeName, biome); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinBlock.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.block.Block; 4 | import org.dimdev.rift.listener.BlockAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Block.class) 12 | public abstract class MixinBlock { 13 | @Inject(method = "registerBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/RegistryNamespacedDefaultedByKey;validateKey()V")) 14 | private static void onRegisterBlocks(CallbackInfo ci) { 15 | for (BlockAdder blockAdder : RiftLoader.instance.getListeners(BlockAdder.class)) { 16 | blockAdder.registerBlocks(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinBootstrap.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.init.Bootstrap; 4 | import org.dimdev.rift.listener.BootstrapListener; 5 | import org.dimdev.rift.listener.DispenserBehaviorAdder; 6 | import org.dimdev.rift.listener.MinecraftStartListener; 7 | import org.dimdev.riftloader.RiftLoader; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(Bootstrap.class) 14 | public class MixinBootstrap { 15 | @Inject(method = "registerDispenserBehaviors", at = @At("RETURN")) 16 | private static void onRegisterDispenserBehaviors(CallbackInfo ci) { 17 | for (DispenserBehaviorAdder dispenserBehaviorAdder : RiftLoader.instance.getListeners(DispenserBehaviorAdder.class)) { 18 | dispenserBehaviorAdder.registerDispenserBehaviors(); 19 | } 20 | } 21 | 22 | @Inject(method = "register", at = @At("HEAD")) 23 | private static void beforeBootstrapRegister(CallbackInfo ci) { 24 | for (MinecraftStartListener listener : RiftLoader.instance.getListeners(MinecraftStartListener.class)) { 25 | listener.onMinecraftStart(); 26 | } 27 | } 28 | 29 | @Inject(method = "register", at = @At(value = "INVOKE", target = "Lnet/minecraft/init/Bootstrap;redirectOutputToLog()V")) 30 | private static void afterBootstrapRegister(CallbackInfo ci) { 31 | for (BootstrapListener listener : RiftLoader.instance.getListeners(BootstrapListener.class)) { 32 | listener.afterVanillaBootstrap(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinCPacketCustomPayload.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.network.PacketBuffer; 4 | import net.minecraft.network.play.client.CPacketCustomPayload; 5 | import net.minecraft.util.ResourceLocation; 6 | import org.dimdev.rift.injectedmethods.RiftCPacketCustomPayload; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | 10 | @Mixin(CPacketCustomPayload.class) 11 | public class MixinCPacketCustomPayload implements RiftCPacketCustomPayload { 12 | @Shadow private ResourceLocation channel; 13 | @Shadow private PacketBuffer data; 14 | 15 | @Override 16 | public ResourceLocation getChannelName() { 17 | return channel; 18 | } 19 | 20 | @Override 21 | public PacketBuffer getData() { 22 | return data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinChunk.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.chunk.Chunk; 4 | import org.dimdev.rift.listener.ChunkEventListener; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Chunk.class) 12 | public class MixinChunk { 13 | @Inject(method = "onLoad", at = @At("RETURN")) 14 | private void onChunkLoad(CallbackInfo ci) { 15 | for (ChunkEventListener listener : RiftLoader.instance.getListeners(ChunkEventListener.class)) { 16 | listener.onChunkLoad((Chunk) (Object) this); 17 | } 18 | } 19 | 20 | @Inject(method = "onUnload", at = @At("RETURN")) 21 | private void onChunkUnoad(CallbackInfo ci) { 22 | for (ChunkEventListener listener : RiftLoader.instance.getListeners(ChunkEventListener.class)) { 23 | listener.onChunkUnload((Chunk) (Object) this); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinCommands.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import com.mojang.brigadier.AmbiguityConsumer; 4 | import com.mojang.brigadier.CommandDispatcher; 5 | import net.minecraft.command.CommandSource; 6 | import net.minecraft.command.Commands; 7 | import org.dimdev.rift.listener.CommandAdder; 8 | import org.dimdev.riftloader.RiftLoader; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Redirect; 12 | 13 | @Mixin(Commands.class) 14 | public class MixinCommands { 15 | // Workaround for https://github.com/SpongePowered/Mixin/issues/267 16 | @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V")) 17 | public void findAmbiguities(CommandDispatcher dispatcher, AmbiguityConsumer consumer) { 18 | for (CommandAdder commandAdder : RiftLoader.instance.getListeners(CommandAdder.class)) { 19 | commandAdder.registerCommands(dispatcher); 20 | } 21 | dispatcher.findAmbiguities(consumer); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinDimensionType.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.dimension.DimensionType; 4 | import org.dimdev.rift.listener.DimensionTypeAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Overwrite; 8 | 9 | import java.util.HashMap; 10 | 11 | @Mixin(DimensionType.class) 12 | public class MixinDimensionType { 13 | @SuppressWarnings("PublicStaticMixinMember") // accessed using reflection 14 | private static HashMap dimensionTypes = new HashMap<>(); 15 | 16 | static { 17 | for (DimensionType dimensionType : DimensionType.values()) { 18 | dimensionTypes.put(dimensionType.getId(), dimensionType); 19 | } 20 | 21 | for (DimensionTypeAdder dimensionTypeAdder : RiftLoader.instance.getListeners(DimensionTypeAdder.class)) { 22 | for (DimensionType dimensionType : dimensionTypeAdder.getDimensionTypes()) { 23 | dimensionTypes.put(dimensionType.getId(), dimensionType); 24 | } 25 | } 26 | } 27 | 28 | @Overwrite 29 | public static DimensionType getById(int id) { 30 | DimensionType dimensionType = dimensionTypes.get(id); 31 | if (dimensionType == null) { 32 | throw new IllegalArgumentException("Invalid dimension id " + id); 33 | } 34 | 35 | return dimensionType; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinEnchantment.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.enchantment.Enchantment; 4 | import org.dimdev.rift.listener.EnchantmentAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Enchantment.class) 12 | public class MixinEnchantment { 13 | @Inject(method = "registerEnchantments", at = @At(value = "RETURN")) 14 | private static void onRegisterEnchantments(CallbackInfo ci) { 15 | for (EnchantmentAdder enchantmentAdder : RiftLoader.instance.getListeners(EnchantmentAdder.class)) { 16 | enchantmentAdder.registerEnchantments(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinEntityType.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import com.mojang.datafixers.DataFixUtils; 4 | import com.mojang.datafixers.types.Type; 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.entity.EntityType; 7 | import net.minecraft.util.datafix.DataFixesManager; 8 | import net.minecraft.util.datafix.TypeReferences; 9 | import net.minecraft.world.World; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | import org.dimdev.rift.listener.EntityTypeAdder; 13 | import org.dimdev.riftloader.RiftLoader; 14 | import org.spongepowered.asm.mixin.Final; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Overwrite; 17 | import org.spongepowered.asm.mixin.Shadow; 18 | 19 | import java.util.function.Function; 20 | 21 | @Mixin(EntityType.class) 22 | public abstract class MixinEntityType { 23 | static { 24 | for (EntityTypeAdder entityTypeAdder : RiftLoader.instance.getListeners(EntityTypeAdder.class)) { 25 | entityTypeAdder.registerEntityTypes(); 26 | } 27 | } 28 | 29 | @Mixin(EntityType.Builder.class) 30 | public abstract static class Builder { 31 | @Shadow private boolean serializable; 32 | 33 | @Shadow @Final private Class entityClass; 34 | @Shadow @Final private Function factory; 35 | @Shadow private boolean summonable; 36 | private static final Logger LOGGER = LogManager.getLogger(); 37 | 38 | @Overwrite 39 | public EntityType build(String id) { 40 | Type dataFixerType = null; 41 | 42 | if (serializable) { 43 | try { 44 | dataFixerType = DataFixesManager.getDataFixer().getSchema(DataFixUtils.makeKey(1519)).getChoiceType(TypeReferences.ENTITY_TYPE, id); 45 | } catch (IllegalStateException | IllegalArgumentException ignored) { 46 | LOGGER.debug("No data fixer registered for entity {}", id); 47 | } 48 | } 49 | 50 | return new EntityType<>(entityClass, factory, serializable, summonable, dataFixerType); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinEnumConnectionState.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.network.EnumConnectionState; 4 | import net.minecraft.network.EnumPacketDirection; 5 | import net.minecraft.network.Packet; 6 | import org.dimdev.rift.listener.PacketAdder; 7 | import org.dimdev.riftloader.RiftLoader; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(EnumConnectionState.class) 15 | public abstract class MixinEnumConnectionState { 16 | @Shadow protected abstract EnumConnectionState registerPacket(EnumPacketDirection direction, Class> packetClass); 17 | 18 | @Mixin(targets = "net/minecraft/network/EnumConnectionState$1") 19 | public abstract static class Handshaking extends MixinEnumConnectionState { 20 | @Inject(method = "", at = @At("RETURN")) 21 | private void registerModPackets(CallbackInfo ci) { 22 | for (PacketAdder packetAdder : RiftLoader.instance.getListeners(PacketAdder.class)) { 23 | packetAdder.registerHandshakingPackets(this::registerPacket); 24 | } 25 | } 26 | } 27 | 28 | @Mixin(targets = "net/minecraft/network/EnumConnectionState$2") 29 | public abstract static class Play extends MixinEnumConnectionState { 30 | @Inject(method = "", at = @At("RETURN")) 31 | private void registerModPackets(CallbackInfo ci) { 32 | for (PacketAdder packetAdder : RiftLoader.instance.getListeners(PacketAdder.class)) { 33 | packetAdder.registerPlayPackets(this::registerPacket); 34 | } 35 | } 36 | } 37 | 38 | @Mixin(targets = "net/minecraft/network/EnumConnectionState$3") 39 | public abstract static class Status extends MixinEnumConnectionState { 40 | @Inject(method = "", at = @At("RETURN")) 41 | private void registerModPackets(CallbackInfo ci) { 42 | for (PacketAdder packetAdder : RiftLoader.instance.getListeners(PacketAdder.class)) { 43 | packetAdder.registerStatusPackets(this::registerPacket); 44 | } 45 | } 46 | } 47 | 48 | @Mixin(targets = "net/minecraft/network/EnumConnectionState$4") 49 | public abstract static class Login extends MixinEnumConnectionState { 50 | @Inject(method = "", at = @At("RETURN")) 51 | private void registerModPackets(CallbackInfo ci) { 52 | for (PacketAdder packetAdder : RiftLoader.instance.getListeners(PacketAdder.class)) { 53 | packetAdder.registerLoginPackets(this::registerPacket); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinFeature.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.gen.feature.Feature; 4 | import net.minecraft.world.gen.feature.structure.Structure; 5 | import org.dimdev.rift.listener.StructureAdder; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | 11 | import java.util.Map; 12 | 13 | @Mixin(Feature.class) 14 | public class MixinFeature { 15 | @Shadow @Final public static Map> STRUCTURES; 16 | 17 | static { 18 | for (StructureAdder structureAdder : RiftLoader.instance.getListeners(StructureAdder.class)) { 19 | structureAdder.addStructuresToMap(STRUCTURES); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinFluid.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.fluid.Fluid; 4 | import org.dimdev.rift.listener.FluidAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Fluid.class) 12 | public abstract class MixinFluid { 13 | @Inject(method = "registerAll", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/RegistryNamespacedDefaultedByKey;validateKey()V")) 14 | private static void onRegisterFluids(CallbackInfo ci) { 15 | for (FluidAdder fluidAdder : RiftLoader.instance.getListeners(FluidAdder.class)) { 16 | fluidAdder.registerFluids(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinFurnace.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.item.Item; 4 | import net.minecraft.tileentity.TileEntityFurnace; 5 | import org.dimdev.rift.listener.BurnTimeProvider; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | import java.util.Map; 13 | 14 | @Mixin(TileEntityFurnace.class) 15 | public class MixinFurnace { 16 | @Inject(method = "getBurnTimes", at = @At(value = "RETURN")) 17 | private static void getBurnTimes(CallbackInfoReturnable> cir) { 18 | for (BurnTimeProvider burnTimeProvider : RiftLoader.instance.getListeners(BurnTimeProvider.class)) { 19 | burnTimeProvider.registerBurnTimes(cir.getReturnValue()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinItem.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.item.Item; 4 | import org.dimdev.rift.listener.ItemAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Item.class) 12 | public abstract class MixinItem { 13 | @Inject(method = "registerItems", at = @At("RETURN")) 14 | private static void onRegisterItems(CallbackInfo ci) { 15 | for (ItemAdder itemAdder : RiftLoader.instance.getListeners(ItemAdder.class)) { 16 | itemAdder.registerItems(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinItemTool.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.item.IItemTier; 5 | import net.minecraft.item.Item; 6 | import net.minecraft.item.ItemTool; 7 | import org.dimdev.rift.listener.ToolEfficiencyProvider; 8 | import org.dimdev.riftloader.RiftLoader; 9 | import org.spongepowered.asm.mixin.Final; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Mutable; 12 | import org.spongepowered.asm.mixin.Shadow; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | import java.util.HashSet; 18 | import java.util.Set; 19 | 20 | @Mixin(ItemTool.class) 21 | public class MixinItemTool { 22 | @Shadow @Mutable @Final private Set effectiveBlocks; 23 | 24 | @Inject(method = "", at = @At("RETURN")) 25 | private void onInit(float attackDamage, float attackSpeed, IItemTier tier, Set effectiveBlocks, Item.Builder builder, CallbackInfo ci) { 26 | this.effectiveBlocks = new HashSet<>(effectiveBlocks); 27 | 28 | for (ToolEfficiencyProvider toolEfficiencyProvider : RiftLoader.instance.getListeners(ToolEfficiencyProvider.class)) { 29 | toolEfficiencyProvider.addEffectiveBlocks((ItemTool) (Object) this, this.effectiveBlocks); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinMinecraftServer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import com.google.gson.JsonElement; 4 | import net.minecraft.profiler.Profiler; 5 | import net.minecraft.resources.IPackFinder; 6 | import net.minecraft.resources.ResourcePackInfo; 7 | import net.minecraft.resources.ResourcePackList; 8 | import net.minecraft.server.CustomBossEvents; 9 | import net.minecraft.server.MinecraftServer; 10 | import net.minecraft.server.management.PlayerList; 11 | import net.minecraft.util.text.ITextComponent; 12 | import net.minecraft.util.text.TextComponentTranslation; 13 | import net.minecraft.world.*; 14 | import net.minecraft.world.dimension.DimensionType; 15 | import net.minecraft.world.storage.ISaveFormat; 16 | import net.minecraft.world.storage.ISaveHandler; 17 | import net.minecraft.world.storage.WorldInfo; 18 | import org.dimdev.rift.listener.DataPackFinderAdder; 19 | import org.dimdev.rift.listener.ServerTickable; 20 | import org.dimdev.riftloader.RiftLoader; 21 | import org.spongepowered.asm.mixin.Final; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.Overwrite; 24 | import org.spongepowered.asm.mixin.Shadow; 25 | import org.spongepowered.asm.mixin.injection.At; 26 | import org.spongepowered.asm.mixin.injection.Inject; 27 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 28 | 29 | import javax.annotation.Nullable; 30 | import java.io.File; 31 | import java.lang.reflect.Field; 32 | import java.util.ArrayList; 33 | import java.util.HashMap; 34 | import java.util.List; 35 | import java.util.Map; 36 | 37 | @Mixin(MinecraftServer.class) 38 | public abstract class MixinMinecraftServer { 39 | @Shadow @Final private ResourcePackList resourcePacks; 40 | @Shadow @Final public Profiler profiler; 41 | @Shadow public abstract void convertMapIfNeeded(String p_convertMapIfNeeded_1_); 42 | @Shadow public WorldServer[] worlds; 43 | @Shadow public long[][] timeOfLastDimensionTick; 44 | @Shadow public abstract ISaveFormat getActiveAnvilConverter(); 45 | @Shadow public abstract void setResourcePackFromWorld(String p_setResourcePackFromWorld_1_, ISaveHandler p_setResourcePackFromWorld_2_); 46 | @Shadow public abstract String getFolderName(); 47 | @Shadow protected abstract void setUserMessage(ITextComponent p_200245_1_); 48 | @Shadow public abstract GameType getGameType(); 49 | @Shadow public abstract boolean canStructuresSpawn(); 50 | @Shadow public abstract boolean isHardcore(); 51 | @Shadow public abstract void func_195560_a(File p_195560_1_, WorldInfo p_195560_2_); 52 | @Shadow public abstract void initialWorldChunkLoad(); 53 | @Shadow public abstract void setDifficultyForAllWorlds(EnumDifficulty p_setDifficultyForAllWorlds_1_); 54 | @Shadow public abstract CustomBossEvents getCustomBossEvents(); 55 | @Shadow public abstract PlayerList getPlayerList(); 56 | @Shadow public abstract boolean isDemo(); 57 | @Shadow public abstract boolean isSinglePlayer(); 58 | @Shadow public abstract EnumDifficulty getDifficulty(); 59 | @Shadow private boolean enableBonusChest; 60 | 61 | private Map dimensionTypeToWorldIndex = new HashMap<>(); 62 | private Map dimensionIdToWorldIndex = new HashMap<>(); 63 | 64 | @Inject(method = "func_195560_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/resources/ResourcePackList;addPackFinder(Lnet/minecraft/resources/IPackFinder;)V", shift = At.Shift.AFTER)) 65 | private void afterAddVanillaPackFinder(File serverDirectory, WorldInfo worldInfo, CallbackInfo ci) { 66 | for (DataPackFinderAdder resourcePackFinderAdder : RiftLoader.instance.getListeners(DataPackFinderAdder.class)) { 67 | for (IPackFinder packFinder : resourcePackFinderAdder.getDataPackFinders()) { 68 | resourcePacks.addPackFinder(packFinder); 69 | } 70 | } 71 | } 72 | 73 | @Inject(method = "tick", at = @At(value = "RETURN")) 74 | private void onTick(CallbackInfo ci) { 75 | profiler.startSection("mods"); 76 | for (ServerTickable tickable : RiftLoader.instance.getListeners(ServerTickable.class)) { 77 | profiler.startSection(() -> tickable.getClass().getCanonicalName().replace('.', '/')); 78 | tickable.serverTick((MinecraftServer) (Object) this); 79 | profiler.endSection(); 80 | } 81 | profiler.endSection(); 82 | } 83 | 84 | @Overwrite 85 | public void loadAllWorlds(String saveName, String worldName, long seed, WorldType type, JsonElement generatorOptions) { 86 | convertMapIfNeeded(saveName); 87 | 88 | setUserMessage(new TextComponentTranslation("menu.loadingLevel")); 89 | 90 | ISaveHandler saveHandler = getActiveAnvilConverter().getSaveLoader(saveName, (MinecraftServer) (Object) this); 91 | setResourcePackFromWorld(getFolderName(), saveHandler); 92 | WorldInfo worldInfo = saveHandler.loadWorldInfo(); 93 | WorldSettings worldSettings = getWorldSettings(worldInfo, seed, type, generatorOptions); 94 | 95 | if (worldInfo == null) { 96 | worldInfo = new WorldInfo(worldSettings, worldName); 97 | } else { 98 | worldInfo.setWorldName(worldName); 99 | } 100 | 101 | func_195560_a(saveHandler.getWorldDirectory(), worldInfo); 102 | 103 | // Create overworld 104 | WorldServer overworld = isDemo() ? new WorldServerDemo((MinecraftServer) (Object) this, saveHandler, worldInfo, 0, profiler) 105 | : new WorldServer((MinecraftServer) (Object) this, saveHandler, worldInfo, 0, profiler); 106 | overworld.init(); 107 | 108 | overworld.initialize(worldSettings); 109 | overworld.addEventListener(new ServerWorldEventHandler((MinecraftServer) (Object) this, overworld)); 110 | if (!isSinglePlayer()) { 111 | overworld.getWorldInfo().setGameType(getGameType()); 112 | } 113 | 114 | List worldList = new ArrayList<>(); 115 | worldList.add(overworld); 116 | dimensionIdToWorldIndex.put(0, 0); 117 | dimensionTypeToWorldIndex.put(DimensionType.OVERWORLD, 0); 118 | 119 | // Create other worlds 120 | List dimensionTypes; 121 | try { 122 | @SuppressWarnings("JavaReflectionMemberAccess") 123 | Field dimensionTypesField = DimensionType.class.getDeclaredField("dimensionTypes"); 124 | dimensionTypesField.setAccessible(true); 125 | //noinspection unchecked 126 | dimensionTypes = new ArrayList<>(((Map) dimensionTypesField.get(null)).values()); 127 | dimensionTypes.remove(DimensionType.OVERWORLD); 128 | } catch (ReflectiveOperationException e) { 129 | throw new RuntimeException(e); 130 | } 131 | 132 | for (DimensionType dimensionType : dimensionTypes) { 133 | dimensionIdToWorldIndex.put(dimensionType.getId(), worldList.size()); 134 | dimensionTypeToWorldIndex.put(dimensionType, worldList.size()); 135 | WorldServerMulti world = new WorldServerMulti((MinecraftServer) (Object) this, saveHandler, dimensionType.getId(), overworld, profiler); 136 | world.init(); 137 | world.addEventListener(new ServerWorldEventHandler((MinecraftServer) (Object) this, world)); 138 | if (!isSinglePlayer()) { 139 | world.getWorldInfo().setGameType(getGameType()); 140 | } 141 | 142 | worldList.add(world); 143 | } 144 | 145 | // Initialize other things 146 | worlds = worldList.toArray(new WorldServer[0]); 147 | timeOfLastDimensionTick = new long[worlds.length][100]; 148 | 149 | getPlayerList().setPlayerManager(worlds); 150 | if (worldInfo.getCustomBossEvents() != null) { 151 | getCustomBossEvents().read(worldInfo.getCustomBossEvents()); 152 | } 153 | 154 | if (overworld.getWorldInfo().getDifficulty() == null) { 155 | setDifficultyForAllWorlds(getInitialDifficulty()); 156 | } 157 | 158 | // initialWorldChunkLoad(); 159 | } 160 | 161 | protected WorldSettings getWorldSettings(@Nullable WorldInfo worldInfo, long seed, WorldType worldType, JsonElement generatorOptions) { 162 | if (worldInfo == null) { 163 | if (isDemo()) { 164 | return WorldServerDemo.DEMO_WORLD_SETTINGS; 165 | } else { 166 | WorldSettings worldSettings = new WorldSettings(seed, getGameType(), canStructuresSpawn(), isHardcore(), worldType); 167 | worldSettings.func_205390_a(generatorOptions); 168 | if (enableBonusChest) { 169 | worldSettings.enableBonusChest(); 170 | } 171 | return worldSettings; 172 | } 173 | } else { 174 | return new WorldSettings(worldInfo); 175 | } 176 | } 177 | 178 | protected EnumDifficulty getInitialDifficulty() { 179 | return getDifficulty(); 180 | } 181 | 182 | @Overwrite 183 | public WorldServer getWorld(DimensionType dimensionType) { 184 | return worlds[dimensionTypeToWorldIndex.get(dimensionType)]; 185 | } 186 | 187 | @Overwrite 188 | public WorldServer getWorld(int dimensionId) { 189 | return worlds[dimensionIdToWorldIndex.get(dimensionId)]; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinNetHandlerPlayServer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.entity.player.EntityPlayerMP; 4 | import net.minecraft.network.NetHandlerPlayServer; 5 | import net.minecraft.network.NetworkManager; 6 | import net.minecraft.network.PacketBuffer; 7 | import net.minecraft.network.play.client.CPacketCustomPayload; 8 | import net.minecraft.server.MinecraftServer; 9 | import net.minecraft.util.ResourceLocation; 10 | import org.dimdev.rift.injectedmethods.RiftCPacketCustomPayload; 11 | import org.dimdev.rift.listener.CustomPayloadHandler; 12 | import org.dimdev.rift.network.Message; 13 | import org.dimdev.rift.network.ServerMessageContext; 14 | import org.dimdev.riftloader.RiftLoader; 15 | import org.spongepowered.asm.mixin.Final; 16 | import org.spongepowered.asm.mixin.Mixin; 17 | import org.spongepowered.asm.mixin.Shadow; 18 | import org.spongepowered.asm.mixin.injection.At; 19 | import org.spongepowered.asm.mixin.injection.Inject; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | 22 | @Mixin(NetHandlerPlayServer.class) 23 | public class MixinNetHandlerPlayServer { 24 | @Shadow @Final private MinecraftServer server; 25 | @Shadow public EntityPlayerMP player; 26 | @Shadow @Final public NetworkManager netManager; 27 | 28 | @SuppressWarnings("deprecation") 29 | @Inject(method = "processCustomPayload", at = @At("HEAD"), cancellable = true) 30 | private void handleModCustomPayload(CPacketCustomPayload packet, CallbackInfo ci) { 31 | ResourceLocation channelName = ((RiftCPacketCustomPayload) packet).getChannelName(); 32 | PacketBuffer data = ((RiftCPacketCustomPayload) packet).getData(); 33 | 34 | for (CustomPayloadHandler customPayloadHandler : RiftLoader.instance.getListeners(CustomPayloadHandler.class)) { 35 | if (customPayloadHandler.serverHandlesChannel(channelName)) { 36 | customPayloadHandler.serverHandleCustomPayload(channelName, data); 37 | } 38 | } 39 | 40 | Class messageClass = Message.REGISTRY.get(channelName); 41 | if (messageClass != null) { 42 | try { 43 | Message message = RiftLoader.instance.newInstance(messageClass); 44 | message.read(data); 45 | message.process(new ServerMessageContext(server, player, netManager)); 46 | } catch (ReflectiveOperationException e) { 47 | throw new RuntimeException("Error creating " + messageClass, e); 48 | } 49 | ci.cancel(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinOverworldBiomeProvider.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.biome.Biome; 4 | import net.minecraft.world.biome.provider.OverworldBiomeProvider; 5 | import org.dimdev.rift.listener.BiomeAdder; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Mutable; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.ArrayList; 16 | import java.util.Arrays; 17 | import java.util.List; 18 | 19 | @Mixin(OverworldBiomeProvider.class) 20 | public abstract class MixinOverworldBiomeProvider { 21 | @Shadow @Final @Mutable private Biome[] biomes; 22 | 23 | @Inject(method = "", at = @At("RETURN")) 24 | private void onInit(CallbackInfo ci) { 25 | List biomes = new ArrayList<>(Arrays.asList(this.biomes)); 26 | for (BiomeAdder biomeAdder : RiftLoader.instance.getListeners(BiomeAdder.class)) { 27 | biomes.addAll(biomeAdder.getOverworldBiomes()); 28 | } 29 | 30 | this.biomes = biomes.toArray(new Biome[0]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinParticleType.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.particles.ParticleType; 4 | import org.dimdev.rift.listener.ParticleTypeAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(ParticleType.class) 12 | public abstract class MixinParticleType { 13 | @Inject(method = "registerAll", at = @At("RETURN")) 14 | private static void onRegisterParticleTypes(CallbackInfo ci) { 15 | for (ParticleTypeAdder particleTypeAdder : RiftLoader.instance.getListeners(ParticleTypeAdder.class)) { 16 | particleTypeAdder.registerParticles(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinPotion.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.potion.Potion; 4 | import org.dimdev.rift.listener.MobEffectAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(Potion.class) 12 | public class MixinPotion { 13 | @Inject(method = "registerPotions", at = @At(value = "RETURN")) 14 | private static void onRegisterPotions(CallbackInfo ci) { 15 | for (MobEffectAdder mobEffectAdder : RiftLoader.instance.getListeners(MobEffectAdder.class)) { 16 | mobEffectAdder.registerMobEffects(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinRecipeManager.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.item.crafting.IRecipe; 4 | import net.minecraft.item.crafting.RecipeManager; 5 | import net.minecraft.resources.IResourceManager; 6 | import net.minecraft.util.ResourceLocation; 7 | import org.dimdev.rift.listener.RecipeAdder; 8 | import org.dimdev.riftloader.RiftLoader; 9 | import org.spongepowered.asm.mixin.Final; 10 | import org.spongepowered.asm.mixin.Mixin; 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 | 16 | import java.util.Map; 17 | 18 | @Mixin(RecipeManager.class) 19 | public class MixinRecipeManager { 20 | @Shadow @Final private Map recipes; 21 | 22 | @Inject(method = "onResourceManagerReload", at = @At(value = "INVOKE", target = "Ljava/util/Map;size()I")) 23 | private void onLoadRecipes(IResourceManager resourceManager, CallbackInfo ci) { 24 | for (RecipeAdder recipeAdder : RiftLoader.instance.getListeners(RecipeAdder.class)) { 25 | recipeAdder.addRecipes(recipes, resourceManager); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinRecipeSerializers.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.item.crafting.RecipeSerializers; 4 | import org.dimdev.rift.listener.RecipeSerializerAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | 8 | @Mixin(RecipeSerializers.class) 9 | public class MixinRecipeSerializers { 10 | static { 11 | for (RecipeSerializerAdder recipeSerializerAdder : RiftLoader.instance.getListeners(RecipeSerializerAdder.class)) { 12 | recipeSerializerAdder.addRecipeSerializers(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinSoundEvent.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.util.SoundEvent; 4 | import org.dimdev.rift.listener.SoundAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(SoundEvent.class) 12 | public abstract class MixinSoundEvent { 13 | @Inject(method = "registerSounds", at = @At("RETURN")) 14 | private static void onRegisterSounds(CallbackInfo ci) { 15 | for (SoundAdder soundAdder : RiftLoader.instance.getListeners(SoundAdder.class)) { 16 | soundAdder.registerSounds(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinStructureIO.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.gen.feature.structure.StructureIO; 4 | import org.dimdev.rift.listener.StructureAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | 8 | @Mixin(StructureIO.class) 9 | public class MixinStructureIO { 10 | static { 11 | for (StructureAdder structureAdder : RiftLoader.instance.getListeners(StructureAdder.class)) { 12 | structureAdder.registerStructureNames(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinTileEntityType.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import com.mojang.datafixers.DataFixUtils; 4 | import com.mojang.datafixers.types.Type; 5 | import net.minecraft.tileentity.TileEntity; 6 | import net.minecraft.tileentity.TileEntityType; 7 | import net.minecraft.util.ResourceLocation; 8 | import net.minecraft.util.datafix.DataFixesManager; 9 | import net.minecraft.util.datafix.TypeReferences; 10 | import net.minecraft.util.registry.RegistryNamespaced; 11 | import org.apache.logging.log4j.Logger; 12 | import org.dimdev.rift.listener.TileEntityTypeAdder; 13 | import org.dimdev.riftloader.RiftLoader; 14 | import org.spongepowered.asm.mixin.Final; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Overwrite; 17 | import org.spongepowered.asm.mixin.Shadow; 18 | import org.spongepowered.asm.mixin.injection.At; 19 | import org.spongepowered.asm.mixin.injection.Inject; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | 22 | @Mixin(TileEntityType.class) 23 | public abstract class MixinTileEntityType { 24 | @Shadow @Final private static Logger LOGGER; 25 | @Shadow @Final public static RegistryNamespaced> REGISTRY; 26 | 27 | @Overwrite 28 | public static TileEntityType registerTileEntityType(String id, TileEntityType.Builder builder) { 29 | Type dataFixerType = null; 30 | 31 | try { 32 | dataFixerType = DataFixesManager.getDataFixer().getSchema(DataFixUtils.makeKey(1519)).getChoiceType(TypeReferences.BLOCK_ENTITY, id); 33 | } catch (IllegalStateException | IllegalArgumentException e) { 34 | LOGGER.debug("No data fixer registered for block entity {}", id); 35 | } 36 | 37 | TileEntityType tileEntityType = builder.build(dataFixerType); 38 | REGISTRY.put(new ResourceLocation(id), tileEntityType); 39 | return tileEntityType; 40 | } 41 | 42 | @Inject(method = "", at = @At("RETURN")) 43 | private static void onRegisterTileEntityTypes(CallbackInfo ci) { 44 | for (TileEntityTypeAdder entityTypeAdder : RiftLoader.instance.getListeners(TileEntityTypeAdder.class)) { 45 | entityTypeAdder.registerTileEntityTypes(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/MixinWorldServer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook; 2 | 3 | import net.minecraft.world.WorldServer; 4 | import net.minecraft.world.WorldType; 5 | import net.minecraft.world.dimension.Dimension; 6 | import net.minecraft.world.gen.IChunkGenSettings; 7 | import net.minecraft.world.gen.IChunkGenerator; 8 | import org.dimdev.rift.listener.ChunkGeneratorReplacer; 9 | import org.dimdev.riftloader.RiftLoader; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | 14 | @Mixin(WorldServer.class) 15 | public class MixinWorldServer { 16 | 17 | @SuppressWarnings("ConstantConditions") 18 | @Redirect(method = "createChunkProvider", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/dimension/Dimension;createChunkGenerator()Lnet/minecraft/world/gen/IChunkGenerator;")) 19 | protected IChunkGenerator onCreateChunkGenerator(Dimension dimension) { 20 | WorldServer world = (WorldServer) (Object) this; 21 | WorldType type = world.getWorldInfo().getTerrainType(); 22 | IChunkGenerator generator = null; 23 | for(ChunkGeneratorReplacer adder : RiftLoader.instance.getListeners(ChunkGeneratorReplacer.class)) { 24 | IChunkGenerator value = adder.createChunkGenerator(world, type, dimension.getType().getId()); 25 | if(value != null) generator = value; 26 | } 27 | return generator != null ? generator : dimension.createChunkGenerator(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinEntityPlayerSP.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.entity.EntityPlayerSP; 4 | import net.minecraft.inventory.IInventory; 5 | import net.minecraft.world.IInteractionObject; 6 | import org.dimdev.rift.listener.client.GameGuiAdder; 7 | import org.dimdev.riftloader.RiftLoader; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(EntityPlayerSP.class) 14 | public class MixinEntityPlayerSP { 15 | @Inject(method = "displayGui", at = @At("HEAD"), cancellable = true) 16 | public void onDisplayGui(IInteractionObject interactionObject, CallbackInfo ci) { 17 | String id = interactionObject.getGuiID(); 18 | if (!id.startsWith("minecraft:")) { 19 | for (GameGuiAdder gameGuiAdder : RiftLoader.instance.getListeners(GameGuiAdder.class)) { 20 | gameGuiAdder.displayGui((EntityPlayerSP) (Object) this, id, interactionObject); 21 | } 22 | ci.cancel(); 23 | } 24 | } 25 | 26 | @Inject(method = "displayGUIChest", at = @At("HEAD"), cancellable = true) 27 | public void onDisplayContainerGui(IInventory inventory, CallbackInfo ci) { 28 | String id = inventory instanceof IInteractionObject ? ((IInteractionObject) inventory).getGuiID() : "minecraft:container"; 29 | if (!id.startsWith("minecraft:")) { 30 | for (GameGuiAdder gameGuiAdder : RiftLoader.instance.getListeners(GameGuiAdder.class)) { 31 | gameGuiAdder.displayContainerGui((EntityPlayerSP) (Object) this, id, inventory); 32 | } 33 | ci.cancel(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinGameSettings.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.GameSettings; 4 | import net.minecraft.client.settings.KeyBinding; 5 | import org.dimdev.rift.listener.client.KeyBindingAdder; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Collections; 15 | import java.util.List; 16 | 17 | @Mixin(GameSettings.class) 18 | public class MixinGameSettings { 19 | @Shadow public KeyBinding[] keyBindings; 20 | 21 | @Inject(method = "loadOptions", at = @At("HEAD")) 22 | private void onLoadOptions(CallbackInfo ci) { 23 | List keyBindingList = new ArrayList<>(keyBindings.length); 24 | Collections.addAll(keyBindingList, keyBindings); 25 | for (KeyBindingAdder keyBindingAdder : RiftLoader.instance.getListeners(KeyBindingAdder.class)) { 26 | keyBindingList.addAll(keyBindingAdder.getKeyBindings()); 27 | } 28 | keyBindings = keyBindingList.toArray(new KeyBinding[0]); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinGuiIngame.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.gui.GuiIngame; 4 | import org.dimdev.rift.listener.client.OverlayRenderer; 5 | import org.dimdev.riftloader.RiftLoader; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(GuiIngame.class) 12 | public class MixinGuiIngame { 13 | @Inject(method = "renderGameOverlay", at = @At("RETURN")) 14 | private void onRenderGameOverlay(CallbackInfo ci) { 15 | for (OverlayRenderer overlayRenderer : RiftLoader.instance.getListeners(OverlayRenderer.class)) { 16 | overlayRenderer.renderOverlay(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinIntegratedServer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import com.google.gson.JsonElement; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.server.integrated.IntegratedServer; 6 | import net.minecraft.world.EnumDifficulty; 7 | import net.minecraft.world.WorldSettings; 8 | import net.minecraft.world.WorldType; 9 | import net.minecraft.world.storage.WorldInfo; 10 | import org.dimdev.rift.mixin.hook.MixinMinecraftServer; 11 | import org.spongepowered.asm.mixin.Final; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Overwrite; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | 16 | import javax.annotation.Nullable; 17 | 18 | @Mixin(IntegratedServer.class) 19 | public abstract class MixinIntegratedServer extends MixinMinecraftServer { 20 | @Shadow @Final private Minecraft mc; 21 | @Shadow @Final private WorldSettings worldSettings; 22 | 23 | @Override 24 | protected WorldSettings getWorldSettings(@Nullable WorldInfo worldInfo, long seed, WorldType worldType, JsonElement generatorOptions) { 25 | return worldSettings; 26 | } 27 | 28 | @Override 29 | protected EnumDifficulty getInitialDifficulty() { 30 | return mc.gameSettings.difficulty; 31 | } 32 | 33 | @Overwrite 34 | @Override 35 | public void loadAllWorlds(String saveName, String worldName, long seed, WorldType type, JsonElement generatorOptions) { 36 | super.loadAllWorlds(saveName, worldName, seed, type, generatorOptions); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinMinecraft.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.audio.MusicTicker; 5 | import net.minecraft.client.resources.ResourcePackInfoClient; 6 | import net.minecraft.profiler.Profiler; 7 | import net.minecraft.resources.IPackFinder; 8 | import net.minecraft.resources.ResourcePackList; 9 | import org.dimdev.rift.listener.client.KeybindHandler; 10 | import org.dimdev.rift.listener.client.AmbientMusicTypeProvider; 11 | import org.dimdev.rift.listener.client.ClientTickable; 12 | import org.dimdev.rift.listener.ResourcePackFinderAdder; 13 | import org.dimdev.riftloader.RiftLoader; 14 | import org.spongepowered.asm.mixin.Final; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Shadow; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.Redirect; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 22 | 23 | @Mixin(Minecraft.class) 24 | public class MixinMinecraft { 25 | @Shadow @Final private ResourcePackList resourcePackRepository; 26 | @Shadow @Final public Profiler profiler; 27 | 28 | @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/resources/ResourcePackList;addPackFinder(Lnet/minecraft/resources/IPackFinder;)V", ordinal = 1)) 29 | private void onAddResourcePacks(ResourcePackList resourcePackList, IPackFinder minecraftPackFinder) { 30 | resourcePackList.addPackFinder(minecraftPackFinder); 31 | 32 | for (ResourcePackFinderAdder resourcePackFinderAdder : RiftLoader.instance.getListeners(ResourcePackFinderAdder.class)) { 33 | for (IPackFinder packFinder : resourcePackFinderAdder.getResourcePackFinders()) { 34 | resourcePackRepository.addPackFinder(packFinder); 35 | } 36 | } 37 | } 38 | 39 | @Inject(method = "runTick", at = @At("RETURN")) 40 | private void onTick(CallbackInfo ci) { 41 | profiler.startSection("mods"); 42 | for (ClientTickable tickable : RiftLoader.instance.getListeners(ClientTickable.class)) { 43 | profiler.startSection(() -> tickable.getClass().getCanonicalName().replace('.', '/')); 44 | tickable.clientTick(); 45 | profiler.endSection(); 46 | } 47 | profiler.endSection(); 48 | } 49 | 50 | @Inject(method = "getAmbientMusicType", at = @At(value = "INVOKE"), cancellable = true) 51 | private void getMusicType(CallbackInfoReturnable cir) { 52 | for (AmbientMusicTypeProvider ambientMusicTypeProvider : RiftLoader.instance.getListeners(AmbientMusicTypeProvider.class)) { 53 | MusicTicker.MusicType type = ambientMusicTypeProvider.getAmbientMusicType((Minecraft) (Object) this); 54 | 55 | if(type != null) { 56 | cir.setReturnValue(type); 57 | cir.cancel(); 58 | return; 59 | } 60 | } 61 | } 62 | 63 | @Inject(method = "processKeyBinds", at = @At("HEAD")) 64 | public void onProcessKeyBinds(CallbackInfo ci) { 65 | for (KeybindHandler keybindHandler : RiftLoader.instance.getListeners(KeybindHandler.class)) { 66 | keybindHandler.processKeybinds(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinModelBakery.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.renderer.block.model.ModelBakery; 4 | import net.minecraft.util.ResourceLocation; 5 | import org.dimdev.rift.listener.client.TextureAdder; 6 | import org.dimdev.riftloader.RiftLoader; 7 | import org.spongepowered.asm.mixin.Final; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | 11 | import java.util.Set; 12 | 13 | @Mixin(ModelBakery.class) 14 | public class MixinModelBakery { 15 | @Shadow @Final private static Set LOCATIONS_BUILTIN_TEXTURES; 16 | 17 | static { 18 | for (TextureAdder textureAdder : RiftLoader.instance.getListeners(TextureAdder.class)) { 19 | LOCATIONS_BUILTIN_TEXTURES.addAll(textureAdder.getBuiltinTextures()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinNetHandlerPlayClient.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import com.mojang.brigadier.CommandDispatcher; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.multiplayer.ClientAdvancementManager; 7 | import net.minecraft.client.multiplayer.ClientSuggestionProvider; 8 | import net.minecraft.client.multiplayer.WorldClient; 9 | import net.minecraft.client.network.NetHandlerPlayClient; 10 | import net.minecraft.client.util.NBTQueryManager; 11 | import net.minecraft.command.ISuggestionProvider; 12 | import net.minecraft.item.crafting.RecipeManager; 13 | import net.minecraft.network.NetworkManager; 14 | import net.minecraft.network.PacketBuffer; 15 | import net.minecraft.network.play.server.SPacketCustomPayload; 16 | import net.minecraft.network.play.server.SPacketUpdateTileEntity; 17 | import net.minecraft.tags.NetworkTagManager; 18 | import net.minecraft.tileentity.TileEntity; 19 | import net.minecraft.tileentity.TileEntityType; 20 | import net.minecraft.util.ResourceLocation; 21 | import org.dimdev.rift.listener.CustomPayloadHandler; 22 | import org.dimdev.rift.network.ClientMessageContext; 23 | import org.dimdev.rift.network.Message; 24 | import org.dimdev.riftloader.RiftLoader; 25 | import org.spongepowered.asm.mixin.Final; 26 | import org.spongepowered.asm.mixin.Mixin; 27 | import org.spongepowered.asm.mixin.Shadow; 28 | import org.spongepowered.asm.mixin.injection.At; 29 | import org.spongepowered.asm.mixin.injection.Inject; 30 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 31 | 32 | @Mixin(NetHandlerPlayClient.class) 33 | public class MixinNetHandlerPlayClient { 34 | @Shadow private WorldClient world; 35 | 36 | @Shadow @Final private GameProfile profile; 37 | @Shadow private Minecraft client; 38 | @Shadow @Final private RecipeManager recipeManager; 39 | @Shadow @Final private ClientAdvancementManager advancementManager; 40 | @Shadow @Final private NetworkManager netManager; 41 | @Shadow private CommandDispatcher commandDispatcher; 42 | @Shadow @Final private ClientSuggestionProvider clientSuggestionProvider; 43 | @Shadow private NetworkTagManager networkTagManager; 44 | @Shadow private NBTQueryManager nbtQueryManager; 45 | 46 | @SuppressWarnings("deprecation") 47 | @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true) 48 | private void handleModCustomPayload(SPacketCustomPayload packet, CallbackInfo ci) { 49 | ResourceLocation channelName = packet.getChannelName(); 50 | PacketBuffer data = packet.getBufferData(); 51 | 52 | for (CustomPayloadHandler customPayloadHandler : RiftLoader.instance.getListeners(CustomPayloadHandler.class)) { 53 | if (customPayloadHandler.clientHandlesChannel(channelName)) { 54 | customPayloadHandler.clientHandleCustomPayload(channelName, data); 55 | } 56 | } 57 | 58 | Class messageClass = Message.REGISTRY.get(channelName); 59 | if (messageClass != null) { 60 | try { 61 | Message message = RiftLoader.instance.newInstance(messageClass); 62 | message.read(data); 63 | message.process(new ClientMessageContext( 64 | client, 65 | profile, 66 | netManager, 67 | recipeManager, 68 | advancementManager, 69 | commandDispatcher, 70 | clientSuggestionProvider, 71 | networkTagManager, 72 | nbtQueryManager 73 | )); 74 | } catch (ReflectiveOperationException e) { 75 | throw new RuntimeException("Error creating " + messageClass, e); 76 | } 77 | ci.cancel(); 78 | } 79 | } 80 | 81 | @Inject(method = "handleUpdateTileEntity", at = @At("RETURN")) 82 | private void handleUpdateModTileEntity(SPacketUpdateTileEntity packet, CallbackInfo ci) { 83 | TileEntity tileEntity = world.getTileEntity(packet.getPos()); 84 | if (tileEntity == null || packet.getNbtCompound() == null || !packet.getNbtCompound().hasKey("id", 8)) { 85 | return; 86 | } 87 | 88 | ResourceLocation tileEntityId = TileEntityType.getId(tileEntity.getType()); 89 | ResourceLocation packetId = new ResourceLocation(packet.getNbtCompound().getString("id")); 90 | if (packetId != null && !packetId.getNamespace().equals("minecraft") && packetId.equals(tileEntityId)) { 91 | tileEntity.readFromNBT(packet.getNbtCompound()); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinRenderManager.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.renderer.ItemRenderer; 4 | import net.minecraft.client.renderer.entity.Render; 5 | import net.minecraft.client.renderer.entity.RenderManager; 6 | import net.minecraft.client.renderer.texture.TextureManager; 7 | import net.minecraft.entity.Entity; 8 | import org.dimdev.rift.listener.client.EntityRendererAdder; 9 | import org.dimdev.riftloader.RiftLoader; 10 | import org.spongepowered.asm.mixin.Final; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.Shadow; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | import java.util.Map; 18 | 19 | @Mixin(RenderManager.class) 20 | public class MixinRenderManager { 21 | @Shadow @Final private Map, Render> entityRenderMap; 22 | 23 | @Inject(method = "", at = @At("RETURN")) 24 | private void onInit(TextureManager textureManager, ItemRenderer itemRenderer, CallbackInfo ci) { 25 | for (EntityRendererAdder entityRendererAdder : RiftLoader.instance.getListeners(EntityRendererAdder.class)) { 26 | entityRendererAdder.addEntityRenderers(entityRenderMap, (RenderManager) (Object) this); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/mixin/hook/client/MixinTileEntityRendererDispatcher.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.mixin.hook.client; 2 | 3 | import net.minecraft.client.renderer.tileentity.TileEntityRenderer; 4 | import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; 5 | import net.minecraft.tileentity.TileEntity; 6 | import org.dimdev.rift.listener.client.TileEntityRendererAdder; 7 | import org.dimdev.riftloader.RiftLoader; 8 | import org.spongepowered.asm.mixin.Final; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.Map; 16 | 17 | @Mixin(TileEntityRendererDispatcher.class) 18 | public class MixinTileEntityRendererDispatcher { 19 | @Shadow @Final private Map, TileEntityRenderer> renderers; 20 | 21 | @Inject(method = "", at = @At(value = "RETURN")) 22 | private void onRegisterTileEntityRenderDispatcher(CallbackInfo ci) { 23 | for (TileEntityRendererAdder tileEntityRendererAdder : RiftLoader.instance.getListeners(TileEntityRendererAdder.class)) { 24 | tileEntityRendererAdder.addTileEntityRenderers(renderers); 25 | } 26 | 27 | for (TileEntityRenderer renderer : renderers.values()) { 28 | renderer.setRendererDispatcher((TileEntityRendererDispatcher) (Object) this); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/network/ClientMessageContext.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.network; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import com.mojang.brigadier.CommandDispatcher; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.multiplayer.ClientAdvancementManager; 7 | import net.minecraft.client.multiplayer.ClientSuggestionProvider; 8 | import net.minecraft.client.util.NBTQueryManager; 9 | import net.minecraft.command.ISuggestionProvider; 10 | import net.minecraft.item.crafting.RecipeManager; 11 | import net.minecraft.network.NetworkManager; 12 | import net.minecraft.tags.NetworkTagManager; 13 | 14 | public class ClientMessageContext implements MessageContext { 15 | private final Minecraft client; 16 | private final GameProfile profile; 17 | private final NetworkManager networkManager; 18 | private final RecipeManager recipeManager; 19 | private final ClientAdvancementManager advancementManager; 20 | private final CommandDispatcher commandDispatcher; 21 | private final ClientSuggestionProvider clientSuggestionProvider; 22 | private final NetworkTagManager networkTagManager; 23 | private final NBTQueryManager nbtQueryManager; 24 | 25 | public ClientMessageContext( 26 | Minecraft client, 27 | GameProfile profile, 28 | NetworkManager networkManager, 29 | RecipeManager recipeManager, 30 | ClientAdvancementManager advancementManager, 31 | CommandDispatcher commandDispatcher, 32 | ClientSuggestionProvider clientSuggestionProvider, 33 | NetworkTagManager networkTagManager, 34 | NBTQueryManager nbtQueryManager 35 | ) { 36 | this.client = client; 37 | this.profile = profile; 38 | this.networkManager = networkManager; 39 | this.recipeManager = recipeManager; 40 | this.advancementManager = advancementManager; 41 | this.commandDispatcher = commandDispatcher; 42 | this.clientSuggestionProvider = clientSuggestionProvider; 43 | this.networkTagManager = networkTagManager; 44 | this.nbtQueryManager = nbtQueryManager; 45 | } 46 | 47 | public Minecraft getClient() { 48 | return client; 49 | } 50 | 51 | public GameProfile getProfile() { 52 | return profile; 53 | } 54 | 55 | @Override 56 | public NetworkManager getNetworkManager() { 57 | return networkManager; 58 | } 59 | 60 | public RecipeManager getRecipeManager() { 61 | return recipeManager; 62 | } 63 | 64 | public ClientAdvancementManager getAdvancementManager() { 65 | return advancementManager; 66 | } 67 | 68 | public CommandDispatcher getCommandDispatcher() { 69 | return commandDispatcher; 70 | } 71 | 72 | public ClientSuggestionProvider getSuggestionProvider() { 73 | return clientSuggestionProvider; 74 | } 75 | 76 | public NetworkTagManager getNetworkTagManager() { 77 | return networkTagManager; 78 | } 79 | 80 | public NBTQueryManager getNbtQueryManager() { 81 | return nbtQueryManager; 82 | } 83 | 84 | @Override 85 | public void reply(Message message) { 86 | message.sendToServer(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/network/Message.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.network; 2 | 3 | import io.netty.buffer.Unpooled; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.entity.EntityPlayerSP; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.entity.player.EntityPlayerMP; 8 | import net.minecraft.network.EnumPacketDirection; 9 | import net.minecraft.network.INetHandler; 10 | import net.minecraft.network.Packet; 11 | import net.minecraft.network.PacketBuffer; 12 | import net.minecraft.network.play.client.CPacketCustomPayload; 13 | import net.minecraft.network.play.server.SPacketCustomPayload; 14 | import net.minecraft.server.MinecraftServer; 15 | import net.minecraft.util.ResourceLocation; 16 | import net.minecraft.util.registry.RegistryNamespaced; 17 | import net.minecraft.world.WorldServer; 18 | 19 | import java.util.function.Predicate; 20 | 21 | public abstract class Message { 22 | public static final RegistryNamespaced> REGISTRY = new RegistryNamespaced<>(); 23 | 24 | public abstract void write(PacketBuffer buffer); 25 | 26 | public abstract void read(PacketBuffer buffer); 27 | 28 | public void process(ClientMessageContext context) { 29 | throw new UnsupportedOperationException("Packet " + getClass() + " can't be processed on client."); 30 | } 31 | 32 | public void process(ServerMessageContext context) { 33 | throw new UnsupportedOperationException("Packet " + getClass() + " can't be processed on server."); 34 | } 35 | 36 | public final Packet toPacket(EnumPacketDirection direction) { 37 | ResourceLocation id = Message.REGISTRY.getKey(getClass()); 38 | if (id == null) { 39 | throw new IllegalArgumentException("Message was not registered: " + this); 40 | } 41 | 42 | PacketBuffer buffer = new PacketBuffer(Unpooled.buffer()); 43 | write(buffer); 44 | switch (direction) { 45 | case CLIENTBOUND: 46 | return new SPacketCustomPayload(id, buffer); 47 | case SERVERBOUND: 48 | return new CPacketCustomPayload(id, buffer); 49 | default: 50 | throw new AssertionError("unreachable"); 51 | } 52 | } 53 | 54 | public final void send(EntityPlayer player) { 55 | if (player instanceof EntityPlayerMP) { 56 | ((EntityPlayerMP) player).connection.getNetworkManager().sendPacket(toPacket(EnumPacketDirection.CLIENTBOUND)); 57 | } else if (player instanceof EntityPlayerSP) { 58 | ((EntityPlayerSP) player).connection.getNetworkManager().sendPacket(toPacket(EnumPacketDirection.SERVERBOUND)); 59 | } else { 60 | throw new IllegalArgumentException("Only supported for EntityPlayerMP and EntityPlayerSP, but got " + player.getClass()); 61 | } 62 | } 63 | 64 | public final void sendToAll(MinecraftServer server) { 65 | for (EntityPlayerMP player : server.getPlayerList().getPlayers()) { 66 | send(player); 67 | } 68 | } 69 | 70 | public final void sendToAll(MinecraftServer server, Predicate filter) { 71 | for (EntityPlayerMP player : server.getPlayerList().getPlayers()) { 72 | if (filter.test(player)) { 73 | send(player); 74 | } 75 | } 76 | } 77 | 78 | public final void sendToAll(WorldServer world, Predicate filter) { 79 | for (EntityPlayerMP player : world.getPlayers(EntityPlayerMP.class, filter)) { 80 | send(player); 81 | } 82 | } 83 | 84 | public final void sendToAll(WorldServer world) { 85 | for (EntityPlayerMP player : world.getPlayers(EntityPlayerMP.class, player -> true)) { 86 | send(player); 87 | } 88 | } 89 | 90 | public void sendToServer() { 91 | Minecraft.getInstance().player.connection.sendPacket(toPacket(EnumPacketDirection.SERVERBOUND)); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/network/MessageContext.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.network; 2 | 3 | import net.minecraft.network.NetworkManager; 4 | 5 | public interface MessageContext { 6 | NetworkManager getNetworkManager(); 7 | 8 | void reply(Message message); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/network/MessageRegistrator.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.network; 2 | 3 | import org.dimdev.rift.listener.BootstrapListener; 4 | import org.dimdev.rift.listener.MessageAdder; 5 | import org.dimdev.riftloader.RiftLoader; 6 | 7 | public class MessageRegistrator implements BootstrapListener { 8 | @Override 9 | public void afterVanillaBootstrap() { 10 | for (MessageAdder messageAdder : RiftLoader.instance.getListeners(MessageAdder.class)) { 11 | messageAdder.registerMessages(Message.REGISTRY); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/network/ServerMessageContext.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.network; 2 | 3 | import net.minecraft.entity.player.EntityPlayerMP; 4 | import net.minecraft.network.NetworkManager; 5 | import net.minecraft.server.MinecraftServer; 6 | 7 | public class ServerMessageContext implements MessageContext { 8 | private final MinecraftServer server; 9 | private final EntityPlayerMP sender; 10 | private final NetworkManager networkManager; 11 | 12 | public ServerMessageContext(MinecraftServer server, EntityPlayerMP sender, NetworkManager networkManager) { 13 | this.server = server; 14 | this.sender = sender; 15 | this.networkManager = networkManager; 16 | } 17 | 18 | public MinecraftServer getServer() { 19 | return server; 20 | } 21 | 22 | public EntityPlayerMP getSender() { 23 | return sender; 24 | } 25 | 26 | @Override 27 | public NetworkManager getNetworkManager() { 28 | return networkManager; 29 | } 30 | 31 | @Override 32 | public void reply(Message message) { 33 | message.send(sender); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/resources/ModPack.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.resources; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.minecraft.resources.AbstractResourcePack; 5 | import net.minecraft.resources.ResourcePackType; 6 | import net.minecraft.util.ResourceLocation; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | import java.io.File; 11 | import java.io.FileNotFoundException; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.net.URI; 15 | import java.net.URISyntaxException; 16 | import java.net.URL; 17 | import java.nio.file.*; 18 | import java.util.*; 19 | import java.util.function.Predicate; 20 | 21 | public class ModPack extends AbstractResourcePack { 22 | private final String root; 23 | private final String name; 24 | private Logger LOGGER = LogManager.getLogger(); 25 | 26 | public ModPack(String name, URL root) { 27 | super(null); 28 | this.name = name; 29 | this.root = root.toString(); 30 | } 31 | 32 | @Override 33 | protected InputStream getInputStream(String path) throws IOException { 34 | return new URL(root + path).openStream(); 35 | } 36 | 37 | @Override 38 | protected boolean resourceExists(String path) { 39 | try (InputStream ignored = getInputStream(path)) { 40 | return true; 41 | } catch (IOException e) { 42 | return false; 43 | } 44 | } 45 | 46 | @Override 47 | public Collection getAllResourceLocations(ResourcePackType type, String path, int maxDepth, Predicate filter) { 48 | Set resourceLocations = new HashSet<>(); 49 | for (String namespace : getResourceNamespaces(type)) { 50 | resourceLocations.addAll(getAllResourceLocations(type, new ResourceLocation(namespace, path), maxDepth, filter)); 51 | } 52 | return resourceLocations; 53 | } 54 | 55 | public Collection getAllResourceLocations(ResourcePackType type, ResourceLocation location, int maxDepth, Predicate filter) { 56 | Set resourceLocations = new HashSet<>(); 57 | 58 | try { 59 | String path = String.format("%s/%s/%s", type.getDirectoryName(), location.getNamespace(), location.getPath()); 60 | URI url = new URL(root + path).toURI(); 61 | if ("file".equals(url.getScheme())) { 62 | resourceLocations.addAll(getAllResourceLocations(maxDepth, location, Paths.get(url), filter)); 63 | } else if ("jar".equals(url.getScheme())) { 64 | try (FileSystem fileSystem = FileSystems.newFileSystem(url, Collections.emptyMap())) { 65 | resourceLocations.addAll(getAllResourceLocations(maxDepth, location, fileSystem.getPath(path), filter)); 66 | } 67 | } else { 68 | LOGGER.error("Unsupported scheme " + url + " trying to list mod resources"); 69 | } 70 | } catch (NoSuchFileException | FileNotFoundException ignored) { 71 | } catch (IOException | URISyntaxException e) { 72 | LOGGER.error("Couldn't get a list of all resources of '" + getName() + "'", e); 73 | } 74 | 75 | return resourceLocations; 76 | } 77 | 78 | private static Collection getAllResourceLocations(int maxDepth, ResourceLocation rootLocation, Path rootPath, Predicate filter) throws IOException { 79 | List resourceLocations = Lists.newArrayList(); 80 | Iterator pathIterator = Files.walk(rootPath, maxDepth).iterator(); 81 | 82 | while (pathIterator.hasNext()) { 83 | Path path = pathIterator.next(); 84 | if (!path.endsWith(".mcmeta") && Files.isRegularFile(path) && filter.test(path.getFileName().toString())) { 85 | resourceLocations.add(new ResourceLocation(rootLocation.getNamespace(), rootLocation.getPath() + "/" + rootPath.toAbsolutePath().relativize(path).toString().replaceAll("\\\\", "/"))); 86 | } 87 | } 88 | 89 | return resourceLocations; 90 | } 91 | 92 | @Override 93 | public Set getResourceNamespaces(ResourcePackType type) { 94 | try { 95 | URI uri = new URL(root + type.getDirectoryName() + "/").toURI(); 96 | if ("file".equals(uri.getScheme())) { 97 | Set namespaces = new HashSet<>(); 98 | File rootFile = new File(uri); 99 | if (rootFile.isDirectory()) { 100 | for (File file : rootFile.listFiles()) { 101 | namespaces.add(file.getName()); 102 | } 103 | } 104 | return namespaces; 105 | } else if ("jar".equals(uri.getScheme())) { 106 | try (FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap()); 107 | DirectoryStream directoryStream = fileSystem.provider().newDirectoryStream(fileSystem.getPath(type.getDirectoryName()), x -> true)) { 108 | Set namespaces = new HashSet<>(); 109 | for (Path p : directoryStream) { 110 | String fileName = p.getFileName().toString(); 111 | namespaces.add(fileName.substring(0, fileName.length() - 1)); 112 | } 113 | return namespaces; 114 | } 115 | } else { 116 | LOGGER.error("Unsupported scheme " + uri + " trying to list mod resource namespaces"); 117 | } 118 | } catch (NoSuchFileException | FileNotFoundException | NotDirectoryException ignored) { 119 | } catch (IOException | URISyntaxException e) { 120 | LOGGER.error("Couldn't get a list of resource namespaces of '" + getName() + "'", e); 121 | } 122 | 123 | return Collections.emptySet(); 124 | } 125 | 126 | @Override 127 | public void close() {} 128 | 129 | @Override 130 | public String getName() { 131 | return name; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/resources/ModPackFinder.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.resources; 2 | 3 | import net.minecraft.resources.IPackFinder; 4 | import net.minecraft.resources.ResourcePackInfo; 5 | import net.minecraft.resources.ResourcePackType; 6 | import net.minecraft.resources.data.PackMetadataSection; 7 | import org.dimdev.riftloader.ModInfo; 8 | import org.dimdev.riftloader.RiftLoader; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.net.URL; 13 | import java.util.Map; 14 | 15 | public class ModPackFinder implements IPackFinder { 16 | private final ResourcePackType type; 17 | 18 | public ModPackFinder(ResourcePackType type) { 19 | this.type = type; 20 | } 21 | 22 | @Override 23 | public void addPackInfosToMap(Map nameToPackMap, ResourcePackInfo.IFactory packInfoFactory) { 24 | for (ModInfo mod : RiftLoader.instance.getMods()) { 25 | URL root = getRootUrl(mod); 26 | 27 | try (ModPack pack = new ModPack(mod.name != null ? mod.name : mod.id, root)) { 28 | PackMetadataSection meta = pack.getMetadata(PackMetadataSection.SERIALIZER); 29 | if (meta != null && !pack.getResourceNamespaces(type).isEmpty()) { 30 | nameToPackMap.put(mod.id, packInfoFactory.create(mod.id, type == ResourcePackType.CLIENT_RESOURCES, () -> pack, pack, meta, ResourcePackInfo.Priority.TOP)); 31 | } 32 | } catch (IOException ignored) {} 33 | } 34 | } 35 | 36 | public URL getRootUrl(ModInfo mod) { 37 | File source = mod.source; 38 | URL root; 39 | try { 40 | if (source.isFile()) { 41 | root = new URL("jar:" + source.toURI().toURL() + "!/"); 42 | } else { 43 | root = source.toURI().toURL(); 44 | } 45 | } catch (IOException e) { 46 | throw new RuntimeException(e); 47 | } 48 | return root; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/resources/ResourceManager.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.resources; 2 | 3 | import net.minecraft.resources.IPackFinder; 4 | import net.minecraft.resources.ResourcePackType; 5 | import org.dimdev.rift.listener.DataPackFinderAdder; 6 | import org.dimdev.rift.listener.ResourcePackFinderAdder; 7 | 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class ResourceManager implements ResourcePackFinderAdder, DataPackFinderAdder { 12 | @Override 13 | public List getResourcePackFinders() { 14 | return Collections.singletonList(new ModPackFinder(ResourcePackType.CLIENT_RESOURCES)); 15 | } 16 | 17 | @Override public List getDataPackFinders() { 18 | return Collections.singletonList(new ModPackFinder(ResourcePackType.SERVER_DATA)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/util/ArmorMaterialImpl.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.util; 2 | 3 | import net.minecraft.inventory.EntityEquipmentSlot; 4 | import net.minecraft.item.ArmorMaterial; 5 | import net.minecraft.item.IArmorMaterial; 6 | import net.minecraft.item.crafting.Ingredient; 7 | import net.minecraft.util.LazyLoadBase; 8 | import net.minecraft.util.SoundEvent; 9 | 10 | import java.util.function.Supplier; 11 | 12 | public class ArmorMaterialImpl implements IArmorMaterial { 13 | private final String name; 14 | private final int maxDamageFactor; 15 | private final int[] damageReductionAmountArray; 16 | private final int enchantability; 17 | private final SoundEvent soundEvent; 18 | private final float toughness; 19 | private final LazyLoadBase ingredient; 20 | 21 | public ArmorMaterialImpl(String name, int maxDamageFactor, int[] damageReductionAmountArray, int enchantability, SoundEvent soundEvent, float toughness, Supplier ingredientSupplier) { 22 | this.name = name; 23 | this.maxDamageFactor = maxDamageFactor; 24 | this.damageReductionAmountArray = damageReductionAmountArray; 25 | this.enchantability = enchantability; 26 | this.soundEvent = soundEvent; 27 | this.toughness = toughness; 28 | this.ingredient = new LazyLoadBase<>(ingredientSupplier); 29 | } 30 | 31 | @Override 32 | public int getDurability(EntityEquipmentSlot slot) { 33 | return ArmorMaterial.MAX_DAMAGE_ARRAY[slot.getIndex()] * maxDamageFactor; 34 | } 35 | 36 | @Override 37 | public int getDamageReductionAmount(EntityEquipmentSlot slot) { 38 | return damageReductionAmountArray[slot.getIndex()]; 39 | } 40 | 41 | @Override 42 | public int getEnchantability() { 43 | return enchantability; 44 | } 45 | 46 | @Override 47 | public SoundEvent getSoundEvent() { 48 | return soundEvent; 49 | } 50 | 51 | @Override 52 | public Ingredient getRepairMaterial() { 53 | return ingredient.getValue(); 54 | } 55 | 56 | @Override 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | @Override 62 | public float getToughness() { 63 | return toughness; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/util/ItemTierImpl.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.util; 2 | 3 | import net.minecraft.item.IItemTier; 4 | import net.minecraft.item.crafting.Ingredient; 5 | import net.minecraft.util.LazyLoadBase; 6 | 7 | import java.util.function.Supplier; 8 | 9 | public class ItemTierImpl implements IItemTier { 10 | private final int harvestLevel; 11 | private final int maxUses; 12 | private final float efficiency; 13 | private final float attackDamage; 14 | private final int enchantability; 15 | private final LazyLoadBase ingredient; 16 | 17 | public ItemTierImpl(int harvestLevel, int maxUses, float efficiency, float attackDamage, int enchantability, Supplier ingredientSupplier) { 18 | this.harvestLevel = harvestLevel; 19 | this.maxUses = maxUses; 20 | this.efficiency = efficiency; 21 | this.attackDamage = attackDamage; 22 | this.enchantability = enchantability; 23 | this.ingredient = new LazyLoadBase<>(ingredientSupplier); 24 | } 25 | 26 | @Override 27 | public int getMaxUses() { 28 | return maxUses; 29 | } 30 | 31 | @Override 32 | public float getEfficiency() { 33 | return efficiency; 34 | } 35 | 36 | @Override 37 | public float getAttackDamage() { 38 | return attackDamage; 39 | } 40 | 41 | @Override 42 | public int getHarvestLevel() { 43 | return harvestLevel; 44 | } 45 | 46 | @Override 47 | public int getEnchantability() { 48 | return enchantability; 49 | } 50 | 51 | @Override 52 | public Ingredient getRepairMaterial() { 53 | return ingredient.getValue(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/util/NBTSerializable.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.util; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * Base interface for (de)serializable objects to serialize 9 | * themselves to and from {@link NBTTagCompound} tag compounds 10 | */ 11 | public interface NBTSerializable { 12 | /** 13 | * Writes this object's data to the given compound 14 | * @param compound The tag compound to be written to 15 | * @return The written tag compound 16 | */ 17 | @Nonnull 18 | NBTTagCompound serialize(@Nonnull NBTTagCompound compound); 19 | 20 | /** 21 | * Reads this object's data from the given compound 22 | * @param compound The tag compound to be read from 23 | * @return The given tag compound 24 | */ 25 | @Nonnull 26 | NBTTagCompound deserialize(@Nonnull NBTTagCompound compound); 27 | 28 | /** 29 | * Writes this object's data to a new tag compound 30 | * @return The written tag compound 31 | */ 32 | @Nonnull 33 | default NBTTagCompound writeToNBT() { 34 | return this.serialize(new NBTTagCompound()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/rift/util/NBTSerializer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.rift.util; 2 | 3 | import net.minecraft.nbt.NBTTagCompound; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * Base interface for (de)serializing objects of type {@code T} 9 | * to and from {@link NBTTagCompound} tag compounds 10 | */ 11 | public interface NBTSerializer { 12 | /** 13 | * Writes an object {@code T} to the given compound 14 | * @param instance The instance to be serialized 15 | * @return The written tag compound 16 | */ 17 | @Nonnull 18 | NBTTagCompound serialize(@Nonnull T instance); 19 | 20 | /** 21 | * Reads an object {@code T} from the given compound 22 | * @param compound The tag compound to be read from 23 | * @return An instance of {@code T} 24 | */ 25 | @Nonnull 26 | T deserialize(@Nonnull NBTTagCompound compound); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/DuplicateModException.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | public class DuplicateModException extends RuntimeException { 4 | private final ModInfo mod1; 5 | private final ModInfo mod2; 6 | 7 | public DuplicateModException(ModInfo mod1, ModInfo mod2) { 8 | if (!mod1.id.equals(mod2.id)) { 9 | throw new IllegalArgumentException(); 10 | } 11 | 12 | this.mod1 = mod1; 13 | this.mod2 = mod2; 14 | } 15 | 16 | public String getMessage() { 17 | return "Duplicate mod " + mod1.id + ":\r\n - " + mod1.source + "\r\n - " + mod2.source; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/Main.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import net.minecraft.launchwrapper.Launch; 4 | import org.dimdev.utils.ReflectionUtils; 5 | 6 | import javax.swing.*; 7 | import java.io.*; 8 | import java.net.URL; 9 | import java.nio.channels.Channels; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | import java.nio.file.StandardCopyOption; 13 | import java.util.*; 14 | 15 | public class Main { 16 | private static final String[] LIBRARIES = { 17 | "https://www.dimdev.org/maven/org/dimdev/mixin/0.7.11-SNAPSHOT/mixin-0.7.11-SNAPSHOT.jar", 18 | "https://repo1.maven.org/maven2/org/ow2/asm/asm/6.2/asm-6.2.jar", 19 | "https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/6.2/asm-commons-6.2.jar", 20 | "https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/6.2/asm-tree-6.2.jar", 21 | "https://libraries.minecraft.net/net/minecraft/launchwrapper/1.12/launchwrapper-1.12.jar" 22 | }; 23 | public static final String VANILLA_SERVER = "https://launcher.mojang.com/mc/game/1.13/server/d0caafb8438ebd206f99930cfaecfa6c9a13dca0/server.jar"; 24 | // public static final String SPIGOT_SERVER = "https://cdn.getbukkit.org/spigot/spigot-1.13.jar"; 25 | 26 | public static void main(String... args) throws Throwable { 27 | if (args.length == 0 || args[0].equals("--install")) { 28 | runClientInstaller(); 29 | } else if (args[0].equals("--server")) { 30 | File serverJar = new File("server.jar"); 31 | if (!serverJar.isFile()) { 32 | System.out.println("File 'server.jar' does not exist"); 33 | System.out.println("Choose which server you'd like to download:"); 34 | System.out.println(" 1) Vanilla"); 35 | // System.out.println(" 2) Spigot"); 36 | System.out.print("Choice: "); 37 | 38 | URL url; 39 | String line = new Scanner(System.in).nextLine().toLowerCase(); 40 | if (line.startsWith("1") || line.startsWith("v")) { 41 | url = new URL(VANILLA_SERVER); 42 | // } else if (line.startsWith("2") || line.startsWith("s")) { 43 | // url = new URL(SPIGOT_SERVER); 44 | } else { 45 | System.err.println("Not a valid choice"); 46 | return; 47 | } 48 | 49 | System.out.println("Downloading server jar: " + url); 50 | new FileOutputStream(serverJar).getChannel().transferFrom(Channels.newChannel(url.openStream()), 0, Long.MAX_VALUE); 51 | } 52 | 53 | ReflectionUtils.addURLToClasspath(serverJar.toURI().toURL()); 54 | 55 | for (String url : LIBRARIES) { 56 | ReflectionUtils.addURLToClasspath(getOrDownload(new File("libs"), new URL(url)).toURI().toURL()); 57 | } 58 | 59 | List argsList = new ArrayList<>(Arrays.asList(args).subList(1, args.length)); 60 | argsList.add("--tweakClass"); 61 | argsList.add("org.dimdev.riftloader.launch.RiftLoaderServerTweaker"); 62 | 63 | System.out.println("Launching server..."); 64 | Launch.main(argsList.toArray(new String[0])); 65 | } 66 | } 67 | 68 | private static File getOrDownload(File directory, URL url) throws IOException { 69 | String urlString = url.toString(); 70 | File target = new File(directory, urlString.substring(urlString.lastIndexOf('/') + 1)); 71 | if (target.isFile()) { 72 | return target; 73 | } 74 | target.getParentFile().mkdirs(); 75 | 76 | System.out.println("Downloading library: " + urlString); 77 | new FileOutputStream(target).getChannel().transferFrom(Channels.newChannel(url.openStream()), 0, Long.MAX_VALUE); 78 | 79 | return target; 80 | } 81 | 82 | public static void runClientInstaller() { 83 | try { 84 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 85 | } catch (Throwable t) { 86 | t.printStackTrace(); 87 | } 88 | 89 | try { 90 | File minecraftFolder; 91 | String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); 92 | if (osName.contains("win")) { 93 | minecraftFolder = new File(System.getenv("APPDATA") + "/.minecraft"); 94 | } else if (osName.contains("mac")) { 95 | minecraftFolder = new File(System.getProperty("user.home") + "/Library/Application Support/minecraft"); 96 | } else { 97 | minecraftFolder = new File(System.getProperty("user.home") + "/.minecraft"); 98 | } 99 | 100 | // Copy the version json 101 | File versionJson = new File(minecraftFolder, "versions/1.13-rift-@VERSION@/1.13-rift-@VERSION@.json"); 102 | versionJson.getParentFile().mkdirs(); 103 | Files.copy(Main.class.getResourceAsStream("/profile.json"), versionJson.toPath(), StandardCopyOption.REPLACE_EXISTING); 104 | 105 | // Make mods directory 106 | try { 107 | File modsFolder = new File(minecraftFolder, "mods"); 108 | modsFolder.mkdirs(); 109 | } catch (Throwable t) { 110 | t.printStackTrace(); 111 | } 112 | 113 | // Add rift as a profile 114 | try { 115 | File profilesJson = new File(minecraftFolder, "launcher_profiles.json"); 116 | if (profilesJson.exists()) { // TODO: use gson instead 117 | String contents = new String(Files.readAllBytes(profilesJson.toPath())); 118 | if (contents.contains("\"rift\"")) { 119 | contents = contents.replaceAll(",\n *\"rift\": \\{[^}]*},", ","); 120 | contents = contents.replaceAll(",?\n *\"rift\": \\{[^}]*},?", ""); 121 | } 122 | 123 | contents = contents.replace("\n \"profiles\": {", "\n \"profiles\": {\n" + 124 | " \"rift\": {\n" + 125 | " \"name\": \"Rift\",\n" + 126 | " \"type\": \"custom\",\n" + 127 | " \"created\": \"2018-08-13T00:00:00.000Z\",\n" + 128 | " \"lastUsed\": \"2100-01-01T00:00:00.000Z\",\n" + 129 | " \"lastVersionId\": \"1.13-rift-@VERSION@\"\n" + 130 | " },"); 131 | 132 | Files.write(profilesJson.toPath(), contents.getBytes()); 133 | } 134 | } catch (Throwable t) { 135 | t.printStackTrace(); 136 | } 137 | 138 | // Copy rift jar to libraries 139 | try { 140 | String source = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 141 | if (source.startsWith("/") && osName.contains("win")) { 142 | source = source.substring(1); 143 | } 144 | File riftJar = new File(minecraftFolder, "libraries/org/dimdev/rift/@VERSION@/rift-@VERSION@.jar"); 145 | riftJar.getParentFile().mkdirs(); 146 | Files.copy(Paths.get(source), riftJar.toPath(), StandardCopyOption.REPLACE_EXISTING); 147 | } catch (Throwable t) { 148 | t.printStackTrace(); 149 | } 150 | 151 | JOptionPane.showMessageDialog(null, 152 | "Rift @VERSION@ for Minecraft 1.13 has been successfully installed!\n" + 153 | "\n" + 154 | "It is available in the dropdown menu of the vanilla Minecraft launcher.\n" + 155 | "You'll need to restart the Minecraft Launcher if you had it open when\n" + 156 | "you ran this installer.", 157 | "Rift Installer", JOptionPane.INFORMATION_MESSAGE); 158 | } catch (Throwable t) { 159 | StringWriter w = new StringWriter(); 160 | t.printStackTrace(new PrintWriter(w)); 161 | JOptionPane.showMessageDialog(null, 162 | "An error occured while installing Rift, please report this to the issue\n" + 163 | "tracker (https://github.com/DimensionalDevelopment/Rift/issues):\n" + 164 | "\n" + 165 | w.toString().replace("\t", " "), "Rift Installer", JOptionPane.ERROR_MESSAGE); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/ModInfo.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import com.google.gson.*; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import java.io.File; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class ModInfo { 11 | public static Gson GSON = new GsonBuilder() 12 | .registerTypeAdapter(Listener.class, (JsonSerializer) (listener, type, context) -> { 13 | if (listener.priority == 0 && listener.side == Side.BOTH) { 14 | return new JsonPrimitive(listener.className); 15 | } 16 | 17 | return new Gson().toJsonTree(listener); 18 | }) 19 | .registerTypeAdapter(Listener.class, (JsonDeserializer) (json, type, context) -> { 20 | if (json.isJsonPrimitive() && json.isJsonPrimitive() && ((JsonPrimitive) json).isString()) { 21 | return new Listener(json.getAsString()); 22 | } 23 | 24 | return new Gson().fromJson(json, type); 25 | }) 26 | .create(); 27 | 28 | public static class Listener { 29 | @SerializedName("class") public String className; 30 | public int priority = 0; 31 | public Side side = Side.BOTH; 32 | 33 | public Listener(String className) { 34 | this.className = className; 35 | } 36 | } 37 | 38 | public File source; 39 | 40 | public String id; 41 | public String name; 42 | public List authors = new ArrayList<>(); 43 | public List listeners = new ArrayList<>(); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/OptifineLoader.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import net.minecraft.launchwrapper.ITweaker; 4 | import net.minecraft.launchwrapper.Launch; 5 | import net.minecraft.launchwrapper.LaunchClassLoader; 6 | import org.dimdev.riftloader.listener.InitializationListener; 7 | 8 | import java.io.File; 9 | import java.util.List; 10 | 11 | public class OptifineLoader implements InitializationListener { 12 | @Override 13 | public void onInitialization() { 14 | //noinspection unchecked 15 | ((List) Launch.blackboard.get("TweakClasses")).add("org.dimdev.riftloader.OptifineLoader$Tweaker"); 16 | Launch.classLoader.addClassLoaderExclusion("optifine."); 17 | } 18 | 19 | public static class Tweaker implements ITweaker { 20 | @Override 21 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) {} 22 | 23 | @Override 24 | public void injectIntoClassLoader(LaunchClassLoader classLoader) { 25 | classLoader.registerTransformer("optifine.OptiFineClassTransformer"); 26 | } 27 | 28 | @Override 29 | public String getLaunchTarget() { 30 | return null; 31 | } 32 | 33 | @Override 34 | public String[] getLaunchArguments() { 35 | return new String[0]; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/RiftAccessTransformer.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import net.minecraft.launchwrapper.IClassTransformer; 4 | 5 | public class RiftAccessTransformer implements IClassTransformer { 6 | @Override 7 | public byte[] transform(String name, String transformedName, byte[] basicClass) { 8 | return RiftLoader.instance.accessTransformer.transformClass(name, basicClass); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/RiftLoader.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import com.google.gson.JsonParseException; 4 | import net.minecraft.launchwrapper.Launch; 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | import org.dimdev.accesstransform.AccessTransformationSet; 8 | import org.dimdev.accesstransform.AccessTransformer; 9 | import org.dimdev.riftloader.listener.InitializationListener; 10 | import org.dimdev.riftloader.listener.Instantiator; 11 | import org.dimdev.utils.InstanceListMap; 12 | import org.dimdev.utils.InstanceMap; 13 | import org.dimdev.utils.ReflectionUtils; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.InputStreamReader; 19 | import java.lang.reflect.Constructor; 20 | import java.net.MalformedURLException; 21 | import java.net.URISyntaxException; 22 | import java.net.URL; 23 | import java.util.*; 24 | import java.util.jar.JarEntry; 25 | import java.util.jar.JarFile; 26 | import java.util.zip.ZipException; 27 | 28 | public class RiftLoader { 29 | public static final RiftLoader instance = new RiftLoader(); 30 | private static final Logger log = LogManager.getLogger("RiftLoader"); 31 | 32 | public final File modsDir = new File(Launch.minecraftHome, "mods"); 33 | public final File configDir = new File(Launch.minecraftHome, "config"); 34 | private Side side; 35 | private boolean loaded; 36 | 37 | public AccessTransformer accessTransformer; 38 | private Map modInfoMap = new LinkedHashMap<>(); 39 | private List> listenerClasses = new ArrayList<>(); 40 | private InstanceMap listenerInstanceMap = new InstanceMap(); 41 | private InstanceListMap listeners = new InstanceListMap(); 42 | private InstanceListMap customListenerInstances = new InstanceListMap(); 43 | 44 | public void load(boolean isClient) { 45 | if (loaded) { 46 | throw new IllegalStateException("Already loaded"); 47 | } 48 | loaded = true; 49 | 50 | side = isClient ? Side.CLIENT : Side.SERVER; 51 | 52 | findMods(modsDir); 53 | sortMods(); 54 | initMods(); 55 | initAccessTransformer(); 56 | } 57 | 58 | /** 59 | * Looks for Rift mods (jars containing a 'riftmod.json' at their root) in 60 | * the 'modsDir' directory (creating it if it doesn't exist) and loads them 61 | * into the 'modInfoMap'. 62 | **/ 63 | private void findMods(File modsDir) { 64 | // Load classpath mods 65 | log.info("Searching mods on classpath"); 66 | try { 67 | Enumeration urls = ClassLoader.getSystemResources("riftmod.json"); 68 | while (urls.hasMoreElements()) { 69 | URL url = urls.nextElement(); 70 | InputStream in = url.openStream(); 71 | 72 | // Convert jar utls to file urls (from JarUrlConnection.parseSpecs) 73 | switch (url.getProtocol()) { 74 | case "jar": 75 | String spec = url.getFile(); 76 | 77 | int separator = spec.indexOf("!/"); 78 | if (separator == -1) { 79 | throw new MalformedURLException("no !/ found in url spec:" + spec); 80 | } 81 | 82 | url = new URL(spec.substring(0, separator)); 83 | 84 | loadModFromJson(in, new File(url.toURI())); 85 | break; 86 | case "file": 87 | loadModFromJson(in, new File(url.toURI()).getParentFile()); 88 | break; 89 | default: 90 | throw new RuntimeException("Unsupported protocol: " + url); 91 | } 92 | } 93 | } catch (IOException | URISyntaxException e) { 94 | throw new RuntimeException(e); 95 | } 96 | 97 | // Load jar mods 98 | log.info("Searching for mods in " + modsDir); 99 | modsDir.mkdirs(); 100 | for (File file : modsDir.listFiles()) { 101 | if (!file.getName().endsWith(".jar")) continue; 102 | 103 | try (JarFile jar = new JarFile(file)) { 104 | // Check if the file contains a 'riftmod.json' 105 | if (!file.isFile()) continue; // Inside try since there may be a SecurityException 106 | 107 | JarEntry entry = jar.getJarEntry("riftmod.json"); 108 | if (entry != null) { 109 | loadModFromJson(jar.getInputStream(entry), file); 110 | continue; 111 | } 112 | 113 | if (jar.getJarEntry("optifine/OptiFineClassTransformer.class") != null) { 114 | ModInfo mod = new ModInfo(); 115 | mod.source = file; 116 | mod.id = "optifine"; 117 | mod.name = "Optifine"; 118 | mod.authors.add("sp614x"); 119 | mod.listeners.add(new ModInfo.Listener("org.dimdev.riftloader.OptifineLoader")); 120 | modInfoMap.put("optifine", mod); 121 | } 122 | 123 | log.debug("Skipping " + file + " since it does not contain riftmod.json"); 124 | } catch (ZipException e) { 125 | log.error("Could not read file " + file + " as a jar file", e); 126 | } catch (Throwable t) { 127 | log.error("Exception while checking if file " + file + " is a mod", t); 128 | } 129 | } 130 | 131 | log.info("Loaded " + modInfoMap.size() + " mods"); 132 | } 133 | 134 | private void loadModFromJson(InputStream in, File source) { 135 | try { 136 | // Parse the 'riftmod.json' and make a ModInfo 137 | ModInfo modInfo = ModInfo.GSON.fromJson(new InputStreamReader(in), ModInfo.class); 138 | modInfo.source = source; 139 | 140 | // Make sure the id isn't null and there aren't any duplicates 141 | if (modInfo.id == null) { 142 | log.error("Mod file " + modInfo.source + "'s riftmod.json is missing a 'id' field"); 143 | return; 144 | } else if (modInfoMap.containsKey(modInfo.id)) { 145 | throw new DuplicateModException(modInfo, modInfoMap.get(modInfo.id)); 146 | } 147 | 148 | // Add the mod to the 'id -> mod info' map 149 | modInfoMap.put(modInfo.id, modInfo); 150 | log.info("Loaded mod '" + modInfo.id + "'"); 151 | } catch (JsonParseException e) { 152 | throw new RuntimeException("Could not read riftmod.json in " + source, e); 153 | } 154 | } 155 | 156 | private void sortMods() { 157 | log.debug("Sorting mods"); 158 | } 159 | 160 | private void initMods() { 161 | log.info("Initializing mods"); 162 | // Load all the mod jars 163 | for (ModInfo modInfo : modInfoMap.values()) { 164 | try { 165 | addURLToClasspath(modInfo.source.toURI().toURL()); 166 | } catch (MalformedURLException e) { 167 | throw new RuntimeException(e); 168 | } 169 | } 170 | 171 | // Load the listener classes 172 | for (ModInfo modInfo : modInfoMap.values()) { 173 | if (modInfo.listeners != null) { 174 | for (ModInfo.Listener listener : modInfo.listeners) { 175 | if (listener.side.includes(side)) { 176 | Class listenerClass; 177 | try { 178 | listenerClass = Launch.classLoader.findClass(listener.className); 179 | listenerClasses.add(listenerClass); 180 | } catch (ReflectiveOperationException e) { 181 | throw new RuntimeException("Failed to find listener class " + listener.className, e); 182 | } 183 | } 184 | } 185 | } 186 | } 187 | 188 | for (InitializationListener listener : getListeners(InitializationListener.class)) { 189 | listener.onInitialization(); 190 | } 191 | 192 | log.info("Done initializing mods"); 193 | } 194 | 195 | private static void addURLToClasspath(URL url) { 196 | ReflectionUtils.addURLToClasspath(url); 197 | Launch.classLoader.addURL(url); 198 | } 199 | 200 | private void initAccessTransformer() { 201 | try { 202 | AccessTransformationSet transformations = new AccessTransformationSet(); 203 | 204 | Enumeration urls = Launch.classLoader.getResources("access_transformations.at"); 205 | while (urls.hasMoreElements()) { 206 | URL url = urls.nextElement(); 207 | try (Scanner scanner = new Scanner(url.openStream())) { 208 | while (scanner.hasNextLine()) { 209 | transformations.addMinimumAccessLevel(scanner.nextLine()); 210 | } 211 | } 212 | } 213 | 214 | accessTransformer = new AccessTransformer(transformations); 215 | Launch.classLoader.registerTransformer("org.dimdev.riftloader.RiftAccessTransformer"); 216 | } catch (Throwable t) { 217 | throw new RuntimeException("Failed to initialize access transformers", t); 218 | } 219 | } 220 | 221 | public Collection getMods() { 222 | return modInfoMap.values(); 223 | } 224 | 225 | public Side getSide() { 226 | return side; 227 | } 228 | 229 | public List getListeners(Class listenerInterface) { 230 | List listenerInstances = listeners.get(listenerInterface); 231 | 232 | if (listenerInstances == null) { 233 | loadListeners(listenerInterface); 234 | listenerInstances = listeners.get(listenerInterface); 235 | } 236 | 237 | return listenerInstances; 238 | } 239 | 240 | public void loadListeners(Class listenerInterface) { 241 | List listenerInstances = new ArrayList<>(); 242 | listeners.put(listenerInterface, listenerInstances); 243 | 244 | for (Class listenerClass : listenerClasses) { 245 | if (listenerInterface.isAssignableFrom(listenerClass)) { 246 | // Initialize the class first, in case it wants to add itself to the listenerInstanceMap 247 | try { 248 | Class.forName(listenerClass.getName(), true, listenerClass.getClassLoader()); 249 | } catch (ClassNotFoundException e) { 250 | throw new IllegalStateException(e); 251 | } 252 | 253 | // Get the instance of that class, or create a new one if it wasn't instantiated yet 254 | T listenerInstance = listenerInterface.cast(listenerInstanceMap.get(listenerClass)); 255 | if (listenerInstance == null) { 256 | try { 257 | listenerInstance = listenerInterface.cast(newInstance(listenerClass)); 258 | listenerInstanceMap.castAndPut(listenerClass, listenerInstance); 259 | } catch (ReflectiveOperationException e) { 260 | throw new RuntimeException("Failed to create listener instance", e); 261 | } 262 | } 263 | 264 | listenerInstances.add(listenerInstance); 265 | } 266 | } 267 | 268 | List customInstances = customListenerInstances.get(listenerInterface); 269 | if (customInstances != null) { 270 | listenerInstances.addAll(customInstances); 271 | } 272 | } 273 | 274 | public T newInstance(Class clazz) throws ReflectiveOperationException { 275 | for (Constructor constructor : clazz.getConstructors()) { 276 | if (constructor.getParameterCount() == 0) { 277 | return clazz.cast(constructor.newInstance()); 278 | } 279 | } 280 | 281 | // No no-args constructor found, ask mod instantiators to build an instance 282 | for (Instantiator instantiator : getListeners(Instantiator.class)) { 283 | T instance = instantiator.newInstance(clazz); 284 | if (instance != null) { 285 | return instance; 286 | } 287 | } 288 | 289 | throw new InstantiationException("Class has no public no-args constructor, and no instantiator handled it either"); 290 | } 291 | 292 | /** 293 | * Register a custom instance of a class for Rift to use rather than creating 294 | * one by invoking its public no-args constructor. 295 | */ 296 | public void setInstanceForListenerClass(Class listenerClass, T instance) { 297 | listenerInstanceMap.put(listenerClass, instance); 298 | } 299 | 300 | /** 301 | * Adds a listener for a particular listener interface. This is an alternative 302 | * to registering the interface class in riftmod.json. 303 | */ 304 | public void addListener(Class listenerInterface, T listener) { 305 | List customInstances = customListenerInstances.get(listenerInterface); 306 | if (customInstances == null) { 307 | customInstances = new ArrayList<>(); 308 | customListenerInstances.put(listenerInterface, customInstances); 309 | } 310 | customInstances.add(listener); 311 | 312 | List loadedInstances = listeners.get(listenerInterface); 313 | if (loadedInstances != null) { 314 | loadedInstances.add(listener); 315 | } 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/Side.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public enum Side { 6 | @SerializedName("client") CLIENT, 7 | @SerializedName("server") SERVER, 8 | @SerializedName("both") BOTH; 9 | 10 | public boolean includes(Side side) { 11 | return this == BOTH || this == side; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/launch/RiftLoaderClientTweaker.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader.launch; 2 | 3 | import org.spongepowered.asm.mixin.MixinEnvironment; 4 | 5 | import java.io.File; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class RiftLoaderClientTweaker extends RiftLoaderTweaker { 10 | @Override 11 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) { 12 | this.args = new ArrayList<>(args); 13 | 14 | addArg("--version", profile); 15 | addArg("--assetsDir", assetsDir.getPath()); 16 | } 17 | 18 | @Override 19 | public String getLaunchTarget() { 20 | return "net.minecraft.client.main.Main"; 21 | } 22 | 23 | @Override 24 | protected boolean isClient() { 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/launch/RiftLoaderServerTweaker.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader.launch; 2 | 3 | import java.io.File; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class RiftLoaderServerTweaker extends RiftLoaderTweaker { 8 | @Override 9 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) { 10 | this.args = new ArrayList<>(args); 11 | 12 | addArg("--version", profile); 13 | } 14 | 15 | @Override 16 | protected boolean isClient() { 17 | return false; 18 | } 19 | 20 | @Override 21 | public String getLaunchTarget() { 22 | return "net.minecraft.server.MinecraftServer"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/launch/RiftLoaderTweaker.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader.launch; 2 | 3 | import net.minecraft.launchwrapper.ITweaker; 4 | import net.minecraft.launchwrapper.Launch; 5 | import net.minecraft.launchwrapper.LaunchClassLoader; 6 | import org.spongepowered.asm.mixin.MixinEnvironment; 7 | 8 | import java.util.List; 9 | 10 | public abstract class RiftLoaderTweaker implements ITweaker { 11 | public List args; 12 | 13 | protected void addArg(String name, String value) { 14 | args.add(name); 15 | if (value != null) { 16 | args.add(value); 17 | } 18 | } 19 | 20 | @Override 21 | public void injectIntoClassLoader(LaunchClassLoader classLoader) { 22 | // Use the Launch classLoader to load the RiftLoader class. Otherwise identical 23 | // classes may not be equal, and 'instanceof' may return false when it should be true. 24 | try { 25 | Class clazz = Launch.classLoader.findClass("org.dimdev.riftloader.RiftLoader"); 26 | clazz.getMethod("load", boolean.class).invoke(clazz.getField("instance").get(null), isClient()); 27 | } catch (ReflectiveOperationException e) { 28 | throw new RuntimeException(e); 29 | } 30 | 31 | MixinEnvironment.getDefaultEnvironment().setSide(isClient() ? MixinEnvironment.Side.CLIENT : MixinEnvironment.Side.SERVER); 32 | } 33 | 34 | protected abstract boolean isClient(); 35 | 36 | @Override 37 | public String[] getLaunchArguments() { 38 | return args.toArray(new String[0]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/listener/InitializationListener.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader.listener; 2 | 3 | /** 4 | * This listener is called during the Tweaker initialization phase, before Minecraft 5 | * has started. It allows you to do things like adding tweakers and mixins. 6 | */ 7 | public interface InitializationListener { 8 | void onInitialization(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/riftloader/listener/Instantiator.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.riftloader.listener; 2 | 3 | /** 4 | * Allows mods to provide ways to create instances of classes which don't 5 | * have a public no-args constructor. 6 | *

7 | * A class implementing the instantiator interface must necessarily contain 8 | * a public no-args constructor, to prevent infinite recursion while attempting 9 | * to create an instance of it. 10 | */ 11 | public interface Instantiator { 12 | /** 13 | * Creates an instance of a certain class, or null if the instantiator 14 | * can't handle it. 15 | * 16 | * @param clazz class to instantiate 17 | * @return an instance of listenerClass, or null to skip this instantiator 18 | * @throws ReflectiveOperationException if the instantiator can handle this type of class, 19 | * but an error occured during instantiation 20 | */ 21 | T newInstance(Class clazz) throws ReflectiveOperationException; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/dimdev/utils/InstanceListMap.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | public class InstanceListMap { // Type-safe map between classes and instances 8 | private Map, List> uncheckedMap = new HashMap<>(); 9 | 10 | public void put(Class key, List value) { 11 | uncheckedMap.put(key, value); 12 | } 13 | 14 | public List get(Class key) { 15 | //noinspection unchecked 16 | return (List) uncheckedMap.get(key); 17 | } 18 | 19 | public List remove(Class key) { 20 | //noinspection unchecked 21 | return (List) uncheckedMap.remove(key); 22 | } 23 | 24 | public void clear() { 25 | uncheckedMap.clear(); 26 | } 27 | 28 | public boolean containsKey(Class key) { 29 | return uncheckedMap.containsKey(key); 30 | } 31 | 32 | public boolean containsValue(List value) { 33 | return uncheckedMap.containsValue(value); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/org/dimdev/utils/InstanceMap.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class InstanceMap { // Type-safe map between classes and instances 7 | private Map, Object> uncheckedMap = new HashMap<>(); 8 | 9 | public void put(Class key, T value) { 10 | uncheckedMap.put(key, value); 11 | } 12 | 13 | public void castAndPut(Class key, Object value) { 14 | uncheckedMap.put(key, key.cast(value)); 15 | } 16 | 17 | public T get(Class key) { 18 | //noinspection unchecked 19 | return (T) uncheckedMap.get(key); 20 | } 21 | 22 | public T remove(Class key) { 23 | //noinspection unchecked 24 | return (T) uncheckedMap.remove(key); 25 | } 26 | 27 | public void clear() { 28 | uncheckedMap.clear(); 29 | } 30 | 31 | public boolean containsKey(Class key) { 32 | return uncheckedMap.containsKey(key); 33 | } 34 | 35 | public boolean containsValue(Object value) { 36 | return uncheckedMap.containsValue(value); 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/org/dimdev/utils/ReflectionUtils.java: -------------------------------------------------------------------------------- 1 | package org.dimdev.utils; 2 | 3 | import java.lang.invoke.MethodHandle; 4 | import java.lang.invoke.MethodHandles; 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.Method; 7 | import java.net.URL; 8 | import java.net.URLClassLoader; 9 | 10 | public class ReflectionUtils { 11 | private static final MethodHandle addURLHandle; 12 | 13 | static { 14 | try { 15 | Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 16 | method.setAccessible(true); 17 | addURLHandle = MethodHandles.lookup().unreflect(method); 18 | } catch (ReflectiveOperationException e) { 19 | throw new AssertionError(e); 20 | } 21 | } 22 | 23 | public static T makeEnumInstance(Class enumClass, Object... constructorArgs) { 24 | try { 25 | Constructor constructor = enumClass.getDeclaredConstructors()[0]; 26 | constructor.setAccessible(true); 27 | 28 | //noinspection unchecked 29 | return (T) MethodHandles.lookup().unreflectConstructor(constructor).invokeWithArguments(constructorArgs); 30 | } catch (Throwable t) { 31 | throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); 32 | } 33 | } 34 | 35 | public static void addURLToClasspath(URL url) { 36 | try { 37 | addURLHandle.invoke(ClassLoader.getSystemClassLoader(), url); 38 | } catch (Throwable t) { 39 | throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/resources/access_transformations.at: -------------------------------------------------------------------------------- 1 | public method bcj a (Ljava/lang/String;Lbcj;)V # net.minecraft.block.Block/registerBlock 2 | public method bcj a (Lpc;Lbcj;)V # net.minecraft.block.Block/registerBlock 3 | public method bcj$c a (Lbhi;)Lbcj$c; # net.minecraft.block.Block$Builder/soundType 4 | public method bcj$c a (I)Lbcj$c; # net.minecraft.block.Block$Builder/lightValue 5 | public method bcj$c b ()Lbcj$c; # net.minecraft.block.Block$Builder/zeroHardnessAndResistance 6 | public method bcj$c c ()Lbcj$c; # net.minecraft.block.Block$Builder/needsRandomTick 7 | public method bcj$c d ()Lbcj$c; # net.minecraft.block.Block$Builder/variableOpacity 8 | public method asw a (Larf;)V # net.minecraft.item.Item/registerItemBlock 9 | public method asw a (Lbcj;Laru;)V # net.minecraft.item.Item/registerItemBlock 10 | public method asw a (Lbcj;Lasw;)V # net.minecraft.item.Item/registerItemBlock 11 | public method asw a (Ljava/lang/String;Lasw;)V # net.minecraft.item.Item/registerItemBlock 12 | public method asw a (Lpc;Lasw;)V # net.minecraft.item.Item/registerItemBlock 13 | public method asw b (Lbcj;)V # net.minecraft.item.Item/registerItemBlock 14 | public method bym a (Ljava/lang/String;Lbym;)V # net.minecraft.fluid.Fluid/registerFluid 15 | public method bym a (Lpc;Lbym;)V # net.minecraft.fluid.Fluid/registerFluid 16 | public method ayn a (ILjava/lang/String;Layn;)V # net.minecraft.world.biome.Biome/registerBiome 17 | public method fl a (Ljava/lang/String;Z)V # net.minecraft.particles.ParticleType/registerParticleType 18 | public method fl a (Ljava/lang/String;ZLfk$a;)V # net.minecraft.particles.ParticleType/registerParticleType 19 | public method fl (Lpc;ZLfk$a;)V # net.minecraft.particles.ParticleType/ 20 | public class fn # net.minecraft.particles.BasicParticleType 21 | public method fn (Lpc;Z)V # net.minecraft.particles.BasicParticleType/ 22 | public method awa a (Ljava/lang/String;Lawa;)V # net.minecraft.enchantment.Enchantment/func_210770_a 23 | public method aeg a (ILjava/lang/String;Laeg;)V # net.minecraft.potion.Potion/func_210759_a 24 | public method bfl (Lbyl;Lbcj$c;)V # net.minecraft.block.BlockFlowingFluid 25 | public method wh a (Ljava/lang/String;)V # net.minecraft.util.SoundEvent 26 | public method axz (ILjava/lang/String;)V # net.minecraft.world.WorldType/ 27 | public method axz (ILjava/lang/String;I)V # net.minecraft.world.WorldType/ 28 | public method axz (ILjava/lang/String;Ljava/lang/String;I)V # net.minecraft.world.WorldType/ 29 | public class bmr # net.minecraft.world.gen.IChunkGeneratorFactory 30 | public class bms$a # net.minecraft.world.gen.ChunkGeneratorType$Settings 31 | public class bmu # net.minecraft.world.chunk.ChunkStatus 32 | public method bwp b (Ljava/lang/Class;Ljava/lang/String;)V registerStructure # net.minecraft.world.gen.feature.structure.StructureIO/registerStructure 33 | public method bwp a (Ljava/lang/Class;Ljava/lang/String;)V # net.minecraft.world.gen.feature.structure.StructureIO/registerStructure 34 | public field aqz g [I # net.minecraft.item.ArmorMaterial/MAX_DAMAGE_ARRAY 35 | -------------------------------------------------------------------------------- /src/main/resources/mixins.rift.core.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.7.7", 4 | "compatibilityLevel": "JAVA_8", 5 | "target": "@env(DEFAULT)", 6 | "package": "org.dimdev.rift.mixin.core", 7 | "refmap": "mixins.rift.refmap.json", 8 | "mixins": [ 9 | "MixinMinecraftServer", 10 | "MixinVanillaPack" 11 | ], 12 | "client": [ 13 | "client.MixinClientBrandRetriever", 14 | "client.MixinLayerArmorBase", 15 | "client.MixinBlockFluidRenderer", 16 | "client.MixinWaterFluid", 17 | "client.MixinLavaFluid" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/mixins.rift.hooks.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.7.7", 4 | "compatibilityLevel": "JAVA_8", 5 | "target": "@env(DEFAULT)", 6 | "package": "org.dimdev.rift.mixin.hook", 7 | "refmap": "mixins.rift.refmap.json", 8 | "mixins": [ 9 | "MixinBlock", 10 | "MixinItem", 11 | "MixinFluid", 12 | "MixinEnumConnectionState", 13 | "MixinEnumConnectionState$Handshaking", 14 | "MixinEnumConnectionState$Play", 15 | "MixinEnumConnectionState$Status", 16 | "MixinEnumConnectionState$Login", 17 | "MixinNetHandlerPlayServer", 18 | "MixinCommands", 19 | "MixinMinecraftServer", 20 | "MixinPotion", 21 | "MixinEnchantment", 22 | "MixinParticleType", 23 | "MixinSoundEvent", 24 | "MixinOverworldBiomeProvider", 25 | "MixinEntityType", 26 | "MixinTileEntityType", 27 | "MixinBootstrap", 28 | "MixinBiome", 29 | "MixinCPacketCustomPayload", 30 | "MixinEntityType$Builder", 31 | "MixinWorldServer", 32 | "MixinFurnace", 33 | "MixinAnvilSaveHandler", 34 | "MixinDimensionType", 35 | "MixinStructureIO", 36 | "MixinFeature", 37 | "MixinChunk", 38 | "MixinRecipeManager", 39 | "MixinRecipeSerializers", 40 | "MixinArgumentTypes", 41 | "MixinItemTool" 42 | ], 43 | "client": [ 44 | "client.MixinMinecraft", 45 | "client.MixinModelBakery", 46 | "client.MixinNetHandlerPlayClient", 47 | "client.MixinTileEntityRendererDispatcher", 48 | "client.MixinRenderManager", 49 | "client.MixinEntityPlayerSP", 50 | "client.MixinGameSettings", 51 | "client.MixinGuiIngame", 52 | "client.MixinIntegratedServer" 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/profile.json: -------------------------------------------------------------------------------- 1 | { 2 | "inheritsFrom": "1.13", 3 | "id": "1.13-rift-${version}", 4 | "releaseTime": "2018-07-18T15:11:46+00:00", 5 | "time": "2018-07-18T15:11:46+00:00", 6 | "type": "release", 7 | "arguments": { 8 | "game": [ 9 | "--tweakClass", 10 | "org.dimdev.riftloader.launch.RiftLoaderClientTweaker" 11 | ] 12 | }, 13 | "mainClass": "net.minecraft.launchwrapper.Launch", 14 | "libraries": [ 15 | { 16 | "name": "org.dimdev:rift:${version}", 17 | "url": "https://www.dimdev.org/maven/" 18 | }, 19 | { 20 | "name": "org.dimdev:mixin:0.7.11-SNAPSHOT", 21 | "url": "https://www.dimdev.org/maven/" 22 | }, 23 | { 24 | "name": "org.ow2.asm:asm:6.2", 25 | "url": "http://repo1.maven.org/maven2/" 26 | }, 27 | { 28 | "name": "org.ow2.asm:asm-commons:6.2", 29 | "url": "http://repo1.maven.org/maven2/" 30 | }, 31 | { 32 | "name": "org.ow2.asm:asm-tree:6.2", 33 | "url": "http://repo1.maven.org/maven2/" 34 | }, 35 | { 36 | "name": "net.minecraft:launchwrapper:1.12" 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /src/main/resources/riftmod.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "rift", 3 | "name": "Rift", 4 | "authors": [ 5 | "Runemoro" 6 | ], 7 | "listeners": [ 8 | "org.dimdev.rift.Rift", 9 | "org.dimdev.rift.resources.ResourceManager", 10 | "org.dimdev.rift.network.MessageRegistrator" 11 | ] 12 | } 13 | --------------------------------------------------------------------------------