Release 2.6.0
This commit is contained in:
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -13,7 +13,7 @@ pipeline {
|
|||||||
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/user_home/wrapper'],
|
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/user_home/wrapper'],
|
||||||
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/loom-cache'],
|
[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: '.gradle/loom-cache'],
|
||||||
]) {
|
]) {
|
||||||
sh './gradlew :jGui:1.7.10:setupCIWorkspace :1.7.10:setupCIWorkspace'
|
// sh './gradlew :jGui:1.7.10:setupCIWorkspace :1.7.10:setupCIWorkspace'
|
||||||
sh './gradlew --parallel'
|
sh './gradlew --parallel'
|
||||||
}
|
}
|
||||||
archiveArtifacts 'versions/*/build/libs/*.jar'
|
archiveArtifacts 'versions/*/build/libs/*.jar'
|
||||||
|
|||||||
56
README.md
56
README.md
@@ -7,8 +7,8 @@ Make sure your sub-projects are up-to-date: `git submodule update --init --recur
|
|||||||
For compiling 1.7.10, you must run `./gradlew :jGui:1.7.10:setupDecompWorkspace :1.7.10:setupDecompWorkspace` once after the initial clone. This may take quite some time.
|
For compiling 1.7.10, you must run `./gradlew :jGui:1.7.10:setupDecompWorkspace :1.7.10:setupDecompWorkspace` once after the initial clone. This may take quite some time.
|
||||||
|
|
||||||
### No IDE
|
### No IDE
|
||||||
You can build the mod by running `./gradlew build` (or just `./gradlew shadowJar`). You can then find the final jar files in `versions/$MCVERSION/build/libs/`.
|
You can build the mod by running `./gradlew build` (or just `./gradlew bundleJar`). You can then find the final jar files in `versions/$MCVERSION/build/libs/`.
|
||||||
You can also build single versions by running `./gradlew :1.8:build` (or just `./gradlew :1.8:shadowJar`) (builds the MC 1.8 version).
|
You can also build single versions by running `./gradlew :1.8:build` (or just `./gradlew :1.8:bundleJar`) (builds the MC 1.8 version).
|
||||||
|
|
||||||
### IntelliJ
|
### IntelliJ
|
||||||
Ensure you have at least IDEA 2020.1.
|
Ensure you have at least IDEA 2020.1.
|
||||||
@@ -30,55 +30,9 @@ The `master` branch is solely to be used for the `version.json` file that contai
|
|||||||
used by the clients to check for updates of this mod.
|
used by the clients to check for updates of this mod.
|
||||||
|
|
||||||
### The Preprocessor
|
### The Preprocessor
|
||||||
To support multiple Minecraft versions with the ReplayMod, a [JCP](https://github.com/raydac/java-comment-preprocessor)-inspired preprocessor is used:
|
To support multiple Minecraft versions with the ReplayMod, a [JCP](https://github.com/raydac/java-comment-preprocessor)-inspired preprocessor is used.
|
||||||
```java
|
It has by now acquired a lot more sophisticated features to make it as noninvasive as possible.
|
||||||
//#if MC>=11200
|
Please read the [preprocessor's README](https://github.com/ReplayMod/preprocessor/blob/master/README.md) to understand how it works.
|
||||||
// This is the block for MC >= 1.12.0
|
|
||||||
category.addDetail(name, callable::call);
|
|
||||||
//#else
|
|
||||||
//$$ // This is the block for MC < 1.12.0
|
|
||||||
//$$ category.setDetail(name, callable::call);
|
|
||||||
//#endif
|
|
||||||
```
|
|
||||||
Any comments starting with `//$$` will automatically be introduced / removed based on the surrounding condition(s).
|
|
||||||
Normal comments are left untouched. The `//#else` branch is optional.
|
|
||||||
|
|
||||||
Conditions can be nested arbitrarily but their indention shall always be equal to the indention of the code at the `//#if` line.
|
|
||||||
The `//$$` shall be aligned with the inner-most `//#if`.
|
|
||||||
```java
|
|
||||||
//#if MC>=10904
|
|
||||||
public CPacketResourcePackStatus makeStatusPacket(String hash, Action action) {
|
|
||||||
//#if MC>=11002
|
|
||||||
return new CPacketResourcePackStatus(action);
|
|
||||||
//#else
|
|
||||||
//$$ return new CPacketResourcePackStatus(hash, action);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public C19PacketResourcePackStatus makeStatusPacket(String hash, Action action) {
|
|
||||||
//$$ return new C19PacketResourcePackStatus(hash, action);
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
```
|
|
||||||
Code for the more recent MC version shall be placed in the first branch of the if-else-construct.
|
|
||||||
Version-dependent import statements shall be placed separately from and after all other imports.
|
|
||||||
Common version dependent code (including the fml and forge event bus) are available as static methods/fields in the `MCVer` class.
|
|
||||||
|
|
||||||
The source code in `src/main` is generally for the most recent Minecraft version and is automatically passed through the
|
|
||||||
preprocessor when any of the other versions are built (gradle projects `:1.8`, `:1.8.9`, etc.).
|
|
||||||
Do **NOT** edit any of the code in `versions/$MCVERSION/build/` as it is automatically generated and will be overwritten without warning.
|
|
||||||
|
|
||||||
You can change the version of the code in `src/main` if you wish to develop/debug with another version of Minecraft:
|
|
||||||
```bash
|
|
||||||
./gradle :1.9.4:setCoreVersion # switches all sources in src/main to 1.9.4
|
|
||||||
```
|
|
||||||
If you do so, you'll also have to refresh the project in your IDE.
|
|
||||||
|
|
||||||
Make sure to switch back to the most recent branch before committing!
|
|
||||||
Care should also be taken that switching to a different branch and back doesn't introduce any uncommitted changes (e.g. due to different indention, especially in case of nested conditions).
|
|
||||||
|
|
||||||
Some files may use the same preprocessor with different keywords.
|
|
||||||
If required, more file extensions and keywords can be added in the `preprocess` block of the `versions/common.gradle` script.
|
|
||||||
|
|
||||||
### Versioning
|
### Versioning
|
||||||
The ReplayMod uses the versioning scheme outlined [here](http://mcforge.readthedocs.io/en/latest/conventions/versioning/)
|
The ReplayMod uses the versioning scheme outlined [here](http://mcforge.readthedocs.io/en/latest/conventions/versioning/)
|
||||||
|
|||||||
102
build.gradle
102
build.gradle
@@ -21,7 +21,7 @@ buildscript {
|
|||||||
if (!fabric) {
|
if (!fabric) {
|
||||||
maven {
|
maven {
|
||||||
name = "forge"
|
name = "forge"
|
||||||
url = "https://files.minecraftforge.net/maven"
|
url = "https://maven.minecraftforge.net"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
@@ -32,21 +32,21 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.2'
|
classpath 'gradle.plugin.com.github.jengelman.gradle.plugins:shadow:7.0.0'
|
||||||
if (fabric) {
|
if (fabric) {
|
||||||
classpath 'fabric-loom:fabric-loom.gradle.plugin:0.5-SNAPSHOT'
|
classpath 'fabric-loom:fabric-loom.gradle.plugin:0.8-SNAPSHOT'
|
||||||
} else if (mcVersion >= 11400) {
|
} else if (mcVersion >= 11400) {
|
||||||
classpath('net.minecraftforge.gradle:ForgeGradle:3.+'){
|
classpath('net.minecraftforge.gradle:ForgeGradle:5.0.5') { // the FG people still haven't learned to not do breaking changes
|
||||||
exclude group: 'trove', module: 'trove' // preprocessor/idea requires more recent one
|
exclude group: 'trove', module: 'trove' // preprocessor/idea requires more recent one
|
||||||
}
|
}
|
||||||
} else if (mcVersion >= 10800) {
|
} else if (mcVersion >= 10800) {
|
||||||
classpath('com.github.ReplayMod:ForgeGradle:' + (
|
classpath('com.github.ReplayMod:ForgeGradle:' + (
|
||||||
mcVersion >= 11200 ? 'b64de9c' : // FG 2.3
|
mcVersion >= 11200 ? '34ab703' : // FG 2.3
|
||||||
mcVersion >= 10904 ? '5bb7a53' : // FG 2.2
|
mcVersion >= 10904 ? '5d1e8d8' : // FG 2.2
|
||||||
'fc1eabc' // FG 2.1
|
'd1a7165' // FG 2.1
|
||||||
) + ':all')
|
) + ':all')
|
||||||
} else {
|
} else {
|
||||||
classpath 'com.github.ReplayMod:ForgeGradle:5fca6853:all' // FG 1.2
|
classpath 'com.github.ReplayMod:ForgeGradle:a8a9e0ca:all' // FG 1.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,12 +102,16 @@ preprocess {
|
|||||||
".vert": PreprocessTask.DEFAULT_KEYWORDS,
|
".vert": PreprocessTask.DEFAULT_KEYWORDS,
|
||||||
".frag": PreprocessTask.DEFAULT_KEYWORDS,
|
".frag": PreprocessTask.DEFAULT_KEYWORDS,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
patternAnnotation.set("com.replaymod.gradle.remap.Pattern")
|
||||||
}
|
}
|
||||||
|
|
||||||
def mcVersionStr = "${(int)(mcVersion/10000)}.${(int)(mcVersion/100)%100}" + (mcVersion%100==0 ? '' : ".${mcVersion%100}")
|
def mcVersionStr = "${(int)(mcVersion/10000)}.${(int)(mcVersion/100)%100}" + (mcVersion%100==0 ? '' : ".${mcVersion%100}")
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = targetCompatibility = mcVersion >= 11700 ? 16 : 1.8
|
||||||
targetCompatibility = 1.8
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.release = mcVersion >= 11700 ? 16 : 8
|
||||||
|
}
|
||||||
|
|
||||||
if (mcVersion >= 11400) {
|
if (mcVersion >= 11400) {
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -122,7 +126,9 @@ archivesBaseName = "replaymod"
|
|||||||
if (FABRIC) {
|
if (FABRIC) {
|
||||||
minecraft {
|
minecraft {
|
||||||
refmapName = 'mixins.replaymod.refmap.json'
|
refmapName = 'mixins.replaymod.refmap.json'
|
||||||
autoGenIDERuns = true
|
runConfigs.all {
|
||||||
|
ideConfigGenerated = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
minecraft {
|
minecraft {
|
||||||
@@ -197,6 +203,12 @@ repositories {
|
|||||||
name = "fabric"
|
name = "fabric"
|
||||||
url = "https://maven.fabricmc.net/"
|
url = "https://maven.fabricmc.net/"
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
url 'https://maven.terraformersmc.com/releases/'
|
||||||
|
content {
|
||||||
|
includeGroup 'com.terraformersmc'
|
||||||
|
}
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
url 'https://jitpack.io'
|
url 'https://jitpack.io'
|
||||||
content {
|
content {
|
||||||
@@ -208,17 +220,17 @@ repositories {
|
|||||||
configurations {
|
configurations {
|
||||||
// Include dep in fat jar without relocation and, when forge supports it, without exploding (TODO)
|
// Include dep in fat jar without relocation and, when forge supports it, without exploding (TODO)
|
||||||
shade
|
shade
|
||||||
compile.extendsFrom shade
|
implementation.extendsFrom shade
|
||||||
// Include dep in fat jar with relocation and minimization
|
// Include dep in fat jar with relocation and minimization
|
||||||
shadow
|
shadow
|
||||||
compile.extendsFrom shadow
|
implementation.extendsFrom shadow
|
||||||
}
|
}
|
||||||
|
|
||||||
def shadeExclusions = {
|
def shadeExclusions = {
|
||||||
// Cannot just add these to the shade configuration because they'd be inherited by the compile configuration then
|
// Cannot just add these to the shade configuration because they'd be inherited by the compile configuration then
|
||||||
exclude group: 'com.google.guava', module: 'guava-jdk5'
|
exclude group: 'com.google.guava', module: 'guava-jdk5'
|
||||||
exclude group: 'com.google.guava', module: 'guava' // provided by MC
|
exclude group: 'com.google.guava', module: 'guava' // provided by MC
|
||||||
exclude group: 'com.google.code.gson', module: 'gson' // provided by MC
|
exclude group: 'com.google.code.gson', module: 'gson' // provided by MC (or manually bundled for 1.11.2 and below)
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -229,6 +241,8 @@ dependencies {
|
|||||||
11601: '1.16.1',
|
11601: '1.16.1',
|
||||||
11603: '1.16.3',
|
11603: '1.16.3',
|
||||||
11604: '1.16.4',
|
11604: '1.16.4',
|
||||||
|
11700: '1.17',
|
||||||
|
11701: '1.17.1',
|
||||||
][mcVersion]
|
][mcVersion]
|
||||||
mappings 'net.fabricmc:yarn:' + [
|
mappings 'net.fabricmc:yarn:' + [
|
||||||
11404: '1.14.4+build.16',
|
11404: '1.14.4+build.16',
|
||||||
@@ -236,20 +250,18 @@ dependencies {
|
|||||||
11601: '1.16.1+build.17:v2',
|
11601: '1.16.1+build.17:v2',
|
||||||
11603: '1.16.3+build.1:v2',
|
11603: '1.16.3+build.1:v2',
|
||||||
11604: '1.16.4+build.6:v2',
|
11604: '1.16.4+build.6:v2',
|
||||||
|
11700: '1.17+build.13:v2',
|
||||||
|
11701: '1.17.1+build.29:v2',
|
||||||
][mcVersion]
|
][mcVersion]
|
||||||
modCompile 'net.fabricmc:fabric-loader:' + [
|
modImplementation 'net.fabricmc:fabric-loader:0.11.6'
|
||||||
11404: '0.7.8+build.189',
|
|
||||||
11502: '0.7.8+build.189',
|
|
||||||
11601: '0.8.8+build.202',
|
|
||||||
11603: '0.9.1+build.205',
|
|
||||||
11604: '0.10.6+build.214',
|
|
||||||
][mcVersion]
|
|
||||||
def fabricApiVersion = [
|
def fabricApiVersion = [
|
||||||
11404: '0.4.3+build.247-1.14',
|
11404: '0.4.3+build.247-1.14',
|
||||||
11502: '0.5.1+build.294-1.15',
|
11502: '0.5.1+build.294-1.15',
|
||||||
11601: '0.14.0+build.371-1.16',
|
11601: '0.14.0+build.371-1.16',
|
||||||
11603: '0.17.1+build.394-1.16',
|
11603: '0.17.1+build.394-1.16',
|
||||||
11604: '0.25.1+build.416-1.16',
|
11604: '0.25.1+build.416-1.16',
|
||||||
|
11700: '0.36.0+1.17',
|
||||||
|
11701: '0.37.1+1.17',
|
||||||
][mcVersion]
|
][mcVersion]
|
||||||
def fabricApiModules = [
|
def fabricApiModules = [
|
||||||
"api-base",
|
"api-base",
|
||||||
@@ -260,8 +272,11 @@ dependencies {
|
|||||||
if (mcVersion >= 11600) {
|
if (mcVersion >= 11600) {
|
||||||
fabricApiModules.add("key-binding-api-v1")
|
fabricApiModules.add("key-binding-api-v1")
|
||||||
}
|
}
|
||||||
|
if (mcVersion >= 11700) {
|
||||||
|
fabricApiModules.add("networking-api-v1")
|
||||||
|
}
|
||||||
fabricApiModules.each { module ->
|
fabricApiModules.each { module ->
|
||||||
modCompile fabricApi.module("fabric-$module", fabricApiVersion)
|
modImplementation fabricApi.module("fabric-$module", fabricApiVersion)
|
||||||
include fabricApi.module("fabric-$module", fabricApiVersion)
|
include fabricApi.module("fabric-$module", fabricApiVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,6 +317,11 @@ dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mcVersion < 11200) {
|
||||||
|
// The version which MC ships is too old, we'll need to ship our own
|
||||||
|
shadow 'com.google.code.gson:gson:2.8.7'
|
||||||
|
}
|
||||||
|
|
||||||
shadow 'com.github.javagl.JglTF:jgltf-model:3af6de4'
|
shadow 'com.github.javagl.JglTF:jgltf-model:3af6de4'
|
||||||
|
|
||||||
if (FABRIC) {
|
if (FABRIC) {
|
||||||
@@ -312,7 +332,7 @@ dependencies {
|
|||||||
|
|
||||||
shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8'
|
shadow 'com.github.ReplayMod.JavaBlend:2.79.0:a0696f8'
|
||||||
|
|
||||||
shadow "com.github.ReplayMod:ReplayStudio:a1f82a7", shadeExclusions
|
shadow "com.github.ReplayMod:ReplayStudio:a67fb11", shadeExclusions
|
||||||
|
|
||||||
implementation(jGui){
|
implementation(jGui){
|
||||||
transitive = false // FG 1.2 puts all MC deps into the compile configuration and we don't want to shade those
|
transitive = false // FG 1.2 puts all MC deps into the compile configuration and we don't want to shade those
|
||||||
@@ -320,17 +340,22 @@ dependencies {
|
|||||||
shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66'
|
shadow 'com.github.ReplayMod:lwjgl-utils:27dcd66'
|
||||||
|
|
||||||
if (FABRIC) {
|
if (FABRIC) {
|
||||||
if (mcVersion >= 11602) {
|
if (mcVersion >= 11700) {
|
||||||
// TODO re-add to runtime once available
|
modImplementation 'com.terraformersmc:modmenu:2.0.0-beta.7'
|
||||||
modCompileOnly 'io.github.prospector:modmenu:1.14.0+build.24'
|
} else if (mcVersion >= 11602) {
|
||||||
|
modImplementation 'com.terraformersmc:modmenu:1.16.8'
|
||||||
} else if (mcVersion >= 11600) {
|
} else if (mcVersion >= 11600) {
|
||||||
modCompile 'io.github.prospector:modmenu:1.14.0+build.24'
|
modImplementation 'io.github.prospector:modmenu:1.14.0+build.24'
|
||||||
} else {
|
} else {
|
||||||
modCompile 'io.github.prospector.modmenu:ModMenu:1.6.2-92'
|
modImplementation 'io.github.prospector.modmenu:ModMenu:1.6.2-92'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testCompile 'junit:junit:4.11'
|
if (mcVersion >= 11600) {
|
||||||
|
modCompileOnly 'com.github.IrisShaders:Iris:1.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.11'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcVersion <= 10710) {
|
if (mcVersion <= 10710) {
|
||||||
@@ -422,8 +447,12 @@ task configureRelocation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.removeByName('shadowJar') // we want to base our shadowed jar on the reobfJar output, not the sourceSet output
|
// we want to base our shadowed jar on the reobfJar output, not the sourceSet output
|
||||||
task shadowJar(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
|
// Tried tasks.replace but that does not actually seem to replace everything.
|
||||||
|
tasks.shadowJar.doFirst {
|
||||||
|
throw new GradleException("Wrong task! You want to run 'bundleJar' instead.")
|
||||||
|
}
|
||||||
|
tasks.register('bundleJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar).configure {
|
||||||
from { (FABRIC ? tasks.remapJar : tasks.jar).archiveFile.get() }
|
from { (FABRIC ? tasks.remapJar : tasks.jar).archiveFile.get() }
|
||||||
dependsOn { FABRIC ? tasks.remapJar : (mcVersion >= 10800 ? tasks.reobfJar : tasks.reobf) }
|
dependsOn { FABRIC ? tasks.remapJar : (mcVersion >= 10800 ? tasks.reobfJar : tasks.reobf) }
|
||||||
|
|
||||||
@@ -469,7 +498,7 @@ task shadowJar(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar)
|
|||||||
exclude(dependency('.*spongepowered:mixin:.*'))
|
exclude(dependency('.*spongepowered:mixin:.*'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tasks.assemble.dependsOn tasks.shadowJar
|
tasks.assemble.dependsOn tasks.bundleJar
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
classifier = 'raw'
|
classifier = 'raw'
|
||||||
@@ -484,6 +513,15 @@ jar {
|
|||||||
'FMLAT': 'replaymod_at.cfg'
|
'FMLAT': 'replaymod_at.cfg'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mcVersion >= 11700) {
|
||||||
|
// Workaround a mixin bug which generates invalid refmaps for the `addDrawableChild` invoker
|
||||||
|
filesMatching("mixins.replaymod.refmap.json") {
|
||||||
|
it.filter {
|
||||||
|
it.replace("addDrawableChild(L/;)L/;", "method_37063(Lnet/minecraft/class_364;)Lnet/minecraft/class_364;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|||||||
@@ -358,7 +358,8 @@ There are **7 Encoding Presets** you can choose from:
|
|||||||
While these video files are of perfect quality, most **non-FFmpeg-based video players and video editing software** (e.g. QuickTime Player, Sony Vegas and Adobe Premiere) can't play these videos. Therefore, you should instead use the **MP4 - High Quality** preset in most cases.
|
While these video files are of perfect quality, most **non-FFmpeg-based video players and video editing software** (e.g. QuickTime Player, Sony Vegas and Adobe Premiere) can't play these videos. Therefore, you should instead use the **MP4 - High Quality** preset in most cases.
|
||||||
- **PNG Sequence**
|
- **PNG Sequence**
|
||||||
Exports the sequence as individual frames in the **PNG Format**.
|
Exports the sequence as individual frames in the **PNG Format**.
|
||||||
**Warning:** This can create a huge amount of files, so make sure to save them in a separate folder.
|
The images are of perfect quality.
|
||||||
|
Depth map images are 32-bit float encoded in the 8-bit components in BGRA order and will need some kind of post-processing to be useful in most editors.
|
||||||
- **OpenEXR Sequence** (Minecraft 1.14 and above)
|
- **OpenEXR Sequence** (Minecraft 1.14 and above)
|
||||||
Exports the sequence as individual frames in the **OpenEXR Format**.
|
Exports the sequence as individual frames in the **OpenEXR Format**.
|
||||||
The images are of perfect quality and may contain
|
The images are of perfect quality and may contain
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=7bdbad1e4f54f13c8a78abc00c26d44dd8709d4aedb704d913fb1bb78ac025dc
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
18
gradlew
vendored
18
gradlew
vendored
@@ -1,5 +1,21 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
## Gradle start up script for UN*X
|
## Gradle start up script for UN*X
|
||||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
|||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS=""
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|||||||
18
gradlew.bat
vendored
18
gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
|||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS=
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|||||||
2
jGui
2
jGui
Submodule jGui updated: 6641836321...71d361746e
@@ -2,8 +2,8 @@ import groovy.json.JsonOutput
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("fabric-loom") version "0.5-SNAPSHOT" apply false
|
id("fabric-loom") version "0.8-SNAPSHOT" apply false
|
||||||
id("com.replaymod.preprocess") version "24ac087"
|
id("com.replaymod.preprocess") version "123fb7a"
|
||||||
id("com.github.hierynomus.license") version "0.15.0"
|
id("com.github.hierynomus.license") version "0.15.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,12 +25,7 @@ if (gitDescribe().endsWith("*")) {
|
|||||||
|
|
||||||
group = "com.replaymod"
|
group = "com.replaymod"
|
||||||
|
|
||||||
// Loom tries to find the active mixin version by recursing up to the root project and checking each project's
|
val bundleJar by tasks.creating(Copy::class) {
|
||||||
// compileClasspath and build script classpath (in that order). Since we've loom in our root project's classpath,
|
|
||||||
// loom will only find it after checking the root project's compileClasspath (which doesn't exist by default).
|
|
||||||
configurations.register("compileClasspath")
|
|
||||||
|
|
||||||
val shadowJar by tasks.creating(Copy::class) {
|
|
||||||
into("$buildDir/libs")
|
into("$buildDir/libs")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +37,10 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
val projectShadowJar = project.tasks.findByName("shadowJar")
|
val projectBundleJar = project.tasks.findByName("bundleJar")
|
||||||
if (projectShadowJar != null && projectShadowJar.hasProperty("archivePath") && project.name != "core") {
|
if (projectBundleJar != null && projectBundleJar.hasProperty("archivePath") && project.name != "core") {
|
||||||
shadowJar.dependsOn(projectShadowJar)
|
bundleJar.dependsOn(projectBundleJar)
|
||||||
shadowJar.from(projectShadowJar.withGroovyBuilder { getProperty("archivePath") })
|
bundleJar.from(projectBundleJar.withGroovyBuilder { getProperty("archivePath") })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,36 +173,41 @@ val doRelease by tasks.registering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultTasks("shadowJar")
|
defaultTasks("bundleJar")
|
||||||
|
|
||||||
preprocess {
|
preprocess {
|
||||||
"1.16.4"(11604, "yarn") {
|
val mc11701 = createNode("1.17.1", 11701, "yarn")
|
||||||
"1.16.1"(11601, "yarn") {
|
val mc11700 = createNode("1.17", 11700, "yarn")
|
||||||
"1.15.2"(11502, "yarn") {
|
val mc11604 = createNode("1.16.4", 11604, "yarn")
|
||||||
"1.14.4"(11404, "yarn", file("versions/mapping-fabric-1.15.2-1.14.4.txt")) {
|
val mc11601 = createNode("1.16.1", 11601, "yarn")
|
||||||
"1.14.4-forge"(11404, "srg", file("versions/mapping-1.14.4-fabric-forge.txt")) {
|
val mc11502 = createNode("1.15.2", 11502, "yarn")
|
||||||
"1.12.2"(11202, "srg", file("versions/1.14.4-forge/mapping.txt")) {
|
val mc11404 = createNode("1.14.4", 11404, "yarn")
|
||||||
"1.12.1"(11201, "srg") {
|
val mc11404Forge = createNode("1.14.4-forge", 11404, "srg")
|
||||||
"1.12"(11200, "srg") {
|
val mc11202 = createNode("1.12.2", 11202, "srg")
|
||||||
"1.11.2"(11102, "srg", file("versions/1.12/mapping.txt")) {
|
val mc11201 = createNode("1.12.1", 11201, "srg")
|
||||||
"1.11"(11100, "srg", file("versions/1.11.2/mapping.txt")) {
|
val mc11200 = createNode("1.12", 11200, "srg")
|
||||||
"1.10.2"(11002, "srg", file("versions/1.11/mapping.txt")) {
|
val mc11102 = createNode("1.11.2", 11102, "srg")
|
||||||
"1.9.4"(10904, "srg") {
|
val mc11100 = createNode("1.11", 11100, "srg")
|
||||||
"1.8.9"(10809, "srg", file("versions/1.9.4/mapping.txt")) {
|
val mc11002 = createNode("1.10.2", 11002, "srg")
|
||||||
"1.8"(10800, "srg", file("versions/1.8.9/mapping.txt")) {
|
val mc10904 = createNode("1.9.4", 10904, "srg")
|
||||||
"1.7.10"(10710, "srg", file("versions/1.8/mapping.txt"))
|
val mc10809 = createNode("1.8.9", 10809, "srg")
|
||||||
}
|
val mc10800 = createNode("1.8", 10800, "srg")
|
||||||
}
|
val mc10710 = createNode("1.7.10", 10710, "srg")
|
||||||
}
|
|
||||||
}
|
mc11701.link(mc11700)
|
||||||
}
|
mc11700.link(mc11604, file("versions/mapping-fabric-1.17-1.16.4.txt"))
|
||||||
}
|
mc11604.link(mc11601)
|
||||||
}
|
mc11601.link(mc11502)
|
||||||
}
|
mc11502.link(mc11404, file("versions/mapping-fabric-1.15.2-1.14.4.txt"))
|
||||||
}
|
mc11404.link(mc11404Forge, file("versions/mapping-1.14.4-fabric-forge.txt"))
|
||||||
}
|
mc11404Forge.link(mc11202, file("versions/1.14.4-forge/mapping.txt"))
|
||||||
}
|
mc11202.link(mc11201)
|
||||||
}
|
mc11201.link(mc11200)
|
||||||
}
|
mc11200.link(mc11102, file("versions/1.12/mapping.txt"))
|
||||||
}
|
mc11102.link(mc11100, file("versions/1.11.2/mapping.txt"))
|
||||||
|
mc11100.link(mc11002, file("versions/1.11/mapping.txt"))
|
||||||
|
mc11002.link(mc10904)
|
||||||
|
mc10904.link(mc10809, file("versions/1.9.4/mapping.txt"))
|
||||||
|
mc10809.link(mc10800, file("versions/1.8.9/mapping.txt"))
|
||||||
|
mc10800.link(mc10710, file("versions/1.8/mapping.txt"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val jGuiVersions = listOf(
|
val jGuiVersions = listOf(
|
||||||
"1.7.10",
|
// "1.7.10",
|
||||||
"1.8",
|
"1.8",
|
||||||
"1.8.9",
|
"1.8.9",
|
||||||
"1.9.4",
|
"1.9.4",
|
||||||
@@ -28,10 +28,12 @@ val jGuiVersions = listOf(
|
|||||||
"1.14.4",
|
"1.14.4",
|
||||||
"1.15.2",
|
"1.15.2",
|
||||||
"1.16.1",
|
"1.16.1",
|
||||||
"1.16.4"
|
"1.16.4",
|
||||||
|
"1.17",
|
||||||
|
"1.17.1",
|
||||||
)
|
)
|
||||||
val replayModVersions = listOf(
|
val replayModVersions = listOf(
|
||||||
"1.7.10",
|
// "1.7.10",
|
||||||
"1.8",
|
"1.8",
|
||||||
"1.8.9",
|
"1.8.9",
|
||||||
"1.9.4",
|
"1.9.4",
|
||||||
@@ -45,7 +47,9 @@ val replayModVersions = listOf(
|
|||||||
"1.14.4",
|
"1.14.4",
|
||||||
"1.15.2",
|
"1.15.2",
|
||||||
"1.16.1",
|
"1.16.1",
|
||||||
"1.16.4"
|
"1.16.4",
|
||||||
|
"1.17",
|
||||||
|
"1.17.1",
|
||||||
)
|
)
|
||||||
|
|
||||||
rootProject.buildFileName = "root.gradle.kts"
|
rootProject.buildFileName = "root.gradle.kts"
|
||||||
|
|||||||
@@ -1,185 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.compat.bettersprinting;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.replay.ReplayModReplay;
|
|
||||||
//$$ import com.replaymod.replay.events.ReplayChatMessageEvent;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import net.minecraft.client.multiplayer.PlayerControllerMP;
|
|
||||||
//$$ import net.minecraft.entity.Entity;
|
|
||||||
//$$ import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiOpenEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ import net.minecraft.block.state.IBlockState;
|
|
||||||
//$$ import net.minecraft.util.SoundCategory;
|
|
||||||
//$$ import net.minecraft.util.SoundEvent;
|
|
||||||
//$$ import net.minecraft.util.math.BlockPos;
|
|
||||||
//$$ import net.minecraft.world.IWorldEventListener;
|
|
||||||
//$$ import net.minecraft.world.World;
|
|
||||||
//$$
|
|
||||||
//$$ import javax.annotation.Nullable;
|
|
||||||
//#else
|
|
||||||
//#if MC>= 10800
|
|
||||||
//$$ import net.minecraft.util.BlockPos;
|
|
||||||
//#endif
|
|
||||||
//$$ import net.minecraft.world.IWorldAccess;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraftforge.fml.common.Loader;
|
|
||||||
//$$ import net.minecraftforge.fml.common.ModContainer;
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion;
|
|
||||||
//$$ import net.minecraftforge.fml.common.versioning.Restriction;
|
|
||||||
//$$ import net.minecraftforge.fml.common.versioning.VersionRange;
|
|
||||||
//#else
|
|
||||||
//$$ import cpw.mods.fml.common.Loader;
|
|
||||||
//$$ import cpw.mods.fml.common.ModContainer;
|
|
||||||
//$$ import cpw.mods.fml.common.eventhandler.EventPriority;
|
|
||||||
//$$ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
//$$ import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
|
||||||
//$$ import cpw.mods.fml.common.versioning.Restriction;
|
|
||||||
//$$ import cpw.mods.fml.common.versioning.VersionRange;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.Collections;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.compat.ReplayModCompat.LOGGER;
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Old Better Sprinting versions replace the vanilla player with their own, overridden instance (replacing the camera entity).
|
|
||||||
//$$ *
|
|
||||||
//$$ * See: https://github.com/chylex/Better-Sprinting/blob/1.8/src/main/java/chylex/bettersprinting/client/player/impl/LogicImplOverride.java
|
|
||||||
//$$ */
|
|
||||||
//$$ public class DisableBetterSprinting {
|
|
||||||
//$$ private static final VersionRange OLD_VERSION = VersionRange.newRange(null,
|
|
||||||
//$$ Collections.singletonList(new Restriction(null, false, new DefaultArtifactVersion("2.0.0"), false)));
|
|
||||||
//$$ private static final String LOGIC_CLASS_NAME = "chylex.bettersprinting.client.player.impl.LogicImplOverride";
|
|
||||||
//$$ private static final String CONTROLLER_OVERRIDE_CLASS_NAME = LOGIC_CLASS_NAME + "$PlayerControllerMPOverride";
|
|
||||||
//$$
|
|
||||||
//$$ public static void register() {
|
|
||||||
//$$ Loader.instance().getModList().stream()
|
|
||||||
//$$ .filter(mod -> mod.getModId().equalsIgnoreCase("bettersprinting"))
|
|
||||||
//$$ .findFirst()
|
|
||||||
//$$ .map(ModContainer::getProcessedVersion).filter(OLD_VERSION::containsVersion)
|
|
||||||
//$$ .ifPresent($_ -> MinecraftForge.EVENT_BUS.register(new DisableBetterSprinting()));
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private DisableBetterSprinting() {
|
|
||||||
//$$ LOGGER.info("BetterSprinting workaround enabled");
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
//$$ private PlayerControllerMP originalController;
|
|
||||||
//$$ private BetterSprintingWorldAccess worldAccessHook = new BetterSprintingWorldAccess();
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent(priority = EventPriority.HIGH)
|
|
||||||
//$$ public void beforeGuiOpenEvent(GuiOpenEvent event) {
|
|
||||||
//$$ if (ReplayModReplay.instance.getReplayHandler() != null && mc.world != null) {
|
|
||||||
//$$ // During replay, get ready to revert BetterSprinting's overwritten playerController
|
|
||||||
//$$ originalController = mc.playerController;
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ mc.world.addEventListener(worldAccessHook);
|
|
||||||
//#else
|
|
||||||
//$$ mc.theWorld.addWorldAccess(worldAccessHook);
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent(priority = EventPriority.LOW)
|
|
||||||
//$$ public void afterGuiOpenEvent(GuiOpenEvent event) {
|
|
||||||
//$$ if (ReplayModReplay.instance.getReplayHandler() != null && mc.world != null) {
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ mc.world.addEventListener(worldAccessHook);
|
|
||||||
//#else
|
|
||||||
//$$ mc.theWorld.addWorldAccess(worldAccessHook);
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onReplayChatMessage(ReplayChatMessageEvent event) {
|
|
||||||
//$$ // Suppress this message if it's the Better Sprinting warning message
|
|
||||||
//$$ for (StackTraceElement elem : Thread.currentThread().getStackTrace()) {
|
|
||||||
//$$ if (LOGIC_CLASS_NAME.equals(elem.getClassName())) {
|
|
||||||
//$$ LOGGER.info("BetterSprinting warning message suppressed.");
|
|
||||||
//$$ event.setCanceled(true);
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private class BetterSprintingWorldAccess
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ implements IWorldEventListener
|
|
||||||
//#else
|
|
||||||
//$$ implements IWorldAccess
|
|
||||||
//#endif
|
|
||||||
//$$ {
|
|
||||||
//$$ @Override
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ public void onEntityRemoved(Entity entityIn) {
|
|
||||||
//#else
|
|
||||||
//$$ public void onEntityDestroy(Entity entityIn) {
|
|
||||||
//#endif
|
|
||||||
//$$ if (mc.playerController != null && mc.playerController.getClass().getName().equals(CONTROLLER_OVERRIDE_CLASS_NAME)) {
|
|
||||||
//$$ // Someone has secretly swapped out the player controller and is about to substitute their own player entity.
|
|
||||||
//$$ // This is the right time to destroy their plan.
|
|
||||||
//$$ LOGGER.info("Preventing player controller {} from being replaced by BetterSprinting with {}.", originalController, mc.playerController);
|
|
||||||
//$$ mc.playerController = originalController;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {}
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ @Override public void notifyLightSet(BlockPos pos) {}
|
|
||||||
//$$ @Override public void spawnParticle(int p_180442_1_, boolean p_180442_2_, double p_180442_3_, double p_180442_5_, double p_180442_7_, double p_180442_9_, double p_180442_11_, double p_180442_13_, int... p_180442_15_) {}
|
|
||||||
//$$ @Override public void onEntityAdded(Entity entityIn) {}
|
|
||||||
//$$ @Override public void broadcastSound(int p_180440_1_, BlockPos p_180440_2_, int p_180440_3_) {}
|
|
||||||
//$$ @Override public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {}
|
|
||||||
//#else
|
|
||||||
//$$ @Override public void markBlockForRenderUpdate(int x, int y, int z) {}
|
|
||||||
//$$ @Override public void spawnParticle(String p_72708_1_, double p_72708_2_, double p_72708_4_, double p_72708_6_, double p_72708_8_, double p_72708_10_, double p_72708_12_) {}
|
|
||||||
//$$ @Override public void onEntityCreate(Entity entityIn) {}
|
|
||||||
//$$ @Override public void broadcastSound(int p_180440_1_, int x, int y, int z, int p_180440_3_) {}
|
|
||||||
//$$ @Override public void destroyBlockPartially(int breakerId, int x, int y, int z, int progress) {}
|
|
||||||
//$$ @Override public void onStaticEntitiesChanged() {}
|
|
||||||
//#endif
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ @Override public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {}
|
|
||||||
//$$ @Override public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch) {}
|
|
||||||
//$$ @Override public void playRecord(SoundEvent soundIn, BlockPos pos) {}
|
|
||||||
//$$ @Override public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) {}
|
|
||||||
//#if MC>=11100
|
|
||||||
//#if MC>=11102
|
|
||||||
//$$ @Override public void spawnParticle(int p_190570_1_, boolean p_190570_2_, boolean p_190570_3_, double p_190570_4_, double p_190570_6_, double p_190570_8_, double p_190570_10_, double p_190570_12_, double p_190570_14_, int... p_190570_16_) {}
|
|
||||||
//#else
|
|
||||||
//$$ @Override public void func_190570_a(int p_190570_1_, boolean p_190570_2_, boolean p_190570_3_, double p_190570_4_, double p_190570_6_, double p_190570_8_, double p_190570_10_, double p_190570_12_, double p_190570_14_, int... p_190570_16_) {}
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//#else
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ @Override public void markBlockForUpdate(BlockPos pos) {}
|
|
||||||
//$$ @Override public void playRecord(String recordName, BlockPos blockPosIn) {}
|
|
||||||
//#else
|
|
||||||
//$$ @Override public void markBlockForUpdate(int x, int y, int z) {}
|
|
||||||
//$$ @Override public void playRecord(String recordName, int x, int y, int z) {}
|
|
||||||
//#endif
|
|
||||||
//$$ @Override public void playSound(String soundName, double x, double y, double z, float volume, float pitch) {}
|
|
||||||
//$$ @Override public void playSoundToNearExcept(EntityPlayer except, String soundName, double x, double y, double z, float volume, float pitch) {}
|
|
||||||
//#if MC>=10809
|
|
||||||
//$$ @Override public void playAuxSFX(EntityPlayer p_180439_1_, int p_180439_2_, BlockPos blockPosIn, int p_180439_4_) {}
|
|
||||||
//#else
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ @Override public void playAusSFX(EntityPlayer p_180439_1_, int p_180439_2_, BlockPos blockPosIn, int p_180439_4_) {}
|
|
||||||
//#else
|
|
||||||
//$$ @Override public void playAuxSFX(EntityPlayer p_72706_1_, int p_72706_2_, int p_72706_3_, int p_72706_4_, int p_72706_5_, int p_72706_6_) {}
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,46 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.compat.mapwriter.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.replay.ReplayModReplay;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import net.minecraft.client.multiplayer.ServerData;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
//$$
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraftforge.fml.common.Loader;
|
|
||||||
//#else
|
|
||||||
//$$ import cpw.mods.fml.common.Loader;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Approximately this for <1.12: https://github.com/Vectron/mapwriter/commit/68234520c7a3a0ae8201a085d7e66369900586ac
|
|
||||||
//$$ */
|
|
||||||
//$$ @Mixin(Minecraft.class)
|
|
||||||
//$$ public abstract class MixinMinecraft {
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow
|
|
||||||
//$$ private ServerData currentServerData;
|
|
||||||
//$$
|
|
||||||
//$$ @Inject(method = "getCurrentServerData", cancellable = true, at = @At("HEAD"))
|
|
||||||
//$$ private void replayModCompat_fixBug96(CallbackInfoReturnable<ServerData> ci) {
|
|
||||||
//$$ if (currentServerData == null
|
|
||||||
//$$ && (Loader.isModLoaded("mapwriter") || Loader.isModLoaded("MapWriter"))
|
|
||||||
//$$ && ReplayModReplay.instance.getReplayHandler() != null) {
|
|
||||||
//$$ for (StackTraceElement elem : Thread.currentThread().getStackTrace()) {
|
|
||||||
//$$ if ("mapwriter.util.Utils".equals(elem.getClassName()) && "getWorldName".equals(elem.getMethodName())) {
|
|
||||||
//#if MC>=10809
|
|
||||||
//$$ ci.setReturnValue(new ServerData(null, "replay", false));
|
|
||||||
//#else
|
|
||||||
//$$ ci.setReturnValue(new ServerData(null, "replay"));
|
|
||||||
//#endif
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,32 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.compat.oranges17animations;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.replay.camera.CameraEntity;
|
|
||||||
//$$ import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import net.minecraftforge.client.event.RenderLivingEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Orange seems to have copied vast parts of the RendererLivingEntity into their ArmorAnimation class which cancels the RenderLivingEvent.Pre and calls its own code instead.
|
|
||||||
//$$ * This breaks our mixin which assures that, even though the camera is in spectator mode, it cannot see invisible entities.
|
|
||||||
//$$ *
|
|
||||||
//$$ * To fix this issue, we simply cancel the RenderLivingEvent.Pre before it gets to ArmorAnimation if the entity is invisible.
|
|
||||||
//$$ */
|
|
||||||
//$$ public class HideInvisibleEntities extends EventRegistrations {
|
|
||||||
//$$ private final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
//$$ private final boolean modLoaded = isModLoaded("animations");
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent(priority = EventPriority.HIGH)
|
|
||||||
//$$ public void preRenderLiving(RenderLivingEvent.Pre event) {
|
|
||||||
//$$ if (modLoaded) {
|
|
||||||
//$$ if (mc.player instanceof CameraEntity && getEntity(event).isInvisible()) {
|
|
||||||
//$$ event.setCanceled(true);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
package com.replaymod.compat.shaders;
|
package com.replaymod.compat.shaders;
|
||||||
|
|
||||||
|
import com.replaymod.core.events.PreRenderCallback;
|
||||||
import com.replaymod.render.hooks.EntityRendererHandler;
|
import com.replaymod.render.hooks.EntityRendererHandler;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.getRenderPartialTicks;
|
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import com.replaymod.core.events.PreRenderCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$ import net.minecraftforge.event.TickEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public class ShaderBeginRender extends EventRegistrations {
|
public class ShaderBeginRender extends EventRegistrations {
|
||||||
|
|
||||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||||
@@ -25,14 +17,8 @@ public class ShaderBeginRender extends EventRegistrations {
|
|||||||
* as this would usually get called by EntityRenderer#renderWorld,
|
* as this would usually get called by EntityRenderer#renderWorld,
|
||||||
* which we're not calling during rendering.
|
* which we're not calling during rendering.
|
||||||
*/
|
*/
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(PreRenderCallback.EVENT, this::onRenderTickStart); }
|
{ on(PreRenderCallback.EVENT, this::onRenderTickStart); }
|
||||||
private void onRenderTickStart() {
|
private void onRenderTickStart() {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onRenderTickStart(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase != TickEvent.Phase.START) return;
|
|
||||||
//#endif
|
|
||||||
if (ShaderReflection.shaders_beginRender == null) return;
|
if (ShaderReflection.shaders_beginRender == null) return;
|
||||||
if (ShaderReflection.config_isShaders == null) return;
|
if (ShaderReflection.config_isShaders == null) return;
|
||||||
|
|
||||||
@@ -48,7 +34,7 @@ public class ShaderBeginRender extends EventRegistrations {
|
|||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
mc.gameRenderer.getCamera(),
|
mc.gameRenderer.getCamera(),
|
||||||
//#endif
|
//#endif
|
||||||
getRenderPartialTicks(), 0);
|
mc.getTickDelta(), 0);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1 @@
|
|||||||
//#if MC<=10710
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.compat.shaders.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.render.hooks.EntityRendererHandler;
|
|
||||||
//$$ import com.replaymod.replay.ReplayHandler;
|
|
||||||
//$$ import com.replaymod.replay.ReplayModReplay;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Pseudo;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
//$$
|
|
||||||
//$$ @Pseudo
|
|
||||||
//$$ @Mixin(targets = "shadersmod/client/Shaders", remap = false)
|
|
||||||
//$$ public abstract class MixinShaders {
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow static Minecraft mc;
|
|
||||||
//$$ @Shadow static long systemTime;
|
|
||||||
//$$ @Shadow static long lastSystemTime;
|
|
||||||
//$$ @Shadow static long diffSystemTime;
|
|
||||||
//$$ @Shadow static int frameCounter;
|
|
||||||
//$$ @Shadow static float frameTime;
|
|
||||||
//$$ @Shadow static float frameTimeCounter;
|
|
||||||
//$$
|
|
||||||
//$$ @Redirect(method = "beginRender", at = @At(value = "INVOKE", target = "Ljava/lang/System;currentTimeMillis()J"))
|
|
||||||
//$$ private static long replayModCompat_currentTimeMillis() {
|
|
||||||
//$$ ReplayHandler replayHandler = ReplayModReplay.instance.getReplayHandler();
|
|
||||||
//$$ if (replayHandler != null) {
|
|
||||||
//$$ systemTime = replayHandler.getReplaySender().currentTimeStamp();
|
|
||||||
//$$
|
|
||||||
//$$ // We need to manipulate all the other previous-frame-time-based variables too
|
|
||||||
//$$
|
|
||||||
//$$ lastSystemTime = 0; // Draw all frames as if they were the first ones
|
|
||||||
//$$ // diffSystemTime will be set to 0 by Shaders
|
|
||||||
//$$ // frameTime will be set to 0 by Shaders
|
|
||||||
//$$ frameTimeCounter = systemTime / 1000f; // will be %= 3600f by Shaders
|
|
||||||
//$$
|
|
||||||
//$$ // Set frameCounter only if rendering is in progress
|
|
||||||
//$$ EntityRendererHandler entityRendererHandler =
|
|
||||||
//$$ ((EntityRendererHandler.IEntityRenderer) mc.entityRenderer).replayModRender_getHandler();
|
|
||||||
//$$ if (entityRendererHandler != null) {
|
|
||||||
//$$ frameCounter = entityRendererHandler.getRenderInfo().getFramesDone();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ return systemTime;
|
|
||||||
//$$ }
|
|
||||||
//$$ return System.currentTimeMillis();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package com.replaymod.core;
|
|||||||
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.replaymod.core.events.PreRenderCallback;
|
||||||
import com.replaymod.core.mixin.KeyBindingAccessor;
|
import com.replaymod.core.mixin.KeyBindingAccessor;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
import com.replaymod.core.events.KeyBindingEventCallback;
|
import com.replaymod.core.events.KeyBindingEventCallback;
|
||||||
import com.replaymod.core.events.KeyEventCallback;
|
import com.replaymod.core.events.KeyEventCallback;
|
||||||
import com.replaymod.core.versions.MCVer;
|
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.options.KeyBinding;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
import net.minecraft.util.crash.CrashReportSection;
|
import net.minecraft.util.crash.CrashReportSection;
|
||||||
@@ -22,15 +22,6 @@ import static com.replaymod.core.ReplayMod.MOD_ID;
|
|||||||
//$$ import net.minecraftforge.fml.client.registry.ClientRegistry;
|
//$$ import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import com.replaymod.core.events.PreRenderCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
//$$ import org.lwjgl.input.Keyboard;
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.FML_BUS;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -102,15 +93,7 @@ public class KeyBindingRegistry extends EventRegistrations {
|
|||||||
return Collections.unmodifiableSet(onlyInReplay);
|
return Collections.unmodifiableSet(onlyInReplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
{ on(PreRenderCallback.EVENT, this::handleRepeatedKeyBindings); }
|
{ on(PreRenderCallback.EVENT, this::handleRepeatedKeyBindings); }
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onTick(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase != TickEvent.Phase.START) return;
|
|
||||||
//$$ handleRepeatedKeyBindings();
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public void handleRepeatedKeyBindings() {
|
public void handleRepeatedKeyBindings() {
|
||||||
for (Binding binding : bindings.values()) {
|
for (Binding binding : bindings.values()) {
|
||||||
@@ -137,8 +120,8 @@ public class KeyBindingRegistry extends EventRegistrations {
|
|||||||
} catch (Throwable cause) {
|
} catch (Throwable cause) {
|
||||||
CrashReport crashReport = CrashReport.create(cause, "Handling Key Binding");
|
CrashReport crashReport = CrashReport.create(cause, "Handling Key Binding");
|
||||||
CrashReportSection category = crashReport.addElement("Key Binding");
|
CrashReportSection category = crashReport.addElement("Key Binding");
|
||||||
MCVer.addDetail(category, "Key Binding", () -> binding.name);
|
category.add("Key Binding", () -> binding.name);
|
||||||
MCVer.addDetail(category, "Handler", runnable::toString);
|
category.add("Handler", runnable::toString);
|
||||||
throw new CrashException(crashReport);
|
throw new CrashException(crashReport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,8 +138,8 @@ public class KeyBindingRegistry extends EventRegistrations {
|
|||||||
} catch (Throwable cause) {
|
} catch (Throwable cause) {
|
||||||
CrashReport crashReport = CrashReport.create(cause, "Handling Raw Key Binding");
|
CrashReport crashReport = CrashReport.create(cause, "Handling Raw Key Binding");
|
||||||
CrashReportSection category = crashReport.addElement("Key Binding");
|
CrashReportSection category = crashReport.addElement("Key Binding");
|
||||||
MCVer.addDetail(category, "Key Code", () -> "" + keyCode);
|
category.add("Key Code", () -> "" + keyCode);
|
||||||
MCVer.addDetail(category, "Handler", handler::toString);
|
category.add("Handler", handler::toString);
|
||||||
throw new CrashException(crashReport);
|
throw new CrashException(crashReport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +160,12 @@ public class KeyBindingRegistry extends EventRegistrations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getBoundKey() {
|
public String getBoundKey() {
|
||||||
return MCVer.getBoundKey(keyBinding);
|
try {
|
||||||
|
return keyBinding.getBoundKeyLocalizedText().getString();
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
// Apparently windows likes to press strange keys, see https://www.replaymod.com/forum/thread/55
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBound() {
|
public boolean isBound() {
|
||||||
|
|||||||
@@ -1,104 +1 @@
|
|||||||
package com.replaymod.core;
|
// 1.12.2 and below
|
||||||
|
|
||||||
//#if MC<11400
|
|
||||||
//$$ import net.minecraft.launchwrapper.Launch;
|
|
||||||
//$$ import org.apache.logging.log4j.LogManager;
|
|
||||||
//$$ import org.spongepowered.asm.launch.MixinBootstrap;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixins;
|
|
||||||
//$$
|
|
||||||
//$$ import net.minecraftforge.fml.relauncher.CoreModManager;
|
|
||||||
//$$ import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
|
||||||
//#if MC<10800
|
|
||||||
//$$ import com.replaymod.core.asm.GLErrorTransformer;
|
|
||||||
//$$ import com.replaymod.core.asm.GLStateTrackerTransformer;
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.ArrayList;
|
|
||||||
//$$ import java.util.List;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ import java.io.File;
|
|
||||||
//$$ import java.net.URISyntaxException;
|
|
||||||
//$$ import java.net.URL;
|
|
||||||
//$$ import java.security.CodeSource;
|
|
||||||
//$$ import java.util.Map;
|
|
||||||
//$$
|
|
||||||
//$$ @IFMLLoadingPlugin.TransformerExclusions("com.replaymod.core.asm.")
|
|
||||||
//$$ public class LoadingPlugin implements IFMLLoadingPlugin {
|
|
||||||
//$$
|
|
||||||
//$$ public LoadingPlugin() {
|
|
||||||
//$$ if (Launch.blackboard.get("fml.deobfuscatedEnvironment") != Boolean.FALSE) {
|
|
||||||
//$$ // Outside of the dev env, this is the job of the tweaker
|
|
||||||
//$$ MixinBootstrap.init();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ Mixins.addConfiguration("mixins.core.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.recording.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.render.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.render.blend.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.replay.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.compat.mapwriter.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.compat.shaders.replaymod.json");
|
|
||||||
//$$ Mixins.addConfiguration("mixins.extras.playeroverview.replaymod.json");
|
|
||||||
//$$
|
|
||||||
//$$ CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
|
|
||||||
//$$ if (codeSource != null) {
|
|
||||||
//$$ URL location = codeSource.getLocation();
|
|
||||||
//$$ try {
|
|
||||||
//$$ File file = new File(location.toURI());
|
|
||||||
//$$ if (file.isFile()) {
|
|
||||||
//$$ // This forces forge to reexamine the jar file for FML mods
|
|
||||||
//$$ // Should eventually be handled by Mixin itself, maybe?
|
|
||||||
//#if MC>=10809
|
|
||||||
//$$ CoreModManager.getIgnoredMods().remove(file.getName());
|
|
||||||
//#else
|
|
||||||
//$$ CoreModManager.getLoadedCoremods().remove(file.getName());
|
|
||||||
//#if MC<=10710
|
|
||||||
//$$ CoreModManager.getReparseableCoremods().add(file.getName());
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$ } catch (URISyntaxException e) {
|
|
||||||
//$$ e.printStackTrace();
|
|
||||||
//$$ }
|
|
||||||
//$$ } else {
|
|
||||||
//$$ LogManager.getLogger().warn("No CodeSource, if this is not a development environment we might run into problems!");
|
|
||||||
//$$ LogManager.getLogger().warn(getClass().getProtectionDomain());
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String[] getASMTransformerClass() {
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ return new String[]{
|
|
||||||
//$$ };
|
|
||||||
//#else
|
|
||||||
//$$ List<String> transformers = new ArrayList<>();
|
|
||||||
//$$ if ("true".equals(System.getProperty("replaymod.glerrors", "false"))) {
|
|
||||||
//$$ transformers.add(GLErrorTransformer.class.getName());
|
|
||||||
//$$ }
|
|
||||||
//$$ transformers.add(GLStateTrackerTransformer.class.getName());
|
|
||||||
//$$ return transformers.stream().toArray(String[]::new);
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String getModContainerClass() {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String getSetupClass() {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void injectData(Map<String, Object> data) {
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String getAccessTransformerClass() {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -5,87 +5,32 @@ import com.replaymod.compat.ReplayModCompat;
|
|||||||
import com.replaymod.core.gui.GuiBackgroundProcesses;
|
import com.replaymod.core.gui.GuiBackgroundProcesses;
|
||||||
import com.replaymod.core.gui.GuiReplaySettings;
|
import com.replaymod.core.gui.GuiReplaySettings;
|
||||||
import com.replaymod.core.gui.RestoreReplayGui;
|
import com.replaymod.core.gui.RestoreReplayGui;
|
||||||
import com.replaymod.core.mixin.MinecraftAccessor;
|
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
|
import com.replaymod.core.versions.scheduler.Scheduler;
|
||||||
|
import com.replaymod.core.versions.scheduler.SchedulerImpl;
|
||||||
import com.replaymod.editor.ReplayModEditor;
|
import com.replaymod.editor.ReplayModEditor;
|
||||||
import com.replaymod.extras.ReplayModExtras;
|
import com.replaymod.extras.ReplayModExtras;
|
||||||
import com.replaymod.recording.ReplayModRecording;
|
import com.replaymod.recording.ReplayModRecording;
|
||||||
import com.replaymod.render.ReplayModRender;
|
import com.replaymod.render.ReplayModRender;
|
||||||
import com.replaymod.replay.ReplayModReplay;
|
import com.replaymod.replay.ReplayModReplay;
|
||||||
|
import com.replaymod.replaystudio.lib.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
||||||
import com.replaymod.replaystudio.studio.ReplayStudio;
|
import com.replaymod.replaystudio.studio.ReplayStudio;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
|
||||||
import com.replaymod.replaystudio.util.I18n;
|
import com.replaymod.replaystudio.util.I18n;
|
||||||
import com.replaymod.replaystudio.viaversion.ViaVersionPacketConverter;
|
|
||||||
import com.replaymod.simplepathing.ReplayModSimplePathing;
|
import com.replaymod.simplepathing.ReplayModSimplePathing;
|
||||||
import de.johni0702.minecraft.gui.container.GuiScreen;
|
import de.johni0702.minecraft.gui.container.GuiScreen;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.client.options.Option;
|
||||||
import net.minecraft.resource.DirectoryResourcePack;
|
import net.minecraft.resource.DirectoryResourcePack;
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.text.Style;
|
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.Style;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.text.TranslatableText;
|
import net.minecraft.text.TranslatableText;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.crash.CrashException;
|
import net.minecraft.util.Identifier;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
//#if MC>=11400
|
|
||||||
import net.minecraft.client.options.Option;
|
|
||||||
import net.minecraft.util.thread.ReentrantThreadExecutor;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
//#else
|
|
||||||
//$$ import com.google.common.util.concurrent.ListenableFutureTask;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$ import java.util.Queue;
|
|
||||||
//$$ import java.util.concurrent.FutureTask;
|
|
||||||
//$$
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import com.replaymod.core.versions.LangResourcePack;
|
|
||||||
//$$ import net.minecraft.resources.IPackFinder;
|
|
||||||
//$$ import net.minecraft.resources.ResourcePackInfo;
|
|
||||||
//$$ import net.minecraftforge.fml.DeferredWorkQueue;
|
|
||||||
//$$ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
|
||||||
//$$ import net.minecraftforge.versions.mcp.MCPVersion;
|
|
||||||
//#else
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.FML_BUS;
|
|
||||||
//$$ import net.minecraft.client.resources.IResourcePack;
|
|
||||||
//$$ import net.minecraftforge.common.config.Configuration;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraft.client.GameSettings;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import net.minecraftforge.fml.ModList;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.Loader;
|
|
||||||
//$$ import net.minecraftforge.fml.common.Mod.EventHandler;
|
|
||||||
//$$ import net.minecraftforge.fml.common.Mod.Instance;
|
|
||||||
//$$ import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
|
||||||
//$$ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraftforge.fml.client.FMLClientHandler;
|
|
||||||
//#else
|
|
||||||
//$$ import com.replaymod.replay.InputReplayTimer;
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.ArrayDeque;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//$$ import net.minecraftforge.fml.common.Mod;
|
|
||||||
//#if MC<11400
|
|
||||||
//$$ import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -102,43 +47,9 @@ import java.nio.file.attribute.BasicFileAttributes;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
//#if FABRIC<=0
|
public class ReplayMod implements Module, Scheduler {
|
||||||
//#if MC>=11400
|
|
||||||
//$$ @Mod(ReplayMod.MOD_ID)
|
|
||||||
//#else
|
|
||||||
//$$ @Mod(modid = ReplayMod.MOD_ID,
|
|
||||||
//$$ useMetadata = true,
|
|
||||||
//$$ version = "@MOD_VERSION@",
|
|
||||||
//$$ acceptedMinecraftVersions = "@MC_VERSION@",
|
|
||||||
//$$ acceptableRemoteVersions = "*",
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ clientSideOnly = true,
|
|
||||||
//$$ updateJSON = "https://raw.githubusercontent.com/ReplayMod/ReplayMod/master/versions.json",
|
|
||||||
//#endif
|
|
||||||
//$$ guiFactory = "com.replaymod.core.gui.GuiFactory")
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
public class ReplayMod implements
|
|
||||||
//#if FABRIC>=1
|
|
||||||
ClientModInitializer,
|
|
||||||
//#endif
|
|
||||||
Module
|
|
||||||
{
|
|
||||||
|
|
||||||
public static String getMinecraftVersion() {
|
|
||||||
//#if MC>=11400
|
|
||||||
return MinecraftClient.getInstance().getGame().getVersion().getName();
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ return MCPVersion.getMCVersion();
|
|
||||||
//#else
|
|
||||||
//$$ return Loader.MC_VERSION;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String MOD_ID = "replaymod";
|
public static final String MOD_ID = "replaymod";
|
||||||
|
|
||||||
@@ -148,23 +59,15 @@ public class ReplayMod implements
|
|||||||
|
|
||||||
private static final MinecraftClient mc = MCVer.getMinecraft();
|
private static final MinecraftClient mc = MCVer.getMinecraft();
|
||||||
|
|
||||||
//#if MC<11400
|
private final ReplayModBackend backend;
|
||||||
//$$ @Deprecated
|
private final SchedulerImpl scheduler = new SchedulerImpl();
|
||||||
//$$ public static Configuration config;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
|
private final KeyBindingRegistry keyBindingRegistry = new KeyBindingRegistry();
|
||||||
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
|
private final SettingsRegistry settingsRegistry = new SettingsRegistry();
|
||||||
{
|
{
|
||||||
settingsRegistry.register(Setting.class);
|
settingsRegistry.register(Setting.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The instance of your mod that Forge uses.
|
|
||||||
//#if MC>=11400
|
|
||||||
{ instance = this; }
|
{ instance = this; }
|
||||||
//#else
|
|
||||||
//$$ @Instance(MOD_ID)
|
|
||||||
//#endif
|
|
||||||
public static ReplayMod instance;
|
public static ReplayMod instance;
|
||||||
|
|
||||||
private final List<Module> modules = new ArrayList<>();
|
private final List<Module> modules = new ArrayList<>();
|
||||||
@@ -181,15 +84,15 @@ public class ReplayMod implements
|
|||||||
*/
|
*/
|
||||||
private boolean minimalMode;
|
private boolean minimalMode;
|
||||||
|
|
||||||
public ReplayMod() {
|
public ReplayMod(ReplayModBackend backend) {
|
||||||
|
this.backend = backend;
|
||||||
|
|
||||||
I18n.setI18n(net.minecraft.client.resource.language.I18n::translate);
|
I18n.setI18n(net.minecraft.client.resource.language.I18n::translate);
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
// Check Minecraft protocol version for compatibility
|
// Check Minecraft protocol version for compatibility
|
||||||
if (!ProtocolVersion.isRegistered(MCVer.getProtocolVersion()) && !Boolean.parseBoolean(System.getProperty("replaymod.skipversioncheck", "false"))) {
|
if (!ProtocolVersion.isRegistered(MCVer.getProtocolVersion()) && !Boolean.parseBoolean(System.getProperty("replaymod.skipversioncheck", "false"))) {
|
||||||
minimalMode = true;
|
minimalMode = true;
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|
||||||
// Register all RM modules
|
// Register all RM modules
|
||||||
modules.add(this);
|
modules.add(this);
|
||||||
@@ -202,21 +105,9 @@ public class ReplayMod implements
|
|||||||
modules.add(new ReplayModExtras(this));
|
modules.add(new ReplayModExtras(this));
|
||||||
modules.add(new ReplayModCompat());
|
modules.add(new ReplayModCompat());
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
settingsRegistry.register();
|
settingsRegistry.register();
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC<=11400
|
|
||||||
//$$ @EventHandler
|
|
||||||
//$$ public void init(FMLPreInitializationEvent event) {
|
|
||||||
//$$ config = new Configuration(event.getSuggestedConfigurationFile());
|
|
||||||
//$$ config.load();
|
|
||||||
//$$ settingsRegistry.setConfiguration(config);
|
|
||||||
//$$ settingsRegistry.save(); // Save default values to disk
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public KeyBindingRegistry getKeyBindingRegistry() {
|
public KeyBindingRegistry getKeyBindingRegistry() {
|
||||||
return keyBindingRegistry;
|
return keyBindingRegistry;
|
||||||
}
|
}
|
||||||
@@ -256,6 +147,8 @@ public class ReplayMod implements
|
|||||||
try {
|
try {
|
||||||
Files.setAttribute(path, "dos:hidden", true);
|
Files.setAttribute(path, "dos:hidden", true);
|
||||||
} catch (UnsupportedOperationException ignored) {
|
} catch (UnsupportedOperationException ignored) {
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -275,19 +168,14 @@ public class ReplayMod implements
|
|||||||
return replayFolder.resolve(relative);
|
return replayFolder.resolve(relative);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final DirectoryResourcePack jGuiResourcePack;
|
public static final DirectoryResourcePack jGuiResourcePack = createJGuiResourcePack();
|
||||||
public static final String JGUI_RESOURCE_PACK_NAME = "replaymod_jgui";
|
public static final String JGUI_RESOURCE_PACK_NAME = "replaymod_jgui";
|
||||||
static { // Note: even preInit is too late and we'd have to issue another resource reload
|
private static DirectoryResourcePack createJGuiResourcePack() {
|
||||||
jGuiResourcePack = initJGuiResourcePack();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DirectoryResourcePack initJGuiResourcePack() {
|
|
||||||
File folder = new File("../jGui/src/main/resources");
|
File folder = new File("../jGui/src/main/resources");
|
||||||
if (!folder.exists()) {
|
if (!folder.exists()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//noinspection UnnecessaryLocalVariable
|
return new DirectoryResourcePack(folder) {
|
||||||
DirectoryResourcePack jGuiResourcePack = new DirectoryResourcePack(folder) {
|
|
||||||
@Override
|
@Override
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@@ -315,56 +203,13 @@ public class ReplayMod implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//#if MC<=11202
|
|
||||||
//$$ @SuppressWarnings("unchecked")
|
|
||||||
//$$ List<IResourcePack> defaultResourcePacks = ((MinecraftAccessor) mc).getDefaultResourcePacks();
|
|
||||||
//$$ defaultResourcePacks.add(jGuiResourcePack);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC<=10710
|
|
||||||
//$$ FolderResourcePack mainResourcePack = new FolderResourcePack(new File("../src/main/resources")) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ protected InputStream getInputStreamByName(String resourceName) throws IOException {
|
|
||||||
//$$ try {
|
|
||||||
//$$ return super.getInputStreamByName(resourceName);
|
|
||||||
//$$ } catch (IOException e) {
|
|
||||||
//$$ if ("pack.mcmeta".equals(resourceName)) {
|
|
||||||
//$$ return new ByteArrayInputStream(("{\"pack\": {\"description\": \"dummy pack for mod resources in dev-env\", \"pack_format\": 1}}").getBytes(StandardCharsets.UTF_8));
|
|
||||||
//$$ }
|
|
||||||
//$$ throw e;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ };
|
|
||||||
//$$ defaultResourcePacks.add(mainResourcePack);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
return jGuiResourcePack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
void initModules() {
|
||||||
@Override
|
|
||||||
public void onInitializeClient() {
|
|
||||||
modules.forEach(Module::initCommon);
|
modules.forEach(Module::initCommon);
|
||||||
modules.forEach(Module::initClient);
|
modules.forEach(Module::initClient);
|
||||||
modules.forEach(m -> m.registerKeyBindings(keyBindingRegistry));
|
modules.forEach(m -> m.registerKeyBindings(keyBindingRegistry));
|
||||||
}
|
}
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ {
|
|
||||||
//$$ FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLCommonSetupEvent event) -> modules.forEach(Module::initCommon));
|
|
||||||
//$$ FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLClientSetupEvent event) -> modules.forEach(Module::initClient));
|
|
||||||
//$$ FMLJavaModLoadingContext.get().getModEventBus().addListener((FMLClientSetupEvent event) -> modules.forEach(m -> m.registerKeyBindings(keyBindingRegistry)));
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ @EventHandler
|
|
||||||
//$$ public void init(FMLInitializationEvent event) {
|
|
||||||
//$$ modules.forEach(Module::initCommon);
|
|
||||||
//$$ modules.forEach(Module::initClient);
|
|
||||||
//$$ modules.forEach(m -> m.registerKeyBindings(keyBindingRegistry));
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerKeyBindings(KeyBindingRegistry registry) {
|
public void registerKeyBindings(KeyBindingRegistry registry) {
|
||||||
@@ -375,26 +220,16 @@ public class ReplayMod implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClient() {
|
public void initClient() {
|
||||||
//#if MC<=10710
|
|
||||||
//$$ FML_BUS.register(this); // For runLater(Runnable)
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
backgroundProcesses.register();
|
backgroundProcesses.register();
|
||||||
keyBindingRegistry.register();
|
keyBindingRegistry.register();
|
||||||
|
|
||||||
// 1.7.10 crashes when render distance > 16
|
// 1.7.10 crashes when render distance > 16
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
if (!MCVer.hasOptifine()) {
|
if (!MCVer.hasOptifine()) {
|
||||||
//#if MC>=11400
|
|
||||||
Option.RENDER_DISTANCE.setMax(64f);
|
Option.RENDER_DISTANCE.setMax(64f);
|
||||||
//#else
|
|
||||||
//$$ GameSettings.Options.RENDER_DISTANCE.setValueMax(64f);
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
testIfMoeshAndExitMinecraft();
|
|
||||||
|
|
||||||
runPostStartup(() -> {
|
runPostStartup(() -> {
|
||||||
final long DAYS = 24 * 60 * 60 * 1000;
|
final long DAYS = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
@@ -493,231 +328,41 @@ public class ReplayMod implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Execute the given runnable on the main client thread, returning only after it has been run (or after 30 seconds).
|
|
||||||
*/
|
|
||||||
public void runSync(Runnable runnable) throws InterruptedException, ExecutionException, TimeoutException {
|
public void runSync(Runnable runnable) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
//#if MC>=11400
|
scheduler.runSync(runnable);
|
||||||
if (mc.isOnThread()) {
|
|
||||||
runnable.run();
|
|
||||||
} else {
|
|
||||||
executor.submit(() -> {
|
|
||||||
runnable.run();
|
|
||||||
return null;
|
|
||||||
}).get(30, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ if (mc.isCallingFromMinecraftThread()) {
|
|
||||||
//$$ runnable.run();
|
|
||||||
//$$ } else {
|
|
||||||
//$$ FutureTask<Void> future = new FutureTask<>(runnable, null);
|
|
||||||
//$$ runLater(future);
|
|
||||||
//$$ future.get(30, TimeUnit.SECONDS);
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Execute the given runnable after game has started (once the overlay has been closed).
|
|
||||||
* Most importantly, it will run after resources (including language keys!) have been loaded.
|
|
||||||
* Below 1.14, this is equivalent to {@link #runLater(Runnable)}.
|
|
||||||
*/
|
|
||||||
public void runPostStartup(Runnable runnable) {
|
public void runPostStartup(Runnable runnable) {
|
||||||
runLater(new Runnable() {
|
scheduler.runPostStartup(runnable);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
//#if MC>=11400
|
|
||||||
if (getMinecraft().overlay != null) {
|
|
||||||
// delay until after resources have been loaded
|
|
||||||
runLater(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Set when the currently running code has been scheduled by runLater.
|
|
||||||
* If this is the case, subsequent calls to runLater have to be delayed until all scheduled tasks have been
|
|
||||||
* processed, otherwise a livelock may occur.
|
|
||||||
*/
|
|
||||||
private boolean inRunLater = false;
|
|
||||||
//#if MC>=11400
|
|
||||||
private boolean inRenderTaskQueue = false;
|
|
||||||
// Starting 1.14 MC clears the queue of scheduled tasks on disconnect.
|
|
||||||
// This works fine for MC since it uses the queue only for packet handling but breaks our assumption that
|
|
||||||
// stuff submitted via runLater is actually always run (e.g. recording might not be fully stopped because parts
|
|
||||||
// of that are run via runLater and stopping the recording happens right around the time MC clears the queue).
|
|
||||||
// Luckily, that's also the version where MC pulled out the executor implementation, so we can just spin up our own.
|
|
||||||
public static class ReplayModExecutor extends ReentrantThreadExecutor<Runnable> {
|
|
||||||
private final Thread mcThread = Thread.currentThread();
|
|
||||||
// Fail-fast in case we ever switch to async loading and forget to change this
|
|
||||||
// (except for fabric 1.15+ because it loads the mod before the client thread is set)
|
|
||||||
//#if FABRIC<1 || MC<11500
|
|
||||||
//$$ { if (!MinecraftClient.getInstance().isOnThread()) throw new RuntimeException(); }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
private ReplayModExecutor(String string_1) {
|
|
||||||
super(string_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Runnable createTask(Runnable runnable) {
|
|
||||||
return runnable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean canExecute(Runnable runnable) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Thread getThread() {
|
|
||||||
return mcThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void runTasks() {
|
|
||||||
super.runTasks();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public final ReplayModExecutor executor = new ReplayModExecutor("Client/ReplayMod");
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// Pre-1.14 MC would hold the lock on the scheduledTasks queue while executing its tasks
|
|
||||||
// such that no new tasks could be submitted while one of them was running.
|
|
||||||
// This would cause issues with long-running tasks (e.g. video rendering) as it would
|
|
||||||
// block all async tasks (e.g. skin loading).
|
|
||||||
public void runLaterWithoutLock(Runnable runnable) {
|
public void runLaterWithoutLock(Runnable runnable) {
|
||||||
//#if MC>=11400
|
scheduler.runLaterWithoutLock(runnable);
|
||||||
// MC 1.14+ no longer synchronizes on the queue while running its tasks
|
|
||||||
runLater(runnable);
|
|
||||||
//#else
|
|
||||||
//$$ runLater(() -> runLaterWithoutLock(runnable), runnable);
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void runLater(Runnable runnable) {
|
public void runLater(Runnable runnable) {
|
||||||
runLater(runnable, () -> runLater(runnable));
|
scheduler.runLater(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runLater(Runnable runnable, Runnable defer) {
|
@Override
|
||||||
//#if MC>=11400
|
public void runTasks() {
|
||||||
if (mc.isOnThread() && inRunLater && !inRenderTaskQueue) {
|
scheduler.runTasks();
|
||||||
((MinecraftAccessor) mc).getRenderTaskQueue().offer(() -> {
|
|
||||||
inRenderTaskQueue = true;
|
|
||||||
try {
|
|
||||||
defer.run();
|
|
||||||
} finally {
|
|
||||||
inRenderTaskQueue = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
executor.send(() -> {
|
|
||||||
inRunLater = true;
|
|
||||||
try {
|
|
||||||
runnable.run();
|
|
||||||
} catch (CrashException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.err.println(e.getReport().asString());
|
|
||||||
mc.setCrashReport(e.getReport());
|
|
||||||
} finally {
|
|
||||||
inRunLater = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ if (mc.isCallingFromMinecraftThread() && inRunLater) {
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ FML_BUS.register(new Object() {
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onRenderTick(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase == TickEvent.Phase.START) {
|
|
||||||
//$$ FML_BUS.unregister(this);
|
|
||||||
//$$ defer.run();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ });
|
|
||||||
//#else
|
|
||||||
//$$ FML_BUS.register(new RunLaterHelper(defer));
|
|
||||||
//#endif
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ Queue<FutureTask<?>> tasks = ((MinecraftAccessor) mc).getScheduledTasks();
|
|
||||||
//$$ //noinspection SynchronizationOnLocalVariableOrMethodParameter
|
|
||||||
//$$ synchronized (tasks) {
|
|
||||||
//#else
|
|
||||||
//$$ Queue<ListenableFutureTask<?>> tasks = scheduledTasks;
|
|
||||||
//$$ synchronized (scheduledTasks) {
|
|
||||||
//#endif
|
|
||||||
//$$ tasks.add(ListenableFutureTask.create(() -> {
|
|
||||||
//$$ inRunLater = true;
|
|
||||||
//$$ try {
|
|
||||||
//$$ runnable.run();
|
|
||||||
//$$ } catch (ReportedException e) {
|
|
||||||
//$$ e.printStackTrace();
|
|
||||||
//$$ System.err.println(e.getCrashReport().getCompleteReport());
|
|
||||||
//$$ mc.crashed(e.getCrashReport());
|
|
||||||
//$$ } finally {
|
|
||||||
//$$ inRunLater = false;
|
|
||||||
//$$ }
|
|
||||||
//$$ }, null));
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC<=10710
|
|
||||||
//$$ // 1.7.10: Cannot use MC's because it is processed only during ticks (so not at all when replay is paused)
|
|
||||||
//$$ private final Queue<ListenableFutureTask<?>> scheduledTasks = new ArrayDeque<>();
|
|
||||||
//$$
|
|
||||||
//$$ // in 1.7.10 apparently events can't be delivered to anonymous classes
|
|
||||||
//$$ public class RunLaterHelper {
|
|
||||||
//$$ private final Runnable defer;
|
|
||||||
//$$
|
|
||||||
//$$ private RunLaterHelper(Runnable defer) {
|
|
||||||
//$$ this.defer = defer;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onRenderTick(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase == TickEvent.Phase.START) {
|
|
||||||
//$$ FML_BUS.unregister(this);
|
|
||||||
//$$ defer.run();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void runScheduledTasks(InputReplayTimer.RunScheduledTasks event) {
|
|
||||||
//$$ synchronized (scheduledTasks) {
|
|
||||||
//$$ while (!scheduledTasks.isEmpty()) {
|
|
||||||
//$$ scheduledTasks.poll().run();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
//#if FABRIC>=1
|
return backend.getVersion();
|
||||||
return FabricLoader.getInstance().getModContainer(MOD_ID)
|
|
||||||
.orElseThrow(IllegalStateException::new)
|
|
||||||
.getMetadata().getVersion().toString();
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ return ModList.get().getModContainerById(MOD_ID).get().getModInfo().getVersion().toString();
|
|
||||||
//#else
|
|
||||||
//$$ return Loader.instance().getIndexedModList().get(MOD_ID).getVersion();
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testIfMoeshAndExitMinecraft() {
|
public String getMinecraftVersion() {
|
||||||
if("currentPlayer".equals("Moesh")) {
|
return backend.getMinecraftVersion();
|
||||||
System.exit(-1);
|
}
|
||||||
}
|
|
||||||
|
public boolean isModLoaded(String id) {
|
||||||
|
return backend.isModLoaded(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinecraftClient getMinecraft() {
|
public MinecraftClient getMinecraft() {
|
||||||
|
|||||||
29
src/main/java/com/replaymod/core/ReplayModBackend.java
Normal file
29
src/main/java/com/replaymod/core/ReplayModBackend.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.replaymod.core;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import static com.replaymod.core.ReplayMod.MOD_ID;
|
||||||
|
|
||||||
|
public class ReplayModBackend implements ClientModInitializer {
|
||||||
|
private final ReplayMod mod = new ReplayMod(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
mod.initModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return FabricLoader.getInstance().getModContainer(MOD_ID)
|
||||||
|
.orElseThrow(IllegalStateException::new)
|
||||||
|
.getMetadata().getVersion().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMinecraftVersion() {
|
||||||
|
return mod.getMinecraft().getGame().getVersion().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModLoaded(String id) {
|
||||||
|
return FabricLoader.getInstance().isModLoaded(id.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,8 @@
|
|||||||
//#if FABRIC>=1
|
//#if FABRIC>=1
|
||||||
package com.replaymod.core;
|
package com.replaymod.core;
|
||||||
|
|
||||||
import com.replaymod.extras.modcore.ModCoreInstaller;
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixins;
|
import org.spongepowered.asm.mixin.Mixins;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
// We need to wait for MM to call us, otherwise we might initialize our mixins before it calls optifabric which would
|
// We need to wait for MM to call us, otherwise we might initialize our mixins before it calls optifabric which would
|
||||||
// result in OF classes not existing while our mixins get resolved.
|
// result in OF classes not existing while our mixins get resolved.
|
||||||
public class ReplayModMMLauncher implements Runnable {
|
public class ReplayModMMLauncher implements Runnable {
|
||||||
@@ -32,43 +26,6 @@ public class ReplayModMMLauncher implements Runnable {
|
|||||||
Mixins.addConfiguration("mixins.render.blend.replaymod.json");
|
Mixins.addConfiguration("mixins.render.blend.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.render.replaymod.json");
|
Mixins.addConfiguration("mixins.render.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.replay.replaymod.json");
|
Mixins.addConfiguration("mixins.replay.replaymod.json");
|
||||||
|
|
||||||
try {
|
|
||||||
initModCore();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
System.err.println("ReplayMod caught error during ModCore init:");
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forge equivalent is in ReplayModTweaker
|
|
||||||
private void initModCore() {
|
|
||||||
if (System.getProperty("REPLAYMOD_SKIP_MODCORE", "false").equalsIgnoreCase("true")) {
|
|
||||||
System.out.println("ReplayMod not initializing ModCore because REPLAYMOD_SKIP_MODCORE is true.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FabricLoader.getInstance().isDevelopmentEnvironment()) {
|
|
||||||
System.out.println("ReplayMod not initializing ModCore because we're in a development environment.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File gameDir = FabricLoader.getInstance().getGameDirectory();
|
|
||||||
|
|
||||||
Optional<ModContainer> minecraft = FabricLoader.getInstance().getModContainer("minecraft");
|
|
||||||
if (!minecraft.isPresent()) {
|
|
||||||
System.err.println("ReplayMod could not determine Minecraft version, skipping ModCore.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String mcVer = minecraft.get().getMetadata().getVersion().getFriendlyString();
|
|
||||||
|
|
||||||
int result = ModCoreInstaller.initialize(gameDir, mcVer + "_fabric");
|
|
||||||
if (result != -2) { // Don't even bother logging the result if there's no ModCore for this version.
|
|
||||||
System.out.println("ReplayMod ModCore init result: " + result);
|
|
||||||
}
|
|
||||||
if (ModCoreInstaller.isErrored()) {
|
|
||||||
System.err.println(ModCoreInstaller.getError());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|||||||
@@ -1,130 +1,18 @@
|
|||||||
package com.replaymod.core;
|
package com.replaymod.core;
|
||||||
|
|
||||||
import com.replaymod.core.events.SettingsChangedCallback;
|
import com.replaymod.core.events.SettingsChangedCallback;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import net.minecraftforge.common.ForgeConfigSpec;
|
|
||||||
//$$ import net.minecraftforge.fml.ModLoadingContext;
|
|
||||||
//$$ import net.minecraftforge.fml.config.ModConfig;
|
|
||||||
//$$ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.common.config.Configuration;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
|
|
||||||
public class SettingsRegistry {
|
public class SettingsRegistry {
|
||||||
private static Logger LOGGER = LogManager.getLogger();
|
private final Map<SettingKey<?>, Object> settings = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||||
private Map<SettingKey<?>, Object> settings = Collections.synchronizedMap(new LinkedHashMap<>());
|
final SettingsRegistryBackend backend = new SettingsRegistryBackend(settings);
|
||||||
//#if MC>=11400
|
|
||||||
private final Path configFile = getMinecraft().runDirectory.toPath().resolve("config/replaymod.json");
|
|
||||||
//#else
|
|
||||||
//$$ private static final Object NULL_OBJECT = new Object();
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ private ForgeConfigSpec spec;
|
|
||||||
//$$ private ModConfig config;
|
|
||||||
//#else
|
|
||||||
//$$ private Configuration configuration;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
public void register() {
|
public void register() {
|
||||||
String config;
|
backend.register();
|
||||||
if (Files.exists(configFile)) {
|
|
||||||
try {
|
|
||||||
config = new String(Files.readAllBytes(configFile), StandardCharsets.UTF_8);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
save();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Gson gson = new Gson();
|
|
||||||
JsonObject root = gson.fromJson(config, JsonObject.class);
|
|
||||||
if (root == null) {
|
|
||||||
LOGGER.error("Config file {} appears corrupted: {}", configFile, config);
|
|
||||||
save();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Map.Entry<SettingKey<?>, Object> entry : settings.entrySet()) {
|
|
||||||
SettingKey<?> key = entry.getKey();
|
|
||||||
JsonElement category = root.get(key.getCategory());
|
|
||||||
if (category != null && category.isJsonObject()) {
|
|
||||||
JsonElement valueElem = category.getAsJsonObject().get(key.getKey());
|
|
||||||
if (valueElem == null || !valueElem.isJsonPrimitive()) continue;
|
|
||||||
JsonPrimitive value = valueElem.getAsJsonPrimitive();
|
|
||||||
if (key.getDefault() instanceof Boolean && value.isBoolean()) {
|
|
||||||
entry.setValue(value.getAsBoolean());
|
|
||||||
}
|
|
||||||
if (key.getDefault() instanceof Integer && value.isNumber()) {
|
|
||||||
entry.setValue(value.getAsNumber().intValue());
|
|
||||||
}
|
|
||||||
if (key.getDefault() instanceof Double && value.isNumber()) {
|
|
||||||
entry.setValue(value.getAsNumber().doubleValue());
|
|
||||||
}
|
|
||||||
if (key.getDefault() instanceof String && value.isString()) {
|
|
||||||
entry.setValue(value.getAsString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ public void register() {
|
|
||||||
//$$ if (spec == null) {
|
|
||||||
//$$ ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
|
|
||||||
//$$ for (SettingKey<?> key : settings.keySet()) {
|
|
||||||
//$$ builder
|
|
||||||
//$$ .translation(key.getDisplayString())
|
|
||||||
//$$ .define(key.getCategory() + "." + key.getKey(), key.getDefault());
|
|
||||||
//$$ }
|
|
||||||
//$$ spec = builder.build();
|
|
||||||
//$$ }
|
|
||||||
//$$ FMLJavaModLoadingContext.get().getModEventBus().addListener(this::load);
|
|
||||||
//$$ ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, spec);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private void load(ModConfig.Loading event) {
|
|
||||||
//$$ config = event.getConfig();
|
|
||||||
//$$ for (Map.Entry<SettingKey<?>, Object> entry : settings.entrySet()) {
|
|
||||||
//$$ SettingKey<?> key = entry.getKey();
|
|
||||||
//$$ Object value = config.getConfigData().get(key.getCategory() + "." + key.getKey());
|
|
||||||
//$$ entry.setValue(value == null ? key.getDefault() : value);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ public void setConfiguration(Configuration configuration) {
|
|
||||||
//$$ this.configuration = configuration;
|
|
||||||
//$$
|
|
||||||
//$$ List<SettingKey<?>> keys = new ArrayList<>(settings.keySet());
|
|
||||||
//$$ settings.clear();
|
|
||||||
//$$ for (SettingKey key : keys) {
|
|
||||||
//$$ register(key);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public void register(Class<?> settingsClass) {
|
public void register(Class<?> settingsClass) {
|
||||||
for (Field field : settingsClass.getDeclaredFields()) {
|
for (Field field : settingsClass.getDeclaredFields()) {
|
||||||
@@ -140,34 +28,8 @@ public class SettingsRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void register(SettingKey<?> key) {
|
public void register(SettingKey<?> key) {
|
||||||
//#if MC>=11400
|
|
||||||
settings.put(key, key.getDefault());
|
settings.put(key, key.getDefault());
|
||||||
//#else
|
backend.register(key);
|
||||||
//#if MC>=11400
|
|
||||||
//$$ if (spec != null) {
|
|
||||||
//$$ throw new IllegalStateException("Cannot register more settings are spec has been built.");
|
|
||||||
//$$ }
|
|
||||||
//$$ settings.put(key, NULL_OBJECT);
|
|
||||||
//#else
|
|
||||||
//$$ Object value;
|
|
||||||
//$$ if (configuration != null) {
|
|
||||||
//$$ if (key.getDefault() instanceof Boolean) {
|
|
||||||
//$$ value = configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).getBoolean();
|
|
||||||
//$$ } else if (key.getDefault() instanceof Integer) {
|
|
||||||
//$$ value = configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).getInt();
|
|
||||||
//$$ } else if (key.getDefault() instanceof Double) {
|
|
||||||
//$$ value = configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).getDouble();
|
|
||||||
//$$ } else if (key.getDefault() instanceof String) {
|
|
||||||
//$$ value = configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).getString();
|
|
||||||
//$$ } else {
|
|
||||||
//$$ throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
|
|
||||||
//$$ }
|
|
||||||
//$$ } else {
|
|
||||||
//$$ value = NULL_OBJECT;
|
|
||||||
//$$ }
|
|
||||||
//$$ settings.put(key, value);
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<SettingKey<?>> getSettings() {
|
public Set<SettingKey<?>> getSettings() {
|
||||||
@@ -183,68 +45,13 @@ public class SettingsRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> void set(SettingKey<T> key, T value) {
|
public <T> void set(SettingKey<T> key, T value) {
|
||||||
//#if MC<11400
|
backend.update(key, value);
|
||||||
//#if MC>=11400
|
|
||||||
//$$ if (config != null) {
|
|
||||||
//$$ config.getConfigData().set(key.getCategory() + "." + key.getKey(), value);
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ if (key.getDefault() instanceof Boolean) {
|
|
||||||
//$$ configuration.get(key.getCategory(), key.getKey(), (Boolean) key.getDefault()).set((Boolean) value);
|
|
||||||
//$$ } else if (key.getDefault() instanceof Integer) {
|
|
||||||
//$$ configuration.get(key.getCategory(), key.getKey(), (Integer) key.getDefault()).set((Integer) value);
|
|
||||||
//$$ } else if (key.getDefault() instanceof Double) {
|
|
||||||
//$$ configuration.get(key.getCategory(), key.getKey(), (Double) key.getDefault()).set((Double) value);
|
|
||||||
//$$ } else if (key.getDefault() instanceof String) {
|
|
||||||
//$$ configuration.get(key.getCategory(), key.getKey(), (String) key.getDefault()).set((String) value);
|
|
||||||
//$$ } else {
|
|
||||||
//$$ throw new IllegalArgumentException("Default type " + key.getDefault().getClass() + " not supported.");
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
settings.put(key, value);
|
settings.put(key, value);
|
||||||
SettingsChangedCallback.EVENT.invoker().onSettingsChanged(this, key);
|
SettingsChangedCallback.EVENT.invoker().onSettingsChanged(this, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
//#if MC>=11400
|
backend.save();
|
||||||
JsonObject root = new JsonObject();
|
|
||||||
for (Map.Entry<SettingKey<?>, Object> entry : settings.entrySet()) {
|
|
||||||
SettingKey<?> key = entry.getKey();
|
|
||||||
JsonObject category = root.getAsJsonObject(key.getCategory());
|
|
||||||
if (category == null) {
|
|
||||||
category = new JsonObject();
|
|
||||||
root.add(key.getCategory(), category);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object value = entry.getValue();
|
|
||||||
if (value instanceof Boolean) {
|
|
||||||
category.addProperty(key.getKey(), (Boolean) value);
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
category.addProperty(key.getKey(), (Number) value);
|
|
||||||
}
|
|
||||||
if (value instanceof String) {
|
|
||||||
category.addProperty(key.getKey(), (String) value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
String config = gson.toJson(root);
|
|
||||||
try {
|
|
||||||
Files.createDirectories(configFile.getParent());
|
|
||||||
Files.write(configFile, config.getBytes(StandardCharsets.UTF_8));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ if (config != null) {
|
|
||||||
//$$ config.save();
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ configuration.save();
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SettingKey<T> {
|
public interface SettingKey<T> {
|
||||||
|
|||||||
188
src/main/java/com/replaymod/core/SettingsRegistryBackend.java
Normal file
188
src/main/java/com/replaymod/core/SettingsRegistryBackend.java
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
package com.replaymod.core;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.replaymod.core.events.SettingsChangedCallback;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardWatchEventKinds;
|
||||||
|
import java.nio.file.WatchEvent;
|
||||||
|
import java.nio.file.WatchKey;
|
||||||
|
import java.nio.file.WatchService;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.replaymod.core.versions.MCVer.getMinecraft;
|
||||||
|
|
||||||
|
class SettingsRegistryBackend {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private final Map<SettingsRegistry.SettingKey<?>, Object> settings;
|
||||||
|
|
||||||
|
private final Path configFile = getMinecraft().runDirectory.toPath().resolve("config/replaymod.json");
|
||||||
|
|
||||||
|
SettingsRegistryBackend(Map<SettingsRegistry.SettingKey<?>, Object> settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register() {
|
||||||
|
load(true);
|
||||||
|
try {
|
||||||
|
registerWatcher();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.warn("Failed to setup file watcher for {}, live-reloading is disabled. Cause: {}", configFile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(boolean createIfMissingOrBroken) {
|
||||||
|
String config;
|
||||||
|
if (Files.exists(configFile)) {
|
||||||
|
try {
|
||||||
|
config = new String(Files.readAllBytes(configFile), StandardCharsets.UTF_8);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (createIfMissingOrBroken) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonObject root = gson.fromJson(config, JsonObject.class);
|
||||||
|
if (root == null) {
|
||||||
|
LOGGER.error("Config file {} appears corrupted: {}", configFile, config);
|
||||||
|
if (createIfMissingOrBroken) {
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Map.Entry<SettingsRegistry.SettingKey<?>, Object> entry : settings.entrySet()) {
|
||||||
|
SettingsRegistry.SettingKey<?> key = entry.getKey();
|
||||||
|
JsonElement category = root.get(key.getCategory());
|
||||||
|
if (category != null && category.isJsonObject()) {
|
||||||
|
JsonElement valueElem = category.getAsJsonObject().get(key.getKey());
|
||||||
|
if (valueElem == null || !valueElem.isJsonPrimitive()) continue;
|
||||||
|
JsonPrimitive value = valueElem.getAsJsonPrimitive();
|
||||||
|
if (key.getDefault() instanceof Boolean && value.isBoolean()) {
|
||||||
|
entry.setValue(value.getAsBoolean());
|
||||||
|
}
|
||||||
|
if (key.getDefault() instanceof Integer && value.isNumber()) {
|
||||||
|
entry.setValue(value.getAsNumber().intValue());
|
||||||
|
}
|
||||||
|
if (key.getDefault() instanceof Double && value.isNumber()) {
|
||||||
|
entry.setValue(value.getAsNumber().doubleValue());
|
||||||
|
}
|
||||||
|
if (key.getDefault() instanceof String && value.isString()) {
|
||||||
|
String valueStr = value.getAsString();
|
||||||
|
if (entry instanceof SettingsRegistry.MultipleChoiceSettingKey) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> choices = ((SettingsRegistry.MultipleChoiceSettingKey<String>) entry).getChoices();
|
||||||
|
if (choices.stream().noneMatch(valueStr::equals)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry.setValue(valueStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerWatcher() throws IOException {
|
||||||
|
WatchService watchService = configFile.getFileSystem().newWatchService();
|
||||||
|
configFile.getParent().register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
|
||||||
|
Thread thread = new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
WatchKey nextKey;
|
||||||
|
try {
|
||||||
|
nextKey = watchService.take();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (WatchEvent<?> event : nextKey.pollEvents()) {
|
||||||
|
WatchEvent.Kind<?> kind = event.kind();
|
||||||
|
if (kind == StandardWatchEventKinds.OVERFLOW) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Path fileName = ((Path) event.context());
|
||||||
|
if (fileName.equals(configFile.getFileName())) {
|
||||||
|
MinecraftClient.getInstance().send(this::reload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nextKey.reset()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.setName("replaymod-config-watcher");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reload() {
|
||||||
|
load(false);
|
||||||
|
|
||||||
|
SettingsRegistry settingsRegistry = ReplayMod.instance.getSettingsRegistry();
|
||||||
|
for (SettingsRegistry.SettingKey<?> key : settings.keySet()) {
|
||||||
|
SettingsChangedCallback.EVENT.invoker().onSettingsChanged(settingsRegistry, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void register(SettingsRegistry.SettingKey<?> key) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public <T> void update(SettingsRegistry.SettingKey<T> key, T value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
JsonObject root = new JsonObject();
|
||||||
|
for (Map.Entry<SettingsRegistry.SettingKey<?>, Object> entry : settings.entrySet()) {
|
||||||
|
SettingsRegistry.SettingKey<?> key = entry.getKey();
|
||||||
|
JsonObject category = root.getAsJsonObject(key.getCategory());
|
||||||
|
if (category == null) {
|
||||||
|
category = new JsonObject();
|
||||||
|
root.add(key.getCategory(), category);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = entry.getValue();
|
||||||
|
if (value instanceof Boolean) {
|
||||||
|
category.addProperty(key.getKey(), (Boolean) value);
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
category.addProperty(key.getKey(), (Number) value);
|
||||||
|
}
|
||||||
|
if (value instanceof String) {
|
||||||
|
category.addProperty(key.getKey(), (String) value);
|
||||||
|
if (key instanceof SettingsRegistry.MultipleChoiceSettingKey) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> choices = ((SettingsRegistry.MultipleChoiceSettingKey<String>) key).getChoices();
|
||||||
|
JsonArray array = new JsonArray();
|
||||||
|
for (String choice : choices) {
|
||||||
|
array.add(choice);
|
||||||
|
}
|
||||||
|
category.add(key.getKey() + "_valid_values", array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
String config = gson.toJson(root);
|
||||||
|
try {
|
||||||
|
Files.createDirectories(configFile.getParent());
|
||||||
|
Files.write(configFile, config.getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,95 +1 @@
|
|||||||
//#if MC<=10710
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.core.asm;
|
|
||||||
//$$
|
|
||||||
//$$ import net.minecraft.launchwrapper.IClassTransformer;
|
|
||||||
//$$ import org.lwjgl.opengl.GL11;
|
|
||||||
//$$ import org.lwjgl.util.glu.GLU;
|
|
||||||
//$$ import org.objectweb.asm.ClassReader;
|
|
||||||
//$$ import org.objectweb.asm.ClassVisitor;
|
|
||||||
//$$ import org.objectweb.asm.ClassWriter;
|
|
||||||
//$$ import org.objectweb.asm.MethodVisitor;
|
|
||||||
//$$ import org.objectweb.asm.Opcodes;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Insert glGetError checks after all calls to any method in any GL*, ARB* and EXT* classes
|
|
||||||
//$$ */
|
|
||||||
//$$ public class GLErrorTransformer implements IClassTransformer {
|
|
||||||
//$$ private static final String GL_CLASS = "org.lwjgl.opengl.GL";
|
|
||||||
//$$ private static final String GL = GL_CLASS.replace('.', '/');
|
|
||||||
//$$ private static final String ARB_CLASS = "org.lwjgl.opengl.ARB";
|
|
||||||
//$$ private static final String ARB = ARB_CLASS.replace('.', '/');
|
|
||||||
//$$ private static final String EXT_CLASS = "org.lwjgl.opengl.EXT";
|
|
||||||
//$$ private static final String EXT = EXT_CLASS.replace('.', '/');
|
|
||||||
//$$ private static final String GLErrorTransformer_CLASS = GLErrorTransformer.class.getName();
|
|
||||||
//$$ private static final String GLErrorTransformer = GLErrorTransformer_CLASS.replace('.', '/');
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public byte[] transform(String name, String transformedName, byte[] basicClass) {
|
|
||||||
//$$ if (basicClass == null) return null;
|
|
||||||
//$$
|
|
||||||
//$$ ClassReader reader = new ClassReader(basicClass);
|
|
||||||
//$$ ClassWriter writer = new ClassWriter(reader, 0);
|
|
||||||
//$$ reader.accept(new ClassVisitor(Opcodes.ASM5, writer) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
|
||||||
//$$ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
|
|
||||||
//$$ return new MethodVisitor(Opcodes.ASM5, mv) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
|
||||||
//$$ super.visitMethodInsn(opcode, owner, name, desc, itf);
|
|
||||||
//$$ if (owner.startsWith(GL) || owner.startsWith(ARB) || owner.startsWith(EXT)) {
|
|
||||||
//$$ visitLdcInsn(owner.replace('/', '.'));
|
|
||||||
//$$ visitLdcInsn(name);
|
|
||||||
//$$ super.visitMethodInsn(Opcodes.INVOKESTATIC, GLErrorTransformer, "glErrorCheck", "(Ljava/lang/String;Ljava/lang/String;)V", false);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void visitMaxs(int maxStack, int maxLocals) {
|
|
||||||
//$$ super.visitMaxs(maxStack + 2, maxLocals);
|
|
||||||
//$$ }
|
|
||||||
//$$ };
|
|
||||||
//$$ }
|
|
||||||
//$$ }, 0);
|
|
||||||
//$$ return writer.toByteArray();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private static boolean inGlBegin;
|
|
||||||
//$$
|
|
||||||
//$$ @SuppressWarnings("unused") // Called via ASM
|
|
||||||
//$$ public static void glErrorCheck(String cls, String method) {
|
|
||||||
//$$ if (method.equals("glBegin") && cls.equals(GL_CLASS + "11")) {
|
|
||||||
//$$ if (inGlBegin) {
|
|
||||||
//$$ // glBegin within glBegin
|
|
||||||
//$$ throw new GLError(GL11.GL_INVALID_OPERATION, cls, method);
|
|
||||||
//$$ }
|
|
||||||
//$$ inGlBegin = true;
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$ if (inGlBegin && method.equals("glEnd") && cls.equals(GL_CLASS + "11")) {
|
|
||||||
//$$ inGlBegin = false;
|
|
||||||
//$$ }
|
|
||||||
//$$ if (inGlBegin) {
|
|
||||||
//$$ return; // Cannot call glGetError in between of glBegin and glEnd
|
|
||||||
//$$ }
|
|
||||||
//$$ int err = GL11.glGetError();
|
|
||||||
//$$ if (err != 0) {
|
|
||||||
//$$ GLError e = new GLError(err, cls, method);
|
|
||||||
//$$ if ("true".equals(System.getProperty("replaymod.glerrors.throw", "true"))) {
|
|
||||||
//$$ throw e;
|
|
||||||
//$$ } else {
|
|
||||||
//$$ e.printStackTrace();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static class GLError extends RuntimeException {
|
|
||||||
//$$ private GLError(int err, String cls, String method) {
|
|
||||||
//$$ super(GLU.gluErrorString(err) + " (" + err + ")");
|
|
||||||
//$$ StackTraceElement[] stack = getStackTrace();
|
|
||||||
//$$ stack[0] = new StackTraceElement(cls, method, stack[0].getFileName(), stack[0].getLineNumber());
|
|
||||||
//$$ setStackTrace(stack);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,106 +1 @@
|
|||||||
//#if MC<=10710
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.core.asm;
|
|
||||||
//$$
|
|
||||||
//$$ import net.minecraft.launchwrapper.IClassTransformer;
|
|
||||||
//$$ import org.objectweb.asm.ClassReader;
|
|
||||||
//$$ import org.objectweb.asm.ClassVisitor;
|
|
||||||
//$$ import org.objectweb.asm.ClassWriter;
|
|
||||||
//$$ import org.objectweb.asm.MethodVisitor;
|
|
||||||
//$$ import org.objectweb.asm.Opcodes;
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.HashSet;
|
|
||||||
//$$ import java.util.Set;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Redirect all calls to GL11.glEnable and GL11.glDisable to the GLStateTracker (excluding that class itself).
|
|
||||||
//$$ */
|
|
||||||
//$$ public class GLStateTrackerTransformer implements IClassTransformer {
|
|
||||||
//$$ private static final String GL11_CLASS = "org.lwjgl.opengl.GL11";
|
|
||||||
//$$ private static final String GL11 = GL11_CLASS.replace('.', '/');
|
|
||||||
//$$ private static final String glEnable = "glEnable";
|
|
||||||
//$$ private static final String glDisable = "glDisable";
|
|
||||||
//$$ private static final String GLStateTracker_CLASS = "com.replaymod.render.hooks.GLStateTracker";
|
|
||||||
//$$ private static final String GLStateTracker = GLStateTracker_CLASS.replace('.', '/');
|
|
||||||
//$$ private static final String hook_glEnable = "hook_glEnable";
|
|
||||||
//$$ private static final String hook_glDisable = "hook_glDisable";
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public byte[] transform(String name, String transformedName, byte[] basicClass) {
|
|
||||||
//$$ if (basicClass == null) return null;
|
|
||||||
//$$ // Ignore the state tracker itself
|
|
||||||
//$$ if (name.equals(GLStateTracker_CLASS)) return basicClass;
|
|
||||||
//$$
|
|
||||||
//$$ ClassReader reader = new ClassReader(basicClass);
|
|
||||||
//$$ Set<Method> eligibleMethods = findEligibleMethods(reader);
|
|
||||||
//$$ if (eligibleMethods.isEmpty()) {
|
|
||||||
//$$ return basicClass;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ ClassWriter writer = new ClassWriter(reader, 0);
|
|
||||||
//$$ reader.accept(new ClassVisitor(Opcodes.ASM5, writer) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
|
||||||
//$$ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
|
|
||||||
//$$ if (!eligibleMethods.contains(new Method(name, desc))) {
|
|
||||||
//$$ return mv;
|
|
||||||
//$$ }
|
|
||||||
//$$ return new MethodVisitor(Opcodes.ASM5, mv) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
|
||||||
//$$ if (owner.equals(GL11)) {
|
|
||||||
//$$ if (name.equals(glEnable)) {
|
|
||||||
//$$ owner = GLStateTracker;
|
|
||||||
//$$ name = hook_glEnable;
|
|
||||||
//$$ } else if (name.equals(glDisable)) {
|
|
||||||
//$$ owner = GLStateTracker;
|
|
||||||
//$$ name = hook_glDisable;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ super.visitMethodInsn(opcode, owner, name, desc, itf);
|
|
||||||
//$$ }
|
|
||||||
//$$ };
|
|
||||||
//$$ }
|
|
||||||
//$$ }, 0);
|
|
||||||
//$$ return writer.toByteArray();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private Set<Method> findEligibleMethods(ClassReader reader) {
|
|
||||||
//$$ Set<Method> eligibleMethods = new HashSet<>();
|
|
||||||
//$$ reader.accept(new ClassVisitor(Opcodes.ASM5) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public MethodVisitor visitMethod(int access, String methodName, String methodDesc, String signature, String[] exceptions) {
|
|
||||||
//$$ return new MethodVisitor(Opcodes.ASM5) {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
|
||||||
//$$ if (owner.equals(GL11) && (name.equals(glEnable) || name.equals(glDisable))) {
|
|
||||||
//$$ eligibleMethods.add(new Method(methodName, methodDesc));
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ };
|
|
||||||
//$$ }
|
|
||||||
//$$ }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
|
||||||
//$$ return eligibleMethods;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private static class Method {
|
|
||||||
//$$ private final String name, desc;
|
|
||||||
//$$
|
|
||||||
//$$ private Method(String name, String desc) {
|
|
||||||
//$$ this.name = name;
|
|
||||||
//$$ this.desc = desc;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public boolean equals(Object o) {
|
|
||||||
//$$ if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
//$$ Method method = (Method) o;
|
|
||||||
//$$ return name.equals(method.name) && desc.equals(method.desc);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public int hashCode() {
|
|
||||||
//$$ return name.hashCode() ^ desc.hashCode();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//#if MC>=11400
|
|
||||||
package com.replaymod.core.events;
|
package com.replaymod.core.events;
|
||||||
|
|
||||||
import de.johni0702.minecraft.gui.utils.Event;
|
import de.johni0702.minecraft.gui.utils.Event;
|
||||||
@@ -14,4 +13,3 @@ public interface PostRenderCallback {
|
|||||||
|
|
||||||
void postRender();
|
void postRender();
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,33 +1,16 @@
|
|||||||
//#if MC>=11400
|
|
||||||
package com.replaymod.core.events;
|
package com.replaymod.core.events;
|
||||||
|
|
||||||
import de.johni0702.minecraft.gui.utils.Event;
|
import de.johni0702.minecraft.gui.utils.Event;
|
||||||
|
|
||||||
//#if MC>=11500
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
//#endif
|
|
||||||
|
|
||||||
public interface PostRenderWorldCallback {
|
public interface PostRenderWorldCallback {
|
||||||
Event<PostRenderWorldCallback> EVENT = Event.create((listeners) ->
|
Event<PostRenderWorldCallback> EVENT = Event.create((listeners) ->
|
||||||
//#if MC>=11500
|
|
||||||
(MatrixStack matrixStack) -> {
|
(MatrixStack matrixStack) -> {
|
||||||
//#else
|
|
||||||
//$$ () -> {
|
|
||||||
//#endif
|
|
||||||
for (PostRenderWorldCallback listener : listeners) {
|
for (PostRenderWorldCallback listener : listeners) {
|
||||||
listener.postRenderWorld(
|
listener.postRenderWorld(matrixStack);
|
||||||
//#if MC>=11500
|
|
||||||
matrixStack
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
void postRenderWorld(
|
void postRenderWorld(MatrixStack matrixStack);
|
||||||
//#if MC>=11500
|
|
||||||
MatrixStack matrixStack
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//#if MC>=11400
|
|
||||||
package com.replaymod.core.events;
|
package com.replaymod.core.events;
|
||||||
|
|
||||||
import de.johni0702.minecraft.gui.utils.Event;
|
import de.johni0702.minecraft.gui.utils.Event;
|
||||||
@@ -14,4 +13,3 @@ public interface PreRenderCallback {
|
|||||||
|
|
||||||
void preRender();
|
void preRender();
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//#if MC>=11400
|
|
||||||
package com.replaymod.core.events;
|
package com.replaymod.core.events;
|
||||||
|
|
||||||
import de.johni0702.minecraft.gui.utils.Event;
|
import de.johni0702.minecraft.gui.utils.Event;
|
||||||
@@ -17,4 +16,3 @@ public interface PreRenderHandCallback {
|
|||||||
|
|
||||||
boolean preRenderHand();
|
boolean preRenderHand();
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -12,30 +12,15 @@ import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
|||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.getGui;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.getMinecraft;
|
import static com.replaymod.core.versions.MCVer.getMinecraft;
|
||||||
|
|
||||||
public class GuiBackgroundProcesses extends EventRegistrations {
|
public class GuiBackgroundProcesses extends EventRegistrations {
|
||||||
private GuiPanel panel = new GuiPanel().setLayout(new VerticalLayout().setSpacing(10));
|
private GuiPanel panel = new GuiPanel().setLayout(new VerticalLayout().setSpacing(10));
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(InitScreenCallback.EVENT, (screen, buttons) -> onGuiInit(screen)); }
|
{ on(InitScreenCallback.EVENT, (screen, buttons) -> onGuiInit(screen)); }
|
||||||
private void onGuiInit(Screen guiScreen) {
|
private void onGuiInit(net.minecraft.client.gui.screen.Screen guiScreen) {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onGuiInit(GuiScreenEvent.InitGuiEvent.Post event) {
|
|
||||||
//$$ net.minecraft.client.gui.screen.Screen guiScreen = getGui(event);
|
|
||||||
//#endif
|
|
||||||
if (guiScreen != getMinecraft().currentScreen) return; // people tend to construct GuiScreens without opening them
|
if (guiScreen != getMinecraft().currentScreen) return; // people tend to construct GuiScreens without opening them
|
||||||
|
|
||||||
VanillaGuiScreen vanillaGui = VanillaGuiScreen.wrap(guiScreen);
|
VanillaGuiScreen vanillaGui = VanillaGuiScreen.wrap(guiScreen);
|
||||||
|
|||||||
@@ -1,63 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.core.gui;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.core.ReplayMod;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import net.minecraft.client.gui.GuiScreen;
|
|
||||||
//$$
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraftforge.fml.client.IModGuiFactory;
|
|
||||||
//#else
|
|
||||||
//$$ import cpw.mods.fml.client.IModGuiFactory;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.Set;
|
|
||||||
//$$
|
|
||||||
//$$ @SuppressWarnings("unused")
|
|
||||||
//$$ public class GuiFactory implements IModGuiFactory {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void initialize(Minecraft minecraftInstance) {
|
|
||||||
//$$
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public boolean hasConfigGui() {
|
|
||||||
//$$ return true;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public GuiScreen createConfigGui(GuiScreen parentScreen) {
|
|
||||||
//$$ return new GuiReplaySettings(parentScreen, ReplayMod.instance.getSettingsRegistry()).toMinecraft();
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public Class<? extends GuiScreen> mainConfigGuiClass() {
|
|
||||||
//$$ return ConfigGuiWrapper.class;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static class ConfigGuiWrapper extends GuiScreen {
|
|
||||||
//$$ private final GuiScreen parent;
|
|
||||||
//$$
|
|
||||||
//$$ public ConfigGuiWrapper(GuiScreen parent) {
|
|
||||||
//$$ this.parent = parent;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void initGui() {
|
|
||||||
//$$ new GuiReplaySettings(parent, ReplayMod.instance.getSettingsRegistry()).display();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
package com.replaymod.core.gui;
|
package com.replaymod.core.gui;
|
||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.RenderInfo;
|
import de.johni0702.minecraft.gui.RenderInfo;
|
||||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
public class GuiReplayButton extends GuiButton {
|
public class GuiReplayButton extends GuiButton {
|
||||||
|
public static final Identifier ICON = new Identifier("replaymod", "logo_button.png");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
|
public void draw(GuiRenderer renderer, ReadableDimension size, RenderInfo renderInfo) {
|
||||||
super.draw(renderer, size, renderInfo);
|
super.draw(renderer, size, renderInfo);
|
||||||
|
|
||||||
renderer.bindTexture(ReplayMod.LOGO_FAVICON);
|
renderer.bindTexture(ICON);
|
||||||
renderer.drawTexturedRect(3, 3, 0, 0, size.getWidth() - 6, size.getHeight() - 6, 1, 1, 1, 1);
|
renderer.drawTexturedRect(3, 3, 0, 0, size.getWidth() - 6, size.getHeight() - 6, 1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,31 @@
|
|||||||
package com.replaymod.core.gui;
|
package com.replaymod.core.gui;
|
||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import io.github.prospector.modmenu.api.ModMenuApi;
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||||
|
//$$ import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||||
|
//#else
|
||||||
|
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||||
|
//#endif
|
||||||
|
|
||||||
public class ModMenuApiImpl implements ModMenuApi {
|
public class ModMenuApiImpl implements ModMenuApi {
|
||||||
|
//#if MC<11700
|
||||||
@Override
|
@Override
|
||||||
public String getModId() {
|
public String getModId() {
|
||||||
return ReplayMod.MOD_ID;
|
return ReplayMod.MOD_ID;
|
||||||
}
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||||
|
//#else
|
||||||
public Function<Screen, ? extends Screen> getConfigScreenFactory() {
|
public Function<Screen, ? extends Screen> getConfigScreenFactory() {
|
||||||
|
//#endif
|
||||||
return parent -> new GuiReplaySettings(parent, ReplayMod.instance.getSettingsRegistry()).toMinecraft();
|
return parent -> new GuiReplaySettings(parent, ReplayMod.instance.getSettingsRegistry()).toMinecraft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,32 +2,33 @@ package com.replaymod.core.mixin;
|
|||||||
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
import java.util.List;
|
//#if MC>=11700
|
||||||
|
//$$ import net.minecraft.client.gui.Drawable;
|
||||||
//#if MC>=11400
|
//$$ import net.minecraft.client.gui.Element;
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
//$$ import net.minecraft.client.gui.Selectable;
|
||||||
//#else
|
//#else
|
||||||
//$$ import net.minecraft.client.gui.GuiButton;
|
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import net.minecraft.client.gui.Element;
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
//#else
|
||||||
|
//$$ import net.minecraft.client.gui.GuiButton;
|
||||||
|
//$$ import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
//$$ import java.util.List;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@Mixin(Screen.class)
|
@Mixin(Screen.class)
|
||||||
public interface GuiScreenAccessor {
|
public interface GuiScreenAccessor {
|
||||||
//#if MC>=11400
|
//#if MC>=11700
|
||||||
@Accessor
|
//$$ @Invoker("addDrawableChild")
|
||||||
List<AbstractButtonWidget> getButtons();
|
//$$ <T extends Element & Drawable & Selectable> T invokeAddButton(T drawableElement);
|
||||||
|
//#elseif MC>=11400
|
||||||
|
@Invoker
|
||||||
|
<T extends AbstractButtonWidget> T invokeAddButton(T button);
|
||||||
//#else
|
//#else
|
||||||
//$$ @Accessor("buttonList")
|
//$$ @Accessor("buttonList")
|
||||||
//$$ List<GuiButton> getButtons();
|
//$$ List<GuiButton> getButtons();
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
@Accessor
|
|
||||||
List<Element> getChildren();
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.replaymod.core.mixin;
|
package com.replaymod.core.mixin;
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
import net.minecraft.client.render.RenderTickCounter;
|
import net.minecraft.client.render.RenderTickCounter;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
@@ -26,6 +28,9 @@ public interface MinecraftAccessor {
|
|||||||
@Accessor("renderTickCounter")
|
@Accessor("renderTickCounter")
|
||||||
RenderTickCounter getTimer();
|
RenderTickCounter getTimer();
|
||||||
@Accessor("renderTickCounter")
|
@Accessor("renderTickCounter")
|
||||||
|
//#if MC>=11200
|
||||||
|
@Mutable
|
||||||
|
//#endif
|
||||||
void setTimer(RenderTickCounter value);
|
void setTimer(RenderTickCounter value);
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
@@ -50,4 +55,9 @@ public interface MinecraftAccessor {
|
|||||||
//$$ @Accessor
|
//$$ @Accessor
|
||||||
//$$ List<IResourcePack> getDefaultResourcePacks();
|
//$$ List<IResourcePack> getDefaultResourcePacks();
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
//#if MC>=11400
|
||||||
|
@Accessor
|
||||||
|
void setConnection(ClientConnection connection);
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,12 @@ import com.replaymod.core.events.PostRenderWorldCallback;
|
|||||||
import com.replaymod.core.events.PreRenderHandCallback;
|
import com.replaymod.core.events.PreRenderHandCallback;
|
||||||
import net.minecraft.client.render.Camera;
|
import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
//#if MC>=11500
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
@Mixin(GameRenderer.class)
|
@Mixin(GameRenderer.class)
|
||||||
public class MixinGameRenderer {
|
public class MixinGameRenderer {
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -30,11 +27,10 @@ public class MixinGameRenderer {
|
|||||||
MatrixStack matrixStack,
|
MatrixStack matrixStack,
|
||||||
//#endif
|
//#endif
|
||||||
CallbackInfo ci) {
|
CallbackInfo ci) {
|
||||||
PostRenderWorldCallback.EVENT.invoker().postRenderWorld(
|
//#if MC<11500
|
||||||
//#if MC>=11500
|
//$$ MatrixStack matrixStack = new MatrixStack();
|
||||||
matrixStack
|
//#endif
|
||||||
//#endif
|
PostRenderWorldCallback.EVENT.invoker().postRenderWorld(matrixStack);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
|
||||||
|
|||||||
@@ -2,19 +2,12 @@ package com.replaymod.core.mixin;
|
|||||||
|
|
||||||
import com.replaymod.core.events.KeyBindingEventCallback;
|
import com.replaymod.core.events.KeyBindingEventCallback;
|
||||||
import com.replaymod.core.events.KeyEventCallback;
|
import com.replaymod.core.events.KeyEventCallback;
|
||||||
|
import net.minecraft.client.Keyboard;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import net.minecraft.client.Keyboard;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.client.settings.KeyBinding;
|
|
||||||
//$$ import org.lwjgl.input.Keyboard;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
@Mixin(Keyboard.class)
|
@Mixin(Keyboard.class)
|
||||||
public class MixinKeyboardListener {
|
public class MixinKeyboardListener {
|
||||||
private static final String ON_KEY_PRESSED = "Lnet/minecraft/client/options/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V";
|
private static final String ON_KEY_PRESSED = "Lnet/minecraft/client/options/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V";
|
||||||
@@ -31,21 +24,3 @@ public class MixinKeyboardListener {
|
|||||||
KeyBindingEventCallback.EVENT.invoker().onKeybindingEvent();
|
KeyBindingEventCallback.EVENT.invoker().onKeybindingEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#else
|
|
||||||
//$$ @Mixin(KeyBinding.class)
|
|
||||||
//$$ public class MixinKeyboardListener {
|
|
||||||
//$$ @Inject(method = "onTick", at = @At("HEAD"), cancellable = true)
|
|
||||||
//$$ private static void beforeKeyBindingTick(CallbackInfo ci) {
|
|
||||||
//$$ int keyCode = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
|
|
||||||
//$$ int action = Keyboard.getEventKeyState() ? KeyEventCallback.ACTION_PRESS : KeyEventCallback.ACTION_RELEASE;
|
|
||||||
//$$ if (KeyEventCallback.EVENT.invoker().onKeyEvent(keyCode, 0, action, 0)) {
|
|
||||||
//$$ ci.cancel();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Inject(method = "onTick", at = @At("RETURN"))
|
|
||||||
//$$ private static void afterKeyBindingTick(CallbackInfo ci) {
|
|
||||||
//$$ KeyBindingEventCallback.EVENT.invoker().onKeybindingEvent();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//#if MC>=11400
|
|
||||||
package com.replaymod.core.mixin;
|
package com.replaymod.core.mixin;
|
||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
@@ -13,6 +12,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -24,16 +24,26 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
@Mixin(KeyBinding.class)
|
@Mixin(KeyBinding.class)
|
||||||
public class Mixin_ContextualKeyBindings {
|
public class Mixin_ContextualKeyBindings {
|
||||||
|
//#if MC>=11200
|
||||||
@Shadow @Final private static Map<String, KeyBinding> keysById;
|
@Shadow @Final private static Map<String, KeyBinding> keysById;
|
||||||
|
@Unique private static Collection<KeyBinding> keyBindings() { return Mixin_ContextualKeyBindings.keysById.values(); }
|
||||||
|
//#else
|
||||||
|
//$$ @Shadow @Final private static List<KeyBinding> KEYBIND_ARRAY;
|
||||||
|
//$$ @Unique private static Collection<KeyBinding> keyBindings() { return Mixin_ContextualKeyBindings.KEYBIND_ARRAY; }
|
||||||
|
//#endif
|
||||||
|
|
||||||
@Unique private static final List<KeyBinding> temporarilyRemoved = new ArrayList<>();
|
@Unique private static final List<KeyBinding> temporarilyRemoved = new ArrayList<>();
|
||||||
|
|
||||||
@Inject(method = "updateKeysByCode", at = @At("HEAD"))
|
@Inject(method = "updateKeysByCode", at = @At("HEAD"))
|
||||||
private static void preContextualKeyBindings(CallbackInfo ci) {
|
private static void preContextualKeyBindings(CallbackInfo ci) {
|
||||||
Set<KeyBinding> onlyInReplay = ReplayMod.instance.getKeyBindingRegistry().getOnlyInReplay();
|
ReplayMod mod = ReplayMod.instance;
|
||||||
|
if (mod == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<KeyBinding> onlyInReplay = mod.getKeyBindingRegistry().getOnlyInReplay();
|
||||||
if (ReplayModReplay.instance.getReplayHandler() != null) {
|
if (ReplayModReplay.instance.getReplayHandler() != null) {
|
||||||
// In replay, remove any conflicting key bindings, so that ours are guaranteed in
|
// In replay, remove any conflicting key bindings, so that ours are guaranteed in
|
||||||
Mixin_ContextualKeyBindings.keysById.values().removeIf(keyBinding -> {
|
keyBindings().removeIf(keyBinding -> {
|
||||||
for (KeyBinding exclusiveBinding : onlyInReplay) {
|
for (KeyBinding exclusiveBinding : onlyInReplay) {
|
||||||
if (keyBinding.equals(exclusiveBinding) && keyBinding != exclusiveBinding) {
|
if (keyBinding.equals(exclusiveBinding) && keyBinding != exclusiveBinding) {
|
||||||
temporarilyRemoved.add(keyBinding);
|
temporarilyRemoved.add(keyBinding);
|
||||||
@@ -44,20 +54,25 @@ public class Mixin_ContextualKeyBindings {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Not in a replay, remove all replay-exclusive keybindings
|
// Not in a replay, remove all replay-exclusive keybindings
|
||||||
for (KeyBinding keyBinding : onlyInReplay) {
|
keyBindings().removeIf(keyBinding -> {
|
||||||
if (Mixin_ContextualKeyBindings.keysById.remove(keyBinding.getTranslationKey()) != null) {
|
if (onlyInReplay.contains(keyBinding)) {
|
||||||
temporarilyRemoved.add(keyBinding);
|
temporarilyRemoved.add(keyBinding);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "updateKeysByCode", at = @At("RETURN"))
|
@Inject(method = "updateKeysByCode", at = @At("RETURN"))
|
||||||
private static void postContextualKeyBindings(CallbackInfo ci) {
|
private static void postContextualKeyBindings(CallbackInfo ci) {
|
||||||
for (KeyBinding keyBinding : temporarilyRemoved) {
|
for (KeyBinding keyBinding : temporarilyRemoved) {
|
||||||
|
//#if MC>=11200
|
||||||
Mixin_ContextualKeyBindings.keysById.put(keyBinding.getTranslationKey(), keyBinding);
|
Mixin_ContextualKeyBindings.keysById.put(keyBinding.getTranslationKey(), keyBinding);
|
||||||
|
//#else
|
||||||
|
//$$ keyBindings().add(keyBinding);
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
temporarilyRemoved.clear();
|
temporarilyRemoved.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,22 +1 @@
|
|||||||
//#if MC<10800
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.core.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import net.minecraft.client.resources.IResourcePack;
|
|
||||||
//$$ import net.minecraft.client.resources.ResourcePackRepository;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
//$$
|
|
||||||
//$$ import java.io.File;
|
|
||||||
//$$
|
|
||||||
//$$ @Mixin(ResourcePackRepository.class)
|
|
||||||
//$$ public interface ResourcePackRepositoryAccessor {
|
|
||||||
//$$ @Accessor("field_148533_g")
|
|
||||||
//$$ boolean isActive();
|
|
||||||
//$$ @Accessor("field_148533_g")
|
|
||||||
//$$ void setActive(boolean value);
|
|
||||||
//$$ @Accessor("field_148532_f")
|
|
||||||
//$$ void setPack(IResourcePack value);
|
|
||||||
//$$ @Accessor("field_148534_e")
|
|
||||||
//$$ File getCacheDir();
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.replaymod.core.mixin;
|
|||||||
|
|
||||||
import net.minecraft.client.render.RenderTickCounter;
|
import net.minecraft.client.render.RenderTickCounter;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
@Mixin(RenderTickCounter.class)
|
@Mixin(RenderTickCounter.class)
|
||||||
@@ -15,6 +16,7 @@ public interface TimerAccessor {
|
|||||||
@Accessor("tickTime")
|
@Accessor("tickTime")
|
||||||
float getTickLength();
|
float getTickLength();
|
||||||
@Accessor("tickTime")
|
@Accessor("tickTime")
|
||||||
|
@Mutable
|
||||||
void setTickLength(float value);
|
void setTickLength(float value);
|
||||||
//#else
|
//#else
|
||||||
//$$ @Accessor
|
//$$ @Accessor
|
||||||
|
|||||||
@@ -1,127 +1 @@
|
|||||||
//#if FABRIC>=1
|
// Forge only
|
||||||
// Fabric equivalent is in ReplayModMMLauncher
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ // Generally not supported by RM
|
|
||||||
//#else
|
|
||||||
//$$ package com.replaymod.core.tweaker;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.extras.modcore.ModCoreInstaller;
|
|
||||||
//$$ import net.minecraft.launchwrapper.ITweaker;
|
|
||||||
//$$ import net.minecraft.launchwrapper.Launch;
|
|
||||||
//$$ import net.minecraft.launchwrapper.LaunchClassLoader;
|
|
||||||
//$$ import org.spongepowered.asm.launch.GlobalProperties;
|
|
||||||
//$$ import org.spongepowered.asm.launch.MixinBootstrap;
|
|
||||||
//$$ import org.spongepowered.asm.launch.platform.MixinPlatformManager;
|
|
||||||
//$$
|
|
||||||
//$$ import java.io.File;
|
|
||||||
//$$ import java.net.URI;
|
|
||||||
//$$ import java.net.URISyntaxException;
|
|
||||||
//$$ import java.util.List;
|
|
||||||
//$$
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ import org.spongepowered.asm.launch.platform.container.ContainerHandleURI;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ public class ReplayModTweaker implements ITweaker {
|
|
||||||
//$$
|
|
||||||
//$$ private static final String MIXIN_TWEAKER = "org.spongepowered.asm.launch.MixinTweaker";
|
|
||||||
//$$
|
|
||||||
//$$ public ReplayModTweaker() {
|
|
||||||
//$$ injectMixinTweaker();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private void injectMixinTweaker() {
|
|
||||||
//$$ @SuppressWarnings("unchecked")
|
|
||||||
//$$ List<String> tweakClasses = (List<String>) Launch.blackboard.get("TweakClasses");
|
|
||||||
//$$
|
|
||||||
//$$ // If the MixinTweaker is already queued (because of another mod), then there's nothing we need to to
|
|
||||||
//$$ if (tweakClasses.contains(MIXIN_TWEAKER)) {
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ // If it is already booted, we're also good to go
|
|
||||||
//$$ if (GlobalProperties.get(GlobalProperties.Keys.INIT) != null) {
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ System.out.println("Injecting MixinTweaker from ReplayModTweaker");
|
|
||||||
//$$
|
|
||||||
//$$ // Otherwise, we need to take things into our own hands because the normal way to chainload a tweaker
|
|
||||||
//$$ // (by adding it to the TweakClasses list during injectIntoClassLoader) is too late for Mixin.
|
|
||||||
//$$ // Instead we instantiate the MixinTweaker on our own and add it to the current Tweaks list immediately.
|
|
||||||
//$$ Launch.classLoader.addClassLoaderExclusion(MIXIN_TWEAKER.substring(0, MIXIN_TWEAKER.lastIndexOf('.')));
|
|
||||||
//$$ @SuppressWarnings("unchecked")
|
|
||||||
//$$ List<ITweaker> tweaks = (List<ITweaker>) Launch.blackboard.get("Tweaks");
|
|
||||||
//$$ try {
|
|
||||||
//$$ tweaks.add((ITweaker) Class.forName(MIXIN_TWEAKER, true, Launch.classLoader).newInstance());
|
|
||||||
//$$ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
|
|
||||||
//$$ throw new RuntimeException(e);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
|
|
||||||
//$$ // Add our jar as a Mixin container (cause normally Mixin detects those via the TweakClass manifest entry)
|
|
||||||
//$$ URI uri;
|
|
||||||
//$$ try {
|
|
||||||
//$$ uri = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI();
|
|
||||||
//$$ } catch (URISyntaxException e) {
|
|
||||||
//$$ throw new RuntimeException(e);
|
|
||||||
//$$ }
|
|
||||||
//$$ MixinPlatformManager platform = MixinBootstrap.getPlatform();
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ platform.addContainer(new ContainerHandleURI(uri));
|
|
||||||
//#else
|
|
||||||
//$$ platform.addContainer(uri);
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=11202 && MC<=11202
|
|
||||||
//$$ initModCore("1.12.2");
|
|
||||||
//#endif
|
|
||||||
//#if MC>=10809 && MC<=10809
|
|
||||||
//$$ initModCore("1.8.9");
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String getLaunchTarget() {
|
|
||||||
//$$ return null;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public String[] getLaunchArguments() {
|
|
||||||
//$$ return new String[0];
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ private void initModCore(String mcVer) {
|
|
||||||
//$$ try {
|
|
||||||
//$$ if (System.getProperty("REPLAYMOD_SKIP_MODCORE", "false").equalsIgnoreCase("true")) {
|
|
||||||
//$$ System.out.println("ReplayMod not initializing ModCore because REPLAYMOD_SKIP_MODCORE is true.");
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ if ((Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment")) {
|
|
||||||
//$$ System.out.println("ReplayMod not initializing ModCore because we're in a development environment.");
|
|
||||||
//$$ return;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ int result = ModCoreInstaller.initialize(Launch.minecraftHome, mcVer + "_forge");
|
|
||||||
//$$ if (result != -2) { // Don't even bother logging the result if there's no ModCore for this version.
|
|
||||||
//$$ System.out.println("ReplayMod ModCore init result: " + result);
|
|
||||||
//$$ }
|
|
||||||
//$$ if (ModCoreInstaller.isErrored()) {
|
|
||||||
//$$ System.err.println(ModCoreInstaller.getError());
|
|
||||||
//$$ }
|
|
||||||
//$$ } catch (Throwable t) {
|
|
||||||
//$$ System.err.println("ReplayMod caught error during ModCore init:");
|
|
||||||
//$$ t.printStackTrace();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|||||||
30
src/main/java/com/replaymod/core/utils/FileTypeAdapter.java
Normal file
30
src/main/java/com/replaymod/core/utils/FileTypeAdapter.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package com.replaymod.core.utils;
|
||||||
|
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class FileTypeAdapter extends TypeAdapter<File> {
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, File value) throws IOException {
|
||||||
|
out.value(value.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File read(JsonReader in) throws IOException {
|
||||||
|
String path;
|
||||||
|
if (in.peek() == JsonToken.BEGIN_OBJECT) {
|
||||||
|
in.beginObject();
|
||||||
|
in.nextName();
|
||||||
|
path = in.nextString();
|
||||||
|
in.endObject();
|
||||||
|
} else {
|
||||||
|
path = in.nextString();
|
||||||
|
}
|
||||||
|
return new File(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,89 +1,12 @@
|
|||||||
package com.replaymod.core.utils;
|
package com.replaymod.core.utils;
|
||||||
|
|
||||||
import com.replaymod.replaystudio.data.ModInfo;
|
import com.replaymod.replaystudio.data.ModInfo;
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
//#else
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ import net.minecraftforge.registries.ForgeRegistry;
|
|
||||||
//$$ import net.minecraftforge.registries.RegistryManager;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.registry.GameData;
|
|
||||||
//$$ import java.util.stream.Stream;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import net.minecraftforge.fml.ModList;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.Loader;
|
|
||||||
//$$ import net.minecraftforge.fml.common.ModContainer;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ModCompat {
|
public class ModCompat {
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Collection<ModInfo> getInstalledNetworkMods() {
|
public static Collection<ModInfo> getInstalledNetworkMods() {
|
||||||
//#if MC>=11400
|
return ModInfoGetter.getInstalledNetworkMods();
|
||||||
//#if FABRIC>=1
|
|
||||||
Map<String, ModInfo> modInfoMap = FabricLoader.getInstance().getAllMods().stream()
|
|
||||||
.map(ModContainer::getMetadata)
|
|
||||||
.map(m -> new ModInfo(m.getId(), m.getName(), m.getVersion().toString()))
|
|
||||||
.collect(Collectors.toMap(ModInfo::getId, Function.identity()));
|
|
||||||
return Registry.REGISTRIES.stream()
|
|
||||||
.map(Registry::getIds).flatMap(Set::stream)
|
|
||||||
//#else
|
|
||||||
//$$ Map<String, ModInfo> modInfoMap = ModList.get().getMods().stream()
|
|
||||||
//$$ .map(m -> new ModInfo(m.getModId(), m.getDisplayName(), m.getVersion().toString()))
|
|
||||||
//$$ .collect(Collectors.toMap(ModInfo::getId, Function.identity()));
|
|
||||||
//$$ return RegistryManager.ACTIVE.takeSnapshot(false).keySet().stream()
|
|
||||||
//$$ .map(RegistryManager.ACTIVE::getRegistry)
|
|
||||||
//$$ .map(ForgeRegistry::getKeys).flatMap(Set::stream)
|
|
||||||
//#endif
|
|
||||||
.map(Identifier::getNamespace).filter(s -> !s.equals("minecraft")).distinct()
|
|
||||||
.map(modInfoMap::get).filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
//#else
|
|
||||||
//$$ Map<String, ModContainer> ignoreCaseMap = Loader.instance().getModList().stream()
|
|
||||||
//$$ .collect(Collectors.toMap(m -> m.getModId().toLowerCase(), Function.identity()));
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ return RegistryManager.ACTIVE.takeSnapshot(false).keySet().stream()
|
|
||||||
//$$ .map(RegistryManager.ACTIVE::getRegistry)
|
|
||||||
//$$ .map(ForgeRegistry::getKeys).flatMap(Set::stream)
|
|
||||||
//$$ .map(ResourceLocation::getResourceDomain).filter(s -> !s.equals("minecraft")).distinct()
|
|
||||||
//$$ .map(String::toLowerCase).map(ignoreCaseMap::get).filter(mod -> mod != null)
|
|
||||||
//$$ .map(mod -> new ModInfo(mod.getModId(), mod.getName(), mod.getVersion()))
|
|
||||||
//$$ .collect(Collectors.toList());
|
|
||||||
//#else
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ return Stream.concat(
|
|
||||||
//$$ ((Set<ResourceLocation>) GameData.getBlockRegistry().getKeys()).stream(),
|
|
||||||
//$$ ((Set<ResourceLocation>) GameData.getItemRegistry().getKeys()).stream()
|
|
||||||
//$$ ).map(ResourceLocation::getResourceDomain).filter(s -> !s.equals("minecraft")).distinct()
|
|
||||||
//$$ .map(String::toLowerCase).map(ignoreCaseMap::get).filter(mod -> mod != null)
|
|
||||||
//$$ .map(mod -> new ModInfo(mod.getModId(), mod.getName(), mod.getVersion()))
|
|
||||||
//$$ .collect(Collectors.toList());
|
|
||||||
//#else
|
|
||||||
//$$ return Stream.concat(
|
|
||||||
//$$ ((Set<String>) GameData.getBlockRegistry().getKeys()).stream(),
|
|
||||||
//$$ ((Set<String>) GameData.getItemRegistry().getKeys()).stream()
|
|
||||||
//$$ ).map(name -> {
|
|
||||||
//$$ if (!name.contains(":")) return null; // Still using old names without namespace, can't do anything, ignore
|
|
||||||
//$$ return name.split(":", 2)[0];
|
|
||||||
//$$ }).filter(s -> !s.equals("minecraft")).distinct()
|
|
||||||
//$$ .map(String::toLowerCase).map(ignoreCaseMap::get).filter(mod -> mod != null)
|
|
||||||
//$$ .map(mod -> new ModInfo(mod.getModId(), mod.getName(), mod.getVersion()))
|
|
||||||
//$$ .collect(Collectors.toList());
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ModInfoDifference {
|
public static final class ModInfoDifference {
|
||||||
|
|||||||
25
src/main/java/com/replaymod/core/utils/ModInfoGetter.java
Normal file
25
src/main/java/com/replaymod/core/utils/ModInfoGetter.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package com.replaymod.core.utils;
|
||||||
|
import com.replaymod.replaystudio.data.ModInfo;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
class ModInfoGetter {
|
||||||
|
static Collection<ModInfo> getInstalledNetworkMods() {
|
||||||
|
Map<String, ModInfo> modInfoMap = FabricLoader.getInstance().getAllMods().stream()
|
||||||
|
.map(ModContainer::getMetadata)
|
||||||
|
.map(m -> new ModInfo(m.getId(), m.getName(), m.getVersion().toString()))
|
||||||
|
.collect(Collectors.toMap(ModInfo::getId, Function.identity()));
|
||||||
|
return Registry.REGISTRIES.stream()
|
||||||
|
.map(Registry::getIds).flatMap(Set::stream)
|
||||||
|
.map(Identifier::getNamespace).filter(s -> !s.equals("minecraft")).distinct()
|
||||||
|
.map(modInfoMap::get).filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ import net.minecraft.util.Identifier;
|
|||||||
//$$ import io.netty.buffer.Unpooled;
|
//$$ import io.netty.buffer.Unpooled;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.readString;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restrictions set by the server,
|
* Restrictions set by the server,
|
||||||
* @see <a href="https://gist.github.com/Johni0702/2547c463e51f65f312cb">Replay Restrictions Gist</a>
|
* @see <a href="https://gist.github.com/Johni0702/2547c463e51f65f312cb">Replay Restrictions Gist</a>
|
||||||
@@ -34,7 +32,7 @@ public class Restrictions {
|
|||||||
//$$ PacketBuffer buffer = new PacketBuffer(Unpooled.wrappedBuffer(packet.func_149168_d()));
|
//$$ PacketBuffer buffer = new PacketBuffer(Unpooled.wrappedBuffer(packet.func_149168_d()));
|
||||||
//#endif
|
//#endif
|
||||||
while (buffer.isReadable()) {
|
while (buffer.isReadable()) {
|
||||||
String name = readString(buffer, 64);
|
String name = buffer.readString(64);
|
||||||
boolean active = buffer.readBoolean();
|
boolean active = buffer.readBoolean();
|
||||||
// if ("no_xray".equals(name)) {
|
// if ("no_xray".equals(name)) {
|
||||||
// noXray = active;
|
// noXray = active;
|
||||||
|
|||||||
142
src/main/java/com/replaymod/core/utils/Result.java
Normal file
142
src/main/java/com/replaymod/core/utils/Result.java
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package com.replaymod.core.utils;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public abstract class Result<Ok, Err> {
|
||||||
|
|
||||||
|
public static <Ok, Err> OkImpl<Ok, Err> ok(Ok value) {
|
||||||
|
return new OkImpl<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <Ok, Err> ErrImpl<Ok, Err> err(Err value) {
|
||||||
|
return new ErrImpl<>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isOk();
|
||||||
|
public abstract boolean isErr();
|
||||||
|
public abstract Ok okOrNull();
|
||||||
|
public abstract Err errOrNull();
|
||||||
|
public abstract void ifOk(Consumer<Ok> consumer);
|
||||||
|
public abstract void ifErr(Consumer<Err> consumer);
|
||||||
|
public abstract Ok okOrElse(Function<Err, Ok> orElse);
|
||||||
|
public abstract Err errOrElse(Function<Ok, Err> orElse);
|
||||||
|
public abstract <T> Result<T, Err> mapOk(Function<Ok, T> func);
|
||||||
|
public abstract <T> Result<Ok, T> mapErr(Function<Err, T> func);
|
||||||
|
|
||||||
|
private static class OkImpl<Ok, Err> extends Result<Ok, Err> {
|
||||||
|
private final Ok value;
|
||||||
|
|
||||||
|
public OkImpl(Ok value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOk() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isErr() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ok okOrNull() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Err errOrNull() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ifOk(Consumer<Ok> consumer) {
|
||||||
|
consumer.accept(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ifErr(Consumer<Err> consumer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ok okOrElse(Function<Err, Ok> orElse) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Err errOrElse(Function<Ok, Err> orElse) {
|
||||||
|
return orElse.apply(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <V> Result<V, Err> mapOk(Function<Ok, V> func) {
|
||||||
|
return ok(func.apply(this.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> Result<Ok, T> mapErr(Function<Err, T> func) {
|
||||||
|
return (Result<Ok, T>) this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ErrImpl<Ok, Err> extends Result<Ok, Err> {
|
||||||
|
private final Err value;
|
||||||
|
|
||||||
|
public ErrImpl(Err value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOk() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isErr() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ok okOrNull() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Err errOrNull() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ifOk(Consumer<Ok> consumer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ifErr(Consumer<Err> consumer) {
|
||||||
|
consumer.accept(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ok okOrElse(Function<Err, Ok> orElse) {
|
||||||
|
return orElse.apply(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Err errOrElse(Function<Ok, Err> orElse) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <V> Result<V, Err> mapOk(Function<Ok, V> func) {
|
||||||
|
return (Result<V, Err>) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Result<Ok, T> mapErr(Function<Err, T> func) {
|
||||||
|
return err(func.apply(this.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import com.google.common.util.concurrent.FutureCallback;
|
|||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
import com.replaymod.replaystudio.lib.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.RenderInfo;
|
import de.johni0702.minecraft.gui.RenderInfo;
|
||||||
import de.johni0702.minecraft.gui.container.AbstractGuiScrollable;
|
import de.johni0702.minecraft.gui.container.AbstractGuiScrollable;
|
||||||
@@ -245,18 +245,10 @@ public class Utils {
|
|||||||
|
|
||||||
logger.trace("Opening crash report popup GUI");
|
logger.trace("Opening crash report popup GUI");
|
||||||
GuiCrashReportPopup popup = new GuiCrashReportPopup(container, crashReportStr);
|
GuiCrashReportPopup popup = new GuiCrashReportPopup(container, crashReportStr);
|
||||||
Futures.addCallback(popup.getFuture(), new FutureCallback<Void>() {
|
popup.onClosed(() -> {
|
||||||
@Override
|
logger.trace("Crash report popup closed");
|
||||||
public void onSuccess(@Nullable Void result) {
|
if (onClose != null) {
|
||||||
logger.trace("Crash report popup closed");
|
onClose.run();
|
||||||
if (onClose != null) {
|
|
||||||
onClose.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
logger.error("During error popup:", t);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return popup;
|
return popup;
|
||||||
@@ -329,18 +321,10 @@ public class Utils {
|
|||||||
LOGGER.trace("Minimal mode active, denying action, opening popup");
|
LOGGER.trace("Minimal mode active, denying action, opening popup");
|
||||||
|
|
||||||
MinimalModeUnsupportedPopup popup = new MinimalModeUnsupportedPopup(container);
|
MinimalModeUnsupportedPopup popup = new MinimalModeUnsupportedPopup(container);
|
||||||
Futures.addCallback(popup.getFuture(), new FutureCallback<Void>() {
|
popup.onClosed(() -> {
|
||||||
@Override
|
LOGGER.trace("Minimal mode popup closed");
|
||||||
public void onSuccess(@Nullable Void result) {
|
if (onPopupClosed != null) {
|
||||||
LOGGER.trace("Minimal mode popup closed");
|
onPopupClosed.run();
|
||||||
if (onPopupClosed != null) {
|
|
||||||
onPopupClosed.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
LOGGER.error("During minimal mode popup:", t);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
@@ -353,7 +337,7 @@ public class Utils {
|
|||||||
|
|
||||||
ProtocolVersion latestVersion = ProtocolVersion.getProtocols()
|
ProtocolVersion latestVersion = ProtocolVersion.getProtocols()
|
||||||
.stream()
|
.stream()
|
||||||
.max(Comparator.comparing(ProtocolVersion::getId))
|
.max(Comparator.comparing(ProtocolVersion::getVersion))
|
||||||
.orElseThrow(RuntimeException::new);
|
.orElseThrow(RuntimeException::new);
|
||||||
getInfo().addElements(new VerticalLayout.Data(0.5),
|
getInfo().addElements(new VerticalLayout.Data(0.5),
|
||||||
new GuiLabel()
|
new GuiLabel()
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
// 1.7.10 and below
|
||||||
1
src/main/java/com/replaymod/core/versions/GLFW.java
Normal file
1
src/main/java/com/replaymod/core/versions/GLFW.java
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// 1.12.2 and below
|
||||||
@@ -1,43 +1,27 @@
|
|||||||
package com.replaymod.core.versions;
|
package com.replaymod.core.versions;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.replaymod.core.mixin.GuiScreenAccessor;
|
import com.replaymod.core.mixin.GuiScreenAccessor;
|
||||||
import com.replaymod.core.mixin.MinecraftAccessor;
|
import com.replaymod.replaystudio.lib.viaversion.api.protocol.packet.State;
|
||||||
|
import com.replaymod.replaystudio.lib.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
import com.replaymod.replaystudio.protocol.PacketTypeRegistry;
|
import com.replaymod.replaystudio.protocol.PacketTypeRegistry;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
import de.johni0702.minecraft.gui.MinecraftGuiRenderer;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.packets.State;
|
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Vector2f;
|
||||||
|
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Vector3f;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.client.render.Tessellator;
|
|
||||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
|
||||||
import net.minecraft.client.model.ModelPart;
|
|
||||||
import net.minecraft.util.crash.CrashReportSection;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.chunk.WorldChunk;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
//#if MC>=11600
|
//#if MC>=11600
|
||||||
import net.minecraft.resource.ResourcePackSource;
|
import net.minecraft.resource.ResourcePackSource;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11500
|
|
||||||
import net.minecraft.client.model.ModelPart.Cuboid;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.client.model.Box;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import com.replaymod.core.mixin.AbstractButtonWidgetAccessor;
|
import com.replaymod.render.mixin.MainWindowAccessor;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
|
import net.minecraft.client.gl.Framebuffer;
|
||||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
|
|
||||||
@@ -56,22 +40,10 @@ import net.minecraft.text.TranslatableText;
|
|||||||
//$$ import net.minecraft.realms.RealmsSharedConstants;
|
//$$ import net.minecraft.realms.RealmsSharedConstants;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.entity.LivingEntity;
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
|
||||||
//$$ import net.minecraftforge.client.event.RenderLivingEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.IEventBus;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import net.minecraft.client.util.Window;
|
|
||||||
import net.minecraft.client.util.InputUtil;
|
import net.minecraft.client.util.InputUtil;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
//#else
|
//#else
|
||||||
//$$ import net.minecraft.client.gui.ScaledResolution;
|
|
||||||
//$$ import net.minecraft.client.resources.ResourcePackRepository;
|
//$$ import net.minecraft.client.resources.ResourcePackRepository;
|
||||||
//$$ import net.minecraftforge.fml.client.FMLClientHandler;
|
//$$ import net.minecraftforge.fml.client.FMLClientHandler;
|
||||||
//$$ import org.apache.logging.log4j.LogManager;
|
//$$ import org.apache.logging.log4j.LogManager;
|
||||||
@@ -80,28 +52,13 @@ import org.lwjgl.glfw.GLFW;
|
|||||||
//$$ import java.io.IOException;
|
//$$ import java.io.IOException;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import net.minecraft.client.sound.PositionedSoundInstance;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.client.audio.PositionedSoundRecord;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10904
|
//#if MC>=10904
|
||||||
import com.replaymod.render.blend.mixin.ParticleAccessor;
|
import com.replaymod.render.blend.mixin.ParticleAccessor;
|
||||||
import net.minecraft.client.particle.Particle;
|
import net.minecraft.client.particle.Particle;
|
||||||
import net.minecraft.sound.SoundEvent;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=10809
|
|
||||||
import net.minecraft.client.render.VertexFormats;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.FMLCommonHandler;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
||||||
import net.minecraft.client.render.VertexFormat;
|
import net.minecraft.client.render.VertexFormat;
|
||||||
import net.minecraft.client.render.VertexFormatElement;
|
import net.minecraft.client.render.VertexFormatElement;
|
||||||
//#if MC<11500
|
//#if MC<11500
|
||||||
@@ -109,28 +66,17 @@ import net.minecraft.client.render.VertexFormatElement;
|
|||||||
//#endif
|
//#endif
|
||||||
//#else
|
//#else
|
||||||
//$$ import com.replaymod.core.mixin.ResourcePackRepositoryAccessor;
|
//$$ import com.replaymod.core.mixin.ResourcePackRepositoryAccessor;
|
||||||
//$$ import com.google.common.util.concurrent.Futures;
|
|
||||||
//$$ import io.netty.handler.codec.DecoderException;
|
//$$ import io.netty.handler.codec.DecoderException;
|
||||||
|
//$$ import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
//$$ import net.minecraft.client.resources.FileResourcePack;
|
//$$ import net.minecraft.client.resources.FileResourcePack;
|
||||||
|
//$$ import net.minecraft.network.PacketBuffer;
|
||||||
//$$
|
//$$
|
||||||
//$$ import static org.lwjgl.opengl.GL11.*;
|
//$$ import static org.lwjgl.opengl.GL11.*;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import net.minecraftforge.fml.ModList;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.Loader;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -138,29 +84,6 @@ import java.util.Optional;
|
|||||||
* Abstraction over things that have changed between different MC versions.
|
* Abstraction over things that have changed between different MC versions.
|
||||||
*/
|
*/
|
||||||
public class MCVer {
|
public class MCVer {
|
||||||
private static Logger LOGGER = LogManager.getLogger();
|
|
||||||
|
|
||||||
//#if FABRIC<=0
|
|
||||||
//$$ public static IEventBus FORGE_BUS = MinecraftForge.EVENT_BUS;
|
|
||||||
//#if MC>=10809
|
|
||||||
//$$ public static IEventBus FML_BUS = FORGE_BUS;
|
|
||||||
//#else
|
|
||||||
//$$ public static EventBus FML_BUS = FMLCommonHandler.instance().bus();
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public static boolean isModLoaded(String id) {
|
|
||||||
//#if FABRIC>=1
|
|
||||||
return FabricLoader.getInstance().isModLoaded(id.toLowerCase());
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ return ModList.get().isLoaded(id.toLowerCase());
|
|
||||||
//#else
|
|
||||||
//$$ return Loader.isModLoaded(id);
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getProtocolVersion() {
|
public static int getProtocolVersion() {
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
return SharedConstants.getGameVersion().getProtocolVersion();
|
return SharedConstants.getGameVersion().getProtocolVersion();
|
||||||
@@ -176,271 +99,33 @@ public class MCVer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addDetail(CrashReportSection category, String name, Callable<String> callable) {
|
public static void resizeMainWindow(MinecraftClient mc, int width, int height) {
|
||||||
//#if MC>=10904
|
|
||||||
//#if MC>=11200
|
|
||||||
category.add(name, callable::call);
|
|
||||||
//#else
|
|
||||||
//$$ category.setDetail(name, callable::call);
|
|
||||||
//#endif
|
|
||||||
//#else
|
|
||||||
//$$ category.addCrashSectionCallable(name, callable);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double Entity_getX(Entity entity) {
|
|
||||||
//#if MC>=11500
|
|
||||||
return entity.getX();
|
|
||||||
//#else
|
|
||||||
//$$ return entity.x;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double Entity_getY(Entity entity) {
|
|
||||||
//#if MC>=11500
|
|
||||||
return entity.getY();
|
|
||||||
//#else
|
|
||||||
//$$ return entity.y;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double Entity_getZ(Entity entity) {
|
|
||||||
//#if MC>=11500
|
|
||||||
return entity.getZ();
|
|
||||||
//#else
|
|
||||||
//$$ return entity.z;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Entity_setPos(Entity entity, double x, double y, double z) {
|
|
||||||
//#if MC>=11500
|
|
||||||
entity.setPos(x, y, z);
|
|
||||||
//#else
|
|
||||||
//$$ entity.x = x;
|
|
||||||
//$$ entity.y = y;
|
|
||||||
//$$ entity.z = z;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
public static void width(AbstractButtonWidget button, int value) {
|
|
||||||
button.setWidth(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int width(AbstractButtonWidget button) {
|
|
||||||
return button.getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int height(AbstractButtonWidget button) {
|
|
||||||
return ((AbstractButtonWidgetAccessor) button).getHeight();
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static void width(GuiButton button, int value) {
|
|
||||||
//$$ button.width = value;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static int width(GuiButton button) {
|
|
||||||
//$$ return button.width;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static int height(GuiButton button) {
|
|
||||||
//$$ return button.height;
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if FABRIC<=0
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ public static void addButton(GuiScreenEvent.InitGuiEvent event, Widget button) {
|
|
||||||
//$$ event.addWidget(button);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static void removeButton(GuiScreenEvent.InitGuiEvent event, Widget button) {
|
|
||||||
//$$ event.removeWidget(button);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static List<Widget> getButtonList(GuiScreenEvent.InitGuiEvent event) {
|
|
||||||
//$$ return event.getWidgetList();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static Widget getButton(GuiScreenEvent.ActionPerformedEvent event) {
|
|
||||||
//$$ return event.getButton();
|
|
||||||
//$$ }
|
|
||||||
//#else
|
|
||||||
//$$ public static void addButton(GuiScreenEvent.InitGuiEvent event, GuiButton button) {
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
//$$ event.addButton(button);
|
Framebuffer fb = mc.getFramebuffer();
|
||||||
//#else
|
if (fb.viewportWidth != width || fb.viewportHeight != height) {
|
||||||
//$$ getButtonList(event).add(button);
|
fb.resize(width, height, false);
|
||||||
|
}
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
MainWindowAccessor mainWindow = (MainWindowAccessor) (Object) mc.getWindow();
|
||||||
|
mainWindow.setFramebufferWidth(width);
|
||||||
|
mainWindow.setFramebufferHeight(height);
|
||||||
|
//#if MC>=11500
|
||||||
|
mc.gameRenderer.onResized(width, height);
|
||||||
//#endif
|
//#endif
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static void removeButton(GuiScreenEvent.InitGuiEvent event, GuiButton button) {
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ event.removeButton(button);
|
|
||||||
//#else
|
//#else
|
||||||
//$$ getButtonList(event).remove(button);
|
//$$ if (width != mc.displayWidth || height != mc.displayHeight) {
|
||||||
//#endif
|
//$$ mc.resize(width, height);
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @SuppressWarnings("unchecked")
|
|
||||||
//$$ public static List<GuiButton> getButtonList(GuiScreenEvent.InitGuiEvent event) {
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ return event.getButtonList();
|
|
||||||
//#else
|
|
||||||
//$$ return event.buttonList;
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static GuiButton getButton(GuiScreenEvent.ActionPerformedEvent event) {
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ return event.getButton();
|
|
||||||
//#else
|
|
||||||
//$$ return event.button;
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ public static Screen getGui(GuiScreenEvent event) {
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ return event.getGui();
|
|
||||||
//#else
|
|
||||||
//$$ return event.gui;
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ public static LivingEntity getEntity(RenderLivingEvent event) {
|
|
||||||
//#if MC>=10904
|
|
||||||
//$$ return event.getEntity();
|
|
||||||
//#else
|
|
||||||
//$$ return event.entity;
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public static String readString(PacketByteBuf buffer, int max) {
|
|
||||||
//#if MC>=10800
|
|
||||||
return buffer.readString(max);
|
|
||||||
//#else
|
|
||||||
//$$ try {
|
|
||||||
//$$ return buffer.readStringFromBuffer(max);
|
|
||||||
//$$ } catch (IOException e) {
|
|
||||||
//$$ throw new DecoderException(e);
|
|
||||||
//$$ }
|
//$$ }
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC<=0
|
//#if MC<10800
|
||||||
//$$ public static RenderGameOverlayEvent.ElementType getType(RenderGameOverlayEvent event) {
|
//$$ public static String tryReadString(PacketBuffer buffer, int max) {
|
||||||
//#if MC>=10904
|
//$$ try {
|
||||||
//$$ return event.getType();
|
//$$ return buffer.readStringFromBuffer(max);
|
||||||
//#else
|
//$$ } catch (IOException e) {
|
||||||
//$$ return event.type;
|
//$$ throw new DecoderException(e);
|
||||||
//#endif
|
//$$ }
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
public static Entity getRenderViewEntity(MinecraftClient mc) {
|
|
||||||
return mc.getCameraEntity();
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static EntityLivingBase getRenderViewEntity(Minecraft mc) {
|
|
||||||
//$$ return mc.renderViewEntity;
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
public static void setRenderViewEntity(MinecraftClient mc, Entity entity) {
|
|
||||||
mc.setCameraEntity(entity);
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static void setRenderViewEntity(Minecraft mc, EntityLivingBase entity) {
|
|
||||||
//$$ mc.renderViewEntity = entity;
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public static Entity getRiddenEntity(Entity ridden) {
|
|
||||||
//#if MC>=10904
|
|
||||||
return ridden.getVehicle();
|
|
||||||
//#else
|
|
||||||
//$$ return ridden.ridingEntity;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Iterable<Entity> loadedEntityList(ClientWorld world) {
|
|
||||||
//#if MC>=11400
|
|
||||||
return world.getEntities();
|
|
||||||
//#else
|
|
||||||
//$$ return world.loadedEntityList;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Collection<Entity>[] getEntityLists(WorldChunk chunk) {
|
|
||||||
//#if MC>=10800
|
|
||||||
return chunk.getEntitySectionArray();
|
|
||||||
//#else
|
|
||||||
//$$ return chunk.entityLists;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
//#if MC>=11500
|
|
||||||
public static List<Cuboid> cubeList(ModelPart modelRenderer) {
|
|
||||||
return new ArrayList<>(); // FIXME 1.15
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static List<Box> cubeList(ModelPart modelRenderer) {
|
|
||||||
//$$ return modelRenderer.boxes;
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static List<PlayerEntity> playerEntities(World world) {
|
|
||||||
//#if MC>=11400
|
|
||||||
return (List) world.getPlayers();
|
|
||||||
//#else
|
|
||||||
//$$ return world.playerEntities;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOnMainThread() {
|
|
||||||
//#if MC>=11400
|
|
||||||
return getMinecraft().isOnThread();
|
|
||||||
//#else
|
|
||||||
//$$ return getMinecraft().isCallingFromMinecraftThread();
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void scheduleOnMainThread(Runnable runnable) {
|
|
||||||
//#if MC>=11400
|
|
||||||
getMinecraft().send(runnable);
|
|
||||||
//#else
|
|
||||||
//$$ getMinecraft().addScheduledTask(runnable);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
public static Window getWindow(MinecraftClient mc) {
|
|
||||||
//#if MC>=11500
|
|
||||||
return mc.getWindow();
|
|
||||||
//#else
|
|
||||||
//$$ return mc.window;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
public static Window newScaledResolution(MinecraftClient mc) {
|
|
||||||
return getWindow(mc);
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static ScaledResolution newScaledResolution(Minecraft mc) {
|
|
||||||
//#if MC>=10809
|
|
||||||
//$$ return new ScaledResolution(mc);
|
|
||||||
//#else
|
|
||||||
//$$ return new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
//$$ }
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@@ -501,69 +186,6 @@ public class MCVer {
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
public static BufferBuilder Tessellator_getBufferBuilder() {
|
|
||||||
return Tessellator.getInstance().getBuffer();
|
|
||||||
}
|
|
||||||
//#else
|
|
||||||
//$$ public static Tessellator Tessellator_getBufferBuilder() {
|
|
||||||
//$$ return Tessellator.instance;
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public static void BufferBuilder_beginPosCol(int mode) {
|
|
||||||
Tessellator_getBufferBuilder().begin(
|
|
||||||
mode
|
|
||||||
//#if MC>=10809
|
|
||||||
, VertexFormats.POSITION_COLOR
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BufferBuilder_addPosCol(double x, double y, double z, int r, int g, int b, int a) {
|
|
||||||
//#if MC>=10809
|
|
||||||
Tessellator_getBufferBuilder().vertex(x, y, z).color(r, g, b, a).next();
|
|
||||||
//#else
|
|
||||||
//$$ Tessellator_getBufferBuilder().setColorRGBA(r, g, b, a);
|
|
||||||
//$$ Tessellator_getBufferBuilder().addVertex(x, y, z);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BufferBuilder_beginPosTex(int mode) {
|
|
||||||
Tessellator_getBufferBuilder().begin(
|
|
||||||
mode
|
|
||||||
//#if MC>=10809
|
|
||||||
, VertexFormats.POSITION_TEXTURE
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BufferBuilder_addPosTex(double x, double y, double z, float u, float v) {
|
|
||||||
//#if MC>=10809
|
|
||||||
Tessellator_getBufferBuilder().vertex(x, y, z).texture(u, v).next();
|
|
||||||
//#else
|
|
||||||
//$$ Tessellator_getBufferBuilder().addVertexWithUV(x, y, z, u, v);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BufferBuilder_beginPosTexCol(int mode) {
|
|
||||||
Tessellator_getBufferBuilder().begin(
|
|
||||||
mode
|
|
||||||
//#if MC>=10809
|
|
||||||
, VertexFormats.POSITION_TEXTURE_COLOR
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void BufferBuilder_addPosTexCol(double x, double y, double z, float u, float v, int r, int g, int b, int a) {
|
|
||||||
//#if MC>=10809
|
|
||||||
Tessellator_getBufferBuilder().vertex(x, y, z).texture(u, v).color(r, g, b, a).next();
|
|
||||||
//#else
|
|
||||||
//$$ Tessellator_getBufferBuilder().setColorRGBA(r, g, b, a);
|
|
||||||
//$$ Tessellator_getBufferBuilder().addVertexWithUV(x, y, z, u, v);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static List<VertexFormatElement> getElements(VertexFormat vertexFormat) {
|
public static List<VertexFormatElement> getElements(VertexFormat vertexFormat) {
|
||||||
@@ -571,30 +193,16 @@ public class MCVer {
|
|||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
public static Tessellator Tessellator_getInstance() {
|
//#if MC<10800
|
||||||
//#if MC>=10800
|
//$$ public static RenderManager getRenderManager(@SuppressWarnings("unused") Minecraft mc) {
|
||||||
return Tessellator.getInstance();
|
//$$ return RenderManager.instance;
|
||||||
//#else
|
//$$ }
|
||||||
//$$ return Tessellator.instance;
|
//#endif
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityRenderDispatcher getRenderManager() {
|
|
||||||
//#if MC>=10800
|
|
||||||
return getMinecraft().getEntityRenderDispatcher();
|
|
||||||
//#else
|
|
||||||
//$$ return RenderManager.instance;
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MinecraftClient getMinecraft() {
|
public static MinecraftClient getMinecraft() {
|
||||||
return MinecraftClient.getInstance();
|
return MinecraftClient.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float getRenderPartialTicks() {
|
|
||||||
return ((MinecraftAccessor) getMinecraft()).getTimer().tickDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addButton(
|
public static void addButton(
|
||||||
Screen screen,
|
Screen screen,
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
@@ -604,14 +212,15 @@ public class MCVer {
|
|||||||
//#endif
|
//#endif
|
||||||
) {
|
) {
|
||||||
GuiScreenAccessor acc = (GuiScreenAccessor) screen;
|
GuiScreenAccessor acc = (GuiScreenAccessor) screen;
|
||||||
acc.getButtons().add(button);
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
acc.getChildren().add(button);
|
acc.invokeAddButton(button);
|
||||||
|
//#else
|
||||||
|
//$$ acc.getButtons().add(button);
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
public static Optional<AbstractButtonWidget> findButton(List<AbstractButtonWidget> buttonList, @SuppressWarnings("unused") String text, @SuppressWarnings("unused") int id) {
|
public static Optional<AbstractButtonWidget> findButton(Iterable<AbstractButtonWidget> buttonList, @SuppressWarnings("unused") String text, @SuppressWarnings("unused") int id) {
|
||||||
//#if MC>=11600
|
//#if MC>=11600
|
||||||
final TranslatableText message = new TranslatableText(text);
|
final TranslatableText message = new TranslatableText(text);
|
||||||
//#else
|
//#else
|
||||||
@@ -621,11 +230,17 @@ public class MCVer {
|
|||||||
if (message.equals(b.getMessage())) {
|
if (message.equals(b.getMessage())) {
|
||||||
return Optional.of(b);
|
return Optional.of(b);
|
||||||
}
|
}
|
||||||
|
//#if MC>=11600
|
||||||
|
// Fuzzy match (copy does not include children)
|
||||||
|
if (b.getMessage() != null && b.getMessage().copy().equals(message)) {
|
||||||
|
return Optional.of(b);
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
//#else
|
//#else
|
||||||
//$$ public static Optional<GuiButton> findButton(List<GuiButton> buttonList, @SuppressWarnings("unused") String text, int id) {
|
//$$ public static Optional<GuiButton> findButton(Iterable<GuiButton> buttonList, @SuppressWarnings("unused") String text, int id) {
|
||||||
//$$ for (GuiButton b : buttonList) {
|
//$$ for (GuiButton b : buttonList) {
|
||||||
//$$ if (b.id == id) {
|
//$$ if (b.id == id) {
|
||||||
//$$ return Optional.of(b);
|
//$$ return Optional.of(b);
|
||||||
@@ -671,26 +286,6 @@ public class MCVer {
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bindTexture(Identifier texture) {
|
|
||||||
//#if MC>=11500
|
|
||||||
getMinecraft().getTextureManager().bindTexture(texture);
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ getMinecraft().getTextureManager().bindTexture(texture);
|
|
||||||
//#else
|
|
||||||
//$$ getMinecraft().renderEngine.bindTexture(texture);
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float cos(float val) {
|
|
||||||
return MathHelper.cos(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float sin(float val) {
|
|
||||||
return MathHelper.sin(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#if MC>=10904
|
//#if MC>=10904
|
||||||
// TODO: this can be inlined once https://github.com/SpongePowered/Mixin/issues/305 is fixed
|
// TODO: this can be inlined once https://github.com/SpongePowered/Mixin/issues/305 is fixed
|
||||||
public static Vec3d getPosition(Particle particle, float partialTicks) {
|
public static Vec3d getPosition(Particle particle, float partialTicks) {
|
||||||
@@ -733,52 +328,68 @@ public class MCVer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void openURL(URI url) {
|
public static void openURL(URI url) {
|
||||||
//#if MC>=11400
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
Util.getOperatingSystem().open(url);
|
Util.getOperatingSystem().open(url);
|
||||||
//#else
|
//#else
|
||||||
//$$ Util.getOSType().openURI(url);
|
|
||||||
//#endif
|
|
||||||
//#else
|
|
||||||
//$$ try {
|
//$$ try {
|
||||||
//$$ Desktop.getDesktop().browse(url);
|
//$$ Desktop.getDesktop().browse(url);
|
||||||
//$$ } catch (Throwable e) {
|
//$$ } catch (Throwable e) {
|
||||||
//$$ LOGGER.error("Failed to open URL: ", e);
|
//$$ LogManager.getLogger().error("Failed to open URL: ", e);
|
||||||
//$$ }
|
//$$ }
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBoundKey(KeyBinding keyBinding) {
|
public static void pushMatrix() {
|
||||||
try {
|
//#if MC>=11700
|
||||||
//#if MC>=11600
|
//$$ RenderSystem.getModelViewStack().push();
|
||||||
return keyBinding.getBoundKeyLocalizedText().getString();
|
//#else
|
||||||
//#else
|
GlStateManager.pushMatrix();
|
||||||
//#if MC>=11400
|
//#endif
|
||||||
//$$ return keyBinding.getLocalizedName();
|
|
||||||
//#else
|
|
||||||
//$$ return Keyboard.getKeyName(keyBinding.getKeyCode());
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
|
||||||
// Apparently windows likes to press strange keys, see https://www.replaymod.com/forum/thread/55
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playSound(Identifier sound) {
|
public static void popMatrix() {
|
||||||
getMinecraft().getSoundManager().play(
|
//#if MC>=11700
|
||||||
//#if MC>=11400
|
//$$ RenderSystem.getModelViewStack().pop();
|
||||||
PositionedSoundInstance.master(new SoundEvent(sound), 1.0F)
|
//$$ RenderSystem.applyModelViewMatrix();
|
||||||
//#elseif MC>=10904
|
//#else
|
||||||
//$$ PositionedSoundRecord.getMasterRecord(new SoundEvent(sound), 1.0F)
|
GlStateManager.popMatrix();
|
||||||
//#elseif MC>=10800
|
//#endif
|
||||||
//$$ PositionedSoundRecord.create(sound, 1.0F)
|
|
||||||
//#else
|
|
||||||
//$$ PositionedSoundRecord.createPositionedSoundRecord(sound, 1.0F)
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void emitLine(BufferBuilder buffer, Vector2f p1, Vector2f p2, int color) {
|
||||||
|
emitLine(buffer, new Vector3f(p1.x, p1.y, 0), new Vector3f(p2.x, p2.y, 0), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void emitLine(BufferBuilder buffer, Vector3f p1, Vector3f p2, int color) {
|
||||||
|
int r = color >> 24 & 0xff;
|
||||||
|
int g = color >> 16 & 0xff;
|
||||||
|
int b = color >> 8 & 0xff;
|
||||||
|
int a = color & 0xff;
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ Vector3f n = Vector3f.sub(p2, p1, null);
|
||||||
|
//#endif
|
||||||
|
buffer.vertex(p1.x, p1.y, p1.z)
|
||||||
|
.color(r, g, b, a)
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ .normal(n.x, n.y, n.z)
|
||||||
|
//#endif
|
||||||
|
.next();
|
||||||
|
buffer.vertex(p2.x, p2.y, p2.z)
|
||||||
|
.color(r, g, b, a)
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ .normal(n.x, n.y, n.z)
|
||||||
|
//#endif
|
||||||
|
.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindTexture(Identifier id) {
|
||||||
|
new MinecraftGuiRenderer(null).bindTexture(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if MC<10900
|
||||||
|
//$$ public static class SoundEvent {}
|
||||||
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
private static Boolean hasOptifine;
|
private static Boolean hasOptifine;
|
||||||
public static boolean hasOptifine() {
|
public static boolean hasOptifine() {
|
||||||
|
|||||||
502
src/main/java/com/replaymod/core/versions/Patterns.java
Normal file
502
src/main/java/com/replaymod/core/versions/Patterns.java
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
package com.replaymod.core.versions;
|
||||||
|
|
||||||
|
import com.replaymod.gradle.remap.Pattern;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
import net.minecraft.client.render.VertexFormat;
|
||||||
|
import net.minecraft.client.texture.TextureManager;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.client.render.Tessellator;
|
||||||
|
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.sound.PositionedSoundInstance;
|
||||||
|
import net.minecraft.util.crash.CrashReportSection;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.chunk.WorldChunk;
|
||||||
|
|
||||||
|
//#if MC>=11700
|
||||||
|
//#else
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#if MC>=11400
|
||||||
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
|
import net.minecraft.client.util.Window;
|
||||||
|
//#else
|
||||||
|
//$$ import net.minecraft.client.gui.GuiButton;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#if MC>=10904
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.util.crash.CrashCallable;
|
||||||
|
//#else
|
||||||
|
//$$ import java.util.concurrent.Callable;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#if MC>=10809
|
||||||
|
import net.minecraft.client.render.VertexFormats;
|
||||||
|
//#else
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//#if MC>=10800
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
//#else
|
||||||
|
//$$ import net.minecraft.entity.EntityLivingBase;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class Patterns {
|
||||||
|
//#if MC>=10904
|
||||||
|
@Pattern
|
||||||
|
private static void addCrashCallable(CrashReportSection category, String name, CrashCallable<String> callable) {
|
||||||
|
//#if MC>=11200
|
||||||
|
category.add(name, callable);
|
||||||
|
//#else
|
||||||
|
//$$ category.setDetail(name, callable);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ @Pattern
|
||||||
|
//$$ private static void addCrashCallable(CrashReportCategory category, String name, Callable<String> callable) {
|
||||||
|
//$$ category.addCrashSectionCallable(name, callable);
|
||||||
|
//$$ }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static double Entity_getX(Entity entity) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return entity.getX();
|
||||||
|
//#else
|
||||||
|
//$$ return entity.x;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static double Entity_getY(Entity entity) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return entity.getY();
|
||||||
|
//#else
|
||||||
|
//$$ return entity.y;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static double Entity_getZ(Entity entity) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return entity.getZ();
|
||||||
|
//#else
|
||||||
|
//$$ return entity.z;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void Entity_setYaw(Entity entity, float value) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ entity.setYaw(value);
|
||||||
|
//#else
|
||||||
|
entity.yaw = value;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static float Entity_getYaw(Entity entity) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ return entity.getYaw();
|
||||||
|
//#else
|
||||||
|
return entity.yaw;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void Entity_setPitch(Entity entity, float value) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ entity.setPitch(value);
|
||||||
|
//#else
|
||||||
|
entity.pitch = value;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static float Entity_getPitch(Entity entity) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ return entity.getPitch();
|
||||||
|
//#else
|
||||||
|
return entity.pitch;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void Entity_setPos(Entity entity, double x, double y, double z) {
|
||||||
|
//#if MC>=11500
|
||||||
|
entity.setPos(x, y, z);
|
||||||
|
//#else
|
||||||
|
//$$ { net.minecraft.entity.Entity self = entity; self.x = x; self.y = y; self.z = z; }
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if MC>=11400
|
||||||
|
@Pattern
|
||||||
|
private static void setWidth(AbstractButtonWidget button, int value) {
|
||||||
|
button.setWidth(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static int getWidth(AbstractButtonWidget button) {
|
||||||
|
return button.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static int getHeight(AbstractButtonWidget button) {
|
||||||
|
//#if MC>=11600
|
||||||
|
return button.getHeight();
|
||||||
|
//#else
|
||||||
|
//$$ return ((com.replaymod.core.mixin.AbstractButtonWidgetAccessor) button).getHeight();
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ @Pattern
|
||||||
|
//$$ private static void setWidth(GuiButton button, int value) {
|
||||||
|
//$$ button.width = value;
|
||||||
|
//$$ }
|
||||||
|
//$$
|
||||||
|
//$$ @Pattern
|
||||||
|
//$$ private static int getWidth(GuiButton button) {
|
||||||
|
//$$ return button.width;
|
||||||
|
//$$ }
|
||||||
|
//$$
|
||||||
|
//$$ @Pattern
|
||||||
|
//$$ private static int getHeight(GuiButton button) {
|
||||||
|
//$$ return button.height;
|
||||||
|
//$$ }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static String readString(PacketByteBuf buffer, int max) {
|
||||||
|
//#if MC>=10800
|
||||||
|
return buffer.readString(max);
|
||||||
|
//#else
|
||||||
|
//$$ return com.replaymod.core.versions.MCVer.tryReadString(buffer, max);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
//#if MC>=10800
|
||||||
|
private static Entity getRenderViewEntity(MinecraftClient mc) {
|
||||||
|
return mc.getCameraEntity();
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ private static EntityLivingBase getRenderViewEntity(Minecraft mc) {
|
||||||
|
//$$ return mc.renderViewEntity;
|
||||||
|
//$$ }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
//#if MC>=10800
|
||||||
|
private static void setRenderViewEntity(MinecraftClient mc, Entity entity) {
|
||||||
|
mc.setCameraEntity(entity);
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ private static void setRenderViewEntity(Minecraft mc, EntityLivingBase entity) {
|
||||||
|
//$$ mc.renderViewEntity = entity;
|
||||||
|
//$$ }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static Entity getVehicle(Entity passenger) {
|
||||||
|
//#if MC>=10904
|
||||||
|
return passenger.getVehicle();
|
||||||
|
//#else
|
||||||
|
//$$ return passenger.ridingEntity;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static Iterable<Entity> loadedEntityList(ClientWorld world) {
|
||||||
|
//#if MC>=11400
|
||||||
|
return world.getEntities();
|
||||||
|
//#else
|
||||||
|
//#if MC>=10809
|
||||||
|
//$$ return world.loadedEntityList;
|
||||||
|
//#else
|
||||||
|
//$$ return ((java.util.List<net.minecraft.entity.Entity>) world.loadedEntityList);
|
||||||
|
//#endif
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ private static void getEntitySectionArray() {}
|
||||||
|
//#else
|
||||||
|
private static Collection<Entity>[] getEntitySectionArray(WorldChunk chunk) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ return obsolete(chunk);
|
||||||
|
//#elseif MC>=10800
|
||||||
|
return chunk.getEntitySectionArray();
|
||||||
|
//#else
|
||||||
|
//$$ return chunk.entityLists;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static List<? extends PlayerEntity> playerEntities(World world) {
|
||||||
|
//#if MC>=11400
|
||||||
|
return world.getPlayers();
|
||||||
|
//#elseif MC>=10809
|
||||||
|
//$$ return world.playerEntities;
|
||||||
|
//#else
|
||||||
|
//$$ return ((List<? extends net.minecraft.entity.player.EntityPlayer>) world.playerEntities);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static boolean isOnMainThread(MinecraftClient mc) {
|
||||||
|
//#if MC>=11400
|
||||||
|
return mc.isOnThread();
|
||||||
|
//#else
|
||||||
|
//$$ return mc.isCallingFromMinecraftThread();
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void scheduleOnMainThread(MinecraftClient mc, Runnable runnable) {
|
||||||
|
//#if MC>=11400
|
||||||
|
mc.send(runnable);
|
||||||
|
//#else
|
||||||
|
//$$ mc.addScheduledTask(runnable);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static Window getWindow(MinecraftClient mc) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return mc.getWindow();
|
||||||
|
//#elseif MC>=11400
|
||||||
|
//$$ return mc.window;
|
||||||
|
//#else
|
||||||
|
//$$ return new com.replaymod.core.versions.Window(mc);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static BufferBuilder Tessellator_getBuffer(Tessellator tessellator) {
|
||||||
|
//#if MC>=10800
|
||||||
|
return tessellator.getBuffer();
|
||||||
|
//#else
|
||||||
|
//$$ return new BufferBuilder(tessellator);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if MC<11700
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginPosCol(BufferBuilder buffer, int mode) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.begin(mode, VertexFormats.POSITION_COLOR);
|
||||||
|
//#else
|
||||||
|
//$$ buffer.startDrawing(mode /* POSITION_COLOR */);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_addPosCol(BufferBuilder buffer, double x, double y, double z, int r, int g, int b, int a) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.vertex(x, y, z).color(r, g, b, a).next();
|
||||||
|
//#else
|
||||||
|
//$$ { WorldRenderer $buffer = buffer; double $x = x; double $y = y; double $z = z; $buffer.setColorRGBA(r, g, b, a); $buffer.addVertex($x, $y, $z); }
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginPosTex(BufferBuilder buffer, int mode) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.begin(mode, VertexFormats.POSITION_TEXTURE);
|
||||||
|
//#else
|
||||||
|
//$$ buffer.startDrawing(mode /* POSITION_TEXTURE */);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_addPosTex(BufferBuilder buffer, double x, double y, double z, float u, float v) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.vertex(x, y, z).texture(u, v).next();
|
||||||
|
//#else
|
||||||
|
//$$ buffer.addVertexWithUV(x, y, z, u, v);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginPosTexCol(BufferBuilder buffer, int mode) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.begin(mode, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||||
|
//#else
|
||||||
|
//$$ buffer.startDrawing(mode /* POSITION_TEXTURE_COLOR */);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_addPosTexCol(BufferBuilder buffer, double x, double y, double z, float u, float v, int r, int g, int b, int a) {
|
||||||
|
//#if MC>=10809
|
||||||
|
buffer.vertex(x, y, z).texture(u, v).color(r, g, b, a).next();
|
||||||
|
//#else
|
||||||
|
//$$ { WorldRenderer $buffer = buffer; double $x = x; double $y = y; double $z = z; float $u = u; float $v = v; $buffer.setColorRGBA(r, g, b, a); $buffer.addVertexWithUV($x, $y, $z, $u, $v); }
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginPosCol() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_addPosCol() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginPosTex() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_addPosTex() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginPosTexCol() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_addPosTexCol() {}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static Tessellator Tessellator_getInstance() {
|
||||||
|
//#if MC>=10800
|
||||||
|
return Tessellator.getInstance();
|
||||||
|
//#else
|
||||||
|
//$$ return Tessellator.instance;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static EntityRenderDispatcher getEntityRenderDispatcher(MinecraftClient mc) {
|
||||||
|
//#if MC>=10800
|
||||||
|
return mc.getEntityRenderDispatcher();
|
||||||
|
//#else
|
||||||
|
//$$ return com.replaymod.core.versions.MCVer.getRenderManager(mc);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static float getCameraYaw(EntityRenderDispatcher dispatcher) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return dispatcher.camera.getYaw();
|
||||||
|
//#else
|
||||||
|
//$$ return dispatcher.cameraYaw;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static float getCameraPitch(EntityRenderDispatcher dispatcher) {
|
||||||
|
//#if MC>=11500
|
||||||
|
return dispatcher.camera.getPitch();
|
||||||
|
//#else
|
||||||
|
//$$ return dispatcher.cameraPitch;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static float getRenderPartialTicks(MinecraftClient mc) {
|
||||||
|
//#if MC>=10900
|
||||||
|
return mc.getTickDelta();
|
||||||
|
//#else
|
||||||
|
//$$ return ((com.replaymod.core.mixin.MinecraftAccessor) mc).getTimer().renderPartialTicks;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static TextureManager getTextureManager(MinecraftClient mc) {
|
||||||
|
//#if MC>=11400
|
||||||
|
return mc.getTextureManager();
|
||||||
|
//#else
|
||||||
|
//$$ return mc.renderEngine;
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static String getBoundKeyName(KeyBinding keyBinding) {
|
||||||
|
//#if MC>=11600
|
||||||
|
return keyBinding.getBoundKeyLocalizedText().getString();
|
||||||
|
//#elseif MC>=11400
|
||||||
|
//$$ return keyBinding.getLocalizedName();
|
||||||
|
//#else
|
||||||
|
//$$ return org.lwjgl.input.Keyboard.getKeyName(keyBinding.getKeyCode());
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static PositionedSoundInstance master(Identifier sound, float pitch) {
|
||||||
|
//#if MC>=10900
|
||||||
|
return PositionedSoundInstance.master(new SoundEvent(sound), pitch);
|
||||||
|
//#elseif MC>=10800
|
||||||
|
//$$ return PositionedSoundRecord.create(sound, pitch);
|
||||||
|
//#else
|
||||||
|
//$$ return PositionedSoundRecord.createPositionedSoundRecord(sound, pitch);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static boolean isKeyBindingConflicting(KeyBinding a, KeyBinding b) {
|
||||||
|
//#if MC>=10900
|
||||||
|
return a.equals(b);
|
||||||
|
//#else
|
||||||
|
//$$ return (a.getKeyCode() == b.getKeyCode());
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if MC>=11600
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginLineStrip(BufferBuilder buffer, VertexFormat vertexFormat) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ buffer.begin(net.minecraft.client.render.VertexFormat.DrawMode.LINE_STRIP, VertexFormats.LINES);
|
||||||
|
//#else
|
||||||
|
buffer.begin(GL11.GL_LINE_STRIP, VertexFormats.POSITION_COLOR);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginLines(BufferBuilder buffer) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ buffer.begin(net.minecraft.client.render.VertexFormat.DrawMode.LINES, VertexFormats.LINES);
|
||||||
|
//#else
|
||||||
|
buffer.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void BufferBuilder_beginQuads(BufferBuilder buffer, VertexFormat vertexFormat) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ buffer.begin(net.minecraft.client.render.VertexFormat.DrawMode.QUADS, vertexFormat);
|
||||||
|
//#else
|
||||||
|
buffer.begin(GL11.GL_QUADS, vertexFormat);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
//#else
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginLineStrip() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginLines() {}
|
||||||
|
//$$ @Pattern private static void BufferBuilder_beginQuads() {}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void GL11_glLineWidth(float width) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ com.mojang.blaze3d.systems.RenderSystem.lineWidth(width);
|
||||||
|
//#else
|
||||||
|
GL11.glLineWidth(width);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void GL11_glTranslatef(float x, float y, float z) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ com.mojang.blaze3d.systems.RenderSystem.getModelViewStack().translate(x, y, z);
|
||||||
|
//#else
|
||||||
|
GL11.glTranslatef(x, y, z);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pattern
|
||||||
|
private static void GL11_glRotatef(float angle, float x, float y, float z) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ { float $angle = angle; com.mojang.blaze3d.systems.RenderSystem.getModelViewStack().multiply(new net.minecraft.util.math.Quaternion(new net.minecraft.util.math.Vec3f(x, y, z), $angle, true)); }
|
||||||
|
//#else
|
||||||
|
GL11.glRotatef(angle, x, y, z);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/main/java/com/replaymod/core/versions/Window.java
Normal file
1
src/main/java/com/replaymod/core/versions/Window.java
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// 1.12.2 and below
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
// Forge only
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
// 1.12.2 and before
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.replaymod.core.versions.scheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
public interface Scheduler {
|
||||||
|
/**
|
||||||
|
* Execute the given runnable on the main client thread, returning only after it has been run (or after 30 seconds).
|
||||||
|
*/
|
||||||
|
void runSync(Runnable runnable) throws InterruptedException, ExecutionException, TimeoutException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the given runnable after game has started (once the overlay has been closed).
|
||||||
|
* Most importantly, it will run after resources (including language keys!) have been loaded.
|
||||||
|
* Below 1.14, this is equivalent to {@link #runLater(Runnable)}.
|
||||||
|
*/
|
||||||
|
void runPostStartup(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-1.14 MC would hold the lock on the scheduledTasks queue while executing its tasks
|
||||||
|
* such that no new tasks could be submitted while one of them was running.
|
||||||
|
* This would cause issues with long-running tasks (e.g. video rendering) as it would
|
||||||
|
* block all async tasks (e.g. skin loading).
|
||||||
|
*/
|
||||||
|
void runLaterWithoutLock(Runnable runnable);
|
||||||
|
|
||||||
|
void runLater(Runnable runnable);
|
||||||
|
|
||||||
|
void runTasks();
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package com.replaymod.core.versions.scheduler;
|
||||||
|
|
||||||
|
import com.replaymod.core.mixin.MinecraftAccessor;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.util.crash.CrashException;
|
||||||
|
import net.minecraft.util.thread.ReentrantThreadExecutor;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
public class SchedulerImpl implements Scheduler {
|
||||||
|
private static final MinecraftClient mc = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runSync(Runnable runnable) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
if (mc.isOnThread()) {
|
||||||
|
runnable.run();
|
||||||
|
} else {
|
||||||
|
executor.submit(() -> {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
}).get(30, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runPostStartup(Runnable runnable) {
|
||||||
|
runLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mc.getOverlay() != null) {
|
||||||
|
// delay until after resources have been loaded
|
||||||
|
runLater(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set when the currently running code has been scheduled by runLater.
|
||||||
|
* If this is the case, subsequent calls to runLater have to be delayed until all scheduled tasks have been
|
||||||
|
* processed, otherwise a livelock may occur.
|
||||||
|
*/
|
||||||
|
private boolean inRunLater = false;
|
||||||
|
private boolean inRenderTaskQueue = false;
|
||||||
|
// Starting 1.14 MC clears the queue of scheduled tasks on disconnect.
|
||||||
|
// This works fine for MC since it uses the queue only for packet handling but breaks our assumption that
|
||||||
|
// stuff submitted via runLater is actually always run (e.g. recording might not be fully stopped because parts
|
||||||
|
// of that are run via runLater and stopping the recording happens right around the time MC clears the queue).
|
||||||
|
// Luckily, that's also the version where MC pulled out the executor implementation, so we can just spin up our own.
|
||||||
|
public static class ReplayModExecutor extends ReentrantThreadExecutor<Runnable> {
|
||||||
|
private final Thread mcThread = Thread.currentThread();
|
||||||
|
|
||||||
|
private ReplayModExecutor(String string_1) {
|
||||||
|
super(string_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Runnable createTask(Runnable runnable) {
|
||||||
|
return runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canExecute(Runnable runnable) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Thread getThread() {
|
||||||
|
return mcThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runTasks() {
|
||||||
|
super.runTasks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public final ReplayModExecutor executor = new ReplayModExecutor("Client/ReplayMod");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runTasks() {
|
||||||
|
executor.runTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runLaterWithoutLock(Runnable runnable) {
|
||||||
|
// MC 1.14+ no longer synchronizes on the queue while running its tasks
|
||||||
|
runLater(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runLater(Runnable runnable) {
|
||||||
|
runLater(runnable, () -> runLater(runnable));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runLater(Runnable runnable, Runnable defer) {
|
||||||
|
if (mc.isOnThread() && inRunLater && !inRenderTaskQueue) {
|
||||||
|
((MinecraftAccessor) mc).getRenderTaskQueue().offer(() -> {
|
||||||
|
inRenderTaskQueue = true;
|
||||||
|
try {
|
||||||
|
defer.run();
|
||||||
|
} finally {
|
||||||
|
inRenderTaskQueue = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
executor.send(() -> {
|
||||||
|
inRunLater = true;
|
||||||
|
try {
|
||||||
|
runnable.run();
|
||||||
|
} catch (CrashException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.err.println(e.getReport().asString());
|
||||||
|
mc.setCrashReport(e.getReport());
|
||||||
|
} finally {
|
||||||
|
inRunLater = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,9 +12,9 @@ import com.replaymod.replaystudio.protocol.PacketTypeRegistry;
|
|||||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||||
import com.replaymod.replaystudio.stream.IteratorStream;
|
import com.replaymod.replaystudio.stream.IteratorStream;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
|
||||||
import com.replaymod.replaystudio.util.Utils;
|
import com.replaymod.replaystudio.util.Utils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -115,7 +115,7 @@ public class MarkerProcessor {
|
|||||||
try (ReplayFile inputReplayFile = mod.openReplay(path)) {
|
try (ReplayFile inputReplayFile = mod.openReplay(path)) {
|
||||||
metaData = inputReplayFile.getMetaData();
|
metaData = inputReplayFile.getMetaData();
|
||||||
}
|
}
|
||||||
return Collections.singletonList(new Pair<>(path, metaData));
|
return Collections.singletonList(Pair.of(path, metaData));
|
||||||
}
|
}
|
||||||
|
|
||||||
String replayName = FilenameUtils.getBaseName(path.getFileName().toString());
|
String replayName = FilenameUtils.getBaseName(path.getFileName().toString());
|
||||||
@@ -249,7 +249,7 @@ public class MarkerProcessor {
|
|||||||
|
|
||||||
outputReplayFile.save();
|
outputReplayFile.save();
|
||||||
|
|
||||||
outputPaths.add(new Pair(outputPath, metaData));
|
outputPaths.add(Pair.of(outputPath, metaData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.replaymod.editor.handler;
|
package com.replaymod.editor.handler;
|
||||||
|
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
|
||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
import com.replaymod.editor.ReplayModEditor;
|
import com.replaymod.editor.ReplayModEditor;
|
||||||
import com.replaymod.editor.gui.GuiEditReplay;
|
import com.replaymod.editor.gui.GuiEditReplay;
|
||||||
@@ -8,31 +7,15 @@ import com.replaymod.replay.gui.screen.GuiReplayViewer;
|
|||||||
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
||||||
import de.johni0702.minecraft.gui.container.GuiScreen;
|
import de.johni0702.minecraft.gui.container.GuiScreen;
|
||||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
|
||||||
import java.util.List;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
|
|
||||||
public class GuiHandler extends EventRegistrations {
|
public class GuiHandler extends EventRegistrations {
|
||||||
//#if FABRIC>=1
|
{ on(InitScreenCallback.EVENT, (vanillaGuiScreen, buttonList) -> injectIntoReplayViewer(vanillaGuiScreen)); }
|
||||||
{ on(InitScreenCallback.EVENT, this::injectIntoReplayViewer); }
|
public void injectIntoReplayViewer(net.minecraft.client.gui.screen.Screen vanillaGuiScreen) {
|
||||||
public void injectIntoReplayViewer(Screen vanillaGuiScreen, List<AbstractButtonWidget> buttonList) {
|
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void injectIntoReplayViewer(GuiScreenEvent.InitGuiEvent.Post event) {
|
|
||||||
//$$ net.minecraft.client.gui.screen.Screen vanillaGuiScreen = getGui(event);
|
|
||||||
//#endif
|
|
||||||
AbstractGuiScreen guiScreen = GuiScreen.from(vanillaGuiScreen);
|
AbstractGuiScreen guiScreen = GuiScreen.from(vanillaGuiScreen);
|
||||||
if (!(guiScreen instanceof GuiReplayViewer)) {
|
if (!(guiScreen instanceof GuiReplayViewer)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.replaymod.extras;
|
package com.replaymod.extras;
|
||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
|
import com.replaymod.core.events.PostRenderCallback;
|
||||||
|
import com.replaymod.core.events.PreRenderCallback;
|
||||||
import com.replaymod.core.versions.MCVer.Keyboard;
|
import com.replaymod.core.versions.MCVer.Keyboard;
|
||||||
import com.replaymod.replay.ReplayHandler;
|
import com.replaymod.replay.ReplayHandler;
|
||||||
import com.replaymod.replay.ReplayModReplay;
|
import com.replaymod.replay.ReplayModReplay;
|
||||||
@@ -14,14 +16,6 @@ import net.minecraft.client.MinecraftClient;
|
|||||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||||
import net.minecraft.entity.effect.StatusEffects;
|
import net.minecraft.entity.effect.StatusEffects;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import com.replaymod.core.events.PreRenderCallback;
|
|
||||||
import com.replaymod.core.events.PostRenderCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$ import net.minecraftforge.event.TickEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public class FullBrightness extends EventRegistrations implements Extra {
|
public class FullBrightness extends EventRegistrations implements Extra {
|
||||||
private ReplayMod core;
|
private ReplayMod core;
|
||||||
private ReplayModReplay module;
|
private ReplayModReplay module;
|
||||||
@@ -72,14 +66,8 @@ public class FullBrightness extends EventRegistrations implements Extra {
|
|||||||
return Type.Gamma;
|
return Type.Gamma;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(PreRenderCallback.EVENT, this::preRender); }
|
{ on(PreRenderCallback.EVENT, this::preRender); }
|
||||||
private void preRender() {
|
private void preRender() {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void preRender(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase != TickEvent.Phase.START) return;
|
|
||||||
//#endif
|
|
||||||
if (active && module.getReplayHandler() != null) {
|
if (active && module.getReplayHandler() != null) {
|
||||||
Type type = getType();
|
Type type = getType();
|
||||||
if (type == Type.Gamma || type == Type.Both) {
|
if (type == Type.Gamma || type == Type.Both) {
|
||||||
@@ -98,14 +86,8 @@ public class FullBrightness extends EventRegistrations implements Extra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(PostRenderCallback.EVENT, this::postRender); }
|
{ on(PostRenderCallback.EVENT, this::postRender); }
|
||||||
private void postRender() {
|
private void postRender() {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void postRender(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase != TickEvent.Phase.END) return;
|
|
||||||
//#endif
|
|
||||||
if (active && module.getReplayHandler() != null) {
|
if (active && module.getReplayHandler() != null) {
|
||||||
Type type = getType();
|
Type type = getType();
|
||||||
if (type == Type.Gamma || type == Type.Both) {
|
if (type == Type.Gamma || type == Type.Both) {
|
||||||
|
|||||||
@@ -1,164 +0,0 @@
|
|||||||
package com.replaymod.extras;
|
|
||||||
|
|
||||||
import com.replaymod.core.ReplayMod;
|
|
||||||
import com.replaymod.core.versions.MCVer;
|
|
||||||
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
|
||||||
import de.johni0702.minecraft.gui.container.GuiContainer;
|
|
||||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
|
||||||
import de.johni0702.minecraft.gui.container.GuiScreen;
|
|
||||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
|
||||||
import de.johni0702.minecraft.gui.element.GuiLabel;
|
|
||||||
import de.johni0702.minecraft.gui.function.Tickable;
|
|
||||||
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
|
||||||
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
|
||||||
import de.johni0702.minecraft.gui.layout.VerticalLayout;
|
|
||||||
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
|
|
||||||
import de.johni0702.minecraft.gui.utils.Colors;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
|
|
||||||
import static com.replaymod.core.utils.Utils.SSL_SOCKET_FACTORY;
|
|
||||||
import static com.replaymod.extras.ReplayModExtras.LOGGER;
|
|
||||||
|
|
||||||
public class OpenEyeExtra implements Extra {
|
|
||||||
private static final String DOWNLOAD_URL = "https://www.replaymod.com/dl/openeye/" + ReplayMod.getMinecraftVersion();
|
|
||||||
|
|
||||||
private ReplayMod mod;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(ReplayMod mod) throws Exception {
|
|
||||||
this.mod = mod;
|
|
||||||
|
|
||||||
boolean isOpenEyeLoaded = MCVer.isModLoaded("OpenEye");
|
|
||||||
if (!isOpenEyeLoaded && mod.getSettingsRegistry().get(Setting.ASK_FOR_OPEN_EYE)) {
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
LOGGER.trace("Checking for OpenEye availability");
|
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(DOWNLOAD_URL).openConnection();
|
|
||||||
connection.setSSLSocketFactory(SSL_SOCKET_FACTORY);
|
|
||||||
connection.setRequestMethod("HEAD");
|
|
||||||
connection.connect();
|
|
||||||
LOGGER.trace("Got response code: {}", connection.getResponseCode());
|
|
||||||
if (connection.getResponseCode() == 200) {
|
|
||||||
mod.runLater(() -> new OfferGui(GuiScreen.wrap(mod.getMinecraft().currentScreen)).display());
|
|
||||||
} else {
|
|
||||||
LOGGER.info("Cannot offer OpenEye, server returned: {} {}",
|
|
||||||
connection.getResponseCode(), connection.getResponseMessage());
|
|
||||||
}
|
|
||||||
connection.disconnect();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.error("Failed to check for OpenEye availability:", e);
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OfferGui extends AbstractGuiScreen<OfferGui> {
|
|
||||||
public final GuiScreen parent;
|
|
||||||
public final GuiPanel textPanel = new GuiPanel().setLayout(new VerticalLayout().setSpacing(3))
|
|
||||||
.addElements(new VerticalLayout.Data(0.5),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye1"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye2"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye3"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye4"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye5"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye6"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye7"),
|
|
||||||
new GuiLabel().setI18nText("replaymod.gui.offeropeneye8"));
|
|
||||||
public final GuiPanel buttonPanel = new GuiPanel()
|
|
||||||
.setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER).setSpacing(5));
|
|
||||||
public final GuiPanel contentPanel = new GuiPanel(this).setLayout(new VerticalLayout().setSpacing(20))
|
|
||||||
.addElements(new VerticalLayout.Data(0.5), textPanel, buttonPanel);
|
|
||||||
public final GuiButton yesButton = new GuiButton(buttonPanel).setSize(150, 20).setI18nLabel("gui.yes");
|
|
||||||
public final GuiButton noButton = new GuiButton(buttonPanel).setSize(150, 20).setI18nLabel("gui.no");
|
|
||||||
|
|
||||||
public OfferGui(GuiScreen parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
|
|
||||||
yesButton.onClick(() -> {
|
|
||||||
GuiPopup popup = new GuiPopup(OfferGui.this);
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
File targetFile = new File(mod.getMinecraft().runDirectory, "mods/" + ReplayMod.getMinecraftVersion() + "/OpenEye.jar");
|
|
||||||
FileUtils.forceMkdir(targetFile.getParentFile());
|
|
||||||
|
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(DOWNLOAD_URL).openConnection();
|
|
||||||
connection.setSSLSocketFactory(SSL_SOCKET_FACTORY);
|
|
||||||
ReadableByteChannel in = Channels.newChannel(connection.getInputStream());
|
|
||||||
FileChannel out = new FileOutputStream(targetFile).getChannel();
|
|
||||||
out.transferFrom(in, 0, Long.MAX_VALUE);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
mod.runLater(() -> {
|
|
||||||
popup.close();
|
|
||||||
parent.display();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
});
|
|
||||||
noButton.onClick(() -> {
|
|
||||||
mod.getSettingsRegistry().set(Setting.ASK_FOR_OPEN_EYE, false);
|
|
||||||
mod.getSettingsRegistry().save();
|
|
||||||
parent.display();
|
|
||||||
});
|
|
||||||
|
|
||||||
setLayout(new CustomLayout<OfferGui>() {
|
|
||||||
@Override
|
|
||||||
protected void layout(OfferGui container, int width, int height) {
|
|
||||||
pos(contentPanel, width / 2 - width(contentPanel) / 2, height / 2 - height(contentPanel) / 2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected OfferGui getThis() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class GuiPopup extends AbstractGuiPopup<GuiPopup> {
|
|
||||||
GuiPopup(GuiContainer container) {
|
|
||||||
super(container);
|
|
||||||
popup.addElements(null, new GuiIndicator().setColor(Colors.BLACK));
|
|
||||||
setBackgroundColor(Colors.DARK_TRANSPARENT);
|
|
||||||
open();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
super.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected GuiPopup getThis() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class GuiIndicator extends GuiLabel implements Tickable {
|
|
||||||
private int tick;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
tick++;
|
|
||||||
setText(new String[]{
|
|
||||||
"Ooooo",
|
|
||||||
"oOooo",
|
|
||||||
"ooOoo",
|
|
||||||
"oooOo",
|
|
||||||
"ooooO",
|
|
||||||
"oooOo",
|
|
||||||
"ooOoo",
|
|
||||||
"oOooo",
|
|
||||||
}[tick / 5 % 8]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,8 +24,7 @@ public class ReplayModExtras implements Module {
|
|||||||
YoutubeUpload.class,
|
YoutubeUpload.class,
|
||||||
FullBrightness.class,
|
FullBrightness.class,
|
||||||
QuickMode.class,
|
QuickMode.class,
|
||||||
HotkeyButtons.class,
|
HotkeyButtons.class
|
||||||
OpenEyeExtra.class
|
|
||||||
);
|
);
|
||||||
|
|
||||||
private final Map<Class<? extends Extra>, Extra> instances = new HashMap<>();
|
private final Map<Class<? extends Extra>, Extra> instances = new HashMap<>();
|
||||||
|
|||||||
@@ -4,22 +4,15 @@ import com.replaymod.core.versions.MCVer;
|
|||||||
import com.replaymod.render.RenderSettings;
|
import com.replaymod.render.RenderSettings;
|
||||||
import com.replaymod.render.blend.BlendState;
|
import com.replaymod.render.blend.BlendState;
|
||||||
import com.replaymod.render.capturer.RenderInfo;
|
import com.replaymod.render.capturer.RenderInfo;
|
||||||
|
import com.replaymod.render.hooks.ForceChunkLoadingHook;
|
||||||
import com.replaymod.render.rendering.Pipelines;
|
import com.replaymod.render.rendering.Pipelines;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.util.Window;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
|
||||||
//#if MC>=11400
|
import static com.replaymod.core.versions.MCVer.resizeMainWindow;
|
||||||
import com.replaymod.render.mixin.MainWindowAccessor;
|
|
||||||
import static com.replaymod.core.versions.MCVer.getWindow;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
import com.replaymod.render.hooks.ChunkLoadingRenderGlobal;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.getRenderPartialTicks;
|
|
||||||
|
|
||||||
public class ScreenshotRenderer implements RenderInfo {
|
public class ScreenshotRenderer implements RenderInfo {
|
||||||
|
|
||||||
@@ -35,20 +28,13 @@ public class ScreenshotRenderer implements RenderInfo {
|
|||||||
|
|
||||||
public boolean renderScreenshot() throws Throwable {
|
public boolean renderScreenshot() throws Throwable {
|
||||||
try {
|
try {
|
||||||
//#if MC>=11400
|
Window window = mc.getWindow();
|
||||||
int displayWidthBefore = getWindow(mc).getFramebufferWidth();
|
int widthBefore = window.getFramebufferWidth();
|
||||||
int displayHeightBefore = getWindow(mc).getFramebufferHeight();
|
int heightBefore = window.getFramebufferHeight();
|
||||||
//#else
|
|
||||||
//$$ int displayWidthBefore = mc.displayWidth;
|
|
||||||
//$$ int displayHeightBefore = mc.displayHeight;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
boolean hideGUIBefore = mc.options.hudHidden;
|
boolean hideGUIBefore = mc.options.hudHidden;
|
||||||
mc.options.hudHidden = true;
|
mc.options.hudHidden = true;
|
||||||
|
|
||||||
//#if MC>=10800
|
ForceChunkLoadingHook clrg = new ForceChunkLoadingHook(mc.worldRenderer);
|
||||||
ChunkLoadingRenderGlobal clrg = new ChunkLoadingRenderGlobal(mc.worldRenderer);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
if (settings.getRenderMethod() == RenderSettings.RenderMethod.BLEND) {
|
if (settings.getRenderMethod() == RenderSettings.RenderMethod.BLEND) {
|
||||||
BlendState.setState(new BlendState(settings.getOutputFile()));
|
BlendState.setState(new BlendState(settings.getOutputFile()));
|
||||||
@@ -58,27 +44,10 @@ public class ScreenshotRenderer implements RenderInfo {
|
|||||||
new ScreenshotWriter(settings.getOutputFile())).run();
|
new ScreenshotWriter(settings.getOutputFile())).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
clrg.uninstall();
|
clrg.uninstall();
|
||||||
//#endif
|
|
||||||
|
|
||||||
mc.options.hudHidden = hideGUIBefore;
|
mc.options.hudHidden = hideGUIBefore;
|
||||||
//#if MC>=11400
|
resizeMainWindow(mc, widthBefore, heightBefore);
|
||||||
//noinspection ConstantConditions
|
|
||||||
MainWindowAccessor acc = (MainWindowAccessor) (Object) getWindow(mc);
|
|
||||||
acc.setFramebufferWidth(displayWidthBefore);
|
|
||||||
acc.setFramebufferHeight(displayHeightBefore);
|
|
||||||
mc.getFramebuffer().resize(displayWidthBefore, displayHeightBefore
|
|
||||||
//#if MC>=11400
|
|
||||||
, false
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
//#if MC>=11500
|
|
||||||
mc.gameRenderer.onResized(displayWidthBefore, displayHeightBefore);
|
|
||||||
//#endif
|
|
||||||
//#else
|
|
||||||
//$$ mc.resize(displayWidthBefore, displayHeightBefore);
|
|
||||||
//#endif
|
|
||||||
return true;
|
return true;
|
||||||
} catch (OutOfMemoryError e) {
|
} catch (OutOfMemoryError e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -107,7 +76,7 @@ public class ScreenshotRenderer implements RenderInfo {
|
|||||||
@Override
|
@Override
|
||||||
public float updateForNextFrame() {
|
public float updateForNextFrame() {
|
||||||
framesDone++;
|
framesDone++;
|
||||||
return getRenderPartialTicks();
|
return mc.getTickDelta();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,485 +0,0 @@
|
|||||||
/* Based on https://github.com/Sk1erLLC/ModCore-Example-Mod/blob/4a362fa1c67cee28bdfc82bd5a99a30896b081fb/src/main/java/club/sk1er/mods/modcoreexample/ModCoreInstaller.java
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2020 Sk1er LLC
|
|
||||||
* Copyright (c) 2020 ModCore Inc.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
package com.replaymod.extras.modcore;
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JProgressBar;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.GridLayout;
|
|
||||||
import java.awt.TextArea;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
//#else
|
|
||||||
//#if MC>=11400
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.launchwrapper.Launch;
|
|
||||||
//$$ import java.net.URLClassLoader;
|
|
||||||
//$$ import java.util.LinkedHashSet;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public class ModCoreInstaller {
|
|
||||||
|
|
||||||
private static final String VERSION_URL = "https://api.sk1er.club/modcore_versions";
|
|
||||||
private static final String className = "club.sk1er.mods.core.tweaker.ModCoreTweaker";
|
|
||||||
private static boolean errored = false;
|
|
||||||
private static String error;
|
|
||||||
private static File dataDir = null;
|
|
||||||
|
|
||||||
|
|
||||||
private static boolean isInitalized() {
|
|
||||||
try {
|
|
||||||
//#if MC<11400
|
|
||||||
//$$ LinkedHashSet<String> objects = new LinkedHashSet<>();
|
|
||||||
//$$ objects.add(className);
|
|
||||||
//$$ Launch.classLoader.clearNegativeEntries(objects);
|
|
||||||
//#endif
|
|
||||||
return Class.forName(className) != null;
|
|
||||||
} catch (ClassNotFoundException ignored) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isErrored() {
|
|
||||||
return errored;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void bail(String error) {
|
|
||||||
errored = true;
|
|
||||||
ModCoreInstaller.error = error;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsonHolder readFile(File in) {
|
|
||||||
try {
|
|
||||||
return new JsonHolder(FileUtils.readFileToString(in));
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return new JsonHolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean initializeModCore(File gameDir) {
|
|
||||||
try {
|
|
||||||
Class<?> modCore = Class.forName("club.sk1er.mods.core.tweaker.ModCoreTweaker");
|
|
||||||
Method initialize = modCore.getMethod("initialize", File.class);
|
|
||||||
initialize.invoke(null, gameDir);
|
|
||||||
System.out.println("Loaded ModCore Successfully");
|
|
||||||
return true;
|
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
System.out.println("Did NOT initialize ModCore Successfully");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int initialize(File gameDir, String minecraftVersion) {
|
|
||||||
if (isInitalized()) return -1;
|
|
||||||
JsonHolder jsonHolder = fetchJSON(VERSION_URL);
|
|
||||||
if (!jsonHolder.has(minecraftVersion)) {
|
|
||||||
System.out.println("No ModCore target for " + minecraftVersion + ". This in fine, unless you're specifically looking for ModCore.");
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
dataDir = new File(gameDir, "modcore");
|
|
||||||
if (!dataDir.exists()) {
|
|
||||||
if (!dataDir.mkdirs()) {
|
|
||||||
bail("Unable to create necessary files");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String latestRemote = jsonHolder.optString(minecraftVersion);
|
|
||||||
boolean failed = jsonHolder.getKeys().size() == 0 || (jsonHolder.has("success") && !jsonHolder.optBoolean("success"));
|
|
||||||
|
|
||||||
File metadataFile = new File(dataDir, "metadata.json");
|
|
||||||
JsonHolder localMetadata = readFile(metadataFile);
|
|
||||||
if (failed) latestRemote = localMetadata.optString(minecraftVersion);
|
|
||||||
File modcoreFile = new File(dataDir, "Sk1er Modcore-" + latestRemote + " (" + minecraftVersion + ").jar");
|
|
||||||
|
|
||||||
if (!modcoreFile.exists() || !localMetadata.optString(minecraftVersion).equalsIgnoreCase(latestRemote) && !failed) {
|
|
||||||
//File does not exist, or is out of date, download it
|
|
||||||
File old = new File(dataDir, "Sk1er Modcore-" + localMetadata.optString(minecraftVersion) + " (" + minecraftVersion + ").jar");
|
|
||||||
if (old.exists()) old.delete();
|
|
||||||
|
|
||||||
if (!download("https://static.sk1er.club/repo/mods/modcore/" + latestRemote + "/" + minecraftVersion + "/ModCore-" + latestRemote + " (" + minecraftVersion + ").jar", latestRemote, modcoreFile, minecraftVersion, localMetadata)) {
|
|
||||||
bail("Unable to download");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
addToClasspath(modcoreFile);
|
|
||||||
|
|
||||||
if (!isInitalized()) {
|
|
||||||
bail("Something went wrong and it did not add the jar to the class path. Local file exists? " + modcoreFile.exists());
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
return initializeModCore(gameDir) ? 0 : 4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void addToClasspath(File file) {
|
|
||||||
try {
|
|
||||||
URL url = file.toURI().toURL();
|
|
||||||
ClassLoader classLoader = ModCoreInstaller.class.getClassLoader();
|
|
||||||
//#if MC>=11400
|
|
||||||
Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class);
|
|
||||||
//#else
|
|
||||||
//$$ Launch.classLoader.addURL(url);
|
|
||||||
//$$ Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
|
||||||
//#endif
|
|
||||||
method.setAccessible(true);
|
|
||||||
method.invoke(classLoader, url);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Unexpected exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean download(String url, String version, File file, String mcver, JsonHolder versionData) {
|
|
||||||
url = url.replace(" ", "%20");
|
|
||||||
System.out.println("Downloading ModCore " + " version " + version + " from: " + url);
|
|
||||||
JFrame frame = new JFrame("ModCore Initializer");
|
|
||||||
JProgressBar bar = new JProgressBar();
|
|
||||||
TextArea comp = new TextArea("", 1, 1, TextArea.SCROLLBARS_NONE);
|
|
||||||
frame.getContentPane().add(comp);
|
|
||||||
frame.getContentPane().add(bar);
|
|
||||||
GridLayout manager = new GridLayout();
|
|
||||||
frame.setLayout(manager);
|
|
||||||
manager.setColumns(1);
|
|
||||||
manager.setRows(2);
|
|
||||||
comp.setText("Downloading Sk1er ModCore Library Version " + version + " for Minecraft " + mcver);
|
|
||||||
comp.setSize(399, 80);
|
|
||||||
comp.setEditable(false);
|
|
||||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
|
||||||
|
|
||||||
|
|
||||||
Dimension preferredSize = new Dimension(400, 225);
|
|
||||||
bar.setSize(preferredSize);
|
|
||||||
frame.setSize(preferredSize);
|
|
||||||
frame.setResizable(false);
|
|
||||||
bar.setBorderPainted(true);
|
|
||||||
bar.setMinimum(0);
|
|
||||||
bar.setStringPainted(true);
|
|
||||||
frame.setVisible(true);
|
|
||||||
frame.setLocation(dim.width / 2 - frame.getSize().width / 2, dim.height / 2 - frame.getSize().height / 2);
|
|
||||||
Font font = bar.getFont();
|
|
||||||
bar.setFont(new Font(font.getName(), font.getStyle(), font.getSize() * 4));
|
|
||||||
comp.setFont(new Font(font.getName(), font.getStyle(), font.getSize() * 2));
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
URL u = new URL(url);
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
|
|
||||||
connection.setRequestMethod("GET");
|
|
||||||
connection.setUseCaches(true);
|
|
||||||
connection.addRequestProperty("User-Agent", "Mozilla/4.76 (Sk1er Modcore Initializer)");
|
|
||||||
connection.setReadTimeout(15000);
|
|
||||||
connection.setConnectTimeout(15000);
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
InputStream is = connection.getInputStream();
|
|
||||||
int contentLength = connection.getContentLength();
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(file);
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
System.out.println("MAX: " + contentLength);
|
|
||||||
bar.setMaximum(contentLength);
|
|
||||||
int read;
|
|
||||||
bar.setValue(0);
|
|
||||||
while ((read = is.read(buffer)) > 0) {
|
|
||||||
outputStream.write(buffer, 0, read);
|
|
||||||
bar.setValue(bar.getValue() + 1024);
|
|
||||||
}
|
|
||||||
outputStream.close();
|
|
||||||
FileUtils.write(new File(dataDir, "metadata.json"), versionData.put(mcver, version).toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
frame.dispose();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
frame.dispose();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final JsonHolder fetchJSON(String url) {
|
|
||||||
return new JsonHolder(fetchString(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String fetchString(String url) {
|
|
||||||
url = url.replace(" ", "%20");
|
|
||||||
System.out.println("Fetching " + url);
|
|
||||||
try {
|
|
||||||
URL u = new URL(url);
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) u.openConnection();
|
|
||||||
connection.setRequestMethod("GET");
|
|
||||||
connection.setUseCaches(true);
|
|
||||||
connection.addRequestProperty("User-Agent", "Mozilla/4.76 (Sk1er ModCore)");
|
|
||||||
connection.setReadTimeout(15000);
|
|
||||||
connection.setConnectTimeout(15000);
|
|
||||||
connection.setDoOutput(true);
|
|
||||||
InputStream is = connection.getInputStream();
|
|
||||||
return IOUtils.toString(is, Charset.defaultCharset());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return "Failed to fetch";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Added because we need to use before ModCore is loaded
|
|
||||||
static class JsonHolder {
|
|
||||||
private JsonObject object;
|
|
||||||
|
|
||||||
public JsonHolder(JsonObject object) {
|
|
||||||
this.object = object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder(String raw) {
|
|
||||||
if (raw == null)
|
|
||||||
object = new JsonObject();
|
|
||||||
else
|
|
||||||
try {
|
|
||||||
this.object = new JsonParser().parse(raw).getAsJsonObject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
this.object = new JsonObject();
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder() {
|
|
||||||
this(new JsonObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (object != null)
|
|
||||||
return object.toString();
|
|
||||||
return "{}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String key, boolean value) {
|
|
||||||
object.addProperty(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mergeNotOverride(JsonHolder merge) {
|
|
||||||
merge(merge, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mergeOverride(JsonHolder merge) {
|
|
||||||
merge(merge, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void merge(JsonHolder merge, boolean override) {
|
|
||||||
JsonObject object = merge.getObject();
|
|
||||||
for (String s : merge.getKeys()) {
|
|
||||||
if (override || !this.has(s))
|
|
||||||
put(s, object.get(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void put(String s, JsonElement element) {
|
|
||||||
this.object.add(s, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String key, String value) {
|
|
||||||
object.addProperty(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String key, int value) {
|
|
||||||
object.addProperty(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String key, double value) {
|
|
||||||
object.addProperty(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String key, long value) {
|
|
||||||
object.addProperty(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonHolder defaultOptJSONObject(String key, JsonObject fallBack) {
|
|
||||||
try {
|
|
||||||
return new JsonHolder(object.get(key).getAsJsonObject());
|
|
||||||
} catch (Exception e) {
|
|
||||||
return new JsonHolder(fallBack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonArray defaultOptJSONArray(String key, JsonArray fallback) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsJsonArray();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonArray optJSONArray(String key) {
|
|
||||||
return defaultOptJSONArray(key, new JsonArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean has(String key) {
|
|
||||||
return object.has(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long optLong(String key, long fallback) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsLong();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long optLong(String key) {
|
|
||||||
return optLong(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean optBoolean(String key, boolean fallback) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsBoolean();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean optBoolean(String key) {
|
|
||||||
return optBoolean(key, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonObject optActualJSONObject(String key) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsJsonObject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return new JsonObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder optJSONObject(String key) {
|
|
||||||
return defaultOptJSONObject(key, new JsonObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int optInt(String key, int fallBack) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsInt();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallBack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int optInt(String key) {
|
|
||||||
return optInt(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String defaultOptString(String key, String fallBack) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsString();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallBack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String optString(String key) {
|
|
||||||
return defaultOptString(key, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public double optDouble(String key, double fallBack) {
|
|
||||||
try {
|
|
||||||
return object.get(key).getAsDouble();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return fallBack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getKeys() {
|
|
||||||
List<String> tmp = new ArrayList<>();
|
|
||||||
object.entrySet().forEach(e -> tmp.add(e.getKey()));
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double optDouble(String key) {
|
|
||||||
return optDouble(key, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public JsonObject getObject() {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNull(String key) {
|
|
||||||
return object.has(key) && object.get(key).isJsonNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String values, JsonHolder values1) {
|
|
||||||
return put(values, values1.getObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonHolder put(String values, JsonObject object) {
|
|
||||||
this.object.add(values, object);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void put(String blacklisted, JsonArray jsonElements) {
|
|
||||||
this.object.add(blacklisted, jsonElements);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(String header) {
|
|
||||||
object.remove(header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2,6 +2,7 @@ package com.replaymod.extras.playeroverview;
|
|||||||
|
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
|
import com.replaymod.core.events.PreRenderHandCallback;
|
||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
import com.replaymod.extras.Extra;
|
import com.replaymod.extras.Extra;
|
||||||
import com.replaymod.replay.ReplayHandler;
|
import com.replaymod.replay.ReplayHandler;
|
||||||
@@ -14,23 +15,11 @@ import net.minecraft.entity.Entity;
|
|||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import com.replaymod.core.events.PreRenderHandCallback;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
//#else
|
//#else
|
||||||
//$$ import net.minecraftforge.client.event.RenderHandEvent;
|
|
||||||
//$$
|
|
||||||
//#if MC>=11400
|
|
||||||
//#else
|
|
||||||
//$$ import org.lwjgl.input.Keyboard;
|
//$$ import org.lwjgl.input.Keyboard;
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
//$$ import com.google.common.base.Predicate;
|
//$$ import com.google.common.base.Predicate;
|
||||||
//#if MC>=11400
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
//#endif
|
|
||||||
//#else
|
//#else
|
||||||
//$$ import cpw.mods.fml.common.eventhandler.EventPriority;
|
//$$ import cpw.mods.fml.common.eventhandler.EventPriority;
|
||||||
//$$ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
//$$ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||||
@@ -126,18 +115,9 @@ public class PlayerOverview extends EventRegistrations implements Extra {
|
|||||||
hiddenPlayers.clear();
|
hiddenPlayers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
{ on(PreRenderHandCallback.EVENT, this::shouldHideHand); }
|
{ on(PreRenderHandCallback.EVENT, this::shouldHideHand); }
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void oRenderHand(RenderHandEvent event) {
|
|
||||||
//$$ if (shouldHideHand()) {
|
|
||||||
//$$ event.setCanceled(true);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
private boolean shouldHideHand() {
|
private boolean shouldHideHand() {
|
||||||
Entity view = getRenderViewEntity(module.getCore().getMinecraft());
|
Entity view = module.getCore().getMinecraft().getCameraEntity();
|
||||||
return view != null && isHidden(view.getUuid());
|
return view != null && isHidden(view.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ public class PlayerOverviewGui extends GuiScreen implements Closeable {
|
|||||||
public final GuiCheckbox checkAll = new GuiCheckbox(contentPanel){
|
public final GuiCheckbox checkAll = new GuiCheckbox(contentPanel){
|
||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
playersScrollable.forEach(IGuiCheckbox.class).setChecked(true);
|
playersScrollable.invokeAll(IGuiCheckbox.class, e -> e.setChecked(true));
|
||||||
}
|
}
|
||||||
}.setLabel("").setChecked(true).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.showall"));
|
}.setLabel("").setChecked(true).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.showall"));
|
||||||
public final GuiCheckbox uncheckAll = new GuiCheckbox(contentPanel){
|
public final GuiCheckbox uncheckAll = new GuiCheckbox(contentPanel){
|
||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
playersScrollable.forEach(IGuiCheckbox.class).setChecked(false);
|
playersScrollable.invokeAll(IGuiCheckbox.class, e -> e.setChecked(false));
|
||||||
}
|
}
|
||||||
}.setLabel("").setChecked(false).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.hideall"));
|
}.setLabel("").setChecked(false).setTooltip(new GuiTooltip().setI18nText("replaymod.gui.playeroverview.hideall"));
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import net.minecraft.util.Util;
|
|||||||
//$$ import org.lwjgl.Sys;
|
//$$ import org.lwjgl.Sys;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
import javax.imageio.stream.ImageInputStream;
|
import javax.imageio.stream.ImageInputStream;
|
||||||
@@ -116,36 +115,27 @@ public class GuiYoutubeUpload extends GuiScreen {
|
|||||||
public final GuiButton thumbnailButton = new GuiButton().onClick(new Runnable() {
|
public final GuiButton thumbnailButton = new GuiButton().onClick(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Futures.addCallback(
|
GuiFileChooserPopup.openLoadGui(
|
||||||
GuiFileChooserPopup.openLoadGui(GuiYoutubeUpload.this, "replaymod.gui.load",
|
GuiYoutubeUpload.this,
|
||||||
ImageIO.getReaderFileSuffixes()).getFuture(),
|
"replaymod.gui.load",
|
||||||
new FutureCallback<File>() {
|
ImageIO.getReaderFileSuffixes()
|
||||||
@Override
|
).onAccept(file -> {
|
||||||
public void onSuccess(@Nullable File result) {
|
thumbnailButton.setLabel(file.getName());
|
||||||
if (result != null) {
|
Image image;
|
||||||
thumbnailButton.setLabel(result.getName());
|
try {
|
||||||
Image image;
|
thumbnailImage = IOUtils.toByteArray(new FileInputStream(file));
|
||||||
try {
|
ImageInputStream in = ImageIO.createImageInputStream(new ByteArrayInputStream(thumbnailImage));
|
||||||
thumbnailImage = IOUtils.toByteArray(new FileInputStream(result));
|
ImageReader reader = ImageIO.getImageReaders(in).next();
|
||||||
ImageInputStream in = ImageIO.createImageInputStream(new ByteArrayInputStream(thumbnailImage));
|
thumbnailFormat = reader.getFormatName().toLowerCase();
|
||||||
ImageReader reader = ImageIO.getImageReaders(in).next();
|
image = Image.read(new ByteArrayInputStream(thumbnailImage));
|
||||||
thumbnailFormat = reader.getFormatName().toLowerCase();
|
} catch (Throwable t) {
|
||||||
image = Image.read(new ByteArrayInputStream(thumbnailImage));
|
t.printStackTrace();
|
||||||
} catch (Throwable t) {
|
thumbnailImage = null;
|
||||||
t.printStackTrace();
|
image = null;
|
||||||
thumbnailImage = null;
|
}
|
||||||
image = null;
|
thumbnail.setTexture(image);
|
||||||
}
|
inputValidation.run();
|
||||||
thumbnail.setTexture(image);
|
});
|
||||||
inputValidation.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
throw new RuntimeException(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).setSize(200, 20).setI18nLabel("replaymod.gui.videothumbnail");
|
}).setSize(200, 20).setI18nLabel("replaymod.gui.videothumbnail");
|
||||||
|
|
||||||
@@ -191,7 +181,7 @@ public class GuiYoutubeUpload extends GuiScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setState(boolean uploading) {
|
private void setState(boolean uploading) {
|
||||||
forEach(GuiElement.class).setEnabled(!uploading);
|
invokeAll(GuiElement.class, e -> e.setEnabled(!uploading));
|
||||||
uploadButton.setEnabled();
|
uploadButton.setEnabled();
|
||||||
if (uploading) {
|
if (uploading) {
|
||||||
uploadButton.onClick(() -> {
|
uploadButton.onClick(() -> {
|
||||||
|
|||||||
@@ -3,19 +3,11 @@ package com.replaymod.extras.youtube;
|
|||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import com.replaymod.extras.Extra;
|
import com.replaymod.extras.Extra;
|
||||||
import com.replaymod.render.gui.GuiRenderingDone;
|
import com.replaymod.render.gui.GuiRenderingDone;
|
||||||
import de.johni0702.minecraft.gui.container.GuiScreen;
|
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
||||||
import de.johni0702.minecraft.gui.element.GuiButton;
|
import de.johni0702.minecraft.gui.element.GuiButton;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.OpenGuiScreenCallback;
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
|
|
||||||
public class YoutubeUpload extends EventRegistrations implements Extra {
|
public class YoutubeUpload extends EventRegistrations implements Extra {
|
||||||
@Override
|
@Override
|
||||||
@@ -23,16 +15,11 @@ public class YoutubeUpload extends EventRegistrations implements Extra {
|
|||||||
register();
|
register();
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
{ on(InitScreenCallback.EVENT, ((screen, buttons) -> onGuiOpen(screen))); }
|
||||||
{ on(OpenGuiScreenCallback.EVENT, this::onGuiOpen); }
|
|
||||||
private void onGuiOpen(Screen vanillaGui) {
|
private void onGuiOpen(Screen vanillaGui) {
|
||||||
//#else
|
AbstractGuiScreen<?> abstractScreen = de.johni0702.minecraft.gui.container.GuiScreen.from(vanillaGui);
|
||||||
//$$ @SubscribeEvent
|
if (abstractScreen instanceof GuiRenderingDone) {
|
||||||
//$$ public void onGuiOpen(GuiScreenEvent.InitGuiEvent.Post event) {
|
GuiRenderingDone gui = (GuiRenderingDone) abstractScreen;
|
||||||
//$$ net.minecraft.client.gui.screen.Screen vanillaGui = getGui(event);
|
|
||||||
//#endif
|
|
||||||
if (GuiScreen.from(vanillaGui) instanceof GuiRenderingDone) {
|
|
||||||
GuiRenderingDone gui = (GuiRenderingDone) GuiScreen.from(vanillaGui);
|
|
||||||
// Check if there already is a youtube button
|
// Check if there already is a youtube button
|
||||||
if (gui.actionsPanel.getChildren().stream().anyMatch(it -> it instanceof YoutubeButton)) {
|
if (gui.actionsPanel.getChildren().stream().anyMatch(it -> it instanceof YoutubeButton)) {
|
||||||
return; // Button already added
|
return; // Button already added
|
||||||
|
|||||||
11
src/main/java/com/replaymod/gradle/remap/Pattern.java
Normal file
11
src/main/java/com/replaymod/gradle/remap/Pattern.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.replaymod.gradle.remap;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface Pattern {
|
||||||
|
}
|
||||||
@@ -65,18 +65,15 @@ public class GuiKeyframeRepository extends GuiScreen implements Closeable, Typea
|
|||||||
public final GuiButton overwriteButton = new GuiButton().onClick(new Runnable() {
|
public final GuiButton overwriteButton = new GuiButton().onClick(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GuiYesNoPopup popup = GuiYesNoPopup.open(GuiKeyframeRepository.this,
|
GuiYesNoPopup.open(GuiKeyframeRepository.this,
|
||||||
new GuiLabel().setI18nText("replaymod.gui.keyframerepo.overwrite").setColor(Colors.BLACK)
|
new GuiLabel().setI18nText("replaymod.gui.keyframerepo.overwrite").setColor(Colors.BLACK)
|
||||||
).setYesI18nLabel("gui.yes").setNoI18nLabel("gui.no");
|
).setYesI18nLabel("gui.yes").setNoI18nLabel("gui.no").onAccept(() -> {
|
||||||
Utils.addCallback(popup.getFuture(), doIt -> {
|
for (Entry entry : selectedEntries) {
|
||||||
if (doIt) {
|
timelines.put(entry.name, currentTimeline);
|
||||||
for (Entry entry : selectedEntries) {
|
|
||||||
timelines.put(entry.name, currentTimeline);
|
|
||||||
}
|
|
||||||
overwriteButton.setDisabled();
|
|
||||||
save();
|
|
||||||
}
|
}
|
||||||
}, Throwable::printStackTrace);
|
overwriteButton.setDisabled();
|
||||||
|
save();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).setSize(75, 20).setI18nLabel("replaymod.gui.overwrite").setDisabled();
|
}).setSize(75, 20).setI18nLabel("replaymod.gui.overwrite").setDisabled();
|
||||||
public final GuiButton saveAsButton = new GuiButton().onClick(new Runnable() {
|
public final GuiButton saveAsButton = new GuiButton().onClick(new Runnable() {
|
||||||
@@ -103,21 +100,11 @@ public class GuiKeyframeRepository extends GuiScreen implements Closeable, Typea
|
|||||||
&& !timelines.containsKey(nameField.getText()));
|
&& !timelines.containsKey(nameField.getText()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Futures.addCallback(popup.getFuture(), new FutureCallback<Boolean>() {
|
popup.onAccept(() -> {
|
||||||
@Override
|
String name = nameField.getText();
|
||||||
public void onSuccess(Boolean save) {
|
timelines.put(name, currentTimeline);
|
||||||
if (save) {
|
list.getListPanel().addElements(null, new Entry(name));
|
||||||
String name = nameField.getText();
|
save();
|
||||||
timelines.put(name, currentTimeline);
|
|
||||||
list.getListPanel().addElements(null, new Entry(name));
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).setSize(75, 20).setI18nLabel("replaymod.gui.saveas");
|
}).setSize(75, 20).setI18nLabel("replaymod.gui.saveas");
|
||||||
@@ -161,50 +148,29 @@ public class GuiKeyframeRepository extends GuiScreen implements Closeable, Typea
|
|||||||
&& !timelines.containsKey(nameField.getText()));
|
&& !timelines.containsKey(nameField.getText()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Futures.addCallback(popup.getFuture(), new FutureCallback<Boolean>() {
|
popup.onAccept(() -> {
|
||||||
@Override
|
String name = nameField.getText();
|
||||||
public void onSuccess(Boolean save) {
|
timelines.put(name, timelines.remove(selectedEntry.name));
|
||||||
if (save) {
|
selectedEntry.name = name;
|
||||||
String name = nameField.getText();
|
selectedEntry.label.setText(name);
|
||||||
timelines.put(name, timelines.remove(selectedEntry.name));
|
save();
|
||||||
selectedEntry.name = name;
|
|
||||||
selectedEntry.label.setText(name);
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).setSize(75, 20).setI18nLabel("replaymod.gui.rename").setDisabled();
|
}).setSize(75, 20).setI18nLabel("replaymod.gui.rename").setDisabled();
|
||||||
public final GuiButton removeButton = new GuiButton().onClick(new Runnable() {
|
public final GuiButton removeButton = new GuiButton().onClick(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GuiYesNoPopup popup = GuiYesNoPopup.open(GuiKeyframeRepository.this,
|
GuiYesNoPopup.open(GuiKeyframeRepository.this,
|
||||||
new GuiLabel().setI18nText("replaymod.gui.keyframerepo.delete").setColor(Colors.BLACK)
|
new GuiLabel().setI18nText("replaymod.gui.keyframerepo.delete").setColor(Colors.BLACK)
|
||||||
).setYesI18nLabel("replaymod.gui.delete").setNoI18nLabel("replaymod.gui.cancel");
|
).setYesI18nLabel("replaymod.gui.delete").setNoI18nLabel("replaymod.gui.cancel").onAccept(() -> {
|
||||||
Futures.addCallback(popup.getFuture(), new FutureCallback<Boolean>() {
|
for (Entry entry : selectedEntries) {
|
||||||
@Override
|
timelines.remove(entry.name);
|
||||||
public void onSuccess(Boolean delete) {
|
list.getListPanel().removeElement(entry);
|
||||||
if (delete) {
|
|
||||||
for (Entry entry : selectedEntries) {
|
|
||||||
timelines.remove(entry.name);
|
|
||||||
list.getListPanel().removeElement(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedEntries.clear();
|
|
||||||
updateButtons();
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
selectedEntries.clear();
|
||||||
public void onFailure(Throwable t) {
|
updateButtons();
|
||||||
t.printStackTrace();
|
save();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).setSize(75, 20).setI18nLabel("replaymod.gui.remove").setDisabled();
|
}).setSize(75, 20).setI18nLabel("replaymod.gui.remove").setDisabled();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.replaymod.core.ReplayMod;
|
|||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.editor.gui.MarkerProcessor;
|
import com.replaymod.editor.gui.MarkerProcessor;
|
||||||
import com.replaymod.recording.Setting;
|
|
||||||
import com.replaymod.recording.packet.PacketListener;
|
import com.replaymod.recording.packet.PacketListener;
|
||||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||||
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
||||||
@@ -12,23 +11,15 @@ import de.johni0702.minecraft.gui.element.GuiButton;
|
|||||||
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
||||||
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
||||||
import net.minecraft.client.gui.screen.GameMenuScreen;
|
import net.minecraft.client.gui.screen.GameMenuScreen;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.getGui;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -85,19 +76,14 @@ public class GuiRecordingControls extends EventRegistrations {
|
|||||||
buttonPauseResume.setEnabled(!stopped);
|
buttonPauseResume.setEnabled(!stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(InitScreenCallback.EVENT, this::injectIntoIngameMenu); }
|
{ on(InitScreenCallback.EVENT, this::injectIntoIngameMenu); }
|
||||||
private void injectIntoIngameMenu(Screen guiScreen, List<AbstractButtonWidget> buttonList) {
|
private void injectIntoIngameMenu(Screen guiScreen,
|
||||||
//#else
|
//#if MC>=11400
|
||||||
//$$ @SubscribeEvent
|
Collection<AbstractButtonWidget> buttonList
|
||||||
//$$ public void injectIntoIngameMenu(GuiScreenEvent.InitGuiEvent.Post event) {
|
//#else
|
||||||
//$$ Screen guiScreen = getGui(event);
|
//$$ Collection<net.minecraft.client.gui.GuiButton> buttonList
|
||||||
//#if MC>=11400
|
//#endif
|
||||||
//$$ List<Widget> buttonList = MCVer.getButtonList(event);
|
) {
|
||||||
//#else
|
|
||||||
//$$ List<net.minecraft.client.gui.GuiButton> buttonList = MCVer.getButtonList(event);
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
if (!(guiScreen instanceof GameMenuScreen)) {
|
if (!(guiScreen instanceof GameMenuScreen)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
package com.replaymod.recording.gui;
|
package com.replaymod.recording.gui;
|
||||||
|
|
||||||
import com.replaymod.core.SettingsRegistry;
|
import com.replaymod.core.SettingsRegistry;
|
||||||
import com.replaymod.core.versions.MCVer;
|
|
||||||
import com.replaymod.recording.Setting;
|
import com.replaymod.recording.Setting;
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.MinecraftGuiRenderer;
|
import de.johni0702.minecraft.gui.MinecraftGuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
import de.johni0702.minecraft.gui.versions.callbacks.RenderHudCallback;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.font.TextRenderer;
|
import net.minecraft.client.font.TextRenderer;
|
||||||
import net.minecraft.client.resource.language.I18n;
|
import net.minecraft.client.resource.language.I18n;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.RenderHudCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static com.replaymod.core.ReplayMod.TEXTURE;
|
import static com.replaymod.core.ReplayMod.TEXTURE;
|
||||||
import static com.replaymod.core.ReplayMod.TEXTURE_SIZE;
|
import static com.replaymod.core.ReplayMod.TEXTURE_SIZE;
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
import static com.mojang.blaze3d.platform.GlStateManager.*;
|
import static com.mojang.blaze3d.platform.GlStateManager.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,27 +32,18 @@ public class GuiRecordingOverlay extends EventRegistrations {
|
|||||||
/**
|
/**
|
||||||
* Render the recording icon and text in the top left corner of the screen.
|
* Render the recording icon and text in the top left corner of the screen.
|
||||||
*/
|
*/
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(RenderHudCallback.EVENT, (stack, partialTicks) -> renderRecordingIndicator(stack)); }
|
{ on(RenderHudCallback.EVENT, (stack, partialTicks) -> renderRecordingIndicator(stack)); }
|
||||||
private void renderRecordingIndicator(MatrixStack stack) {
|
private void renderRecordingIndicator(MatrixStack stack) {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void renderRecordingIndicator(RenderGameOverlayEvent.Post event) {
|
|
||||||
//$$ if (getType(event) != RenderGameOverlayEvent.ElementType.ALL) return;
|
|
||||||
//$$ MatrixStack stack = new MatrixStack();
|
|
||||||
//#endif
|
|
||||||
if (guiControls.isStopped()) return;
|
if (guiControls.isStopped()) return;
|
||||||
if (settingsRegistry.get(Setting.INDICATOR)) {
|
if (settingsRegistry.get(Setting.INDICATOR)) {
|
||||||
TextRenderer fontRenderer = mc.textRenderer;
|
TextRenderer fontRenderer = mc.textRenderer;
|
||||||
String text = guiControls.isPaused() ? I18n.translate("replaymod.gui.paused") : I18n.translate("replaymod.gui.recording");
|
String text = guiControls.isPaused() ? I18n.translate("replaymod.gui.paused") : I18n.translate("replaymod.gui.recording");
|
||||||
fontRenderer.draw(
|
MinecraftGuiRenderer renderer = new MinecraftGuiRenderer(stack);
|
||||||
//#if MC>=11600
|
renderer.drawString(30, 18 - (fontRenderer.fontHeight / 2), 0xffffffff, text.toUpperCase());
|
||||||
stack,
|
renderer.bindTexture(TEXTURE);
|
||||||
//#endif
|
//#if MC<11700
|
||||||
text.toUpperCase(), 30, 18 - (fontRenderer.fontHeight / 2), 0xffffffff);
|
|
||||||
bindTexture(TEXTURE);
|
|
||||||
enableAlphaTest();
|
enableAlphaTest();
|
||||||
GuiRenderer renderer = new MinecraftGuiRenderer(stack, MCVer.newScaledResolution(mc));
|
//#endif
|
||||||
renderer.drawTexturedRect(10, 10, 58, 20, 16, 16, 16, 16, TEXTURE_SIZE, TEXTURE_SIZE);
|
renderer.drawTexturedRect(10, 10, 58, 20, 16, 16, 16, 16, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.replaymod.core.utils.Utils;
|
|||||||
import com.replaymod.recording.Setting;
|
import com.replaymod.recording.Setting;
|
||||||
import com.replaymod.replay.gui.screen.GuiReplayViewer;
|
import com.replaymod.replay.gui.screen.GuiReplayViewer;
|
||||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
|
||||||
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
import de.johni0702.minecraft.gui.container.AbstractGuiScreen;
|
||||||
import de.johni0702.minecraft.gui.container.GuiContainer;
|
import de.johni0702.minecraft.gui.container.GuiContainer;
|
||||||
import de.johni0702.minecraft.gui.container.GuiPanel;
|
import de.johni0702.minecraft.gui.container.GuiPanel;
|
||||||
@@ -25,6 +24,7 @@ import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
|||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.replaymod.recording.handler;
|
|||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
import com.replaymod.core.utils.ModCompat;
|
import com.replaymod.core.utils.ModCompat;
|
||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.editor.gui.MarkerProcessor;
|
import com.replaymod.editor.gui.MarkerProcessor;
|
||||||
import com.replaymod.recording.ServerInfoExt;
|
import com.replaymod.recording.ServerInfoExt;
|
||||||
import com.replaymod.recording.Setting;
|
import com.replaymod.recording.Setting;
|
||||||
@@ -137,7 +138,7 @@ public class ConnectionEventHandler {
|
|||||||
metaData.setCustomServerName(serverName);
|
metaData.setCustomServerName(serverName);
|
||||||
metaData.setGenerator("ReplayMod v" + ReplayMod.instance.getVersion());
|
metaData.setGenerator("ReplayMod v" + ReplayMod.instance.getVersion());
|
||||||
metaData.setDate(System.currentTimeMillis());
|
metaData.setDate(System.currentTimeMillis());
|
||||||
metaData.setMcVersion(ReplayMod.getMinecraftVersion());
|
metaData.setMcVersion(ReplayMod.instance.getMinecraftVersion());
|
||||||
packetListener = new PacketListener(core, outputPath, replayFile, metaData);
|
packetListener = new PacketListener(core, outputPath, replayFile, metaData);
|
||||||
Channel channel = ((NetworkManagerAccessor) networkManager).getChannel();
|
Channel channel = ((NetworkManagerAccessor) networkManager).getChannel();
|
||||||
channel.pipeline().addBefore(packetHandlerKey, "replay_recorder", packetListener);
|
channel.pipeline().addBefore(packetHandlerKey, "replay_recorder", packetListener);
|
||||||
|
|||||||
@@ -1,31 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.recording.handler;
|
|
||||||
//$$
|
|
||||||
//$$ import io.netty.channel.ChannelHandlerContext;
|
|
||||||
//$$ import io.netty.channel.SimpleChannelInboundHandler;
|
|
||||||
//$$ import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Filters out all handshake packets that were sent for recording but must
|
|
||||||
//$$ * not actually be handled.
|
|
||||||
//$$ * This handler is only present when connected to the integrated server as
|
|
||||||
//$$ * otherwise all packets must be handled.
|
|
||||||
//$$ *
|
|
||||||
//$$ * When in single player, the game state packets must never be handled
|
|
||||||
//$$ * otherwise wired bugs related to semi-singletons can occur.
|
|
||||||
//$$ * See https://bugs.replaymod.com/show_bug.cgi?id=44
|
|
||||||
//$$ */
|
|
||||||
//$$ public class FMLHandshakeFilter extends SimpleChannelInboundHandler<FMLHandshakeMessage> {
|
|
||||||
//$$ @Override
|
|
||||||
//$$ protected void channelRead0(ChannelHandlerContext ctx, FMLHandshakeMessage msg) throws Exception {
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ if (!(msg instanceof FMLHandshakeMessage.RegistryData)) {
|
|
||||||
//#else
|
|
||||||
//$$ if (!(msg instanceof FMLHandshakeMessage.ModIdData)) {
|
|
||||||
//#endif
|
|
||||||
//$$ // Pass on everything but RegistryData messages
|
|
||||||
//$$ ctx.fireChannelRead(msg);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -14,23 +14,13 @@ import de.johni0702.minecraft.gui.element.GuiToggleButton;
|
|||||||
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
import de.johni0702.minecraft.gui.layout.CustomLayout;
|
||||||
import de.johni0702.minecraft.gui.popup.GuiInfoPopup;
|
import de.johni0702.minecraft.gui.popup.GuiInfoPopup;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
||||||
import net.minecraft.client.gui.screen.AddServerScreen;
|
import net.minecraft.client.gui.screen.AddServerScreen;
|
||||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||||
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
|
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
|
||||||
import net.minecraft.client.network.ServerInfo;
|
import net.minecraft.client.network.ServerInfo;
|
||||||
import net.minecraft.client.resource.language.I18n;
|
import net.minecraft.client.resource.language.I18n;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.getGui;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public class GuiHandler extends EventRegistrations {
|
public class GuiHandler extends EventRegistrations {
|
||||||
|
|
||||||
private final ReplayMod mod;
|
private final ReplayMod mod;
|
||||||
@@ -39,14 +29,8 @@ public class GuiHandler extends EventRegistrations {
|
|||||||
this.mod = mod;
|
this.mod = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(InitScreenCallback.EVENT, (screen, buttons) -> onGuiInit(screen)); }
|
{ on(InitScreenCallback.EVENT, (screen, buttons) -> onGuiInit(screen)); }
|
||||||
private void onGuiInit(Screen gui) {
|
private void onGuiInit(net.minecraft.client.gui.screen.Screen gui) {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onGuiInit(GuiScreenEvent.InitGuiEvent.Post event) {
|
|
||||||
//$$ net.minecraft.client.gui.screen.Screen gui = getGui(event);
|
|
||||||
//#endif
|
|
||||||
if (gui instanceof SelectWorldScreen || gui instanceof MultiplayerScreen) {
|
if (gui instanceof SelectWorldScreen || gui instanceof MultiplayerScreen) {
|
||||||
boolean sp = gui instanceof SelectWorldScreen;
|
boolean sp = gui instanceof SelectWorldScreen;
|
||||||
SettingsRegistry settingsRegistry = mod.getSettingsRegistry();
|
SettingsRegistry settingsRegistry = mod.getSettingsRegistry();
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.replaymod.recording.handler;
|
package com.replaymod.recording.handler;
|
||||||
|
|
||||||
|
import com.replaymod.core.events.PreRenderCallback;
|
||||||
import com.replaymod.recording.mixin.IntegratedServerAccessor;
|
import com.replaymod.recording.mixin.IntegratedServerAccessor;
|
||||||
import com.replaymod.recording.packet.PacketListener;
|
import com.replaymod.recording.packet.PacketListener;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
|
import de.johni0702.minecraft.gui.versions.callbacks.PreTickCallback;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.network.packet.s2c.play.BlockBreakingProgressS2CPacket;
|
import net.minecraft.network.packet.s2c.play.BlockBreakingProgressS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.EntityAttachS2CPacket;
|
import net.minecraft.network.packet.s2c.play.EntityAttachS2CPacket;
|
||||||
@@ -20,15 +23,11 @@ import net.minecraft.network.Packet;
|
|||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
// FIXME not (yet?) 1.13 import net.minecraftforge.event.entity.minecart.MinecartInteractEvent;
|
// FIXME not (yet?) 1.13 import net.minecraftforge.event.entity.minecart.MinecartInteractEvent;
|
||||||
|
|
||||||
//#if FABRIC>=1
|
//#if FABRIC<1
|
||||||
import com.replaymod.core.events.PreRenderCallback;
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.PreTickCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.network.play.server.SCollectItemPacket;
|
//$$ import net.minecraft.network.play.server.SCollectItemPacket;
|
||||||
//$$ import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent;
|
//$$ import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent;
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
//$$ import net.minecraftforge.event.entity.player.PlayerEvent.ItemPickupEvent;
|
//$$ import net.minecraftforge.event.entity.player.PlayerEvent.ItemPickupEvent;
|
||||||
//$$ import net.minecraftforge.event.TickEvent;
|
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if MC>=11600
|
//#if MC>=11600
|
||||||
@@ -139,24 +138,18 @@ public class RecordingEventHandler extends EventRegistrations {
|
|||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(PreTickCallback.EVENT, this::onPlayerTick); }
|
{ on(PreTickCallback.EVENT, this::onPlayerTick); }
|
||||||
private void onPlayerTick() {
|
private void onPlayerTick() {
|
||||||
if (mc.player == null) return;
|
if (mc.player == null) return;
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onPlayerTick(TickEvent.ClientTickEvent e) {
|
|
||||||
//$$ if(e.phase != TickEvent.Phase.START || mc.player == null) return;
|
|
||||||
//#endif
|
|
||||||
ClientPlayerEntity player = mc.player;
|
ClientPlayerEntity player = mc.player;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
boolean force = false;
|
boolean force = false;
|
||||||
if(lastX == null || lastY == null || lastZ == null) {
|
if(lastX == null || lastY == null || lastZ == null) {
|
||||||
force = true;
|
force = true;
|
||||||
lastX = Entity_getX(player);
|
lastX = player.getX();
|
||||||
lastY = Entity_getY(player);
|
lastY = player.getY();
|
||||||
lastZ = Entity_getZ(player);
|
lastZ = player.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
ticksSinceLastCorrection++;
|
ticksSinceLastCorrection++;
|
||||||
@@ -165,13 +158,13 @@ public class RecordingEventHandler extends EventRegistrations {
|
|||||||
force = true;
|
force = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double dx = Entity_getX(player) - lastX;
|
double dx = player.getX() - lastX;
|
||||||
double dy = Entity_getY(player) - lastY;
|
double dy = player.getY() - lastY;
|
||||||
double dz = Entity_getZ(player) - lastZ;
|
double dz = player.getZ() - lastZ;
|
||||||
|
|
||||||
lastX = Entity_getX(player);
|
lastX = player.getX();
|
||||||
lastY = Entity_getY(player);
|
lastY = player.getY();
|
||||||
lastZ = Entity_getZ(player);
|
lastZ = player.getZ();
|
||||||
|
|
||||||
Packet packet;
|
Packet packet;
|
||||||
if (force || Math.abs(dx) > 8.0 || Math.abs(dy) > 8.0 || Math.abs(dz) > 8.0) {
|
if (force || Math.abs(dx) > 8.0 || Math.abs(dy) > 8.0 || Math.abs(dz) > 8.0) {
|
||||||
@@ -317,18 +310,16 @@ public class RecordingEventHandler extends EventRegistrations {
|
|||||||
|
|
||||||
//Leaving Ride
|
//Leaving Ride
|
||||||
|
|
||||||
if((!player.isRiding() && lastRiding != -1) ||
|
Entity vehicle = player.getVehicle();
|
||||||
(player.isRiding() && lastRiding != getRiddenEntity(player).getEntityId())) {
|
int vehicleId = vehicle == null ? -1 : vehicle.getEntityId();
|
||||||
if(!player.isRiding()) {
|
if (lastRiding != vehicleId) {
|
||||||
lastRiding = -1;
|
lastRiding = vehicleId;
|
||||||
} else {
|
|
||||||
lastRiding = getRiddenEntity(player).getEntityId();
|
|
||||||
}
|
|
||||||
packetListener.save(new EntityAttachS2CPacket(
|
packetListener.save(new EntityAttachS2CPacket(
|
||||||
//#if MC<10904
|
//#if MC<10904
|
||||||
//$$ 0,
|
//$$ 0,
|
||||||
//#endif
|
//#endif
|
||||||
player, getRiddenEntity(player)
|
player,
|
||||||
|
vehicle
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,14 +456,8 @@ public class RecordingEventHandler extends EventRegistrations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(PreRenderCallback.EVENT, this::checkForGamePaused); }
|
{ on(PreRenderCallback.EVENT, this::checkForGamePaused); }
|
||||||
private void checkForGamePaused() {
|
private void checkForGamePaused() {
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void checkForGamePaused(TickEvent.RenderTickEvent event) {
|
|
||||||
//$$ if (event.phase != TickEvent.Phase.START) return;
|
|
||||||
//#endif
|
|
||||||
if (mc.isIntegratedServerRunning()) {
|
if (mc.isIntegratedServerRunning()) {
|
||||||
IntegratedServer server = mc.getServer();
|
IntegratedServer server = mc.getServer();
|
||||||
if (server != null && ((IntegratedServerAccessor) server).isGamePaused()) {
|
if (server != null && ((IntegratedServerAccessor) server).isGamePaused()) {
|
||||||
|
|||||||
@@ -1,45 +1 @@
|
|||||||
//#if MC<=10710
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.recording.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
|
||||||
//$$ import net.minecraft.client.gui.GuiScreen;
|
|
||||||
//$$ import org.lwjgl.input.Keyboard;
|
|
||||||
//$$ import org.lwjgl.input.Mouse;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
//$$
|
|
||||||
//$$ @Mixin(GuiScreen.class)
|
|
||||||
//$$ public abstract class MixinGuiScreen {
|
|
||||||
//$$
|
|
||||||
//$$ @Inject(method = "handleInput", at = @At("HEAD"), cancellable = true)
|
|
||||||
//$$ private void handleJGuiInput(CallbackInfo ci) {
|
|
||||||
//$$ ci.cancel();
|
|
||||||
//$$ if (Mouse.isCreated()) {
|
|
||||||
//$$ while (Mouse.next()) {
|
|
||||||
//$$ if (FORGE_BUS.post(new VanillaGuiScreen.MouseInputEvent())) {
|
|
||||||
//$$ continue;
|
|
||||||
//$$ }
|
|
||||||
//$$ handleMouseInput();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ if (Keyboard.isCreated()) {
|
|
||||||
//$$ while (Keyboard.next()) {
|
|
||||||
//$$ if (FORGE_BUS.post(new VanillaGuiScreen.KeyboardInputEvent())) {
|
|
||||||
//$$ continue;
|
|
||||||
//$$ }
|
|
||||||
//$$ handleKeyboardInput();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow public abstract void handleMouseInput();
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow public abstract void handleKeyboardInput();
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,35 +1,26 @@
|
|||||||
package com.replaymod.recording.mixin;
|
package com.replaymod.recording.mixin;
|
||||||
|
|
||||||
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.recording.ReplayModRecording;
|
import com.replaymod.recording.ReplayModRecording;
|
||||||
|
import com.replaymod.recording.handler.RecordingEventHandler.RecordingEventSender;
|
||||||
import net.minecraft.client.network.ClientLoginNetworkHandler;
|
import net.minecraft.client.network.ClientLoginNetworkHandler;
|
||||||
import net.minecraft.network.ClientConnection;
|
import net.minecraft.network.ClientConnection;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.packet.s2c.login.LoginQueryRequestS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.login.LoginSuccessS2CPacket;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import com.replaymod.core.versions.MCVer;
|
|
||||||
import com.replaymod.recording.handler.RecordingEventHandler.RecordingEventSender;
|
|
||||||
import net.minecraft.network.Packet;
|
|
||||||
import net.minecraft.network.packet.s2c.login.LoginQueryRequestS2CPacket;
|
|
||||||
import net.minecraft.network.packet.s2c.login.LoginSuccessS2CPacket;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.fml.common.network.FMLNetworkEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
@Mixin(ClientLoginNetworkHandler.class)
|
@Mixin(ClientLoginNetworkHandler.class)
|
||||||
public abstract class MixinNetHandlerLoginClient {
|
public abstract class MixinNetHandlerLoginClient {
|
||||||
|
|
||||||
@Shadow
|
@Final @Shadow
|
||||||
//#if MC>=10800
|
|
||||||
private ClientConnection connection;
|
private ClientConnection connection;
|
||||||
//#else
|
|
||||||
//$$ private NetworkManager field_147393_d;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
@Inject(method = "onQueryRequest", at=@At("HEAD"))
|
@Inject(method = "onQueryRequest", at=@At("HEAD"))
|
||||||
private void earlyInitiateRecording(LoginQueryRequestS2CPacket packet, CallbackInfo ci) {
|
private void earlyInitiateRecording(LoginQueryRequestS2CPacket packet, CallbackInfo ci) {
|
||||||
initiateRecording(packet);
|
initiateRecording(packet);
|
||||||
@@ -50,27 +41,4 @@ public abstract class MixinNetHandlerLoginClient {
|
|||||||
eventSender.getRecordingEventHandler().onPacket(packet);
|
eventSender.getRecordingEventHandler().onPacket(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#else
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Starts the recording right before switching into PLAY state.
|
|
||||||
//$$ * We cannot use the {@link FMLNetworkEvent.ClientConnectedToServerEvent}
|
|
||||||
//$$ * as it only fires after the forge handshake.
|
|
||||||
//$$ */
|
|
||||||
//$$ @Inject(method = "handleLoginSuccess", at=@At("HEAD"))
|
|
||||||
//$$ public void replayModRecording_initiateRecording(CallbackInfo cb) {
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ ReplayModRecording.instance.initiateRecording(this.networkManager);
|
|
||||||
//#else
|
|
||||||
//$$ ReplayModRecording.instance.initiateRecording(this.field_147393_d);
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// Race condition in Forge's networking (not sure if still present in 1.13)
|
|
||||||
//#if MC>=11200 && MC<11400
|
|
||||||
//$$ @Inject(method = "handleLoginSuccess", at=@At("RETURN"))
|
|
||||||
//$$ public void replayModRecording_raceConditionWorkAround(CallbackInfo cb) {
|
|
||||||
//$$ ((NetworkManagerAccessor) this.networkManager).getChannel().config().setAutoRead(true);
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public abstract class MixinNetHandlerPlayClient {
|
|||||||
//$$ @Inject(method = "handlePlayerListItem", at=@At("HEAD"))
|
//$$ @Inject(method = "handlePlayerListItem", at=@At("HEAD"))
|
||||||
//#endif
|
//#endif
|
||||||
public void recordOwnJoin(PlayerListS2CPacket packet, CallbackInfo ci) {
|
public void recordOwnJoin(PlayerListS2CPacket packet, CallbackInfo ci) {
|
||||||
if (!MCVer.isOnMainThread()) return;
|
if (!mcStatic.isOnThread()) return;
|
||||||
if (mcStatic.player == null) return;
|
if (mcStatic.player == null) return;
|
||||||
|
|
||||||
RecordingEventHandler handler = getRecordingEventHandler();
|
RecordingEventHandler handler = getRecordingEventHandler();
|
||||||
|
|||||||
@@ -1,70 +1 @@
|
|||||||
//#if MC<11400
|
// 1.12.2 and below
|
||||||
//$$ package com.replaymod.recording.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import com.replaymod.recording.handler.FMLHandshakeFilter;
|
|
||||||
//$$ import io.netty.channel.ChannelPipeline;
|
|
||||||
//$$ import io.netty.channel.embedded.EmbeddedChannel;
|
|
||||||
//$$ import net.minecraftforge.fml.common.network.handshake.FMLHandshakeCodec;
|
|
||||||
//$$ import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
|
||||||
//$$ import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
//$$
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ import io.netty.channel.ChannelConfig;
|
|
||||||
//$$ import net.minecraft.network.EnumConnectionState;
|
|
||||||
//$$ import net.minecraft.network.NetworkManager;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
//#endif
|
|
||||||
//$$
|
|
||||||
//$$ @Mixin(value = NetworkDispatcher.class, remap = false)
|
|
||||||
//$$ public abstract class MixinNetworkDispatcher {
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow
|
|
||||||
//$$ private Side side;
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow
|
|
||||||
//$$ private EmbeddedChannel handshakeChannel;
|
|
||||||
//$$
|
|
||||||
//$$ /**
|
|
||||||
//$$ * Always sets fml:isLocal to false on the server side.
|
|
||||||
//$$ * This effectively removes the difference in the FML handshake between SP and MP
|
|
||||||
//$$ * and forces the block/item ids, etc. to always be send.
|
|
||||||
//$$ * Injects a {@link FMLHandshakeFilter} on the client side to filter out
|
|
||||||
//$$ * those extra, unexpected packets.
|
|
||||||
//$$ */
|
|
||||||
//$$ @Inject(method = "insertIntoChannel", at=@At("HEAD"))
|
|
||||||
//$$ public void replayModRecording_setupForLocalRecording(CallbackInfo cb) {
|
|
||||||
//$$ // If we're in multiplayer, everything is fine as is
|
|
||||||
//$$ if (!handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).get()) return;
|
|
||||||
//$$
|
|
||||||
//$$ if (side == Side.SERVER) {
|
|
||||||
//$$ // On the server side, force all packets to be sent
|
|
||||||
//$$ handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).set(false);
|
|
||||||
//$$ } else {
|
|
||||||
//$$ // On the client side, discard additional packets
|
|
||||||
//$$ ChannelPipeline pipeline = handshakeChannel.pipeline();
|
|
||||||
//$$ pipeline.addAfter(pipeline.context(FMLHandshakeCodec.class).name(),
|
|
||||||
//$$ "replaymod_filter", new FMLHandshakeFilter());
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//#if MC>=11200
|
|
||||||
//$$ @Redirect(method = "clientListenForServerHandshake", at = @At(value = "INVOKE", remap = true, target =
|
|
||||||
//$$ "Lnet/minecraft/network/NetworkManager;setConnectionState(Lnet/minecraft/network/EnumConnectionState;)V"))
|
|
||||||
//$$ public void replayModRecording_raceConditionWorkAround1(NetworkManager self, EnumConnectionState ignored) { }
|
|
||||||
//$$
|
|
||||||
//$$ @Redirect(method = "insertIntoChannel", at = @At(value = "INVOKE", target =
|
|
||||||
//$$ "Lio/netty/channel/ChannelConfig;setAutoRead(Z)Lio/netty/channel/ChannelConfig;"))
|
|
||||||
//$$ public ChannelConfig replayModRecording_raceConditionWorkAround2(ChannelConfig self, boolean autoRead) {
|
|
||||||
//$$ if (side == Side.CLIENT) {
|
|
||||||
//$$ autoRead = false;
|
|
||||||
//$$ }
|
|
||||||
//$$ return self.setAutoRead(autoRead);
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,32 +1 @@
|
|||||||
package com.replaymod.recording.mixin;
|
// 1.9.4 - 1.12.2
|
||||||
|
|
||||||
//#if MC>=10904 && MC<11400
|
|
||||||
//$$ import com.replaymod.recording.handler.RecordingEventHandler;
|
|
||||||
//$$ import net.minecraft.client.Minecraft;
|
|
||||||
//$$ import net.minecraft.client.multiplayer.PlayerControllerMP;
|
|
||||||
//$$ import net.minecraft.util.math.BlockPos;
|
|
||||||
//$$ import net.minecraft.world.World;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
//$$
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
//$$
|
|
||||||
//$$ @Mixin(PlayerControllerMP.class)
|
|
||||||
//$$ public abstract class MixinPlayerControllerMP implements RecordingEventHandler.RecordingEventSender {
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow
|
|
||||||
//$$ private Minecraft mc;
|
|
||||||
//$$
|
|
||||||
//$$ // Redirects the call to playEvent without the initial player argument to the method with that argument
|
|
||||||
//$$ // The new method will then play it and (if applicable) record it. (See MixinWorldClient)
|
|
||||||
//$$ // This is necessary for the block break event (particles and sound) to be recorded. Otherwise it looks like the
|
|
||||||
//$$ // event was emitted because of a packet (player will be null) and not as it actually was (by the player).
|
|
||||||
//$$ @Redirect(method = "onPlayerDestroyBlock", at = @At(value = "INVOKE",
|
|
||||||
//$$ target = "Lnet/minecraft/world/World;playEvent(ILnet/minecraft/util/math/BlockPos;I)V"))
|
|
||||||
//$$ public void replayModRecording_playEvent_fixed(World world, int type, BlockPos pos, int data) {
|
|
||||||
//$$ world.playEvent(mc.player, type, pos, data);
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -1,38 +1 @@
|
|||||||
//#if MC<=10710
|
// 1.7.10 and below
|
||||||
//$$ package com.replaymod.recording.mixin;
|
|
||||||
//$$
|
|
||||||
//$$ import net.minecraft.network.PacketBuffer;
|
|
||||||
//$$ import net.minecraft.network.play.server.S21PacketChunkData;
|
|
||||||
//$$ import net.minecraft.network.play.server.S26PacketMapChunkBulk;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
//$$ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
//$$
|
|
||||||
//$$ import java.util.concurrent.Semaphore;
|
|
||||||
//$$
|
|
||||||
//$$ @Mixin({ S21PacketChunkData.class, S26PacketMapChunkBulk.class })
|
|
||||||
//$$ public abstract class MixinS26PacketMapChunkBulk {
|
|
||||||
//$$
|
|
||||||
//$$ private byte[] rawData;
|
|
||||||
//$$
|
|
||||||
//$$ @Shadow(remap = false)
|
|
||||||
//$$ private Semaphore deflateGate;
|
|
||||||
//$$
|
|
||||||
//$$ @Inject(method = "readPacketData", at = @At("HEAD"))
|
|
||||||
//$$ private void replayModRecording_readRawPacketData(PacketBuffer data, CallbackInfo ci) {
|
|
||||||
//$$ int readerIndex = data.readerIndex();
|
|
||||||
//$$ data.readBytes(rawData = new byte[data.readableBytes()]);
|
|
||||||
//$$ data.readerIndex(readerIndex);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Inject(method = "writePacketData", at = @At("HEAD"), cancellable = true)
|
|
||||||
//$$ private void replayModRecording_writePacketData(PacketBuffer data, CallbackInfo ci) {
|
|
||||||
//$$ if (rawData != null && deflateGate == null) {
|
|
||||||
//$$ data.writeBytes(rawData);
|
|
||||||
//$$ ci.cancel();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import com.replaymod.replaystudio.data.Marker;
|
|||||||
import com.replaymod.replaystudio.io.ReplayOutputStream;
|
import com.replaymod.replaystudio.io.ReplayOutputStream;
|
||||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
|
||||||
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
import de.johni0702.minecraft.gui.container.VanillaGuiScreen;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.DisconnectS2CPacket;
|
import net.minecraft.network.packet.s2c.play.DisconnectS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.ItemPickupAnimationS2CPacket;
|
import net.minecraft.network.packet.s2c.play.ItemPickupAnimationS2CPacket;
|
||||||
@@ -40,6 +40,7 @@ import net.minecraft.network.PacketByteBuf;
|
|||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@@ -163,8 +164,8 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
|||||||
// to happen on the main thread so we can guarantee correct ordering of inbound and inject packets.
|
// to happen on the main thread so we can guarantee correct ordering of inbound and inject packets.
|
||||||
// Otherwise, injected packets may end up further down the packet stream than they were supposed to and other
|
// Otherwise, injected packets may end up further down the packet stream than they were supposed to and other
|
||||||
// inbound packets which may rely on the injected packet would behave incorrectly when played back.
|
// inbound packets which may rely on the injected packet would behave incorrectly when played back.
|
||||||
if (!MCVer.isOnMainThread()) {
|
if (!mc.isOnThread()) {
|
||||||
MCVer.scheduleOnMainThread(() -> save(packet));
|
mc.send(() -> save(packet));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -295,7 +296,7 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
|||||||
if (core.getSettingsRegistry().get(Setting.AUTO_POST_PROCESS) && !ReplayMod.isMinimalMode()) {
|
if (core.getSettingsRegistry().get(Setting.AUTO_POST_PROCESS) && !ReplayMod.isMinimalMode()) {
|
||||||
outputPaths = MarkerProcessor.apply(outputPath, guiSavingReplay.getProgressBar()::setProgress);
|
outputPaths = MarkerProcessor.apply(outputPath, guiSavingReplay.getProgressBar()::setProgress);
|
||||||
} else {
|
} else {
|
||||||
outputPaths = Collections.singletonList(new Pair<>(outputPath, metaData));
|
outputPaths = Collections.singletonList(Pair.of(outputPath, metaData));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Saving replay file:", e);
|
logger.error("Saving replay file:", e);
|
||||||
@@ -339,7 +340,8 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
//#if MC>=10800
|
//#if MC>=10800
|
||||||
if (packet instanceof ResourcePackSendS2CPacket) {
|
if (packet instanceof ResourcePackSendS2CPacket) {
|
||||||
save(resourcePackRecorder.handleResourcePack((ResourcePackSendS2CPacket) packet));
|
ClientConnection connection = ctx.pipeline().get(ClientConnection.class);
|
||||||
|
save(resourcePackRecorder.handleResourcePack(connection, (ResourcePackSendS2CPacket) packet));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//#else
|
//#else
|
||||||
@@ -488,15 +490,15 @@ public class PacketListener extends ChannelInboundHandlerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addMarker(String name, int timestamp) {
|
public void addMarker(String name, int timestamp) {
|
||||||
Entity view = getRenderViewEntity(mc);
|
Entity view = mc.getCameraEntity();
|
||||||
|
|
||||||
Marker marker = new Marker();
|
Marker marker = new Marker();
|
||||||
marker.setName(name);
|
marker.setName(name);
|
||||||
marker.setTime(timestamp);
|
marker.setTime(timestamp);
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
marker.setX(Entity_getX(view));
|
marker.setX(view.getX());
|
||||||
marker.setY(Entity_getY(view));
|
marker.setY(view.getY());
|
||||||
marker.setZ(Entity_getZ(view));
|
marker.setZ(view.getZ());
|
||||||
marker.setYaw(view.yaw);
|
marker.setYaw(view.yaw);
|
||||||
marker.setPitch(view.pitch);
|
marker.setPitch(view.pitch);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
//#else
|
//#else
|
||||||
//$$ import com.google.common.util.concurrent.ListenableFuture;
|
//$$ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
//#endif
|
//#endif
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
|
||||||
import net.minecraft.network.ClientConnection;
|
import net.minecraft.network.ClientConnection;
|
||||||
//#else
|
//#else
|
||||||
//$$ import com.replaymod.core.mixin.ResourcePackRepositoryAccessor;
|
//$$ import com.replaymod.core.mixin.ResourcePackRepositoryAccessor;
|
||||||
@@ -111,10 +110,8 @@ public class ResourcePackRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized ResourcePackSendS2CPacket handleResourcePack(ResourcePackSendS2CPacket packet) {
|
public synchronized ResourcePackSendS2CPacket handleResourcePack(ClientConnection netManager, ResourcePackSendS2CPacket packet) {
|
||||||
final int requestId = nextRequestId++;
|
final int requestId = nextRequestId++;
|
||||||
final ClientPlayNetworkHandler netHandler = mc.getNetworkHandler();
|
|
||||||
final ClientConnection netManager = netHandler.getConnection();
|
|
||||||
final String url = packet.getURL();
|
final String url = packet.getURL();
|
||||||
final String hash = packet.getSHA1();
|
final String hash = packet.getSHA1();
|
||||||
|
|
||||||
@@ -138,7 +135,7 @@ public class ResourcePackRecorder {
|
|||||||
final ServerInfo serverData = mc.getCurrentServerEntry();
|
final ServerInfo serverData = mc.getCurrentServerEntry();
|
||||||
if (serverData != null && serverData.getResourcePack() == ServerInfo.ResourcePackState.ENABLED) {
|
if (serverData != null && serverData.getResourcePack() == ServerInfo.ResourcePackState.ENABLED) {
|
||||||
netManager.send(makeStatusPacket(hash, Status.ACCEPTED));
|
netManager.send(makeStatusPacket(hash, Status.ACCEPTED));
|
||||||
downloadResourcePackFuture(requestId, url, hash);
|
downloadResourcePackFuture(netManager, requestId, url, hash);
|
||||||
} else if (serverData != null && serverData.getResourcePack() != ServerInfo.ResourcePackState.PROMPT) {
|
} else if (serverData != null && serverData.getResourcePack() != ServerInfo.ResourcePackState.PROMPT) {
|
||||||
netManager.send(makeStatusPacket(hash, Status.DECLINED));
|
netManager.send(makeStatusPacket(hash, Status.DECLINED));
|
||||||
} else {
|
} else {
|
||||||
@@ -156,7 +153,7 @@ public class ResourcePackRecorder {
|
|||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
netManager.send(makeStatusPacket(hash, Status.ACCEPTED));
|
netManager.send(makeStatusPacket(hash, Status.ACCEPTED));
|
||||||
downloadResourcePackFuture(requestId, url, hash);
|
downloadResourcePackFuture(netManager, requestId, url, hash);
|
||||||
} else {
|
} else {
|
||||||
netManager.send(makeStatusPacket(hash, Status.DECLINED));
|
netManager.send(makeStatusPacket(hash, Status.DECLINED));
|
||||||
}
|
}
|
||||||
@@ -172,13 +169,18 @@ public class ResourcePackRecorder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResourcePackSendS2CPacket("replay://" + requestId, "");
|
return new ResourcePackSendS2CPacket(
|
||||||
|
"replay://" + requestId, ""
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ , packet.isRequired(), packet.getPrompt()
|
||||||
|
//#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadResourcePackFuture(int requestId, String url, final String hash) {
|
private void downloadResourcePackFuture(ClientConnection connection, int requestId, String url, final String hash) {
|
||||||
addCallback(downloadResourcePack(requestId, url, hash),
|
addCallback(downloadResourcePack(requestId, url, hash),
|
||||||
result -> mc.getNetworkHandler().sendPacket(makeStatusPacket(hash, Status.SUCCESSFULLY_LOADED)),
|
result -> connection.send(makeStatusPacket(hash, Status.SUCCESSFULLY_LOADED)),
|
||||||
throwable -> mc.getNetworkHandler().sendPacket(makeStatusPacket(hash, Status.FAILED_DOWNLOAD)));
|
throwable -> connection.send(makeStatusPacket(hash, Status.FAILED_DOWNLOAD)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -190,7 +192,11 @@ public class ResourcePackRecorder {
|
|||||||
downloadResourcePack(final int requestId, String url, String hash) {
|
downloadResourcePack(final int requestId, String url, String hash) {
|
||||||
ClientBuiltinResourcePackProvider packFinder = mc.getResourcePackDownloader();
|
ClientBuiltinResourcePackProvider packFinder = mc.getResourcePackDownloader();
|
||||||
((IDownloadingPackFinder) packFinder).setRequestCallback(file -> recordResourcePack(file, requestId));
|
((IDownloadingPackFinder) packFinder).setRequestCallback(file -> recordResourcePack(file, requestId));
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ return packFinder.download(url, hash, true);
|
||||||
|
//#else
|
||||||
return packFinder.download(url, hash);
|
return packFinder.download(url, hash);
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IDownloadingPackFinder {
|
public interface IDownloadingPackFinder {
|
||||||
|
|||||||
@@ -126,8 +126,8 @@ public class FFmpegWriter implements FrameConsumer<BitmapFrame> {
|
|||||||
}
|
}
|
||||||
CrashReport report = CrashReport.create(t, "Exporting frame");
|
CrashReport report = CrashReport.create(t, "Exporting frame");
|
||||||
CrashReportSection exportDetails = report.addElement("Export details");
|
CrashReportSection exportDetails = report.addElement("Export details");
|
||||||
MCVer.addDetail(exportDetails, "Export command", settings::getExportCommand);
|
exportDetails.add("Export command", settings::getExportCommand);
|
||||||
MCVer.addDetail(exportDetails, "Export args", commandArgs::toString);
|
exportDetails.add("Export args", commandArgs::toString);
|
||||||
MCVer.getMinecraft().setCrashReport(report);
|
MCVer.getMinecraft().setCrashReport(report);
|
||||||
} finally {
|
} finally {
|
||||||
channels.values().forEach(it -> ByteBufferPool.release(it.getByteBuffer()));
|
channels.values().forEach(it -> ByteBufferPool.release(it.getByteBuffer()));
|
||||||
|
|||||||
71
src/main/java/com/replaymod/render/PNGWriter.java
Normal file
71
src/main/java/com/replaymod/render/PNGWriter.java
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package com.replaymod.render;
|
||||||
|
|
||||||
|
import com.replaymod.core.versions.MCVer;
|
||||||
|
import com.replaymod.render.blend.Util.IOConsumer;
|
||||||
|
import com.replaymod.render.frame.BitmapFrame;
|
||||||
|
import com.replaymod.render.rendering.Channel;
|
||||||
|
import com.replaymod.render.rendering.FrameConsumer;
|
||||||
|
import com.replaymod.render.utils.ByteBufferPool;
|
||||||
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
|
import de.johni0702.minecraft.gui.versions.Image;
|
||||||
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PNGWriter implements FrameConsumer<BitmapFrame> {
|
||||||
|
|
||||||
|
private final Path outputFolder;
|
||||||
|
|
||||||
|
public PNGWriter(Path outputFolder) throws IOException {
|
||||||
|
this.outputFolder = outputFolder;
|
||||||
|
|
||||||
|
Files.createDirectories(outputFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consume(Map<Channel, BitmapFrame> channels) {
|
||||||
|
BitmapFrame bgraFrame = channels.get(Channel.BRGA);
|
||||||
|
BitmapFrame depthFrame = channels.get(Channel.DEPTH);
|
||||||
|
try {
|
||||||
|
if (bgraFrame != null) {
|
||||||
|
withImage(bgraFrame, image ->
|
||||||
|
image.writePNG(outputFolder.resolve(bgraFrame.getFrameId() + ".png").toFile()));
|
||||||
|
}
|
||||||
|
if (depthFrame != null) {
|
||||||
|
withImage(depthFrame, image ->
|
||||||
|
image.writePNG(outputFolder.resolve(depthFrame.getFrameId() + ".depth.png").toFile()));
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
MCVer.getMinecraft().setCrashReport(CrashReport.create(t, "Exporting EXR frame"));
|
||||||
|
} finally {
|
||||||
|
channels.values().forEach(it -> ByteBufferPool.release(it.getByteBuffer()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void withImage(BitmapFrame frame, IOConsumer<Image> consumer) throws IOException {
|
||||||
|
ByteBuffer buffer = frame.getByteBuffer();
|
||||||
|
ReadableDimension size = frame.getSize();
|
||||||
|
int width = size.getWidth();
|
||||||
|
int height = size.getHeight();
|
||||||
|
try (Image image = new Image(width, height)) {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
byte b = buffer.get();
|
||||||
|
byte g = buffer.get();
|
||||||
|
byte r = buffer.get();
|
||||||
|
byte a = buffer.get();
|
||||||
|
image.setRGBA(x, y, r, g, b, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consumer.accept(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.replaymod.render;
|
package com.replaymod.render;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.JsonAdapter;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import com.replaymod.core.utils.FileTypeAdapter;
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableColor;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableColor;
|
||||||
import net.minecraft.client.resource.language.I18n;
|
import net.minecraft.client.resource.language.I18n;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
|
import org.apache.maven.artifact.versioning.ComparableVersion;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -19,16 +22,6 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import static com.replaymod.render.ReplayModRender.LOGGER;
|
import static com.replaymod.render.ReplayModRender.LOGGER;
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import org.apache.maven.artifact.versioning.ComparableVersion;
|
|
||||||
//#else
|
|
||||||
//#if MC>=10800
|
|
||||||
//$$ import net.minecraftforge.fml.common.versioning.ComparableVersion;
|
|
||||||
//#else
|
|
||||||
//$$ import cpw.mods.fml.common.versioning.ComparableVersion;
|
|
||||||
//#endif
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
public class RenderSettings {
|
public class RenderSettings {
|
||||||
public enum RenderMethod {
|
public enum RenderMethod {
|
||||||
DEFAULT, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
DEFAULT, STEREOSCOPIC, CUBIC, EQUIRECTANGULAR, ODS, BLEND;
|
||||||
@@ -69,8 +62,6 @@ public class RenderSettings {
|
|||||||
public enum EncodingPreset {
|
public enum EncodingPreset {
|
||||||
MP4_CUSTOM("-an -c:v libx264 -b:v %BITRATE% -pix_fmt yuv420p \"%FILENAME%\"", "mp4"),
|
MP4_CUSTOM("-an -c:v libx264 -b:v %BITRATE% -pix_fmt yuv420p \"%FILENAME%\"", "mp4"),
|
||||||
|
|
||||||
MP4_DEFAULT("-an -c:v libx264 -preset ultrafast -pix_fmt yuv420p \"%FILENAME%\"", "mp4"),
|
|
||||||
|
|
||||||
MP4_POTATO("-an -c:v libx264 -preset ultrafast -crf 51 -pix_fmt yuv420p \"%FILENAME%\"", "mp4"),
|
MP4_POTATO("-an -c:v libx264 -preset ultrafast -crf 51 -pix_fmt yuv420p \"%FILENAME%\"", "mp4"),
|
||||||
|
|
||||||
WEBM_CUSTOM("-an -c:v libvpx -b:v %BITRATE% -pix_fmt yuv420p \"%FILENAME%\"", "webm"),
|
WEBM_CUSTOM("-an -c:v libvpx -b:v %BITRATE% -pix_fmt yuv420p \"%FILENAME%\"", "webm"),
|
||||||
@@ -81,7 +72,7 @@ public class RenderSettings {
|
|||||||
|
|
||||||
EXR(null, "exr"),
|
EXR(null, "exr"),
|
||||||
|
|
||||||
PNG("\"%FILENAME%-%06d.png\"", "png");
|
PNG(null, "png");
|
||||||
|
|
||||||
private final String preset;
|
private final String preset;
|
||||||
private final String fileExtension;
|
private final String fileExtension;
|
||||||
@@ -155,6 +146,7 @@ public class RenderSettings {
|
|||||||
private final int videoHeight;
|
private final int videoHeight;
|
||||||
private final int framesPerSecond;
|
private final int framesPerSecond;
|
||||||
private final int bitRate;
|
private final int bitRate;
|
||||||
|
@JsonAdapter(FileTypeAdapter.class)
|
||||||
private final File outputFile;
|
private final File outputFile;
|
||||||
|
|
||||||
private final boolean renderNameTags;
|
private final boolean renderNameTags;
|
||||||
@@ -342,9 +334,13 @@ public class RenderSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Homebrew doesn't seem to reliably symlink its installed binaries either
|
// Homebrew doesn't seem to reliably symlink its installed binaries either
|
||||||
File homebrewFolder = new File("/usr/local/Cellar/ffmpeg");
|
// and there's multiple locations for where Homebrew is.
|
||||||
String[] homebrewVersions = homebrewFolder.list();
|
for (String path : new String[]{"/usr/local", "/opt/homebrew"}) {
|
||||||
if (homebrewVersions != null) {
|
File homebrewFolder = new File(path + "/Cellar/ffmpeg");
|
||||||
|
String[] homebrewVersions = homebrewFolder.list();
|
||||||
|
if (homebrewVersions == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Optional<File> latestOpt = Arrays.stream(homebrewVersions)
|
Optional<File> latestOpt = Arrays.stream(homebrewVersions)
|
||||||
.map(ComparableVersion::new) // Convert file name to comparable version
|
.map(ComparableVersion::new) // Convert file name to comparable version
|
||||||
.sorted(Comparator.reverseOrder()) // Sort for latest version
|
.sorted(Comparator.reverseOrder()) // Sort for latest version
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ public final class Setting<T> {
|
|||||||
new SettingsRegistry.SettingKeys<>("advanced", "renderPath", null, "./replay_videos/");
|
new SettingsRegistry.SettingKeys<>("advanced", "renderPath", null, "./replay_videos/");
|
||||||
public static final SettingsRegistry.SettingKey<Boolean> SKIP_POST_RENDER_GUI =
|
public static final SettingsRegistry.SettingKey<Boolean> SKIP_POST_RENDER_GUI =
|
||||||
new SettingsRegistry.SettingKeys<>("advanced", "skipPostRenderGui", null, false);
|
new SettingsRegistry.SettingKeys<>("advanced", "skipPostRenderGui", null, false);
|
||||||
|
public static final SettingsRegistry.SettingKey<Boolean> FRAME_TIME_FROM_WORLD_TIME =
|
||||||
|
new SettingsRegistry.SettingKeys<>("render", "frameTimeFromWorldTime", null, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.replaymod.render.blend;
|
package com.replaymod.render.blend;
|
||||||
|
|
||||||
import com.replaymod.core.versions.MCVer;
|
|
||||||
import com.replaymod.render.capturer.RenderInfo;
|
import com.replaymod.render.capturer.RenderInfo;
|
||||||
import com.replaymod.render.capturer.WorldRenderer;
|
import com.replaymod.render.capturer.WorldRenderer;
|
||||||
import com.replaymod.render.frame.BitmapFrame;
|
import com.replaymod.render.frame.BitmapFrame;
|
||||||
@@ -8,6 +7,7 @@ import com.replaymod.render.rendering.Channel;
|
|||||||
import com.replaymod.render.rendering.FrameCapturer;
|
import com.replaymod.render.rendering.FrameCapturer;
|
||||||
import com.replaymod.render.utils.ByteBufferPool;
|
import com.replaymod.render.utils.ByteBufferPool;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -37,7 +37,7 @@ public class BlendFrameCapturer implements FrameCapturer<BitmapFrame> {
|
|||||||
renderInfo.updateForNextFrame();
|
renderInfo.updateForNextFrame();
|
||||||
|
|
||||||
BlendState.getState().preFrame(framesDone);
|
BlendState.getState().preFrame(framesDone);
|
||||||
worldRenderer.renderWorld(MCVer.getRenderPartialTicks(), null);
|
worldRenderer.renderWorld(MinecraftClient.getInstance().getTickDelta(), null);
|
||||||
BlendState.getState().postFrame(framesDone);
|
BlendState.getState().postFrame(framesDone);
|
||||||
|
|
||||||
BitmapFrame frame = new BitmapFrame(framesDone++, new Dimension(0, 0), 0, ByteBufferPool.allocate(0));
|
BitmapFrame frame = new BitmapFrame(framesDone++, new Dimension(0, 0), 0, ByteBufferPool.allocate(0));
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import de.johni0702.minecraft.gui.utils.lwjgl.vector.Vector3f;
|
|||||||
import net.minecraft.client.render.Tessellator;
|
import net.minecraft.client.render.Tessellator;
|
||||||
import net.minecraft.client.render.VertexFormat;
|
import net.minecraft.client.render.VertexFormat;
|
||||||
import net.minecraft.client.render.VertexFormatElement;
|
import net.minecraft.client.render.VertexFormatElement;
|
||||||
|
import net.minecraft.client.render.VertexFormats;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
//#if MC>=11500
|
//#if MC>=11500
|
||||||
@@ -62,7 +63,9 @@ public class BlendMeshBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
//#if MC>=10809
|
//#if MC>=11700
|
||||||
|
//$$ public void begin(VertexFormat.DrawMode mode, VertexFormat vertexFormat) {
|
||||||
|
//#elseif MC>=10809
|
||||||
public void begin(int mode, VertexFormat vertexFormat) {
|
public void begin(int mode, VertexFormat vertexFormat) {
|
||||||
//#else
|
//#else
|
||||||
//$$ public void startDrawing(int mode) {
|
//$$ public void startDrawing(int mode) {
|
||||||
@@ -82,7 +85,7 @@ public class BlendMeshBuilder
|
|||||||
|
|
||||||
if (!wellBehaved) {
|
if (!wellBehaved) {
|
||||||
// In case the calling code finishes with Tessellator.getInstance().draw()
|
// In case the calling code finishes with Tessellator.getInstance().draw()
|
||||||
BufferBuilder_beginPosTexCol(mode);
|
Tessellator.getInstance().getBuffer().begin(mode, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if MC>=10809
|
//#if MC>=10809
|
||||||
@@ -147,7 +150,17 @@ public class BlendMeshBuilder
|
|||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DMesh addBufferToMesh(ByteBuffer buffer, int mode, VertexFormat vertexFormat, DMesh mesh, ReadableVector3f vertOffset) {
|
public static DMesh addBufferToMesh(
|
||||||
|
ByteBuffer buffer,
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ VertexFormat.DrawMode mode,
|
||||||
|
//#else
|
||||||
|
int mode,
|
||||||
|
//#endif
|
||||||
|
VertexFormat vertexFormat,
|
||||||
|
DMesh mesh,
|
||||||
|
ReadableVector3f vertOffset
|
||||||
|
) {
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
int vertexCount = buffer.remaining() / vertexFormat.getVertexSize();
|
int vertexCount = buffer.remaining() / vertexFormat.getVertexSize();
|
||||||
//#else
|
//#else
|
||||||
@@ -156,7 +169,18 @@ public class BlendMeshBuilder
|
|||||||
return addBufferToMesh(buffer, vertexCount, mode, vertexFormat, mesh, vertOffset);
|
return addBufferToMesh(buffer, vertexCount, mode, vertexFormat, mesh, vertOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DMesh addBufferToMesh(ByteBuffer buffer, int vertexCount, int mode, VertexFormat vertexFormat, DMesh mesh, ReadableVector3f vertOffset) {
|
public static DMesh addBufferToMesh(
|
||||||
|
ByteBuffer buffer,
|
||||||
|
int vertexCount,
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ VertexFormat.DrawMode mode,
|
||||||
|
//#else
|
||||||
|
int mode,
|
||||||
|
//#endif
|
||||||
|
VertexFormat vertexFormat,
|
||||||
|
DMesh mesh,
|
||||||
|
ReadableVector3f vertOffset
|
||||||
|
) {
|
||||||
if (mesh == null) {
|
if (mesh == null) {
|
||||||
mesh = new DMesh();
|
mesh = new DMesh();
|
||||||
}
|
}
|
||||||
@@ -260,7 +284,11 @@ public class BlendMeshBuilder
|
|||||||
|
|
||||||
// Bundle vertices into shapes and add them to the mesh
|
// Bundle vertices into shapes and add them to the mesh
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ case TRIANGLES:
|
||||||
|
//#else
|
||||||
case GL11.GL_TRIANGLES:
|
case GL11.GL_TRIANGLES:
|
||||||
|
//#endif
|
||||||
for (int i = 0; i < vertices.size(); i+=3) {
|
for (int i = 0; i < vertices.size(); i+=3) {
|
||||||
mesh.addTriangle(
|
mesh.addTriangle(
|
||||||
vertices.get(i ),
|
vertices.get(i ),
|
||||||
@@ -276,7 +304,11 @@ public class BlendMeshBuilder
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
//#if MC>=11700
|
||||||
|
//$$ case QUADS:
|
||||||
|
//#else
|
||||||
case GL11.GL_QUADS:
|
case GL11.GL_QUADS:
|
||||||
|
//#endif
|
||||||
for (int i = 0; i < vertices.size(); i+=4) {
|
for (int i = 0; i < vertices.size(); i+=4) {
|
||||||
mesh.addQuad(
|
mesh.addQuad(
|
||||||
vertices.get(i ),
|
vertices.get(i ),
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class BlendState implements Exporter {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CrashReport report = CrashReport.create(e, "Setup of blend exporter");
|
CrashReport report = CrashReport.create(e, "Setup of blend exporter");
|
||||||
CrashReportSection category = report.addElement("Exporter");
|
CrashReportSection category = report.addElement("Exporter");
|
||||||
addDetail(category, "Exporter", exporter::toString);
|
category.add("Exporter", exporter::toString);
|
||||||
throw new CrashException(report);
|
throw new CrashException(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ public class BlendState implements Exporter {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CrashReport report = CrashReport.create(e, "Tear down of blend exporter");
|
CrashReport report = CrashReport.create(e, "Tear down of blend exporter");
|
||||||
CrashReportSection category = report.addElement("Exporter");
|
CrashReportSection category = report.addElement("Exporter");
|
||||||
addDetail(category, "Exporter", exporter::toString);
|
category.add("Exporter", exporter::toString);
|
||||||
throw new CrashException(report);
|
throw new CrashException(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,8 +139,8 @@ public class BlendState implements Exporter {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CrashReport report = CrashReport.create(e, "Pre frame of blend exporter");
|
CrashReport report = CrashReport.create(e, "Pre frame of blend exporter");
|
||||||
CrashReportSection category = report.addElement("Exporter");
|
CrashReportSection category = report.addElement("Exporter");
|
||||||
addDetail(category, "Exporter", exporter::toString);
|
category.add("Exporter", exporter::toString);
|
||||||
addDetail(category, "Frame", () -> String.valueOf(frame));
|
category.add("Frame", () -> String.valueOf(frame));
|
||||||
throw new CrashException(report);
|
throw new CrashException(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,8 +154,8 @@ public class BlendState implements Exporter {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CrashReport report = CrashReport.create(e, "Post frame of blend exporter");
|
CrashReport report = CrashReport.create(e, "Post frame of blend exporter");
|
||||||
CrashReportSection category = report.addElement("Exporter");
|
CrashReportSection category = report.addElement("Exporter");
|
||||||
addDetail(category, "Exporter", exporter::toString);
|
category.add("Exporter", exporter::toString);
|
||||||
addDetail(category, "Frame", () -> String.valueOf(frame));
|
category.add("Frame", () -> String.valueOf(frame));
|
||||||
throw new CrashException(report);
|
throw new CrashException(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class Util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FloatBuffer floatBuffer = GlAllocationUtils.allocateFloatBuffer(16);
|
private static FloatBuffer floatBuffer = GlAllocationUtils.allocateByteBuffer(16 * 4).asFloatBuffer();
|
||||||
public static Matrix4f getGlMatrix(int matrix) {
|
public static Matrix4f getGlMatrix(int matrix) {
|
||||||
floatBuffer.clear();
|
floatBuffer.clear();
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import net.minecraft.client.model.ModelPart;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
import static com.replaymod.render.blend.Util.isGlTextureMatrixIdentity;
|
import static com.replaymod.render.blend.Util.isGlTextureMatrixIdentity;
|
||||||
|
|
||||||
public class ModelRendererExporter implements Exporter {
|
public class ModelRendererExporter implements Exporter {
|
||||||
@@ -86,11 +85,13 @@ public class ModelRendererExporter implements Exporter {
|
|||||||
DMesh mesh = new DMesh();
|
DMesh mesh = new DMesh();
|
||||||
BlendMeshBuilder builder = new BlendMeshBuilder(mesh);
|
BlendMeshBuilder builder = new BlendMeshBuilder(mesh);
|
||||||
//#if MC>=11500
|
//#if MC>=11500
|
||||||
for (Cuboid box : cubeList(model)) {
|
// FIXME 1.15
|
||||||
// FIXME 1.15
|
//#elseif MC>=10809
|
||||||
}
|
//$$ for (Box box : model.boxes) {
|
||||||
|
//$$ box.render(builder, scale);
|
||||||
|
//$$ }
|
||||||
//#else
|
//#else
|
||||||
//$$ for (Box box : cubeList(model)) {
|
//$$ for (ModelBox box : (java.util.List<ModelBox>) model.cubeList) {
|
||||||
//$$ box.render(builder, scale);
|
//$$ box.render(builder, scale);
|
||||||
//$$ }
|
//$$ }
|
||||||
//#endif
|
//#endif
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.replaymod.render.blend.mixin.ParticleAccessor;
|
|||||||
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Matrix4f;
|
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Matrix4f;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Vector3f;
|
import de.johni0702.minecraft.gui.utils.lwjgl.vector.Vector3f;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -169,7 +170,7 @@ public class ParticlesExporter implements Exporter {
|
|||||||
builder.setReverseOffset(offset);
|
builder.setReverseOffset(offset);
|
||||||
builder.setWellBehaved(true);
|
builder.setWellBehaved(true);
|
||||||
//#if MC>=10809
|
//#if MC>=10809
|
||||||
builder.begin(7, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
builder.begin(GL11.GL_QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
||||||
//#else
|
//#else
|
||||||
//$$ builder.startDrawingQuads();
|
//$$ builder.startDrawingQuads();
|
||||||
//#endif
|
//#endif
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
//#if MC>=11600
|
||||||
|
package com.replaymod.render.capturer;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.replaymod.render.RenderSettings;
|
||||||
|
import com.replaymod.render.frame.CubicOpenGlFrame;
|
||||||
|
import com.replaymod.render.frame.ODSOpenGlFrame;
|
||||||
|
import com.replaymod.render.frame.OpenGlFrame;
|
||||||
|
import com.replaymod.render.rendering.Channel;
|
||||||
|
import com.replaymod.render.rendering.FrameCapturer;
|
||||||
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
|
import net.coderbot.iris.Iris;
|
||||||
|
import net.coderbot.iris.config.IrisConfig;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.replaymod.core.versions.MCVer.popMatrix;
|
||||||
|
import static com.replaymod.core.versions.MCVer.pushMatrix;
|
||||||
|
import static com.replaymod.core.versions.MCVer.resizeMainWindow;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||||
|
|
||||||
|
public class IrisODSFrameCapturer implements FrameCapturer<ODSOpenGlFrame> {
|
||||||
|
|
||||||
|
public static final String SHADER_PACK_NAME = "assets/replaymod/iris/ods";
|
||||||
|
public static IrisODSFrameCapturer INSTANCE;
|
||||||
|
private final CubicPboOpenGlFrameCapturer left, right;
|
||||||
|
private final String prevShaderPack;
|
||||||
|
private int direction;
|
||||||
|
private boolean isLeftEye;
|
||||||
|
|
||||||
|
public IrisODSFrameCapturer(WorldRenderer worldRenderer, final RenderInfo renderInfo, int frameSize) {
|
||||||
|
RenderInfo fakeInfo = new RenderInfo() {
|
||||||
|
private int call;
|
||||||
|
private float partialTicks;
|
||||||
|
@Override
|
||||||
|
public ReadableDimension getFrameSize() {
|
||||||
|
return renderInfo.getFrameSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFramesDone() {
|
||||||
|
return renderInfo.getFramesDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTotalFrames() {
|
||||||
|
return renderInfo.getTotalFrames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float updateForNextFrame() {
|
||||||
|
if (call++ % 2 == 0) {
|
||||||
|
partialTicks = renderInfo.updateForNextFrame();
|
||||||
|
}
|
||||||
|
return partialTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RenderSettings getRenderSettings() {
|
||||||
|
return renderInfo.getRenderSettings();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
left = new CubicStereoFrameCapturer(worldRenderer, fakeInfo, frameSize);
|
||||||
|
right = new CubicStereoFrameCapturer(worldRenderer, fakeInfo, frameSize);
|
||||||
|
|
||||||
|
INSTANCE = this;
|
||||||
|
prevShaderPack = Iris.getIrisConfig().getShaderPackName().orElse(null);
|
||||||
|
setShaderPack(SHADER_PACK_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setShaderPack(String name) {
|
||||||
|
IrisConfig irisConfig = Iris.getIrisConfig();
|
||||||
|
irisConfig.setShaderPackName(name);
|
||||||
|
try {
|
||||||
|
irisConfig.save();
|
||||||
|
Iris.reload();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLeftEye() {
|
||||||
|
return isLeftEye;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDone() {
|
||||||
|
return left.isDone() && right.isDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Channel, ODSOpenGlFrame> process() {
|
||||||
|
isLeftEye = true;
|
||||||
|
Map<Channel, CubicOpenGlFrame> leftChannels = left.process();
|
||||||
|
isLeftEye = false;
|
||||||
|
Map<Channel, CubicOpenGlFrame> rightChannels = right.process();
|
||||||
|
|
||||||
|
if (leftChannels != null && rightChannels != null) {
|
||||||
|
Map<Channel, ODSOpenGlFrame> result = new HashMap<>();
|
||||||
|
for (Channel channel : Channel.values()) {
|
||||||
|
CubicOpenGlFrame leftFrame = leftChannels.get(channel);
|
||||||
|
CubicOpenGlFrame rightFrame = rightChannels.get(channel);
|
||||||
|
if (leftFrame != null && rightFrame != null) {
|
||||||
|
result.put(channel, new ODSOpenGlFrame(leftFrame, rightFrame));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
left.close();
|
||||||
|
right.close();
|
||||||
|
INSTANCE = null;
|
||||||
|
setShaderPack(prevShaderPack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CubicStereoFrameCapturer extends CubicPboOpenGlFrameCapturer {
|
||||||
|
public CubicStereoFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo, int frameSize) {
|
||||||
|
super(worldRenderer, renderInfo, frameSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected OpenGlFrame renderFrame(int frameId, float partialTicks, CubicOpenGlFrameCapturer.Data captureData) {
|
||||||
|
resizeMainWindow(mc, getFrameWidth(), getFrameHeight());
|
||||||
|
|
||||||
|
pushMatrix();
|
||||||
|
frameBuffer().beginWrite(true);
|
||||||
|
|
||||||
|
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
||||||
|
//#if MC>=11400
|
||||||
|
, false
|
||||||
|
//#endif
|
||||||
|
);
|
||||||
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
|
direction = captureData.ordinal();
|
||||||
|
worldRenderer.renderWorld(partialTicks, null);
|
||||||
|
|
||||||
|
frameBuffer().endWrite();
|
||||||
|
popMatrix();
|
||||||
|
|
||||||
|
return captureFrame(frameId, captureData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.replaymod.render.capturer;
|
package com.replaymod.render.capturer;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.replaymod.render.rendering.Channel;
|
import com.replaymod.render.rendering.Channel;
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
||||||
import com.replaymod.render.RenderSettings;
|
import com.replaymod.render.RenderSettings;
|
||||||
@@ -15,12 +16,13 @@ import net.minecraft.util.crash.CrashReport;
|
|||||||
import net.minecraft.util.crash.CrashException;
|
import net.minecraft.util.crash.CrashException;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import static com.mojang.blaze3d.platform.GlStateManager.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.replaymod.core.versions.MCVer.popMatrix;
|
||||||
|
import static com.replaymod.core.versions.MCVer.pushMatrix;
|
||||||
|
import static com.replaymod.core.versions.MCVer.resizeMainWindow;
|
||||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||||
|
|
||||||
@@ -164,17 +166,17 @@ public class ODSFrameCapturer implements FrameCapturer<ODSOpenGlFrame> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OpenGlFrame renderFrame(int frameId, float partialTicks, CubicOpenGlFrameCapturer.Data captureData) {
|
protected OpenGlFrame renderFrame(int frameId, float partialTicks, CubicOpenGlFrameCapturer.Data captureData) {
|
||||||
resize(getFrameWidth(), getFrameHeight());
|
resizeMainWindow(mc, getFrameWidth(), getFrameHeight());
|
||||||
|
|
||||||
pushMatrix();
|
pushMatrix();
|
||||||
frameBuffer().beginWrite(true);
|
frameBuffer().beginWrite(true);
|
||||||
|
|
||||||
clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
, false
|
, false
|
||||||
//#endif
|
//#endif
|
||||||
);
|
);
|
||||||
enableTexture();
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
directionVariable.set(captureData.ordinal());
|
directionVariable.set(captureData.ordinal());
|
||||||
worldRenderer.renderWorld(partialTicks, null);
|
worldRenderer.renderWorld(partialTicks, null);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.replaymod.render.capturer;
|
package com.replaymod.render.capturer;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.render.frame.OpenGlFrame;
|
import com.replaymod.render.frame.OpenGlFrame;
|
||||||
import com.replaymod.render.rendering.Frame;
|
import com.replaymod.render.rendering.Frame;
|
||||||
@@ -16,17 +17,9 @@ import org.lwjgl.opengl.GL12;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
//#if MC>=11400
|
import static com.replaymod.core.versions.MCVer.popMatrix;
|
||||||
import com.replaymod.render.mixin.MainWindowAccessor;
|
import static com.replaymod.core.versions.MCVer.pushMatrix;
|
||||||
import static com.replaymod.core.versions.MCVer.getWindow;
|
import static com.replaymod.core.versions.MCVer.resizeMainWindow;
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=10800
|
|
||||||
import static com.mojang.blaze3d.platform.GlStateManager.*;
|
|
||||||
//#else
|
|
||||||
//$$ import static com.replaymod.core.versions.MCVer.GlStateManager.*;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||||
|
|
||||||
@@ -36,7 +29,7 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
|||||||
protected int framesDone;
|
protected int framesDone;
|
||||||
private Framebuffer frameBuffer;
|
private Framebuffer frameBuffer;
|
||||||
|
|
||||||
private final MinecraftClient mc = MCVer.getMinecraft();
|
protected final MinecraftClient mc = MCVer.getMinecraft();
|
||||||
|
|
||||||
public OpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
public OpenGlFrameCapturer(WorldRenderer worldRenderer, RenderInfo renderInfo) {
|
||||||
this.worldRenderer = worldRenderer;
|
this.worldRenderer = worldRenderer;
|
||||||
@@ -85,17 +78,17 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected OpenGlFrame renderFrame(int frameId, float partialTicks, D captureData) {
|
protected OpenGlFrame renderFrame(int frameId, float partialTicks, D captureData) {
|
||||||
resize(getFrameWidth(), getFrameHeight());
|
resizeMainWindow(mc, getFrameWidth(), getFrameHeight());
|
||||||
|
|
||||||
pushMatrix();
|
pushMatrix();
|
||||||
frameBuffer().beginWrite(true);
|
frameBuffer().beginWrite(true);
|
||||||
|
|
||||||
clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
GlStateManager.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
, false
|
, false
|
||||||
//#endif
|
//#endif
|
||||||
);
|
);
|
||||||
enableTexture();
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
worldRenderer.renderWorld(partialTicks, captureData);
|
worldRenderer.renderWorld(partialTicks, captureData);
|
||||||
|
|
||||||
@@ -115,30 +108,6 @@ public abstract class OpenGlFrameCapturer<F extends Frame, D extends CaptureData
|
|||||||
return new OpenGlFrame(frameId, new Dimension(getFrameWidth(), getFrameHeight()), 4, buffer);
|
return new OpenGlFrame(frameId, new Dimension(getFrameWidth(), getFrameHeight()), 4, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resize(int width, int height) {
|
|
||||||
//#if MC>=11400
|
|
||||||
Framebuffer fb = mc.getFramebuffer();
|
|
||||||
if (fb.viewportWidth != width || fb.viewportHeight != height) {
|
|
||||||
fb.resize(width, height
|
|
||||||
//#if MC>=11400
|
|
||||||
, false
|
|
||||||
//#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
MainWindowAccessor mainWindow = (MainWindowAccessor) (Object) getWindow(mc);
|
|
||||||
mainWindow.setFramebufferWidth(width);
|
|
||||||
mainWindow.setFramebufferHeight(height);
|
|
||||||
//#if MC>=11500
|
|
||||||
mc.gameRenderer.onResized(width, height);
|
|
||||||
//#endif
|
|
||||||
//#else
|
|
||||||
//$$ if (width != mc.displayWidth || height != mc.displayHeight) {
|
|
||||||
//$$ mc.resize(width, height);
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import net.minecraft.util.crash.CrashException;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.addDetail;
|
|
||||||
import static com.replaymod.render.ReplayModRender.LOGGER;
|
import static com.replaymod.render.ReplayModRender.LOGGER;
|
||||||
|
|
||||||
public class GuiExportFailed extends GuiScreen {
|
public class GuiExportFailed extends GuiScreen {
|
||||||
@@ -33,8 +32,8 @@ public class GuiExportFailed extends GuiScreen {
|
|||||||
// If they haven't, then this is probably a faulty ffmpeg installation and there's nothing we can do
|
// If they haven't, then this is probably a faulty ffmpeg installation and there's nothing we can do
|
||||||
CrashReport crashReport = CrashReport.create(e, "Exporting video");
|
CrashReport crashReport = CrashReport.create(e, "Exporting video");
|
||||||
CrashReportSection details = crashReport.addElement("Export details");
|
CrashReportSection details = crashReport.addElement("Export details");
|
||||||
addDetail(details, "Settings", settings::toString);
|
details.add("Settings", settings::toString);
|
||||||
addDetail(details, "FFmpeg log", e::getLog);
|
details.add("FFmpeg log", e::getLog);
|
||||||
throw new CrashException(crashReport);
|
throw new CrashException(crashReport);
|
||||||
} else {
|
} else {
|
||||||
// If they have, ask them whether it was intentional
|
// If they have, ask them whether it was intentional
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.replaymod.render.gui;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.replaymod.core.ReplayMod;
|
import com.replaymod.core.ReplayMod;
|
||||||
|
import com.replaymod.core.utils.Result;
|
||||||
import com.replaymod.core.utils.Utils;
|
import com.replaymod.core.utils.Utils;
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.render.RenderSettings;
|
import com.replaymod.render.RenderSettings;
|
||||||
@@ -14,7 +15,6 @@ import com.replaymod.replay.ReplayModReplay;
|
|||||||
import com.replaymod.replay.ReplaySender;
|
import com.replaymod.replay.ReplaySender;
|
||||||
import com.replaymod.replaystudio.pathing.path.Timeline;
|
import com.replaymod.replaystudio.pathing.path.Timeline;
|
||||||
import com.replaymod.replaystudio.replay.ReplayFile;
|
import com.replaymod.replaystudio.replay.ReplayFile;
|
||||||
import com.replaymod.replaystudio.us.myles.ViaVersion.api.Pair;
|
|
||||||
import de.johni0702.minecraft.gui.GuiRenderer;
|
import de.johni0702.minecraft.gui.GuiRenderer;
|
||||||
import de.johni0702.minecraft.gui.RenderInfo;
|
import de.johni0702.minecraft.gui.RenderInfo;
|
||||||
import de.johni0702.minecraft.gui.container.AbstractGuiClickableContainer;
|
import de.johni0702.minecraft.gui.container.AbstractGuiClickableContainer;
|
||||||
@@ -31,6 +31,7 @@ import de.johni0702.minecraft.gui.layout.CustomLayout;
|
|||||||
import de.johni0702.minecraft.gui.layout.GridLayout;
|
import de.johni0702.minecraft.gui.layout.GridLayout;
|
||||||
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
import de.johni0702.minecraft.gui.layout.HorizontalLayout;
|
||||||
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
|
import de.johni0702.minecraft.gui.popup.AbstractGuiPopup;
|
||||||
|
import de.johni0702.minecraft.gui.popup.GuiInfoPopup;
|
||||||
import de.johni0702.minecraft.gui.utils.Colors;
|
import de.johni0702.minecraft.gui.utils.Colors;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.Dimension;
|
||||||
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
import de.johni0702.minecraft.gui.utils.lwjgl.ReadableDimension;
|
||||||
@@ -39,6 +40,7 @@ import net.minecraft.client.MinecraftClient;
|
|||||||
import net.minecraft.client.gui.screen.NoticeScreen;
|
import net.minecraft.client.gui.screen.NoticeScreen;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -88,7 +90,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
private final AbstractGuiScreen<?> container;
|
private final AbstractGuiScreen<?> container;
|
||||||
private final ReplayHandler replayHandler;
|
private final ReplayHandler replayHandler;
|
||||||
private final Set<Entry> selectedEntries = new HashSet<>();
|
private final Set<Entry> selectedEntries = new HashSet<>();
|
||||||
private final Supplier<Timeline> timelineSupplier;
|
private final Supplier<Result<Timeline, String[]>> timelineSupplier;
|
||||||
private boolean opened;
|
private boolean opened;
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -113,7 +115,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
private final ReplayModRender mod = ReplayModRender.instance;
|
private final ReplayModRender mod = ReplayModRender.instance;
|
||||||
private final List<RenderJob> jobs = mod.getRenderQueue();
|
private final List<RenderJob> jobs = mod.getRenderQueue();
|
||||||
|
|
||||||
public GuiRenderQueue(AbstractGuiScreen<?> container, ReplayHandler replayHandler, Supplier<Timeline> timelineSupplier) {
|
public GuiRenderQueue(AbstractGuiScreen<?> container, ReplayHandler replayHandler, Supplier<Result<Timeline, String[]>> timelineSupplier) {
|
||||||
super(container);
|
super(container);
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.replayHandler = replayHandler;
|
this.replayHandler = replayHandler;
|
||||||
@@ -127,7 +129,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
list.getListPanel().addElements(null, new Entry(renderJob));
|
list.getListPanel().addElements(null, new Entry(renderJob));
|
||||||
}
|
}
|
||||||
|
|
||||||
addButton.onClick(this::addButtonClicked);
|
addButton.onClick(() -> addButtonClicked().ifErr(lines -> GuiInfoPopup.open(container, lines)));
|
||||||
|
|
||||||
editButton.onClick(() -> {
|
editButton.onClick(() -> {
|
||||||
Entry job = selectedEntries.iterator().next();
|
Entry job = selectedEntries.iterator().next();
|
||||||
@@ -267,15 +269,12 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private GuiRenderSettings addButtonClicked() {
|
private Result<GuiRenderSettings, String[]> addButtonClicked() {
|
||||||
Timeline timeline = timelineSupplier.get();
|
return timelineSupplier.get().mapOk(timeline -> {
|
||||||
if (timeline != null) {
|
|
||||||
GuiRenderSettings popup = addJob(timeline);
|
GuiRenderSettings popup = addJob(timeline);
|
||||||
popup.open();
|
popup.open();
|
||||||
return popup;
|
return popup;
|
||||||
} else {
|
});
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GuiRenderSettings addJob(Timeline timeline) {
|
public GuiRenderSettings addJob(Timeline timeline) {
|
||||||
@@ -317,9 +316,8 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
@Override
|
@Override
|
||||||
public void open() {
|
public void open() {
|
||||||
if (jobs.isEmpty() && timelineSupplier != null) {
|
if (jobs.isEmpty() && timelineSupplier != null) {
|
||||||
if (addButtonClicked() == null) {
|
addButtonClicked().ifErr(lines ->
|
||||||
close();
|
GuiInfoPopup.open(container, lines).onClosed(this::close));
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +346,7 @@ public class GuiRenderQueue extends AbstractGuiPopup<GuiRenderQueue> implements
|
|||||||
renderButton.setEnabled(jobs.size() > 0);
|
renderButton.setEnabled(jobs.size() > 0);
|
||||||
renderButton.setI18nLabel("replaymod.gui.renderqueue.render" + (selected > 0 ? "selected" : "all"));
|
renderButton.setI18nLabel("replaymod.gui.renderqueue.render" + (selected > 0 ? "selected" : "all"));
|
||||||
|
|
||||||
String[] compatError = VideoRenderer.checkCompat();
|
String[] compatError = VideoRenderer.checkCompat(jobs.stream().map(RenderJob::getSettings));
|
||||||
if (compatError != null) {
|
if (compatError != null) {
|
||||||
renderButton.setDisabled().setTooltip(new GuiTooltip().setText(compatError));
|
renderButton.setDisabled().setTooltip(new GuiTooltip().setText(compatError));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.replaymod.render.gui;
|
package com.replaymod.render.gui;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.InstanceCreator;
|
import com.google.gson.InstanceCreator;
|
||||||
@@ -39,7 +37,6 @@ import net.minecraft.client.gui.screen.NoticeScreen;
|
|||||||
import net.minecraft.client.resource.language.I18n;
|
import net.minecraft.client.resource.language.I18n;
|
||||||
import net.minecraft.util.crash.CrashReport;
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -73,7 +70,7 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
if (renderMethodDropdown.getSelectedValue() == RenderSettings.RenderMethod.BLEND) {
|
if (renderMethodDropdown.getSelectedValue() == RenderSettings.RenderMethod.BLEND) {
|
||||||
encodingPresetDropdown.setSelected(RenderSettings.EncodingPreset.BLEND);
|
encodingPresetDropdown.setSelected(RenderSettings.EncodingPreset.BLEND);
|
||||||
} else {
|
} else {
|
||||||
encodingPresetDropdown.setSelected(RenderSettings.EncodingPreset.MP4_DEFAULT);
|
encodingPresetDropdown.setSelected(RenderSettings.EncodingPreset.MP4_CUSTOM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateInputs();
|
updateInputs();
|
||||||
@@ -131,25 +128,13 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
encodingPresetDropdown.getSelectedValue().getFileExtension());
|
encodingPresetDropdown.getSelectedValue().getFileExtension());
|
||||||
popup.setFolder(getParentFile(outputFile));
|
popup.setFolder(getParentFile(outputFile));
|
||||||
popup.setFileName(outputFile.getName());
|
popup.setFileName(outputFile.getName());
|
||||||
Futures.addCallback(
|
popup.onAccept(file -> {
|
||||||
popup.getFuture(),
|
if (!file.getName().equals(outputFile.getName())) {
|
||||||
new FutureCallback<File>() {
|
userDefinedOutputFileName = true;
|
||||||
@Override
|
}
|
||||||
public void onSuccess(@Nullable File result) {
|
outputFile = file;
|
||||||
if (result != null) {
|
outputFileButton.setLabel(file.getName());
|
||||||
if (!result.getName().equals(outputFile.getName())) {
|
});
|
||||||
userDefinedOutputFileName = true;
|
|
||||||
}
|
|
||||||
outputFile = result;
|
|
||||||
outputFileButton.setLabel(result.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable t) {
|
|
||||||
throw new RuntimeException(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -378,7 +363,7 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
videoHeight.setTextColor(Colors.RED);
|
videoHeight.setTextColor(Colors.RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] compatError = VideoRenderer.checkCompat();
|
String[] compatError = VideoRenderer.checkCompat(save(false));
|
||||||
if (resolutionError != null) {
|
if (resolutionError != null) {
|
||||||
renderButton.setDisabled().setTooltip(new GuiTooltip().setI18nText(resolutionError));
|
renderButton.setDisabled().setTooltip(new GuiTooltip().setI18nText(resolutionError));
|
||||||
} else if (compatError != null) {
|
} else if (compatError != null) {
|
||||||
@@ -401,10 +386,10 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
case CUBIC:
|
case CUBIC:
|
||||||
case EQUIRECTANGULAR:
|
case EQUIRECTANGULAR:
|
||||||
case ODS:
|
case ODS:
|
||||||
stabilizePanel.forEach(IGuiCheckbox.class).setEnabled();
|
stabilizePanel.invokeAll(IGuiCheckbox.class, GuiElement::setEnabled);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
stabilizePanel.forEach(IGuiCheckbox.class).setDisabled();
|
stabilizePanel.invokeAll(IGuiCheckbox.class, GuiElement::setDisabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable/Disable Spherical FOV slider
|
// Enable/Disable Spherical FOV slider
|
||||||
@@ -421,8 +406,9 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
|
|
||||||
// Enable/Disable various options for blend export
|
// Enable/Disable various options for blend export
|
||||||
boolean isEXR = encodingPresetDropdown.getSelectedValue() == RenderSettings.EncodingPreset.EXR;
|
boolean isEXR = encodingPresetDropdown.getSelectedValue() == RenderSettings.EncodingPreset.EXR;
|
||||||
|
boolean isPNG = encodingPresetDropdown.getSelectedValue() == RenderSettings.EncodingPreset.PNG;
|
||||||
boolean isBlend = renderMethod == RenderSettings.RenderMethod.BLEND;
|
boolean isBlend = renderMethod == RenderSettings.RenderMethod.BLEND;
|
||||||
boolean isFFmpeg = !isBlend && !isEXR;
|
boolean isFFmpeg = !isBlend && !isEXR && !isPNG;
|
||||||
if (isBlend) {
|
if (isBlend) {
|
||||||
videoWidth.setDisabled();
|
videoWidth.setDisabled();
|
||||||
videoHeight.setDisabled();
|
videoHeight.setDisabled();
|
||||||
@@ -432,11 +418,11 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
exportArguments.setEnabled(isFFmpeg);
|
exportArguments.setEnabled(isFFmpeg);
|
||||||
antiAliasingDropdown.setEnabled(isFFmpeg);
|
antiAliasingDropdown.setEnabled(isFFmpeg);
|
||||||
|
|
||||||
if (isEXR) {
|
if (isEXR || isPNG) {
|
||||||
depthMap.setEnabled().setTooltip(null);
|
depthMap.setEnabled().setTooltip(null);
|
||||||
} else {
|
} else {
|
||||||
depthMap.setDisabled().setTooltip(new GuiTooltip().setColor(Colors.RED)
|
depthMap.setDisabled().setTooltip(new GuiTooltip().setColor(Colors.RED)
|
||||||
.setI18nText("replaymod.gui.rendersettings.depthmap.onlyexr"));
|
.setI18nText("replaymod.gui.rendersettings.depthmap.only_exr_or_png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable/Disable export args reset button
|
// Enable/Disable export args reset button
|
||||||
@@ -520,7 +506,8 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
}
|
}
|
||||||
RenderSettings.EncodingPreset encodingPreset = settings.getEncodingPreset();
|
RenderSettings.EncodingPreset encodingPreset = settings.getEncodingPreset();
|
||||||
/* encodingPreset can be null from a previously supported and later removed preset */
|
/* encodingPreset can be null from a previously supported and later removed preset */
|
||||||
if (encodingPreset == null || !encodingPreset.isSupported()) {
|
boolean invalidEncodingPreset = encodingPreset == null || !encodingPreset.isSupported();
|
||||||
|
if (invalidEncodingPreset) {
|
||||||
encodingPreset = getDefaultRenderSettings().getEncodingPreset();
|
encodingPreset = getDefaultRenderSettings().getEncodingPreset();
|
||||||
}
|
}
|
||||||
encodingPresetDropdown.setSelected(encodingPreset);
|
encodingPresetDropdown.setSelected(encodingPreset);
|
||||||
@@ -569,7 +556,7 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
antiAliasingDropdown.setSelected(settings.getAntiAliasing());
|
antiAliasingDropdown.setSelected(settings.getAntiAliasing());
|
||||||
exportCommand.setText(settings.getExportCommand());
|
exportCommand.setText(settings.getExportCommand());
|
||||||
String exportArguments = settings.getExportArguments();
|
String exportArguments = settings.getExportArguments();
|
||||||
if (exportArguments == null || settings.getEncodingPreset() == null) {
|
if (exportArguments == null || settings.getEncodingPreset() == null || invalidEncodingPreset) {
|
||||||
// backwards compat, see RenderSettings#exportArguments
|
// backwards compat, see RenderSettings#exportArguments
|
||||||
exportArguments = encodingPreset.getValue();
|
exportArguments = encodingPreset.getValue();
|
||||||
}
|
}
|
||||||
@@ -642,8 +629,8 @@ public class GuiRenderSettings extends AbstractGuiPopup<GuiRenderSettings> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private RenderSettings getDefaultRenderSettings() {
|
private RenderSettings getDefaultRenderSettings() {
|
||||||
return new RenderSettings(RenderSettings.RenderMethod.DEFAULT, RenderSettings.EncodingPreset.MP4_DEFAULT, 1920, 1080, 60, 10 << 20, null,
|
return new RenderSettings(RenderSettings.RenderMethod.DEFAULT, RenderSettings.EncodingPreset.MP4_CUSTOM, 1920, 1080, 60, 20 << 20, null,
|
||||||
true, false, false, false, null, 360, 180, false, false, false, RenderSettings.AntiAliasing.NONE, "", RenderSettings.EncodingPreset.MP4_DEFAULT.getValue(), false);
|
true, false, false, false, null, 360, 180, false, false, false, RenderSettings.AntiAliasing.NONE, "", RenderSettings.EncodingPreset.MP4_CUSTOM.getValue(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user